2 \author Travis Goodspeed
3 \brief Chipcon SPI Register Interface
5 Unfortunately, there is very little similarity between the CC2420
6 and the CC2500, to name just two of the myriad of Chipcon SPI
7 radios. Auto-detection will be a bit difficult, but more to the
8 point, all high level functionality must be moved into the client.
11 //Higher level left to client application.
15 #include <stdlib.h> //added for itoa
20 //! Handles a Chipcon SPI command.
21 void ccspi_handle_fn( uint8_t const app,
25 // define the ccspi app's app_t
26 app_t const ccspi_app = {
38 "\tThe CCSPI app adds support for the Chipcon SPI register\n"
39 "\tinterface. Unfortunately, there is very little similarity\n"
40 "\tbetween the CC2420 and the CC2500, to name just two of the\n"
41 "\tmyriad of Chipcon SPI radios. Auto-detection will be a bit\n"
42 "\tdifficult, but more to the point, all high level functionality\n"
43 "\tmust be moved into the client.\n"
46 //! Set up the pins for CCSPI mode.
53 P4OUT|=BIT5; //activate CC2420 voltage regulator
60 //Begin a new transaction.
65 //! Read and write an CCSPI byte.
66 u8 ccspitrans8(u8 byte){
67 register unsigned int bit;
68 //This function came from the CCSPI Wikipedia article.
71 for (bit = 0; bit < 8; bit++) {
72 /* write MOSI on trailing edge of previous clock */
81 /* read MISO on trailing edge */
90 //! Reflexively jam on the present channel.
91 void ccspireflexjam(){
93 #if defined(FIFOP) && defined(SFD) && defined(FIFO) && defined(PLED2DIR) && defined(PLED2PIN) && defined(PLED2OUT)
94 debugstr("Reflex jamming until reset.");
95 txdata(CCSPI,CCSPI_REFLEX,1); //Let the client continue its business.
97 //Wait until a packet is received
99 //Has there been an overflow in the RX buffer?
101 debugstr("Clearing RX overflow");
103 ccspitrans8(0x08); //SFLUSHRX
107 //Turn on LED 2 (green) as signal
108 PLED2DIR |= PLED2PIN;
109 PLED2OUT &= ~PLED2PIN;
111 //Put radio in TX mode
116 //Load the jamming packet.
117 //Note: attempts to preload this actually slowed the jam time down from 7 to 9 bytes.
119 ccspitrans8(CCSPI_TXFIFO);
120 char pkt[15] = {0x0f, 0x01, 0x08, 0x82, 0xff, 0xff, 0xff, 0xff, 0xde, 0xad, 0xbe, 0xef, 0xba, 0xbe, 0xc0};
121 //char pkt[12] = {0x0c, 0x01, 0x08, 0x82, 0xff, 0xff, 0xff, 0xff, 0xde, 0xad, 0xbe, 0xef};
122 for(i=0;i<pkt[0];i++)
126 //Transmit the packet.
128 ccspitrans8(0x04); //STXON
130 msdelay(100); //Instead of waiting for pulse on SFD
133 ccspitrans8(0x09); //SFLUSHTX
136 //Turn off LED 2 (green) as signal
137 PLED2DIR |= PLED2PIN;
138 PLED2OUT |= PLED2PIN;
141 debugstr("Can't reflexively jam without SFD, FIFO, FIFOP, and P2LEDx definitions - try using telosb platform.");
148 //! Writes a register
149 u8 ccspi_regwrite(u8 reg, const u8 *buf, int len){
152 reg=ccspitrans8(reg);
160 u8 ccspi_regread(u8 reg, u8 *buf, int len){
163 reg=ccspitrans8(reg);
165 *buf++=ccspitrans8(0);
171 //! Handles a Chipcon SPI command.
172 void ccspi_handle_fn( uint8_t const app,
178 //debugstr("Chipcon SPI handler.");
182 cmddata[0]|=0x40; //Set the read bit.
187 CLRSS; //Drop !SS to begin transaction.
188 j=cmddata[0];//Backup address.
190 cmddata[i]=ccspitrans8(cmddata[i]);
191 SETSS; //Raise !SS to end transaction.
192 cmddata[0]=j&~0x40;//Restore address.
193 txdata(app,verb,len);
201 //Has there been an overflow?
203 //debugstr("Clearing overflow");
205 ccspitrans8(0x08); //SFLUSHRX
211 //Wait for completion.
216 ccspitrans8(CCSPI_RXFIFO | 0x40);
217 //ccspitrans8(0x3F|0x40);
218 cmddata[0]=0xff; //to be replaced with length
219 for(i=0;i<cmddata[0]+2;i++)
220 cmddata[i]=ccspitrans8(0xde);
225 ccspitrans8(0x08); //SFLUSHRX
229 //Only should transmit length of one more than the reported
230 // length of the frame, which holds the length byte:
231 txdata(app,verb,cmddata[0]+1);
237 debugstr("Can't RX a packet with SFD and FIFOP definitions.");
244 ccspitrans8(CCSPI_SFLUSHRX);
254 case CCSPI_REFLEX_AUTOACK:
255 #if defined(FIFOP) && defined(SFD) && defined(FIFO) && defined(PLED2DIR) && defined(PLED2PIN) && defined(PLED2OUT)
256 //txdata(app, verb, 1);
260 //Has there been an overflow in the RX buffer?
262 //debugstr("Clearing overflow");
264 ccspitrans8(0x08); //SFLUSHRX
268 //Wait until a packet is received
270 //Turn on LED 2 (green) as signal
271 PLED2DIR |= PLED2PIN;
272 PLED2OUT &= ~PLED2PIN;
274 //Put radio in TX mode
275 //Note: Not doing this slows down jamming, so can't jam short packets.
276 // However, if we do this, it seems to mess up our RXFIFO ability.
280 //Load the jamming packet
282 ccspitrans8(CCSPI_TXFIFO);
283 char pkt[7] = {0x07, 0x01, 0x08, 0xff, 0xff, 0xff, 0xff};
284 for(i=0;i<pkt[0];i++)
287 //Transmit the jamming packet
289 ccspitrans8(0x04); //STXON
291 msdelay(200); //Instead of examining SFD line status
294 ccspitrans8(0x09); //SFLUSHTX
297 //Get the orignally received packet, up to the seqnum field.
299 ccspitrans8(CCSPI_RXFIFO | 0x40);
301 cmddata[i]=ccspitrans8(0xde);
305 ccspitrans8(0x08); //SFLUSHRX
307 //Send the sequence number of the jammed packet back to the client
308 //itoa(cmddata[3], byte, 16);
310 //txdata(app,verb,cmddata[3]);
312 //TODO turn on AUTOCRC for it to apply to the TX???
313 // this may overcome issues of bad crc / length issues?
314 //mdmctrl0 (0x11) register set bit 5 to true.
316 //Create the forged ACK packet
317 cmddata[0] = 6; //length of ack frame plus length
318 cmddata[1] = 0x02; //first byte of FCF
319 cmddata[2] = 0x00; //second byte of FCF
320 //[3] is already filled with the sequence number
324 int q = (crc ^ c) & 15; //Do low-order 4 bits
325 crc = (crc / 16) ^ (q * 4225);
326 q = (crc ^ (c / 16)) & 15; //And high 4 bits
327 crc = (crc / 16) ^ (q * 4225);
329 cmddata[4] = crc & 0xFF;
330 cmddata[5] = (crc >> 8) & 0xFF;
332 for(i=0;i<cmddata[0];i++) {
333 itoa(cmddata[i], byte, 16);
336 //Load the forged ACK packet
338 ccspitrans8(CCSPI_TXFIFO);
339 for(i=0;i<cmddata[0];i++)
340 ccspitrans8(cmddata[i]);
342 //Transmit the forged ACK packet
345 ccspitrans8(0x04); //STXON
347 msdelay(200); //TODO try doing this based on SFD line status instead
350 ccspitrans8(0x09); //SFLUSHTX
353 //TODO disable AUTOCRC here again to go back to promiscous mode
355 //Turn off LED 2 (green) as signal
356 PLED2DIR |= PLED2PIN;
357 PLED2OUT |= PLED2PIN;
359 //TODO the firmware stops staying in this mode after a while, and stops jamming... need to find a fix.
361 debugstr("Can't reflexively jam without SFD, FIFO, FIFOP, and P2LEDx definitions - try using telosb platform.");
369 ccspitrans8(CCSPI_SFLUSHTX);
377 //Wait for last packet to TX.
378 //while(ccspi_status()&BIT3);
382 ccspitrans8(0x09); //SFLUSHTX
388 ccspitrans8(CCSPI_TXFIFO);
389 for(i=0;i<cmddata[0];i++)
390 ccspitrans8(cmddata[i]);
393 //Transmit the packet.
395 ccspitrans8(0x04); //STXON
398 //Wait for the pulse on SFD, after which the packet has been sent.
404 debugstr("Can't TX a packet with SFD and FIFOP definitions.");
409 debugstr("Not yet supported in CCSPI");