mirror of https://github.com/contiki-ng/mspsim
added improved support for Z1/2xxx platform
This commit is contained in:
parent
d7a36abbfb
commit
6ab1eadb97
|
|
@ -0,0 +1,2 @@
|
|||
*.class
|
||||
.DS_Store
|
||||
|
|
@ -141,7 +141,7 @@ public abstract class AT45DB extends Chip implements USARTListener {
|
|||
status &= ~STATUS_RDY;
|
||||
}
|
||||
|
||||
public void dataReceived(USART source, int data) {
|
||||
public void dataReceived(USARTSource source, int data) {
|
||||
int buf_num = 1;
|
||||
|
||||
if (chipSelect) {
|
||||
|
|
|
|||
|
|
@ -715,7 +715,7 @@ public class CC2420 extends Chip implements USARTListener, RFListener, RFSource
|
|||
configurationChanged(address, oldValue, data);
|
||||
}
|
||||
|
||||
public void dataReceived(USART source, int data) {
|
||||
public void dataReceived(USARTSource source, int data) {
|
||||
int oldStatus = status;
|
||||
if (DEBUG) {
|
||||
log("byte received: " + Utils.hex8(data) +
|
||||
|
|
@ -880,6 +880,10 @@ public class CC2420 extends Chip implements USARTListener, RFListener, RFSource
|
|||
break;
|
||||
}
|
||||
source.byteReceived(oldStatus);
|
||||
} else {
|
||||
/* No VREG but chip select */
|
||||
if (chipSelect) source.byteReceived(0);
|
||||
System.out.println("**** Warning - writing to CC2420 when VREG is off!!!");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1268,7 +1272,8 @@ public class CC2420 extends Chip implements USARTListener, RFListener, RFSource
|
|||
|
||||
if(newOn) {
|
||||
// 0.6ms maximum vreg startup from datasheet pg 13
|
||||
cpu.scheduleTimeEventMillis(vregEvent, 0.1);
|
||||
// but Z1 platform does not work with 0.1 so trying with lower...
|
||||
cpu.scheduleTimeEventMillis(vregEvent, 0.05);
|
||||
if (DEBUG) log("Scheduling vregEvent at: cyc = " + cpu.cycles +
|
||||
" target: " + vregEvent.getTime() + " current: " + cpu.getTime());
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ public abstract class M25P80 extends Chip implements USARTListener, PortListener
|
|||
public void stateChanged(int state) {
|
||||
}
|
||||
|
||||
public void dataReceived(USART source, int data) {
|
||||
public void dataReceived(USARTSource source, int data) {
|
||||
if (chipSelect) {
|
||||
if (DEBUG) {
|
||||
log("byte received: " + data);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ import se.sics.mspsim.core.Chip;
|
|||
import se.sics.mspsim.core.MSP430Core;
|
||||
import se.sics.mspsim.core.USART;
|
||||
import se.sics.mspsim.core.USARTListener;
|
||||
import se.sics.mspsim.core.USARTSource;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -66,7 +67,7 @@ public class TR1001 extends Chip implements RFListener, RFSource {
|
|||
setMode(MODE_TXRX_OFF);
|
||||
usart.setUSARTListener(new USARTListener() {
|
||||
|
||||
public void dataReceived(USART source, int data) {
|
||||
public void dataReceived(USARTSource source, int data) {
|
||||
RFListener listener = rfListener;
|
||||
if (getMode() != MODE_TXRX_ON) {
|
||||
// Radio is turned off during transmission
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
package se.sics.mspsim.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import se.sics.mspsim.core.DMA;
|
||||
import se.sics.mspsim.core.IOUnit;
|
||||
import se.sics.mspsim.core.InterruptMultiplexer;
|
||||
|
|
@ -56,7 +57,7 @@ public class MSP430f1611Config extends MSP430Config {
|
|||
}
|
||||
|
||||
|
||||
public int setup(MSP430Core cpu, IOUnit[] ioUnits, int ioPos) {
|
||||
public int setup(MSP430Core cpu, ArrayList<IOUnit> ioUnits) {
|
||||
System.out.println("*** Setting up f1611 IO!");
|
||||
|
||||
USART usart0 = new USART(cpu, 0, cpu.memory, 0x70);
|
||||
|
|
@ -71,8 +72,8 @@ public class MSP430f1611Config extends MSP430Config {
|
|||
}
|
||||
|
||||
// Usarts
|
||||
ioUnits[ioPos] = usart0;
|
||||
ioUnits[ioPos + 1] = usart1;
|
||||
ioUnits.add(usart0);
|
||||
ioUnits.add(usart1);
|
||||
|
||||
DMA dma = new DMA("dma", cpu.memory, 0, cpu);
|
||||
for (int i = 0, n = 24; i < n; i++) {
|
||||
|
|
@ -91,7 +92,7 @@ public class MSP430f1611Config extends MSP430Config {
|
|||
dma.setDMATrigger(DMA.UTXIFG1, usart1, 1);
|
||||
dma.setInterruptMultiplexer(new InterruptMultiplexer(cpu, 0));
|
||||
|
||||
ioUnits[ioPos + 2] = dma;
|
||||
ioUnits.add(dma);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,10 +35,12 @@
|
|||
|
||||
package se.sics.mspsim.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import se.sics.mspsim.core.IOUnit;
|
||||
import se.sics.mspsim.core.MSP430Config;
|
||||
import se.sics.mspsim.core.MSP430Core;
|
||||
import se.sics.mspsim.core.Timer;
|
||||
import se.sics.mspsim.core.USCI;
|
||||
|
||||
public class MSP430f2617Config extends MSP430Config {
|
||||
|
||||
|
|
@ -52,10 +54,46 @@ public class MSP430f2617Config extends MSP430Config {
|
|||
TimerConfig timerA = new TimerConfig(25, 24, 3, 0x160, Timer.TIMER_Ax149, "TimerA");
|
||||
TimerConfig timerB = new TimerConfig(29, 28, 7, 0x180, Timer.TIMER_Bx149, "TimerB");
|
||||
timerConfig = new TimerConfig[] {timerA, timerB};
|
||||
|
||||
/* TX Vec, RX Vec, TX Bit, RX Bit, SFR-reg, Offset, Name, A?*/
|
||||
UARTConfig uA0 = new UARTConfig(22, 23, 1, 0, 1, 0x60, "USCI A0", true);
|
||||
UARTConfig uB0 = new UARTConfig(22, 23, 3, 2, 1, 0x60, "USCI B0", false);
|
||||
UARTConfig uA1 = new UARTConfig(16, 17, 1, 0, 6, 0xD0, "USCI A1", true);
|
||||
UARTConfig uB1 = new UARTConfig(16, 17, 3, 2, 6, 0xD0, "USCI B1", false);
|
||||
uartConfig = new UARTConfig[] {uA0, uB0, uA1, uB1};
|
||||
}
|
||||
|
||||
public int setup(MSP430Core cpu, IOUnit[] ioUnits, int ioPos) {
|
||||
return 0;
|
||||
public int setup(MSP430Core cpu, ArrayList<IOUnit> ioUnits) {
|
||||
USCI usciA0 = new USCI(cpu, 0, cpu.memory, this);
|
||||
USCI usciB0 = new USCI(cpu, 1, cpu.memory, this);
|
||||
USCI usciA1 = new USCI(cpu, 2, cpu.memory, this);
|
||||
USCI usciB1 = new USCI(cpu, 3, cpu.memory, this);
|
||||
|
||||
for (int i = 0, n = 8; i < n; i++) {
|
||||
cpu.memOut[0x60 + i] = usciA0;
|
||||
cpu.memIn[0x60 + i] = usciA0;
|
||||
cpu.memOut[0x68 + i] = usciB0;
|
||||
cpu.memIn[0x68 + i] = usciB0;
|
||||
|
||||
cpu.memOut[0xd0 + i] = usciA1;
|
||||
cpu.memIn[0xd0 + i] = usciA1;
|
||||
cpu.memOut[0xd8 + i] = usciB1;
|
||||
cpu.memIn[0xd8 + i] = usciB1;
|
||||
}
|
||||
|
||||
ioUnits.add(usciA0);
|
||||
ioUnits.add(usciB0);
|
||||
ioUnits.add(usciA1);
|
||||
ioUnits.add(usciB1);
|
||||
|
||||
/* usciA1 handles interrupts for both usciA1 and B1 */
|
||||
cpu.memOut[6] = usciA1;
|
||||
cpu.memIn[6] = usciA1;
|
||||
cpu.memOut[7] = usciA1;
|
||||
cpu.memIn[7] = usciA1;
|
||||
|
||||
/* 4 usci units */
|
||||
return 4;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
package se.sics.mspsim.core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public abstract class MSP430Config {
|
||||
|
||||
public class TimerConfig {
|
||||
|
|
@ -21,13 +23,40 @@ public abstract class MSP430Config {
|
|||
}
|
||||
}
|
||||
|
||||
public class UARTConfig {
|
||||
int txVector;
|
||||
int rxVector;
|
||||
int offset;
|
||||
String name;
|
||||
int txBit;
|
||||
int rxBit;
|
||||
int sfrAddr;
|
||||
boolean usciA;
|
||||
|
||||
public UARTConfig(int txVector, int rxVector, int txBit, int rxBit, int sftAddr, int offset,
|
||||
String name, boolean usciA) {
|
||||
this.txVector = txVector;
|
||||
this.rxVector = rxVector;
|
||||
this.txBit = txBit;
|
||||
this.rxBit = rxBit;
|
||||
this.offset = offset;
|
||||
this.name = name;
|
||||
this.usciA = usciA;
|
||||
this.sfrAddr = sftAddr;
|
||||
}
|
||||
}
|
||||
|
||||
public UARTConfig[] uartConfig;
|
||||
|
||||
/* default for the 149/1611 */
|
||||
public TimerConfig[] timerConfig = {
|
||||
new TimerConfig(6, 5, 3, 0x160, Timer.TIMER_Ax149, "TimerA"),
|
||||
new TimerConfig(13, 12, 7, 0x180, Timer.TIMER_Bx149, "TimerB")
|
||||
};
|
||||
|
||||
public int maxMemIO = 0x200;
|
||||
public int maxInterruptVector = 15;
|
||||
public boolean MSP430XArch = false;
|
||||
|
||||
public abstract int setup(MSP430Core cpu, IOUnit[] ioUnits, int ioPos);
|
||||
public abstract int setup(MSP430Core cpu, ArrayList<IOUnit> ioUnits);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ public class MSP430Core extends Chip implements MSP430Constants {
|
|||
|
||||
// Try it out with 64 k memory
|
||||
public static final int MAX_MEM = 64*1024;
|
||||
public static final int MAX_MEM_IO = 0x200;
|
||||
public final int MAX_MEM_IO;
|
||||
public static final int PORTS = 6;
|
||||
|
||||
// 16 registers of which some are "special" - PC, SP, etc.
|
||||
|
|
@ -86,11 +86,11 @@ public class MSP430Core extends Chip implements MSP430Constants {
|
|||
|
||||
// Most HW needs only notify write and clocking, others need also read...
|
||||
// For notify write...
|
||||
public IOUnit[] memOut = new IOUnit[MAX_MEM_IO];
|
||||
public IOUnit[] memOut;
|
||||
// For notify read... -> which will happen before actual read!
|
||||
public IOUnit[] memIn = new IOUnit[MAX_MEM_IO];
|
||||
public IOUnit[] memIn;
|
||||
|
||||
private IOUnit[] ioUnits;
|
||||
private ArrayList<IOUnit> ioUnits;
|
||||
private SFR sfr;
|
||||
private Watchdog watchdog;
|
||||
|
||||
|
|
@ -142,6 +142,9 @@ public class MSP430Core extends Chip implements MSP430Constants {
|
|||
public MSP430Core(int type, ComponentRegistry registry, MSP430Config config) {
|
||||
super("MSP430", "MSP430 Core", null);
|
||||
MAX_INTERRUPT = config.maxInterruptVector;
|
||||
MAX_MEM_IO = config.maxMemIO;
|
||||
memOut = new IOUnit[MAX_MEM_IO];
|
||||
memIn = new IOUnit[MAX_MEM_IO];
|
||||
this.registry = registry;
|
||||
this.config = config;
|
||||
// The CPU need to register itself as chip
|
||||
|
|
@ -149,10 +152,9 @@ public class MSP430Core extends Chip implements MSP430Constants {
|
|||
|
||||
// Ignore type for now...
|
||||
setModeNames(MODE_NAMES);
|
||||
int passIO = 0;
|
||||
// IOUnits should likely be placed in a hashtable?
|
||||
// Maybe for debugging purposes...
|
||||
ioUnits = new IOUnit[PORTS + 9];
|
||||
ioUnits = new ArrayList<IOUnit>();
|
||||
|
||||
// first step towards making core configurable
|
||||
Timer ta = new Timer(this, memory, config.timerConfig[0]);
|
||||
|
|
@ -201,44 +203,45 @@ public class MSP430Core extends Chip implements MSP430Constants {
|
|||
|
||||
|
||||
// Add port 1,2 with interrupt capability!
|
||||
ioUnits[0] = new IOPort(this, 1, 4, memory, 0x20);
|
||||
ioUnits[1] = new IOPort(this, 2, 1, memory, 0x28);
|
||||
ioUnits.add(new IOPort(this, 1, 4, memory, 0x20));
|
||||
ioUnits.add(new IOPort(this, 2, 1, memory, 0x28));
|
||||
for (int i = 0, n = 8; i < n; i++) {
|
||||
memOut[0x20 + i] = ioUnits[0];
|
||||
memOut[0x28 + i] = ioUnits[1];
|
||||
memOut[0x20 + i] = ioUnits.get(0);
|
||||
memOut[0x28 + i] = ioUnits.get(1);
|
||||
}
|
||||
|
||||
// Add port 3,4 & 5,6
|
||||
for (int i = 0, n = 2; i < n; i++) {
|
||||
ioUnits[i + 2] = new IOPort(this, (3 + i), 0, memory, 0x18 + i * 4);
|
||||
memOut[0x18 + i * 4] = ioUnits[i + 2];
|
||||
memOut[0x19 + i * 4] = ioUnits[i + 2];
|
||||
memOut[0x1a + i * 4] = ioUnits[i + 2];
|
||||
memOut[0x1b + i * 4] = ioUnits[i + 2];
|
||||
ioUnits.add(new IOPort(this, (3 + i), 0, memory, 0x18 + i * 4));
|
||||
memOut[0x18 + i * 4] = ioUnits.get(i + 2);
|
||||
memOut[0x19 + i * 4] = ioUnits.get(i + 2);
|
||||
memOut[0x1a + i * 4] = ioUnits.get(i + 2);
|
||||
memOut[0x1b + i * 4] = ioUnits.get(i + 2);
|
||||
}
|
||||
|
||||
ioUnits[i + 4] = new IOPort(this, (5 + i), 0, memory, 0x30 + i * 4);
|
||||
for (int i = 0, n = 2; i < n; i++) {
|
||||
ioUnits.add(new IOPort(this, (5 + i), 0, memory, 0x30 + i * 4));
|
||||
|
||||
memOut[0x30 + i * 4] = ioUnits[i + 4];
|
||||
memOut[0x31 + i * 4] = ioUnits[i + 4];
|
||||
memOut[0x32 + i * 4] = ioUnits[i + 4];
|
||||
memOut[0x33 + i * 4] = ioUnits[i + 4];
|
||||
memOut[0x30 + i * 4] = ioUnits.get(i + 4);
|
||||
memOut[0x31 + i * 4] = ioUnits.get(i + 4);
|
||||
memOut[0x32 + i * 4] = ioUnits.get(i + 4);
|
||||
memOut[0x33 + i * 4] = ioUnits.get(i + 4);
|
||||
}
|
||||
passIO = 6;
|
||||
|
||||
// SFR and Basic clock system.
|
||||
ioUnits[passIO++] = sfr;
|
||||
ioUnits[passIO++] = bcs;
|
||||
ioUnits.add(sfr);
|
||||
ioUnits.add(bcs);
|
||||
|
||||
passIO += config.setup(this, ioUnits, passIO);
|
||||
config.setup(this, ioUnits);
|
||||
|
||||
// Add the timers
|
||||
ioUnits[passIO++] = ta;
|
||||
ioUnits[passIO++] = tb;
|
||||
ioUnits.add(ta);
|
||||
ioUnits.add(tb);
|
||||
|
||||
ADC12 adc12 = new ADC12(this);
|
||||
ioUnits[passIO++] = adc12;
|
||||
ioUnits.add(adc12);
|
||||
|
||||
ioUnits[passIO++] = watchdog;
|
||||
ioUnits.add(watchdog);
|
||||
|
||||
for (int i = 0, n = 16; i < n; i++) {
|
||||
memOut[0x80 + i] = adc12;
|
||||
|
|
@ -252,9 +255,8 @@ public class MSP430Core extends Chip implements MSP430Constants {
|
|||
memOut[0x1A0 + i] = adc12;
|
||||
memIn[0x1A0 + i] = adc12;
|
||||
}
|
||||
|
||||
|
||||
if (DEBUG) System.out.println("Number of passive: " + passIO);
|
||||
|
||||
if (DEBUG) System.out.println("Number of passive: " + ioUnits.size());
|
||||
}
|
||||
|
||||
public Profiler getProfiler() {
|
||||
|
|
@ -278,7 +280,7 @@ public class MSP430Core extends Chip implements MSP430Constants {
|
|||
/* returns port 1 ... 6 */
|
||||
public IOPort getIOPort(int portID) {
|
||||
if (portID > 0 && portID < 7) {
|
||||
return (IOPort) ioUnits[portID - 1];
|
||||
return (IOPort) ioUnits.get(portID - 1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
@ -311,12 +313,12 @@ public class MSP430Core extends Chip implements MSP430Constants {
|
|||
}
|
||||
|
||||
public Loggable[] getLoggables() {
|
||||
Loggable[] ls = new Loggable[ioUnits.length + chips.size()];
|
||||
for (int i = 0; i < ioUnits.length; i++) {
|
||||
ls[i] = ioUnits[i];
|
||||
Loggable[] ls = new Loggable[ioUnits.size() + chips.size()];
|
||||
for (int i = 0; i < ioUnits.size(); i++) {
|
||||
ls[i] = ioUnits.get(i);
|
||||
}
|
||||
for (int i = 0; i < chips.size(); i++) {
|
||||
ls[i + ioUnits.length] = chips.get(i);
|
||||
ls[i + ioUnits.size()] = chips.get(i);
|
||||
}
|
||||
return ls;
|
||||
}
|
||||
|
|
@ -580,17 +582,19 @@ public class MSP430Core extends Chip implements MSP430Constants {
|
|||
|
||||
// Should also return active units...
|
||||
public IOUnit getIOUnit(String name) {
|
||||
for (int i = 0, n = ioUnits.length; i < n; i++) {
|
||||
if (name.equalsIgnoreCase(ioUnits[i].getID()) || name.equalsIgnoreCase(ioUnits[i].getName())) {
|
||||
return ioUnits[i];
|
||||
for (int i = 0, n = ioUnits.size(); i < n; i++) {
|
||||
IOUnit ioUnit = ioUnits.get(i);
|
||||
if (ioUnit != null && name.equalsIgnoreCase(ioUnit.getID()) ||
|
||||
name.equalsIgnoreCase(ioUnit.getName())) {
|
||||
return ioUnit;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void resetIOUnits() {
|
||||
for (int i = 0, n = ioUnits.length; i < n; i++) {
|
||||
ioUnits[i].reset(RESET_POR);
|
||||
for (int i = 0, n = ioUnits.size(); i < n; i++) {
|
||||
ioUnits.get(i).reset(RESET_POR);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,11 +65,12 @@ public class SFR extends IOUnit {
|
|||
private int[] memory;
|
||||
private MSP430Core cpu;
|
||||
|
||||
private SFRModule[] sfrModule = new SFRModule[16];
|
||||
private int[] irqVector = new int[16];
|
||||
private boolean[] irqTriggered = new boolean[16];
|
||||
private boolean[] autoclear = new boolean[16];
|
||||
private int[] irqTriggeredPos = new int[16];
|
||||
/* 64 = max number of interrupts */
|
||||
private SFRModule[] sfrModule = new SFRModule[64];
|
||||
private int[] irqVector = new int[64];
|
||||
private boolean[] irqTriggered = new boolean[64];
|
||||
private boolean[] autoclear = new boolean[64];
|
||||
private int[] irqTriggeredPos = new int[64];
|
||||
|
||||
public SFR(MSP430Core cpu, int[] memory) {
|
||||
super("SFR", "Special Function Register", memory, 0);
|
||||
|
|
@ -223,6 +224,7 @@ public class SFR extends IOUnit {
|
|||
int change = value ^ after;
|
||||
if (index == 0) ifg1 = after;
|
||||
else ifg2 = after;
|
||||
|
||||
updateIRQ(index, change);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
|
||||
package se.sics.mspsim.core;
|
||||
|
||||
public class USART extends IOUnit implements SFRModule, DMATrigger {
|
||||
public class USART extends IOUnit implements SFRModule, DMATrigger, USARTSource {
|
||||
|
||||
// USART 0/1 register offset (0x70 / 0x78)
|
||||
public static final int UCTL = 0;
|
||||
|
|
|
|||
|
|
@ -43,5 +43,5 @@ package se.sics.mspsim.core;
|
|||
|
||||
public interface USARTListener {
|
||||
public static int RXFLAG_CLEARED = 1;
|
||||
public void dataReceived(USART source, int data);
|
||||
public void dataReceived(USARTSource source, int data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
package se.sics.mspsim.core;
|
||||
|
||||
public interface USARTSource {
|
||||
|
||||
public void setUSARTListener(USARTListener listener);
|
||||
|
||||
/* for input into this UART */
|
||||
public boolean isReceiveFlagCleared();
|
||||
public void byteReceived(int b);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,500 @@
|
|||
/**
|
||||
* Copyright (c) 2007, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of MSPSim.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* -----------------------------------------------------------------
|
||||
*
|
||||
* USART
|
||||
*
|
||||
* Author : Joakim Eriksson
|
||||
* Created : Sun Oct 21 22:00:00 2007
|
||||
* Updated : $Date$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
package se.sics.mspsim.core;
|
||||
|
||||
|
||||
public class USCI extends IOUnit implements SFRModule, DMATrigger, USARTSource {
|
||||
|
||||
// USART 0/1 register offset (0x60 / 0xD0)
|
||||
public static final int UAxCTL0 = 0;
|
||||
public static final int UAxCTL1 = 1;
|
||||
public static final int UAxBR0 = 2;
|
||||
public static final int UAxBR1 = 3;
|
||||
public static final int UAxMCTL = 4;
|
||||
public static final int UAxSTAT = 5;
|
||||
public static final int UAxRXBUF = 6;
|
||||
public static final int UAxTXBUF = 7;
|
||||
|
||||
// SPI related registers
|
||||
public static final int UBxCTL0 = 8;
|
||||
public static final int UBxCTL1 = 9;
|
||||
public static final int UBxBR0 = 0xa;
|
||||
public static final int UBxBR1 = 0xb;
|
||||
public static final int UBxSTAT = 0xd;
|
||||
public static final int UBxRXBUF = 0xe;
|
||||
public static final int UBxTXBUF = 0xf;
|
||||
|
||||
// IrDA related (negative offset ??)
|
||||
public static final int UABCTL = -3; /* very odd... */
|
||||
public static final int UIRTCTL = -2;
|
||||
public static final int UIRRCTL = -1;
|
||||
|
||||
// Interrupt flags...
|
||||
public static final int UTXIFG0 = 0x80;
|
||||
public static final int URXIFG0 = 0x40;
|
||||
|
||||
public static final int UTXIFG1 = 0x20;
|
||||
public static final int URXIFG1 = 0x10;
|
||||
|
||||
// USART SRF mod enable registers (absolute + 1)
|
||||
public static final int ME1 = 4;
|
||||
public static final int IE1 = 0;
|
||||
public static final int IFG1 = 2;
|
||||
|
||||
private final int uartID;
|
||||
|
||||
// Flags.
|
||||
public static final int UTCTL_TXEMPTY = 0x01;
|
||||
public static final int UTCTL_URXSE = 0x08;
|
||||
public static final int USCI_BUSY = 0x01;
|
||||
|
||||
private USARTListener listener;
|
||||
|
||||
private int utxifg;
|
||||
private int urxifg;
|
||||
private int rxVector;
|
||||
|
||||
private int clockSource = 0;
|
||||
private int baudRate = 0;
|
||||
private int tickPerByte = 1000;
|
||||
private long nextTXReady = -1;
|
||||
private int nextTXByte = -1;
|
||||
private int txShiftReg = -1;
|
||||
private boolean transmitting = false;
|
||||
|
||||
private MSP430Core cpu;
|
||||
private SFR sfr;
|
||||
private int sfrAddress;
|
||||
|
||||
/* ifg and ie if not in sfr... - assume IE in sfraddr and IFG in addr + 1*/
|
||||
private int ifgAddress = 0;
|
||||
private int ieAddress = 0;
|
||||
|
||||
private int uctl0;
|
||||
private int uctl1;
|
||||
private int umctl;
|
||||
private int ubr0;
|
||||
private int ubr1;
|
||||
private int urxbuf;
|
||||
private int utxbuf;
|
||||
private int ustat;
|
||||
private int txbit;
|
||||
|
||||
private boolean txEnabled = false;
|
||||
private boolean rxEnabled = false;
|
||||
private boolean spiMode = false;
|
||||
|
||||
/* DMA controller that needs to be called at certain times */
|
||||
private DMA dma;
|
||||
private int dmaIndex;
|
||||
|
||||
private boolean usciA = true; /* if this is an USCI A or B */
|
||||
|
||||
private TimeEvent txTrigger = new TimeEvent(0) {
|
||||
public void execute(long t) {
|
||||
// Ready to transmit new byte!
|
||||
handleTransmit(t);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a new <code>USART</code> instance.
|
||||
*
|
||||
*/
|
||||
public USCI(MSP430Core cpu, int uartID, int[] memory, MSP430Config config) {
|
||||
super(config.uartConfig[uartID].name, config.uartConfig[uartID].name, memory, config.uartConfig[uartID].offset);
|
||||
System.out.println("NAME: " + config.uartConfig[uartID].name);
|
||||
this.cpu = cpu;
|
||||
this.uartID = uartID;
|
||||
MSP430Config.UARTConfig uartConfig = config.uartConfig[uartID];
|
||||
|
||||
// Initialize - transmit = ok...
|
||||
// and set which interrupts are used
|
||||
if (uartConfig.sfrAddr < 2) {
|
||||
sfr = cpu.getSFR();
|
||||
sfrAddress = uartConfig.sfrAddr;
|
||||
sfr.registerSFDModule(uartConfig.sfrAddr, uartConfig.rxBit, this, uartConfig.rxVector);
|
||||
sfr.registerSFDModule(uartConfig.sfrAddr, uartConfig.txBit, this, uartConfig.txVector);
|
||||
} else {
|
||||
ieAddress = uartConfig.sfrAddr;
|
||||
ifgAddress = uartConfig.sfrAddr + 1;
|
||||
}
|
||||
utxifg = 1 << uartConfig.txBit;
|
||||
urxifg = 1 << uartConfig.rxBit;
|
||||
txbit = uartConfig.txBit;
|
||||
rxVector = uartConfig.rxVector;
|
||||
usciA = uartConfig.usciA;
|
||||
reset(0);
|
||||
}
|
||||
|
||||
public void setDMA(DMA dma) {
|
||||
this.dma = dma;
|
||||
}
|
||||
|
||||
|
||||
public void reset(int type) {
|
||||
nextTXReady = cpu.cycles + 100;
|
||||
txShiftReg = nextTXByte = -1;
|
||||
transmitting = false;
|
||||
clrBitIFG(urxifg);
|
||||
setBitIFG(utxifg); /* empty at start! */
|
||||
ustat &= ~USCI_BUSY;
|
||||
txEnabled = true; //false;
|
||||
rxEnabled = true; //false;
|
||||
}
|
||||
|
||||
public void enableChanged(int reg, int bit, boolean enabled) {
|
||||
if (DEBUG) log("enableChanged: " + reg + " bit: " + bit +
|
||||
" enabled = " + enabled + " txBit: " + txbit);
|
||||
if (bit == txbit) {
|
||||
txEnabled = enabled;
|
||||
} else {
|
||||
rxEnabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
private void setBitIFG(int bits) {
|
||||
if ((bits) > 0) {
|
||||
System.out.println(getName() + " Set utxifg = " + utxifg +
|
||||
" sfrA: " + sfrAddress + " bits: " + bits);
|
||||
}
|
||||
if (sfr != null) {
|
||||
sfr.setBitIFG(sfrAddress, bits);
|
||||
System.out.println("SFR =>" + sfr.getIFG(sfrAddress));
|
||||
} else {
|
||||
memory[ifgAddress] |= bits;
|
||||
}
|
||||
if (dma != null) {
|
||||
/* set bit first, then trigger DMA transfer - this should
|
||||
* be made via a 1 cycle or so delayed action */
|
||||
if ((bits & urxifg) > 0) dma.trigger(this, 0);
|
||||
if ((bits & utxifg) > 0) dma.trigger(this, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void clrBitIFG(int bits) {
|
||||
// if ((bits & utxifg) > 0) {
|
||||
// System.out.println(getName() + " Clear utxifg");
|
||||
// }
|
||||
if (sfr != null) {
|
||||
sfr.clrBitIFG(sfrAddress, bits);
|
||||
} else {
|
||||
memory[ifgAddress] &= ~bits;
|
||||
}
|
||||
}
|
||||
|
||||
private int getIFG() {
|
||||
if (sfr != null)
|
||||
return sfr.getIFG(sfrAddress);
|
||||
return memory[ifgAddress];
|
||||
}
|
||||
|
||||
private boolean isIEBitsSet(int bits) {
|
||||
if (sfr != null)
|
||||
return sfr.isIEBitsSet(sfrAddress, bits);
|
||||
return (memory[ieAddress] & bits) > 0;
|
||||
}
|
||||
|
||||
/* reuse USART listener API for USCI */
|
||||
public void setUSARTListener(USARTListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
// Only 8 bits / read!
|
||||
public void write(int address, int data, boolean word, long cycles) {
|
||||
if (address == ieAddress || address == ifgAddress) {
|
||||
memory[address] = data;
|
||||
}
|
||||
address = address - offset;
|
||||
|
||||
// Indicate ready to write!!! - this should not be done here...
|
||||
// System.out.println(">>>> Write to " + getName() + " at " +
|
||||
// address + " = " + data);
|
||||
switch (address) {
|
||||
case UAxCTL0:
|
||||
case UBxCTL0:
|
||||
uctl0 = data;
|
||||
spiMode = (data & 0x01) > 0;
|
||||
if (DEBUG) log(" write to UAxCTL0 " + data);
|
||||
break;
|
||||
case UAxCTL1:
|
||||
case UBxCTL1:
|
||||
/* emulate the reset */
|
||||
if ((uctl1 & 1) == 1 && (data & 1) == 0)
|
||||
reset(0);
|
||||
uctl1 = data;
|
||||
if (DEBUG) log(" write to UAxCTL1 " + data);
|
||||
|
||||
if (((data >> 6) & 3) == 1) {
|
||||
clockSource = MSP430Constants.CLK_ACLK;
|
||||
if (DEBUG) {
|
||||
log(" Selected ACLK as source");
|
||||
}
|
||||
} else {
|
||||
clockSource = MSP430Constants.CLK_SMCLK;
|
||||
if (DEBUG) {
|
||||
log(" Selected SMCLK as source");
|
||||
}
|
||||
}
|
||||
updateBaudRate();
|
||||
break;
|
||||
case UAxMCTL:
|
||||
umctl = data;
|
||||
if (DEBUG) log(" write to UMCTL " + data);
|
||||
break;
|
||||
case UAxBR0:
|
||||
case UBxBR0:
|
||||
ubr0 = data;
|
||||
updateBaudRate();
|
||||
break;
|
||||
case UAxBR1:
|
||||
case UBxBR1:
|
||||
ubr1 = data;
|
||||
updateBaudRate();
|
||||
break;
|
||||
case UAxSTAT:
|
||||
case UBxSTAT:
|
||||
//ustat = data;
|
||||
break;
|
||||
case UAxTXBUF:
|
||||
case UBxTXBUF:
|
||||
if (DEBUG) log(": USART_UTXBUF:" + (char) data + " = " + data + "\n");
|
||||
if (txEnabled || (spiMode && rxEnabled)) {
|
||||
// Interruptflag not set!
|
||||
clrBitIFG(utxifg);
|
||||
/* the TX is no longer empty ! */
|
||||
ustat |= USCI_BUSY;
|
||||
/* should the interrupt be flagged off here ? - or only the flags */
|
||||
if (DEBUG) log(" flagging off transmit interrupt");
|
||||
// cpu.flagInterrupt(transmitInterrupt, this, false);
|
||||
|
||||
// Schedule on cycles here
|
||||
// TODO: adding 3 extra cycles here seems to give
|
||||
// slightly better timing in some test...
|
||||
|
||||
nextTXByte = data;
|
||||
if (!transmitting) {
|
||||
/* how long time will the copy from the TX_BUF to the shift reg take? */
|
||||
/* assume 3 cycles? */
|
||||
nextTXReady = cycles + 1; //tickPerByte + 3;
|
||||
cpu.scheduleCycleEvent(txTrigger, nextTXReady);
|
||||
}
|
||||
} else {
|
||||
log("Ignoring UTXBUF data since TX not active...");
|
||||
}
|
||||
utxbuf = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public int read(int address, boolean word, long cycles) {
|
||||
if (address == ieAddress || address == ifgAddress) {
|
||||
return memory[address];
|
||||
}
|
||||
address = address - offset;
|
||||
// System.out.println(">>>>> Read from " + getName() + " at " +
|
||||
// address);
|
||||
|
||||
switch (address) {
|
||||
case UAxCTL0:
|
||||
case UBxCTL0:
|
||||
if (DEBUG) log(" read from UCTL");
|
||||
return uctl0;
|
||||
case UAxCTL1:
|
||||
case UBxCTL1:
|
||||
if (DEBUG) log(" read from UTCTL: " + uctl1);
|
||||
return uctl1;
|
||||
case UAxMCTL:
|
||||
return umctl;
|
||||
case UAxBR0:
|
||||
case UBxBR0:
|
||||
return ubr0;
|
||||
case UAxBR1:
|
||||
case UBxBR1:
|
||||
return ubr1;
|
||||
case UAxTXBUF:
|
||||
case UBxTXBUF:
|
||||
return utxbuf;
|
||||
case UAxSTAT:
|
||||
case UBxSTAT:
|
||||
// System.out.println(getName() + " Reading STAT: " + ustat);
|
||||
return ustat;
|
||||
case UAxRXBUF:
|
||||
case UBxRXBUF:
|
||||
int tmp = urxbuf;
|
||||
// When byte is read - the interruptflag is cleared!
|
||||
// and error status should also be cleared later...
|
||||
// is this cleared also on the MSP430x2xx series???
|
||||
if (MSP430Constants.DEBUGGING_LEVEL > 0) {
|
||||
log(" clearing rx interrupt flag " + cpu.getPC() + " byte: " + tmp);
|
||||
}
|
||||
clrBitIFG(urxifg);
|
||||
/* This should be changed to a state rather than an "event" */
|
||||
/* Force callback since this is not used as a state */
|
||||
stateChanged(USARTListener.RXFLAG_CLEARED, true);
|
||||
return tmp;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void updateBaudRate() {
|
||||
int div = ubr0 + (ubr1 << 8);
|
||||
if (div == 0) {
|
||||
div = 1;
|
||||
}
|
||||
if (clockSource == MSP430Constants.CLK_ACLK) {
|
||||
if (DEBUG) {
|
||||
log(" Baud rate is (bps): " + cpu.aclkFrq / div + " div = " + div);
|
||||
}
|
||||
baudRate = cpu.aclkFrq / div;
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
log(" Baud rate is (bps): " + cpu.smclkFrq / div + " div = " + div);
|
||||
}
|
||||
baudRate = cpu.smclkFrq / div;
|
||||
}
|
||||
if (baudRate == 0) baudRate = 1;
|
||||
// Is this correct??? Is it the DCO or smclkFRQ we should have here???
|
||||
tickPerByte = (8 * cpu.smclkFrq) / baudRate;
|
||||
if (DEBUG) {
|
||||
log(" Ticks per byte: " + tickPerByte);
|
||||
}
|
||||
}
|
||||
|
||||
// We should add "Interrupt serviced..." to indicate that its latest
|
||||
// Interrupt was serviced...
|
||||
public void interruptServiced(int vector) {
|
||||
/* NOTE: this is handled by SFR : clear IFG bit if interrupt is serviced */
|
||||
// System.out.println(getName() + " SFR irq " + vector + " " + txShiftReg + " " + getIFG());
|
||||
}
|
||||
|
||||
private void handleTransmit(long cycles) {
|
||||
if (cpu.getMode() >= MSP430Core.MODE_LPM3) {
|
||||
System.out.println(getName() + " Warning: USART transmission during LPM!!! " + nextTXByte);
|
||||
}
|
||||
|
||||
if (transmitting) {
|
||||
/* in this case we have shifted out the last character */
|
||||
if (listener != null && txShiftReg != -1) {
|
||||
listener.dataReceived(this, txShiftReg);
|
||||
}
|
||||
/* nothing more to transmit after this - stop transmission */
|
||||
if (nextTXByte == -1) {
|
||||
/* ~BUSY - nothing more to send - and last data already in RX */
|
||||
ustat &= ~USCI_BUSY;
|
||||
transmitting = false;
|
||||
txShiftReg = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* any more chars to transmit? */
|
||||
if (nextTXByte != -1) {
|
||||
txShiftReg = nextTXByte;
|
||||
nextTXByte = -1;
|
||||
/* txbuf always empty after this */
|
||||
setBitIFG(utxifg);
|
||||
transmitting = true;
|
||||
nextTXReady = cycles + tickPerByte + 1;
|
||||
cpu.scheduleCycleEvent(txTrigger, nextTXReady);
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
if (isIEBitsSet(utxifg)) {
|
||||
log(" flagging on transmit interrupt");
|
||||
}
|
||||
log(" Ready to transmit next at: " + cycles);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean isReceiveFlagCleared() {
|
||||
return (getIFG() & urxifg) == 0;
|
||||
}
|
||||
|
||||
// A byte have been received!
|
||||
// This needs to be complemented with a method for checking if the USART
|
||||
// is ready for next byte (readyForReceive) that respects the current speed
|
||||
public void byteReceived(int b) {
|
||||
System.out.println(getName() + " byte received: " + b + " enabled:" + rxEnabled);
|
||||
if (!rxEnabled) return;
|
||||
|
||||
if (DEBUG || true) {
|
||||
log(" byteReceived: " + b + " " + (char) b);
|
||||
}
|
||||
urxbuf = b & 0xff;
|
||||
// Indicate interrupt also!
|
||||
setBitIFG(urxifg);
|
||||
|
||||
// Check if the IE flag is enabled! - same as the IFlag to indicate!
|
||||
if (isIEBitsSet(urxifg)) {
|
||||
if (DEBUG) {
|
||||
log(" flagging receive interrupt ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String info() {
|
||||
return "UTXIE: " + isIEBitsSet(utxifg) + " URXIE:" + isIEBitsSet(urxifg) + "\n" +
|
||||
"UTXIFG: " + ((getIFG() & utxifg) > 0) + " URXIFG:" + ((getIFG() & urxifg) > 0);
|
||||
}
|
||||
|
||||
public boolean getDMATriggerState(int index) {
|
||||
if (index == 0) {
|
||||
return (getIFG() & urxifg) > 0;
|
||||
} else {
|
||||
return (getIFG() & utxifg) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void clearDMATrigger(int index) {
|
||||
System.out.println("UART clearing DMA " + index);
|
||||
if (index == 0) {
|
||||
/* clear RX - might be different in different modes... */
|
||||
System.out.println("UART clearing read bit!");
|
||||
clrBitIFG(urxifg);
|
||||
stateChanged(USARTListener.RXFLAG_CLEARED, true);
|
||||
} else {
|
||||
/* clear TX - might be different in different modes... */
|
||||
clrBitIFG(utxifg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -51,6 +51,7 @@ import se.sics.mspsim.core.ADCInput;
|
|||
import se.sics.mspsim.core.IOPort;
|
||||
import se.sics.mspsim.core.IOUnit;
|
||||
import se.sics.mspsim.core.USART;
|
||||
import se.sics.mspsim.core.USARTSource;
|
||||
import se.sics.mspsim.platform.sky.CC2420Node;
|
||||
import se.sics.mspsim.util.ArgumentManager;
|
||||
|
||||
|
|
@ -97,7 +98,7 @@ public class JCreateNode extends CC2420Node {
|
|||
|
||||
// USART Listener
|
||||
@Override
|
||||
public void dataReceived(USART source, int data) {
|
||||
public void dataReceived(USARTSource source, int data) {
|
||||
radio.dataReceived(source, data);
|
||||
flash.dataReceived(source, data);
|
||||
/* if nothing selected, just write back a random byte to this device */
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ import se.sics.mspsim.chip.Leds;
|
|||
import se.sics.mspsim.chip.M25P80;
|
||||
import se.sics.mspsim.core.IOPort;
|
||||
import se.sics.mspsim.core.USART;
|
||||
import se.sics.mspsim.core.USARTSource;
|
||||
import se.sics.mspsim.platform.sky.CC2420Node;
|
||||
import se.sics.mspsim.util.ArgumentManager;
|
||||
|
||||
|
|
@ -91,7 +92,7 @@ public class SentillaUSBNode extends CC2420Node {
|
|||
|
||||
// USART Listener
|
||||
@Override
|
||||
public void dataReceived(USART source, int data) {
|
||||
public void dataReceived(USARTSource source, int data) {
|
||||
radio.dataReceived(source, data);
|
||||
flash.dataReceived(source, data);
|
||||
/* if nothing selected, just write back a random byte to this device */
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import se.sics.mspsim.core.MSP430Config;
|
|||
import se.sics.mspsim.core.PortListener;
|
||||
import se.sics.mspsim.core.USART;
|
||||
import se.sics.mspsim.core.USARTListener;
|
||||
import se.sics.mspsim.core.USARTSource;
|
||||
import se.sics.mspsim.extutil.jfreechart.DataChart;
|
||||
import se.sics.mspsim.extutil.jfreechart.DataSourceSampler;
|
||||
import se.sics.mspsim.platform.GenericNode;
|
||||
|
|
@ -200,7 +201,7 @@ public abstract class CC2420Node extends GenericNode implements PortListener, US
|
|||
|
||||
protected abstract void flashWrite(IOPort source, int data);
|
||||
|
||||
public abstract void dataReceived(USART source, int data);
|
||||
public abstract void dataReceived(USARTSource source, int data);
|
||||
|
||||
public void stateChanged(int state) {
|
||||
// Ignore UART state changes by default
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ import se.sics.mspsim.chip.FileM25P80;
|
|||
import se.sics.mspsim.chip.M25P80;
|
||||
import se.sics.mspsim.core.IOPort;
|
||||
import se.sics.mspsim.core.USART;
|
||||
import se.sics.mspsim.core.USARTSource;
|
||||
import se.sics.mspsim.util.ArgumentManager;
|
||||
|
||||
/**
|
||||
|
|
@ -74,7 +75,7 @@ public class SkyNode extends MoteIVNode {
|
|||
}
|
||||
|
||||
// USART Listener
|
||||
public void dataReceived(USART source, int data) {
|
||||
public void dataReceived(USARTSource source, int data) {
|
||||
radio.dataReceived(source, data);
|
||||
flash.dataReceived(source, data);
|
||||
/* if nothing selected, just write back a random byte to these devs */
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ import se.sics.mspsim.chip.AT45DB;
|
|||
import se.sics.mspsim.chip.FileAT45DB;
|
||||
import se.sics.mspsim.core.IOPort;
|
||||
import se.sics.mspsim.core.USART;
|
||||
import se.sics.mspsim.core.USARTSource;
|
||||
import se.sics.mspsim.util.ArgumentManager;
|
||||
|
||||
/**
|
||||
|
|
@ -84,7 +85,7 @@ public class TelosNode extends MoteIVNode {
|
|||
}
|
||||
|
||||
// USART Listener
|
||||
public void dataReceived(USART source, int data) {
|
||||
public void dataReceived(USARTSource source, int data) {
|
||||
radio.dataReceived(source, data);
|
||||
flash.dataReceived(source, data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ import se.sics.mspsim.core.IOUnit;
|
|||
import se.sics.mspsim.core.PortListener;
|
||||
import se.sics.mspsim.core.USART;
|
||||
import se.sics.mspsim.core.USARTListener;
|
||||
import se.sics.mspsim.core.USARTSource;
|
||||
import se.sics.mspsim.core.USCI;
|
||||
import se.sics.mspsim.platform.GenericNode;
|
||||
import se.sics.mspsim.ui.SerialMon;
|
||||
import se.sics.mspsim.util.ArgumentManager;
|
||||
|
|
@ -59,7 +61,8 @@ public class Z1Node extends GenericNode implements PortListener, USARTListener {
|
|||
registry.registerComponent("xmem", flash);
|
||||
}
|
||||
|
||||
public void dataReceived(USART source, int data) {
|
||||
public void dataReceived(USARTSource source, int data) {
|
||||
USCI s = (USCI) source;
|
||||
radio.dataReceived(source, data);
|
||||
flash.dataReceived(source, data);
|
||||
/* if nothing selected, just write back a random byte to these devs */
|
||||
|
|
@ -69,17 +72,16 @@ public class Z1Node extends GenericNode implements PortListener, USARTListener {
|
|||
}
|
||||
|
||||
public void portWrite(IOPort source, int data) {
|
||||
System.out.println("Write to port: " + source + " => " + data);
|
||||
if (source == port5) {
|
||||
System.out.println("LEDS GREEN = " + ((data & LEDS_CONF_GREEN) > 0));
|
||||
System.out.println("LEDS RED = " + ((data & LEDS_CONF_RED) > 0));
|
||||
System.out.println("LEDS YELLOW = " + ((data & LEDS_CONF_YELLOW) > 0));
|
||||
}
|
||||
if (source == port3) {
|
||||
// Chip select = active low...
|
||||
radio.setChipSelect((data & CC2420_CHIP_SELECT) == 0);
|
||||
}
|
||||
if (source == port4) {
|
||||
// Chip select = active low...
|
||||
radio.setVRegOn((data & CC2420_VREG) != 0);
|
||||
//radio.portWrite(source, data);
|
||||
flash.portWrite(source, data);
|
||||
|
|
@ -112,18 +114,17 @@ public class Z1Node extends GenericNode implements PortListener, USARTListener {
|
|||
port5.setPortListener(this);
|
||||
}
|
||||
|
||||
IOUnit usart0 = cpu.getIOUnit("USART0");
|
||||
if (usart0 instanceof USART) {
|
||||
IOUnit usart0 = cpu.getIOUnit("USCI B0");
|
||||
if (usart0 instanceof USCI) {
|
||||
radio = new CC2420(cpu);
|
||||
radio.setCCAPort(port1, CC2420_CCA);
|
||||
radio.setFIFOPPort(port1, CC2420_FIFOP);
|
||||
radio.setFIFOPort(port1, CC2420_FIFO);
|
||||
|
||||
((USART) usart0).setUSARTListener(this);
|
||||
((USARTSource) usart0).setUSARTListener(this);
|
||||
if (port4 != null) {
|
||||
radio.setSFDPort(port4, CC2420_SFD);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -151,9 +152,9 @@ public class Z1Node extends GenericNode implements PortListener, USARTListener {
|
|||
setupGUI();
|
||||
|
||||
// Add some windows for listening to serial output
|
||||
IOUnit usart = cpu.getIOUnit("USART1");
|
||||
if (usart instanceof USART) {
|
||||
SerialMon serial = new SerialMon((USART)usart, "USART1 Port Output");
|
||||
IOUnit usart = cpu.getIOUnit("USCI A0");
|
||||
if (usart instanceof USARTSource) {
|
||||
SerialMon serial = new SerialMon((USARTSource)usart, "USART1 Port Output");
|
||||
registry.registerComponent("serialgui", serial);
|
||||
}
|
||||
}
|
||||
|
|
@ -175,4 +176,5 @@ public class Z1Node extends GenericNode implements PortListener, USARTListener {
|
|||
config.handleArguments(args);
|
||||
node.setupArgs(config);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,9 +54,10 @@ import javax.swing.JTextArea;
|
|||
import javax.swing.JTextField;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import se.sics.mspsim.core.IOUnit;
|
||||
import se.sics.mspsim.core.StateChangeListener;
|
||||
import se.sics.mspsim.core.USART;
|
||||
import se.sics.mspsim.core.USARTListener;
|
||||
import se.sics.mspsim.core.USARTSource;
|
||||
import se.sics.mspsim.util.ComponentRegistry;
|
||||
import se.sics.mspsim.util.ServiceComponent;
|
||||
|
||||
|
|
@ -67,7 +68,7 @@ public class SerialMon implements USARTListener, StateChangeListener, ServiceCom
|
|||
private String name;
|
||||
private ServiceComponent.Status status = Status.STOPPED;
|
||||
|
||||
private final USART usart;
|
||||
private final USARTSource usart;
|
||||
private final String title;
|
||||
|
||||
private JFrame window;
|
||||
|
|
@ -86,7 +87,7 @@ public class SerialMon implements USARTListener, StateChangeListener, ServiceCom
|
|||
private int lines = 1;
|
||||
private boolean isUpdatePending = false;
|
||||
|
||||
public SerialMon(USART usart, String title) {
|
||||
public SerialMon(USARTSource usart, String title) {
|
||||
this.usart = usart;
|
||||
this.title = title;
|
||||
}
|
||||
|
|
@ -199,7 +200,7 @@ public class SerialMon implements USARTListener, StateChangeListener, ServiceCom
|
|||
if (window == null) {
|
||||
initGUI();
|
||||
usart.setUSARTListener(this);
|
||||
usart.addStateChangeListener(this);
|
||||
((IOUnit) usart).addStateChangeListener(this);
|
||||
}
|
||||
window.setVisible(true);
|
||||
status = Status.STARTED;
|
||||
|
|
@ -212,7 +213,7 @@ public class SerialMon implements USARTListener, StateChangeListener, ServiceCom
|
|||
}
|
||||
}
|
||||
|
||||
public void dataReceived(USART source, int data) {
|
||||
public void dataReceived(USARTSource source, int data) {
|
||||
if (data == '\n') {
|
||||
if (lines >= MAX_LINES) {
|
||||
int index = text.indexOf('\n');
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ public class Test implements USARTListener {
|
|||
}
|
||||
}
|
||||
|
||||
public void dataReceived(USART source, int data) {
|
||||
public void dataReceived(USARTSource source, int data) {
|
||||
if (data == '\n') {
|
||||
String line = lineBuffer.toString();
|
||||
lineBuffer.setLength(0);
|
||||
|
|
|
|||
Loading…
Reference in New Issue