diff --git a/se/sics/mspsim/chip/CC2520.java b/se/sics/mspsim/chip/CC2520.java index 884f963..7564b34 100644 --- a/se/sics/mspsim/chip/CC2520.java +++ b/se/sics/mspsim/chip/CC2520.java @@ -398,6 +398,8 @@ public class CC2520 extends Chip implements USARTListener, RFListener, RFSource, private final int[] registers = new int[128]; private final int[] memory = new int[384 + 128]; + private CC2520SPI cc2520SPI = new CC2520SPI(this); + private SPICommand command; private int[] spiData = new int[20]; /* SPI data buffer */ private int spiLen; @@ -896,6 +898,24 @@ public class CC2520 extends Chip implements USARTListener, RFListener, RFSource, return; } + if (command == null) { + command = cc2520SPI.getCommand(data); + if (command == null) { + logw("**** Warning - not implemented command on SPI: " + data); + } + } + + spiData[spiLen] = data; + if (spiLen < spiData.length) spiLen++; + if (command != null) { + command.dataReceived(data); + if (spiLen == command.commandLen) { + System.out.println("CC2520 Executing command: " + command.name); + command.executeSPICommand(); + command = null; + } + } + if (instruction == -1) { // New instruction if ((data & 0xc0) == INS_REGRD) { @@ -1664,6 +1684,8 @@ public class CC2520 extends Chip implements USARTListener, RFListener, RFSource, // setReg(usartDataAddress, usartDataValue); // } instruction = -1; + spiLen = 0; + command = null; // state = SpiState.WAITING; } diff --git a/se/sics/mspsim/chip/CC2520SPI.java b/se/sics/mspsim/chip/CC2520SPI.java index fff57f0..c5b2596 100644 --- a/se/sics/mspsim/chip/CC2520SPI.java +++ b/se/sics/mspsim/chip/CC2520SPI.java @@ -1,59 +1,86 @@ package se.sics.mspsim.chip; public class CC2520SPI { - SPICommand[] spiCommands = { - new SPICommand("SNOP 0 0 0 0 0 0 0 0"), - new SPICommand("IBUFLD 0 0 0 0 0 0 1 0 i i i i i i i i"), - new SPICommand("SIBUFEX 0 0 0 0 0 0 1 1"), - new SPICommand("SSAMPLECCA 0 0 0 0 0 1 0 0"), - new SPICommand("SRES 0 0 0 0 1 1 1 1 - - - - - - - -"), - new SPICommand("MEMRD 0 0 0 1 a a a a a a a a a a a a - - - - - - - - ..."), - new SPICommand("MEMWR 0 0 1 0 a a a a a a a a a a a a d d d d d d d d ..."), - new SPICommand("RXBUF 0 0 1 1 0 0 0 0 - - - - - - - - ..."), - new SPICommand("RXBUFCP 0 0 1 1 1 0 0 0 0 0 0 0 a a a a a a a a a a a a - - - - - - - - ..."), - new SPICommand("RXBUFMOV 0 0 1 1 0 0 1 p c c c c c c c c 0 0 0 0 a a a a a a a a a a a a"), - new SPICommand("TXBUF 0 0 1 1 1 0 1 0 d d d d d d d d d d d d d d d d ..."), - new SPICommand("TXBUFCP 0 0 1 1 1 1 1 p c c c c c c c c 0 0 0 0 a a a a a a a a a a a a"), - new SPICommand("RANDOM 0 0 1 1 1 1 0 0 - - - - - - - - - - - - - - - - ..."), - new SPICommand("SXOSCON 0 1 0 0 0 0 0 0"), - new SPICommand("STXCAL 0 1 0 0 0 0 0 1"), - new SPICommand("SRXON 0 1 0 0 0 0 1 0"), - new SPICommand("STXON 0 1 0 0 0 0 1 1"), - new SPICommand("STXONCCA 0 1 0 0 0 1 0 0"), - new SPICommand("SRFOFF 0 1 0 0 0 1 0 1"), - new SPICommand("SXOSCOFF 0 1 0 0 0 1 1 0"), - new SPICommand("SFLUSHRX 0 1 0 0 0 1 1 1"), - new SPICommand("SFLUSHTX 0 1 0 0 1 0 0 0"), - new SPICommand("SACK 0 1 0 0 1 0 0 1"), - new SPICommand("SACKPEND 0 1 0 0 1 0 1 0"), - new SPICommand("SNACK 0 1 0 0 1 0 1 1"), - new SPICommand("SRXMASKBITSET 0 1 0 0 1 1 0 0"), - new SPICommand("SRXMASKBITCLR 0 1 0 0 1 1 0 1"), - new SPICommand("RXMASKAND 0 1 0 0 1 1 1 0 d d d d d d d d d d d d d d d d"), - new SPICommand("RXMASKOR 0 1 0 0 1 1 1 1 d d d d d d d d d d d d d d d d"), - new SPICommand("MEMCP 0 1 0 1 0 0 0 p c c c c c c c c a a a a e e e e a a a a a a a a e e e e e e e e"), - new SPICommand("MEMCPR 0 1 0 1 0 0 1 p c c c c c c c c a a a a e e e e a a a a a a a a e e e e e e e e"), - new SPICommand("MEMXCP 0 1 0 1 0 1 0 p c c c c c c c c a a a a e e e e a a a a a a a a e e e e e e e e"), - new SPICommand("MEMXWR 0 1 0 1 0 1 1 0 0 0 0 0 a a a a a a a a a a a a d d d d d d d d ..."), - new SPICommand("BCLR 0 1 0 1 1 0 0 0 a a a a a b b b"), - new SPICommand("BSET 0 1 0 1 1 0 0 1 a a a a a b b b"), - new SPICommand("CTR/UCTR 0 1 1 0 0 0 0 p k k k k k k k k 0 c c c c c c c n n n n n n n n a a a a e e e e a a a a a a a a e e e e e e e e"), - new SPICommand("CBCMAC 0 1 1 0 0 1 0 p k k k k k k k k 0 c c c c c c c a a a a e e e e a a a a a a a a e e e e e e e e 0 0 0 0 0 mmm"), - new SPICommand("UCBCMAC 0 1 1 0 0 1 1 p k k k k k k k k 0 c c c c c c c 0 0 0 0 a a a a a a a a a a a a 0 0 0 0 0 mmm"), - new SPICommand("CCM 0 1 1 0 1 0 0 p k k k k k k k k 0 c c c c c c c n n n n n n n n a a a a e e e e a a a a a a a a e e e e e e e e 0 f f f f f f f 0 0 0 0 0 0 mm"), - new SPICommand("UCCM 0 1 1 0 1 0 1 p k k k k k k k k 0 c c c c c c c n n n n n n n n a a a a e e e e a a a a a a a a e e e e e e e e 0 f f f f f f f 0 0 0 0 0 0 mm"), - new SPICommand("ECB 0 1 1 1 0 0 0 p k k k k k k k k c c c c a a a a a a a a a a a a 0 0 0 0 e e e e e e e e e e e e"), - new SPICommand("ECBO 0 1 1 1 0 0 1 p k k k k k k k k c c c c a a a a a a a a a a a a"), - new SPICommand("ECBX 0 1 1 1 0 1 0 p k k k k k k k k c c c c a a a a a a a a a a a a 0 0 0 0 e e e e e e e e e e e e"), - new SPICommand("INC 0 1 1 1 1 0 0 p 0 0 c c a a a a a a a a a a a a"), - new SPICommand("ABORT 0 1 1 1 1 1 1 1 0 0 0 0 0 0 c c"), - new SPICommand("REGRD 1 0 a a a a a a - - - - - - - - ..."), - new SPICommand("REGWR 1 1 a a a a a a d d d d d d d d ...") - }; + CC2520 cc2520; + private int[] memory; /* pointer to the memory of cc2520 */ SPICommand[] commands = new SPICommand[256]; - CC2520SPI() { + public CC2520SPI(CC2520 cc) { + /* the SPI commands for CC2520 */ + SPICommand[] spiCommands = { + new SPICommand("SNOP 0 0 0 0 0 0 0 0",cc2520) { + public void executeSPICommand() {} + }, + new SPICommand("IBUFLD 0 0 0 0 0 0 1 0 i i i i i i i i",cc2520) { + public void executeSPICommand() { + System.out.println(name + " storing in buffer: " + spiData.getSPIData()[1]); + cc2520.instructionBuffer = spiData.getSPIData()[1]; + } + }, + new SPICommand("SIBUFEX 0 0 0 0 0 0 1 1",cc2520), + new SPICommand("SSAMPLECCA 0 0 0 0 0 1 0 0",cc2520), + new SPICommand("SRES 0 0 0 0 1 1 1 1 - - - - - - - -",cc2520), + new SPICommand("MEMRD 0 0 0 1 a a a a a a a a a a a a - - - - - - - - ...",cc2520), + new SPICommand("MEMWR 0 0 1 0 a a a a a a a a a a a a d d d d d d d d ...",cc2520), + new SPICommand("RXBUF 0 0 1 1 0 0 0 0 - - - - - - - - ...",cc2520), + new SPICommand("RXBUFCP 0 0 1 1 1 0 0 0 0 0 0 0 a a a a a a a a a a a a - - - - - - - - ...",cc2520), + new SPICommand("RXBUFMOV 0 0 1 1 0 0 1 p c c c c c c c c 0 0 0 0 a a a a a a a a a a a a",cc2520), + new SPICommand("TXBUF 0 0 1 1 1 0 1 0 d d d d d d d d d d d d d d d d ...",cc2520), + new SPICommand("TXBUFCP 0 0 1 1 1 1 1 p c c c c c c c c 0 0 0 0 a a a a a a a a a a a a",cc2520), + new SPICommand("RANDOM 0 0 1 1 1 1 0 0 - - - - - - - - - - - - - - - - ...",cc2520), + new SPICommand("SXOSCON 0 1 0 0 0 0 0 0",cc2520), + new SPICommand("STXCAL 0 1 0 0 0 0 0 1",cc2520), + new SPICommand("SRXON 0 1 0 0 0 0 1 0",cc2520), + new SPICommand("STXON 0 1 0 0 0 0 1 1",cc2520) { + public void executeSPICommand() { + cc2520.stxon(); + } + }, + new SPICommand("STXONCCA 0 1 0 0 0 1 0 0",cc2520), + new SPICommand("SRFOFF 0 1 0 0 0 1 0 1",cc2520), + new SPICommand("SXOSCOFF 0 1 0 0 0 1 1 0",cc2520), + new SPICommand("SFLUSHRX 0 1 0 0 0 1 1 1",cc2520), + new SPICommand("SFLUSHTX 0 1 0 0 1 0 0 0",cc2520), + new SPICommand("SACK 0 1 0 0 1 0 0 1",cc2520), + new SPICommand("SACKPEND 0 1 0 0 1 0 1 0",cc2520), + new SPICommand("SNACK 0 1 0 0 1 0 1 1",cc2520), + new SPICommand("SRXMASKBITSET 0 1 0 0 1 1 0 0",cc2520), + new SPICommand("SRXMASKBITCLR 0 1 0 0 1 1 0 1",cc2520), + new SPICommand("RXMASKAND 0 1 0 0 1 1 1 0 d d d d d d d d d d d d d d d d",cc2520), + new SPICommand("RXMASKOR 0 1 0 0 1 1 1 1 d d d d d d d d d d d d d d d d",cc2520), + new SPICommand("MEMCP 0 1 0 1 0 0 0 p c c c c c c c c a a a a e e e e a a a a a a a a e e e e e e e e",cc2520), + new SPICommand("MEMCPR 0 1 0 1 0 0 1 p c c c c c c c c a a a a e e e e a a a a a a a a e e e e e e e e",cc2520), + new SPICommand("MEMXCP 0 1 0 1 0 1 0 p c c c c c c c c a a a a e e e e a a a a a a a a e e e e e e e e",cc2520), + new SPICommand("MEMXWR 0 1 0 1 0 1 1 0 0 0 0 0 a a a a a a a a a a a a d d d d d d d d ...",cc2520), + new SPICommand("BCLR 0 1 0 1 1 0 0 0 a a a a a b b b",cc2520), + new SPICommand("BSET 0 1 0 1 1 0 0 1 a a a a a b b b",cc2520), + new SPICommand("CTR/UCTR 0 1 1 0 0 0 0 p k k k k k k k k 0 c c c c c c c n n n n n n n n a a a a e e e e a a a a a a a a e e e e e e e e",cc2520), + new SPICommand("CBCMAC 0 1 1 0 0 1 0 p k k k k k k k k 0 c c c c c c c a a a a e e e e a a a a a a a a e e e e e e e e 0 0 0 0 0 mmm",cc2520), + new SPICommand("UCBCMAC 0 1 1 0 0 1 1 p k k k k k k k k 0 c c c c c c c 0 0 0 0 a a a a a a a a a a a a 0 0 0 0 0 mmm",cc2520), + new SPICommand("CCM 0 1 1 0 1 0 0 p k k k k k k k k 0 c c c c c c c n n n n n n n n a a a a e e e e a a a a a a a a e e e e e e e e 0 f f f f f f f 0 0 0 0 0 0 mm",cc2520), + new SPICommand("UCCM 0 1 1 0 1 0 1 p k k k k k k k k 0 c c c c c c c n n n n n n n n a a a a e e e e a a a a a a a a e e e e e e e e 0 f f f f f f f 0 0 0 0 0 0 mm",cc2520), + new SPICommand("ECB 0 1 1 1 0 0 0 p k k k k k k k k c c c c a a a a a a a a a a a a 0 0 0 0 e e e e e e e e e e e e",cc2520), + new SPICommand("ECBO 0 1 1 1 0 0 1 p k k k k k k k k c c c c a a a a a a a a a a a a",cc2520), + new SPICommand("ECBX 0 1 1 1 0 1 0 p k k k k k k k k c c c c a a a a a a a a a a a a 0 0 0 0 e e e e e e e e e e e e",cc2520), + new SPICommand("INC 0 1 1 1 1 0 0 p 0 0 c c a a a a a a a a a a a a",cc2520), + new SPICommand("ABORT 0 1 1 1 1 1 1 1 0 0 0 0 0 0 c c",cc2520), + new SPICommand("REGRD 1 0 a a a a a a - - - - - - - - ...",cc2520) { + BitField adr = getBitField("a"); + int cAdr = 0; + public boolean dataReceived(int data) { + /* check if this is first byte*/ + if (spiData.getSPIlen() == 0) { + cAdr = adr.getValue(); + } else { + spiData.outputSPI(memory[cAdr++]); + } + return true; + } + public void executeSPICommand() {} + }, + new SPICommand("REGWR 1 1 a a a a a a d d d d d d d d ...",cc2520)}; + /* set up the commands */ for (int i = 0; i < spiCommands.length; i++) { SPICommand c = spiCommands[i]; @@ -70,6 +97,7 @@ public class CC2520SPI { } } + SPICommand getCommand(int cmd) { if (cmd < 256 && commands[cmd] != null) return commands[cmd]; @@ -77,11 +105,11 @@ public class CC2520SPI { } - public static void main(String[] args) { - CC2520SPI spi = new CC2520SPI(); - SPICommand cmd = spi.getCommand(0xff); - /* commands that take infinite number of bytes have the bitfield ... */ - System.out.println("Has ... => " + cmd.getBitField("...")); - } +// public static void main(String[] args) { +// CC2520SPI spi = new CC2520SPI(); +// SPICommand cmd = spi.getCommand(0xff); +// /* commands that take infinite number of bytes have the bitfield ... */ +// System.out.println("Has ... => " + cmd.getBitField("...",cc2520)); +// } } diff --git a/se/sics/mspsim/chip/SPICommand.java b/se/sics/mspsim/chip/SPICommand.java index 55ebfe0..b52abfb 100644 --- a/se/sics/mspsim/chip/SPICommand.java +++ b/se/sics/mspsim/chip/SPICommand.java @@ -1,19 +1,22 @@ package se.sics.mspsim.chip; import java.util.ArrayList; -import java.util.Iterator; public class SPICommand { /* * MEMXCP 0 1 0 1 0 1 0 p c c c c c c c c a a a a e e e e a a a a a a a a e e e e e e e e */ + public final static int DYNAMIC_LENGTH = 0xffff; + String name; int mask; int value; int bitCount; int commandLen = 0; + + SPIData spiData; - private class BitField { + class BitField { String name; int startBit; int endBit; @@ -28,15 +31,15 @@ public class SPICommand { System.out.printf("First mask %x\n", firstMask); } - public int getValue(int[] spiData) { + public int getValue() { int value; int firstByte = startBit / 8; int lastByte = endBit / 8; int nrBitsRoll = 7 - endBit & 7; - value = spiData[firstByte] & firstMask; + value = spiData.getSPIData()[firstByte] & firstMask; for (int i = firstByte + 1; i < lastByte; i++) { - value = value << 8 + spiData[firstByte]; + value = value << 8 + spiData.getSPIData()[firstByte]; } value = value >> nrBitsRoll; @@ -46,7 +49,8 @@ public class SPICommand { ArrayList bitFields; - SPICommand(String pattern) { + SPICommand(String pattern, SPIData data) { + spiData = data; String[] subs = pattern.split(" "); name = subs[0]; System.out.println("Name:" + subs[0]); @@ -98,9 +102,12 @@ public class SPICommand { bitFields = new ArrayList(); bitFields.add(new BitField(currentName, start, c - 1)); } - + commandLen = c / 8; + if ("...".equals(currentName)) + commandLen = DYNAMIC_LENGTH; System.out.printf("Value %x\n", value); System.out.printf("Mask %x\n", mask); + System.out.println("Command len: " + commandLen); } /* return -1 if no match */ @@ -112,15 +119,15 @@ public class SPICommand { return -1; } + /* do nothing here... - override if needed */ - public boolean dataReceived(int spiData) { + public boolean dataReceived(int data) { return true; } /* for any command that is executable (finite commands) */ - public boolean executeSPICommand(int[] spiData) { + public void executeSPICommand() { System.out.println("Command " + name + " not implemented..."); - return true; } public BitField getBitField(String arg) { @@ -128,29 +135,6 @@ public class SPICommand { if (b.name.equals(arg)) return b; } /* not existing ... */ - return null; - } - - public static void main(String[] args) { - SPICommand c = new SPICommand("MEMXCP 0 1 0 1 0 1 0 p c c c c c c c c a a a a e e e e a a a a a a a a e e e e e e e e") { - public boolean executeSPICommand(int[] spiData) { - System.out.println("Yes!"); - return true; - } - }; - int[] data = new int[]{1,0x13,0xab,0xaa,0xbb}; - for (int i = 0; i < c.bitFields.size(); i++) { - System.out.printf("Data %s: %x\n", c.bitFields.get(i).name, c.bitFields.get(i).getValue(data)); - } - c.executeSPICommand(data); - - System.out.println("Bitcount:" + c.bitCount); - int maxv = 1 << (8 - c.bitCount); - int v = c.value; - - /* populate an array with the values for quick decoding */ - for (int i = 0; i < maxv; i++) { - System.out.printf("Value: %x\n", (v + i)); - } + throw new IllegalArgumentException("No bitfield with name " + arg + " exists for " + name); } }