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 //Transmit the packet.
125 //Load the next 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[5] = {0x05, 0, 0, 0, 0};
130 //char pkt[15] = {0x0f, 0x01, 0x08, 0x82, 0xff, 0xff, 0xff, 0xff, 0xde, 0xad, 0xbe, 0xef, 0xba, 0xbe, 0xc0};
131 //char pkt[12] = {0x0c, 0x01, 0x08, 0x82, 0xff, 0xff, 0xff, 0xff, 0xde, 0xad, 0xbe, 0xef};
132 for(i=0;i<pkt[0];i++)
136 //* I think this might be unnecessary.
137 //msdelay(100+delay); //Instead of waiting for pulse on SFD
141 ccspitrans8(0x09); //SFLUSHTX
145 //Turn off LED 2 (green) as signal
146 PLED2DIR |= PLED2PIN;
147 PLED2OUT |= PLED2PIN;
150 debugstr("Can't reflexively jam without SFD, FIFO, FIFOP, and P2LEDx definitions - try using telosb platform.");
157 //! Writes a register
158 u8 ccspi_regwrite(u8 reg, const u8 *buf, int len){
161 reg=ccspitrans8(reg);
169 u8 ccspi_regread(u8 reg, u8 *buf, int len){
172 reg=ccspitrans8(reg);
174 *buf++=ccspitrans8(0);
180 //! Handles a Chipcon SPI command.
181 void ccspi_handle_fn( uint8_t const app,
187 //debugstr("Chipcon SPI handler.");
191 cmddata[0]|=0x40; //Set the read bit.
196 CLRSS; //Drop !SS to begin transaction.
197 j=cmddata[0];//Backup address.
199 cmddata[i]=ccspitrans8(cmddata[i]);
200 SETSS; //Raise !SS to end transaction.
201 cmddata[0]=j&~0x40;//Restore address.
202 txdata(app,verb,len);
210 //Has there been an overflow?
212 //debugstr("Clearing overflow");
214 ccspitrans8(0x08); //SFLUSHRX
220 //Wait for completion.
225 ccspitrans8(CCSPI_RXFIFO | 0x40);
226 //ccspitrans8(0x3F|0x40);
227 cmddata[0]=0xff; //to be replaced with length
228 for(i=0;i<cmddata[0]+2;i++)
229 cmddata[i]=ccspitrans8(0xde);
234 ccspitrans8(0x08); //SFLUSHRX
238 //Only should transmit length of one more than the reported
239 // length of the frame, which holds the length byte:
240 txdata(app,verb,cmddata[0]+1);
246 debugstr("Can't RX a packet with SFD and FIFOP definitions.");
253 ccspitrans8(CCSPI_SFLUSHRX);
260 ccspireflexjam(len?cmddataword[0]:0);
263 case CCSPI_REFLEX_AUTOACK:
264 #if defined(FIFOP) && defined(SFD) && defined(FIFO) && defined(PLED2DIR) && defined(PLED2PIN) && defined(PLED2OUT)
265 //txdata(app, verb, 1);
269 //Has there been an overflow in the RX buffer?
271 //debugstr("Clearing overflow");
273 ccspitrans8(0x08); //SFLUSHRX
277 //Wait until a packet is received
279 //Turn on LED 2 (green) as signal
280 PLED2DIR |= PLED2PIN;
281 PLED2OUT &= ~PLED2PIN;
283 //Put radio in TX mode
284 //Note: Not doing this slows down jamming, so can't jam short packets.
285 // However, if we do this, it seems to mess up our RXFIFO ability.
289 //Load the jamming packet
291 ccspitrans8(CCSPI_TXFIFO);
292 char pkt[7] = {0x07, 0x01, 0x08, 0xff, 0xff, 0xff, 0xff};
293 for(i=0;i<pkt[0];i++)
296 //Transmit the jamming packet
298 ccspitrans8(0x04); //STXON
300 msdelay(200); //Instead of examining SFD line status
303 ccspitrans8(0x09); //SFLUSHTX
306 //Get the orignally received packet, up to the seqnum field.
308 ccspitrans8(CCSPI_RXFIFO | 0x40);
310 cmddata[i]=ccspitrans8(0xde);
314 ccspitrans8(0x08); //SFLUSHRX
316 //Send the sequence number of the jammed packet back to the client
317 //itoa(cmddata[3], byte, 16);
319 //txdata(app,verb,cmddata[3]);
321 //TODO turn on AUTOCRC for it to apply to the TX???
322 // this may overcome issues of bad crc / length issues?
323 //mdmctrl0 (0x11) register set bit 5 to true.
325 //Create the forged ACK packet
326 cmddata[0] = 6; //length of ack frame plus length
327 cmddata[1] = 0x02; //first byte of FCF
328 cmddata[2] = 0x00; //second byte of FCF
329 //[3] is already filled with the sequence number
333 int q = (crc ^ c) & 15; //Do low-order 4 bits
334 crc = (crc / 16) ^ (q * 4225);
335 q = (crc ^ (c / 16)) & 15; //And high 4 bits
336 crc = (crc / 16) ^ (q * 4225);
338 cmddata[4] = crc & 0xFF;
339 cmddata[5] = (crc >> 8) & 0xFF;
341 for(i=0;i<cmddata[0];i++) {
342 itoa(cmddata[i], byte, 16);
345 //Load the forged ACK packet
347 ccspitrans8(CCSPI_TXFIFO);
348 for(i=0;i<cmddata[0];i++)
349 ccspitrans8(cmddata[i]);
351 //Transmit the forged ACK packet
354 ccspitrans8(0x04); //STXON
356 msdelay(200); //TODO try doing this based on SFD line status instead
359 ccspitrans8(0x09); //SFLUSHTX
362 //TODO disable AUTOCRC here again to go back to promiscous mode
364 //Turn off LED 2 (green) as signal
365 PLED2DIR |= PLED2PIN;
366 PLED2OUT |= PLED2PIN;
368 //TODO the firmware stops staying in this mode after a while, and stops jamming... need to find a fix.
370 debugstr("Can't reflexively jam without SFD, FIFO, FIFOP, and P2LEDx definitions - try using telosb platform.");
378 ccspitrans8(CCSPI_SFLUSHTX);
386 //Wait for last packet to TX.
387 //while(ccspi_status()&BIT3);
391 ccspitrans8(0x09); //SFLUSHTX
397 ccspitrans8(CCSPI_TXFIFO);
398 for(i=0;i<cmddata[0];i++)
399 ccspitrans8(cmddata[i]);
402 //Transmit the packet.
404 ccspitrans8(0x04); //STXON
407 //Wait for the pulse on SFD, after which the packet has been sent.
413 debugstr("Can't TX a packet with SFD and FIFOP definitions.");
418 debugstr("Not yet supported in CCSPI");