mirror of https://github.com/contiki-ng/mspsim
Emulation support for the TI CC430 sub-GHz SoC
This commit is contained in:
parent
5d60f2736c
commit
f1e8246a1d
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
|
|
@ -0,0 +1,166 @@
|
|||
/**
|
||||
* Copyright (c) 2011, 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.
|
||||
*
|
||||
*
|
||||
* -----------------------------------------------------------------
|
||||
*
|
||||
* Author : Joakim Eriksson
|
||||
*/
|
||||
|
||||
package se.sics.mspsim.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import se.sics.mspsim.core.ClockSystem;
|
||||
import se.sics.mspsim.core.GenericUSCI;
|
||||
import se.sics.mspsim.core.IOPort;
|
||||
import se.sics.mspsim.core.IOUnit;
|
||||
import se.sics.mspsim.core.MSP430Config;
|
||||
import se.sics.mspsim.core.MSP430Core;
|
||||
import se.sics.mspsim.core.Multiplier32;
|
||||
import se.sics.mspsim.core.PMM;
|
||||
import se.sics.mspsim.core.PMMDummy;
|
||||
import se.sics.mspsim.core.SysReg;
|
||||
import se.sics.mspsim.core.Timer;
|
||||
import se.sics.mspsim.core.UnifiedClockSystem;
|
||||
import se.sics.mspsim.util.Utils;
|
||||
import se.sics.mspsim.core.RF1A;
|
||||
|
||||
public class CC430f5137Config extends MSP430Config {
|
||||
|
||||
// NOTE: this MCU also needs to configure
|
||||
// - positions of all timers (A0, A1, B)
|
||||
// - memory configuration
|
||||
// -
|
||||
private static final String portConfig[] = {
|
||||
"P1=200,IN 00,OUT 02,DIR 04,REN 06,DS 08,SEL 0A,IV_L 0E,IV_H 0F,IES 18,IE 1A,IFG 1C",
|
||||
"P2=200,IN 01,OUT 03,DIR 05,REN 07,DS 09,SEL 0B,IV_L 1E,IV_H 1F,IES 19,IE 1B,IFG 1D",
|
||||
"P3=220,IN 00,OUT 02,DIR 04,REN 06,DS 08,SEL 0A",
|
||||
"P4=220,IN 01,OUT 03,DIR 05,REN 07,DS 09,SEL 0B",
|
||||
"P5=240,IN 00,OUT 02,DIR 04,REN 06,DS 08,SEL 0A",
|
||||
"P6=240,IN 01,OUT 03,DIR 05,REN 07,DS 09,SEL 0B",
|
||||
"P7=260,IN 00,OUT 02,DIR 04,REN 06,DS 08,SEL 0A",
|
||||
"P8=260,IN 01,OUT 03,DIR 05,REN 07,DS 09,SEL 0B",
|
||||
"P9=280,IN 00,OUT 02,DIR 04,REN 06,DS 08,SEL 0A",
|
||||
"P:=280,IN 01,OUT 03,DIR 05,REN 07,DS 09,SEL 0B",
|
||||
};
|
||||
|
||||
public CC430f5137Config() {
|
||||
/* 64 vectors for the MSP430f54xx series */
|
||||
maxInterruptVector = 63;
|
||||
MSP430XArch = true;
|
||||
flashControllerOffset = 0x140;
|
||||
sfrOffset = 0x100;
|
||||
|
||||
/* configuration for the timers - need to set-up new source maps!!! */
|
||||
|
||||
/* XXX Adam: the ints after TimerConfig(X, Y) seem to be the interrupt vectors, i.e. i = (vector_addresss - 0xff80)/2 */
|
||||
|
||||
//#define TIMER1_A1_VECTOR (0x0064) /* 0xFFE4 Timer1_A3 CC1-2, TA1 */
|
||||
//#define TIMER1_A0_VECTOR (0x0066) /* 0xFFE6 Timer1_A3 CC0 */
|
||||
//#define DMA_VECTOR (0x0068) /* 0xFFE8 DMA */
|
||||
//#define CC1101_VECTOR (0x006A) /* 0xFFEA CC1101 Radio Interface */
|
||||
//#define TIMER0_A1_VECTOR (0x006C) /* 0xFFEC Timer0_A5 CC1-4, TA */
|
||||
//#define TIMER0_A0_VECTOR (0x006E) /* 0xFFEE Timer0_A5 CC0 */
|
||||
|
||||
|
||||
TimerConfig timerA0 = new TimerConfig(0x6e / 2, 0x6c / 2, 5, 0x340, Timer.TIMER_Bx149, "TimerA0", 0x340 + 0x2e);
|
||||
TimerConfig timerA1 = new TimerConfig(0x66 / 2, 0x64 / 2, 3, 0x380, Timer.TIMER_Ax149, "TimerA1", 0x380 + 0x2e);
|
||||
|
||||
timerConfig = new TimerConfig[] {timerA0, timerA1};
|
||||
|
||||
uartConfig = new UARTConfig[] {
|
||||
new UARTConfig("USCI A0", 57, 0x5c0),
|
||||
new UARTConfig("USCI B0", 56, 0x5e0),
|
||||
new UARTConfig("USCI A1", 46, 0x600),
|
||||
new UARTConfig("USCI B1", 45, 0x620),
|
||||
};
|
||||
|
||||
/* configure memory */
|
||||
infoMemConfig(0x1800, 128 * 4);
|
||||
ramConfig(0x1c00, 4 * 1024);
|
||||
mainFlashConfig(0x8000, 32 * 1024);
|
||||
|
||||
ioMemSize(0x1000); /* 4 KB of IO Memory */
|
||||
|
||||
watchdogOffset = 0x15c;
|
||||
// bsl, IO, etc at a later stage...
|
||||
}
|
||||
|
||||
public int setup(MSP430Core cpu, ArrayList<IOUnit> ioUnits) {
|
||||
|
||||
Multiplier32 mp = new Multiplier32(cpu, cpu.memory, 0x4c0);
|
||||
cpu.setIORange(0x4c0, 0x2e, mp);
|
||||
|
||||
/* this code should be slightly more generic... and be somewhere else... */
|
||||
for (int i = 0, n = uartConfig.length; i < n; i++) {
|
||||
GenericUSCI usci = new GenericUSCI(cpu, i, cpu.memory, this);
|
||||
/* setup 0 - 1f as IO addresses */
|
||||
cpu.setIORange(uartConfig[i].offset, 0x20, usci);
|
||||
// System.out.println("Adding IOUnit USCI: " + usci.getName());
|
||||
ioUnits.add(usci);
|
||||
}
|
||||
IOPort last = null;
|
||||
ioUnits.add(last = IOPort.parseIOPort(cpu, 47, portConfig[0], last));
|
||||
ioUnits.add(last = IOPort.parseIOPort(cpu, 42, portConfig[1], last));
|
||||
|
||||
for (int i = 2; i < portConfig.length; i++) {
|
||||
ioUnits.add(last = IOPort.parseIOPort(cpu, 0, portConfig[i], last));
|
||||
}
|
||||
|
||||
/* XXX: Stub IO units: Sysreg and PMM */
|
||||
SysReg sysreg = new SysReg(cpu, cpu.memory);
|
||||
cpu.setIORange(SysReg.ADDRESS, SysReg.SIZE, sysreg);
|
||||
ioUnits.add(sysreg);
|
||||
|
||||
PMMDummy pmmDummy = new PMMDummy(cpu, cpu.memory, 0x110);
|
||||
cpu.setIORange(0x110, PMMDummy.SIZE, pmmDummy);
|
||||
ioUnits.add(pmmDummy);
|
||||
|
||||
PMM pmm = new PMM(cpu, cpu.memory, 0x120);
|
||||
cpu.setIORange(0x120, PMM.SIZE, pmm);
|
||||
ioUnits.add(pmm);
|
||||
|
||||
RF1A rf1a = new RF1A(cpu, cpu.memory);
|
||||
cpu.setIORange(RF1A.ADDRESS, RF1A.SIZE, rf1a);
|
||||
ioUnits.add(rf1a);
|
||||
|
||||
|
||||
return portConfig.length + uartConfig.length;
|
||||
}
|
||||
|
||||
public String getAddressAsString(int addr) {
|
||||
return Utils.hex20(addr);
|
||||
}
|
||||
|
||||
public ClockSystem createClockSystem(MSP430Core cpu, int[] memory, Timer[] timers) {
|
||||
return new UnifiedClockSystem(cpu, memory, 0, timers);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2012, Thingsquare.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package se.sics.mspsim.core;
|
||||
|
||||
public class PMMDummy extends IOUnit {
|
||||
public static int SIZE = 0x10;
|
||||
|
||||
public PMMDummy(MSP430Core cpu, int[] memory, int address) {
|
||||
super("PMMDummy", "PMMDummy", cpu, memory, address);
|
||||
reset(0);
|
||||
}
|
||||
|
||||
public void reset(int type) {
|
||||
}
|
||||
|
||||
public void write(int address, int value, boolean word, long cycles) {
|
||||
memory[address] = value;
|
||||
}
|
||||
|
||||
public int read(int address, boolean word, long cycles) {
|
||||
return memory[address];
|
||||
}
|
||||
|
||||
public void interruptServiced(int vector) {
|
||||
if (DEBUG) {
|
||||
log(this.getName() + ": Interrupt services vector: " + vector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
* Copyright (c) 2012, Thingsquare.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package se.sics.mspsim.core;
|
||||
|
||||
import se.sics.mspsim.chip.CC1101;
|
||||
import se.sics.mspsim.chip.CC1101.GDOListener;
|
||||
import se.sics.mspsim.core.IOPort.PinState;
|
||||
|
||||
public class RF1A extends IOUnit implements InterruptHandler {
|
||||
private boolean DEBUG = true;
|
||||
|
||||
public static int ADDRESS = 0xf00;
|
||||
public static int SIZE = 64;
|
||||
|
||||
private static final int RF1AIFCTL0 = 0x00;
|
||||
private static final int RF1AIFCTL1 = 0x02;
|
||||
private static final int RF1AIFCTL2 = 0x04;
|
||||
private static final int RF1AIFERR = 0x06;
|
||||
private static final int RF1AIFERRV = 0x0c;
|
||||
private static final int RF1AIFIV = 0x0e;
|
||||
private static final int RF1AINSTRW = 0x10;
|
||||
private static final int RF1AINSTR1W = 0x12;
|
||||
private static final int RF1AINSTR2B = 0x14;
|
||||
private static final int RF1ADINW = 0x16;
|
||||
private static final int RF1ADOUTB = 0x20;
|
||||
private static final int RF1ASTATB = 0x21;
|
||||
private static final int RF1ASTAT1W = 0x22;
|
||||
private static final int RF1ASTAT2W = 0x24;
|
||||
private static final int RF1ADOUT0W = 0x28;
|
||||
private static final int RF1ADOUT1W = 0x2a;
|
||||
private static final int RF1ADOUT2W = 0x2c;
|
||||
private static final int RF1AIN = 0x30;
|
||||
private static final int RF1AIFG = 0x32;
|
||||
private static final int RF1AIES = 0x34;
|
||||
private static final int RF1AIE = 0x36;
|
||||
private static final int RF1AIV = 0x38;
|
||||
private static final int RF1ARXFIFO = 0x3c;
|
||||
private static final int RF1ATXFIFO = 0x3e;
|
||||
|
||||
private CC1101 cc1101;
|
||||
|
||||
private boolean interruptOnCC1101GDO0 = false;
|
||||
private boolean gdo0IsHigh = false;
|
||||
|
||||
public RF1A(final MSP430Core cpu, int[] memory) {
|
||||
super("RF1A", "RF1A", cpu, memory, ADDRESS);
|
||||
cc1101 = new CC1101(cpu);
|
||||
cc1101.setGDO0Listener(new GDOListener() {
|
||||
public void event(PinState state) {
|
||||
/* cc430f5137 datasheet p. 17 */
|
||||
gdo0IsHigh = (state == PinState.HI);
|
||||
cpu.flagInterrupt(53, RF1A.this, gdo0IsHigh);
|
||||
}
|
||||
});
|
||||
|
||||
reset(0);
|
||||
}
|
||||
|
||||
public void reset(int type) {
|
||||
/* Initial values */
|
||||
memory[ADDRESS + 0x00] = 0x0000; /* RF1AIFCTL0 */
|
||||
memory[ADDRESS + 0x02] = 0x0000; /* RF1AIFCTL1 */
|
||||
memory[ADDRESS + 0x04] = 0x0000; /* RF1AIFCTL2 */
|
||||
memory[ADDRESS + 0x06] = 0x0000; /* RF1AIFERR */
|
||||
memory[ADDRESS + 0x0c] = 0x0000; /* RF1AIFERRV */
|
||||
memory[ADDRESS + 0x0e] = 0x0000; /* RF1AIFIV */
|
||||
memory[ADDRESS + 0x10] = 0x0000; /* RF1AINSTRW */
|
||||
|
||||
memory[ADDRESS + 0x12] = 0x0000; /* RF1AINSTR1W */
|
||||
memory[ADDRESS + 0x14] = 0x0000; /* RF1AINSTR2B */
|
||||
memory[ADDRESS + 0x16] = 0x0000; /* RF1ADINW */
|
||||
|
||||
memory[ADDRESS + 0x20] = 0x0000; /* RF1ASTAT0W */
|
||||
memory[ADDRESS + 0x22] = 0x0000; /* RF1ASTAT1W */
|
||||
memory[ADDRESS + 0x24] = 0x0000; /* RF1ASTAT2W */
|
||||
memory[ADDRESS + 0x28] = 0x0000; /* RF1ADOUT0W */
|
||||
|
||||
memory[ADDRESS + 0x2a] = 0x0000; /* RF1ADOUT1W */
|
||||
memory[ADDRESS + 0x2c] = 0x0000; /* RF1ADOUT2W */
|
||||
|
||||
memory[ADDRESS + 0x30] = 0x0000; /* RF1AIN */
|
||||
memory[ADDRESS + 0x32] = 0x0000; /* RF1AIFG */
|
||||
memory[ADDRESS + 0x34] = 0x0000; /* RF1AIES */
|
||||
memory[ADDRESS + 0x36] = 0x0000; /* RF1AIE */
|
||||
memory[ADDRESS + 0x38] = 0x0000; /* RF1AIV */
|
||||
|
||||
memory[ADDRESS + 0x3c] = 0x0000; /* RF1ARXFIFO */
|
||||
memory[ADDRESS + 0x3e] = 0x0000; /* RF1ATXFIFO */
|
||||
|
||||
interruptOnCC1101GDO0 = false;
|
||||
|
||||
ioAddress = -1;
|
||||
ioBurst = false;
|
||||
ioRead = false;
|
||||
ioWrite = false;
|
||||
expectingDummyWrite = false;
|
||||
}
|
||||
|
||||
private int ioAddress = -1;
|
||||
private boolean ioBurst = false;
|
||||
private boolean ioRead = false;
|
||||
private boolean ioWrite = false;
|
||||
private boolean expectingDummyWrite = false;
|
||||
public void write(int address, int value, boolean word, long cycles) {
|
||||
/*if (DEBUG) {
|
||||
System.out.printf(this.getName() + ": Write to 0x%04x: 0x%04x\n", address, value);
|
||||
}*/
|
||||
|
||||
if (address == ADDRESS + RF1AIE) {
|
||||
/* Configure interrupts */
|
||||
interruptOnCC1101GDO0 = (value & 1) != 0;
|
||||
} else if (address == ADDRESS + RF1AINSTRW + 1) {
|
||||
/* Store address. Read/write? Burst/single? */
|
||||
expectingDummyWrite = false;
|
||||
ioBurst = CC1101.spiIsBurst(value);
|
||||
if (!ioBurst && CC1101.spiIsStrobe(value)) {
|
||||
/* Execute strobe command */
|
||||
cc1101.setLastInstructionWasRead(false); /* This is probably wrong! */
|
||||
ioBurst = false;
|
||||
ioRead = false;
|
||||
ioWrite = false;
|
||||
expectingDummyWrite = true;
|
||||
cc1101.strobe(value & (~CC1101.SPI_READ_BIT) & (~CC1101.SPI_BURST_BIT));
|
||||
} else {
|
||||
/* Store address */
|
||||
ioRead = CC1101.spiIsRead(value);
|
||||
ioWrite = !ioRead;
|
||||
cc1101.setLastInstructionWasRead(ioRead);
|
||||
ioAddress = value & (~CC1101.SPI_READ_BIT) & (~CC1101.SPI_BURST_BIT);
|
||||
if (DEBUG) {
|
||||
if (ioAddress == CC1101.CC1101_RXFIFO) {
|
||||
} else if (ioAddress == CC1101.CC1101_MARCSTATE) {
|
||||
} else if (ioAddress == CC1101.CC1101_RXBYTES) {
|
||||
} else if (ioAddress == CC1101.CC1101_TXBYTES) {
|
||||
} else {
|
||||
System.out.printf("IO address 0x%04x (" + (ioRead?"read":"write") + ", " + (ioBurst?"burst":"single") + ")\n", ioAddress);
|
||||
}
|
||||
}
|
||||
if (ioRead) {
|
||||
expectingDummyWrite = true;
|
||||
}
|
||||
}
|
||||
} else if (address == ADDRESS + RF1AINSTRW) {
|
||||
if (expectingDummyWrite) {
|
||||
/* Ignore dummy write */
|
||||
expectingDummyWrite = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ioRead && !ioWrite) {
|
||||
System.out.printf("Error: Unknown data mode for write 0x%04x\n", address);
|
||||
return;
|
||||
} else if (ioRead) {
|
||||
System.out.printf("Error: writing in read mode: 0x%04x\n", address);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Write CC1101 register */
|
||||
cc1101.setReg(ioAddress, value);
|
||||
if (ioBurst) {
|
||||
if (ioAddress != CC1101.CC1101_TXFIFO && ioAddress != CC1101.CC1101_PATABLE) {
|
||||
ioAddress++;
|
||||
}
|
||||
} else {
|
||||
ioWrite = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int read(int address, boolean word, long cycles) {
|
||||
/*if (DEBUG) {
|
||||
System.out.printf(this.getName() + ": Read from 0x%04x\n", address);
|
||||
}*/
|
||||
|
||||
if (address == ADDRESS + RF1AIV) {
|
||||
if (interruptOnCC1101GDO0 && gdo0IsHigh) {
|
||||
return 2; /* RF1AIV_RFIFG0 */
|
||||
}
|
||||
return 0;
|
||||
} else if (address == ADDRESS + RF1AIFCTL1) {
|
||||
/* XXX TODO: CTL1 always return 0xFF */
|
||||
return 0xff;
|
||||
} else if (address == ADDRESS + RF1ASTAT1W + 1) {
|
||||
/* Marcstate */
|
||||
return cc1101.getMarcstate();
|
||||
} else if (!word && address == ADDRESS + RF1ASTATB) {
|
||||
/* Status byte */
|
||||
return cc1101.getStatusByte();
|
||||
} else if (address == ADDRESS + RF1ADOUTB) {
|
||||
/* Return last received byte from emulated SPI interface */
|
||||
|
||||
if (!ioRead && !ioWrite) {
|
||||
System.out.printf("Error: Unknown data mode for read 0x%04x\n", address);
|
||||
return -1;
|
||||
} else if (ioWrite) {
|
||||
System.out.printf("Error: reading in write mode: 0x%04x\n", address);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Read CC1101 register */
|
||||
int val = cc1101.getReg(ioAddress);
|
||||
|
||||
if (ioBurst) {
|
||||
if (ioAddress != CC1101.CC1101_TXFIFO && ioAddress != CC1101.CC1101_PATABLE) {
|
||||
ioAddress++;
|
||||
}
|
||||
} else {
|
||||
ioRead = false;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void interruptServiced(int vector) {
|
||||
if (DEBUG) {
|
||||
System.out.println(this.getName() + ": Interrupt services vector: " + vector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
package se.sics.mspsim.platform.ti;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import se.sics.mspsim.config.CC430f5137Config;
|
||||
import se.sics.mspsim.core.IOPort;
|
||||
import se.sics.mspsim.core.IOUnit;
|
||||
import se.sics.mspsim.core.PortListener;
|
||||
import se.sics.mspsim.core.USARTListener;
|
||||
import se.sics.mspsim.core.USARTSource;
|
||||
import se.sics.mspsim.platform.GenericNode;
|
||||
import se.sics.mspsim.ui.SerialMon;
|
||||
import se.sics.mspsim.util.ArgumentManager;
|
||||
|
||||
public class CC430Node extends GenericNode implements PortListener, USARTListener {
|
||||
|
||||
IOPort port1;
|
||||
IOPort port3;
|
||||
IOPort port4;
|
||||
IOPort port5;
|
||||
IOPort port7;
|
||||
IOPort port8;
|
||||
|
||||
public CC430Node() {
|
||||
/* TODO XXX MSP430F5438 */
|
||||
super("CC430", new CC430f5137Config());
|
||||
}
|
||||
|
||||
public void dataReceived(USARTSource source, int data) {
|
||||
}
|
||||
|
||||
public void portWrite(IOPort source, int data) {
|
||||
|
||||
}
|
||||
|
||||
private void setupNodePorts() {
|
||||
port1 = cpu.getIOUnit(IOPort.class, "P1");
|
||||
port1.addPortListener(this);
|
||||
port3 = cpu.getIOUnit(IOPort.class, "P3");
|
||||
port3.addPortListener(this);
|
||||
port4 = cpu.getIOUnit(IOPort.class, "P4");
|
||||
port4.addPortListener(this);
|
||||
port5 = cpu.getIOUnit(IOPort.class, "P5");
|
||||
port5.addPortListener(this);
|
||||
port7 = cpu.getIOUnit(IOPort.class, "P7");
|
||||
port7.addPortListener(this);
|
||||
port8 = cpu.getIOUnit(IOPort.class, "P8");
|
||||
port8.addPortListener(this);
|
||||
|
||||
IOUnit usart0 = cpu.getIOUnit("USCI B0");
|
||||
if (usart0 instanceof USARTSource) {
|
||||
registry.registerComponent("serialio0", usart0);
|
||||
}
|
||||
|
||||
IOUnit usart = cpu.getIOUnit("USCI A0");
|
||||
if (usart instanceof USARTSource) {
|
||||
registry.registerComponent("serialio", usart);
|
||||
}
|
||||
}
|
||||
|
||||
public void setupNode() {
|
||||
setupNodePorts();
|
||||
|
||||
if (!config.getPropertyAsBoolean("nogui", true)) {
|
||||
// Add some windows for listening to serial output
|
||||
IOUnit usart = cpu.getIOUnit("USCI A0");
|
||||
if (usart instanceof USARTSource) {
|
||||
SerialMon serial = new SerialMon((USARTSource)usart, "USCI A0 Port Output");
|
||||
registry.registerComponent("serialgui", serial);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getModeMax() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
CC430Node node = new CC430Node();
|
||||
ArgumentManager config = new ArgumentManager();
|
||||
config.handleArguments(args);
|
||||
node.setupArgs(config);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue