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