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(u16 delay){
93 #if defined(FIFOP) && defined(SFD) && defined(FIFO) && defined(PLED2DIR) && defined(PLED2PIN) && defined(PLED2OUT)
96 debugstr("Reflex jamming until reset.");
98 txdata(CCSPI,CCSPI_REFLEX,1); //Let the client continue its business.
100 //Wait until a packet is received
102 //Has there been an overflow in the RX buffer?
104 debugstr("Clearing RX overflow");
106 ccspitrans8(0x08); //SFLUSHRX
110 //Turn on LED 2 (green) as signal
111 PLED2DIR |= PLED2PIN;
112 PLED2OUT &= ~PLED2PIN;
116 //Wait a few us to send it.
119 //Put radio in TX mode
125 //Load the jamming packet.
126 //Note: attempts to preload this actually slowed the jam time down from 7 to 9 bytes.
128 ccspitrans8(CCSPI_TXFIFO);
129 char pkt[15] = {0x0f, 0x01, 0x08, 0x82, 0xff, 0xff, 0xff, 0xff, 0xde, 0xad, 0xbe, 0xef, 0xba, 0xbe, 0xc0};
130 //char pkt[12] = {0x0c, 0x01, 0x08, 0x82, 0xff, 0xff, 0xff, 0xff, 0xde, 0xad, 0xbe, 0xef};
131 for(i=0;i<pkt[0];i++)
136 //Transmit the packet.
138 ccspitrans8(0x04); //STXON
141 //msdelay(100+delay); //Instead of waiting for pulse on SFD
145 ccspitrans8(0x09); //SFLUSHTX
148 //Turn off LED 2 (green) as signal
149 PLED2DIR |= PLED2PIN;
150 PLED2OUT |= PLED2PIN;
153 debugstr("Can't reflexively jam without SFD, FIFO, FIFOP, and P2LEDx definitions - try using telosb platform.");
160 //! Writes a register
161 u8 ccspi_regwrite(u8 reg, const u8 *buf, int len){
164 reg=ccspitrans8(reg);
172 u8 ccspi_regread(u8 reg, u8 *buf, int len){
175 reg=ccspitrans8(reg);
177 *buf++=ccspitrans8(0);
183 //! Handles a Chipcon SPI command.
184 void ccspi_handle_fn( uint8_t const app,
190 //debugstr("Chipcon SPI handler.");
194 cmddata[0]|=0x40; //Set the read bit.
199 CLRSS; //Drop !SS to begin transaction.
200 j=cmddata[0];//Backup address.
202 cmddata[i]=ccspitrans8(cmddata[i]);
203 SETSS; //Raise !SS to end transaction.
204 cmddata[0]=j&~0x40;//Restore address.
205 txdata(app,verb,len);
213 //Has there been an overflow?
215 //debugstr("Clearing overflow");
217 ccspitrans8(0x08); //SFLUSHRX
223 //Wait for completion.
228 ccspitrans8(CCSPI_RXFIFO | 0x40);
229 //ccspitrans8(0x3F|0x40);
230 cmddata[0]=0xff; //to be replaced with length
231 for(i=0;i<cmddata[0]+2;i++)
232 cmddata[i]=ccspitrans8(0xde);
237 ccspitrans8(0x08); //SFLUSHRX
241 //Only should transmit length of one more than the reported
242 // length of the frame, which holds the length byte:
243 txdata(app,verb,cmddata[0]+1);
249 debugstr("Can't RX a packet with SFD and FIFOP definitions.");
256 ccspitrans8(CCSPI_SFLUSHRX);
263 ccspireflexjam(len?cmddataword[0]:0);
266 case CCSPI_REFLEX_AUTOACK:
267 #if defined(FIFOP) && defined(SFD) && defined(FIFO) && defined(PLED2DIR) && defined(PLED2PIN) && defined(PLED2OUT)
268 //txdata(app, verb, 1);
272 //Has there been an overflow in the RX buffer?
274 //debugstr("Clearing overflow");
276 ccspitrans8(0x08); //SFLUSHRX
280 //Wait until a packet is received
282 //Turn on LED 2 (green) as signal
283 PLED2DIR |= PLED2PIN;
284 PLED2OUT &= ~PLED2PIN;
286 //Put radio in TX mode
287 //Note: Not doing this slows down jamming, so can't jam short packets.
288 // However, if we do this, it seems to mess up our RXFIFO ability.
292 //Load the jamming packet
294 ccspitrans8(CCSPI_TXFIFO);
295 char pkt[7] = {0x07, 0x01, 0x08, 0xff, 0xff, 0xff, 0xff};
296 for(i=0;i<pkt[0];i++)
299 //Transmit the jamming packet
301 ccspitrans8(0x04); //STXON
303 msdelay(200); //Instead of examining SFD line status
306 ccspitrans8(0x09); //SFLUSHTX
309 //Get the orignally received packet, up to the seqnum field.
311 ccspitrans8(CCSPI_RXFIFO | 0x40);
313 cmddata[i]=ccspitrans8(0xde);
317 ccspitrans8(0x08); //SFLUSHRX
319 //Send the sequence number of the jammed packet back to the client
320 //itoa(cmddata[3], byte, 16);
322 //txdata(app,verb,cmddata[3]);
324 //TODO turn on AUTOCRC for it to apply to the TX???
325 // this may overcome issues of bad crc / length issues?
326 //mdmctrl0 (0x11) register set bit 5 to true.
328 //Create the forged ACK packet
329 cmddata[0] = 6; //length of ack frame plus length
330 cmddata[1] = 0x02; //first byte of FCF
331 cmddata[2] = 0x00; //second byte of FCF
332 //[3] is already filled with the sequence number
336 int q = (crc ^ c) & 15; //Do low-order 4 bits
337 crc = (crc / 16) ^ (q * 4225);
338 q = (crc ^ (c / 16)) & 15; //And high 4 bits
339 crc = (crc / 16) ^ (q * 4225);
341 cmddata[4] = crc & 0xFF;
342 cmddata[5] = (crc >> 8) & 0xFF;
344 for(i=0;i<cmddata[0];i++) {
345 itoa(cmddata[i], byte, 16);
348 //Load the forged ACK packet
350 ccspitrans8(CCSPI_TXFIFO);
351 for(i=0;i<cmddata[0];i++)
352 ccspitrans8(cmddata[i]);
354 //Transmit the forged ACK packet
357 ccspitrans8(0x04); //STXON
359 msdelay(200); //TODO try doing this based on SFD line status instead
362 ccspitrans8(0x09); //SFLUSHTX
365 //TODO disable AUTOCRC here again to go back to promiscous mode
367 //Turn off LED 2 (green) as signal
368 PLED2DIR |= PLED2PIN;
369 PLED2OUT |= PLED2PIN;
371 //TODO the firmware stops staying in this mode after a while, and stops jamming... need to find a fix.
373 debugstr("Can't reflexively jam without SFD, FIFO, FIFOP, and P2LEDx definitions - try using telosb platform.");
381 ccspitrans8(CCSPI_SFLUSHTX);
389 //Wait for last packet to TX.
390 //while(ccspi_status()&BIT3);
394 ccspitrans8(0x09); //SFLUSHTX
400 ccspitrans8(CCSPI_TXFIFO);
401 for(i=0;i<cmddata[0];i++)
402 ccspitrans8(cmddata[i]);
405 //Transmit the packet.
407 ccspitrans8(0x04); //STXON
410 //Wait for the pulse on SFD, after which the packet has been sent.
416 debugstr("Can't TX a packet with SFD and FIFOP definitions.");
421 debugstr("Not yet supported in CCSPI");