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 */
91 u8 ccspi_regwrite(u8 reg, const u8 *buf, int len){
102 u8 ccspi_regread(u8 reg, u8 *buf, int len){
105 reg=ccspitrans8(reg);
107 *buf++=ccspitrans8(0);
113 //! Handles a Chipcon SPI command.
114 void ccspi_handle_fn( uint8_t const app,
120 //debugstr("Chipcon SPI handler.");
124 cmddata[0]|=0x40; //Set the read bit.
129 CLRSS; //Drop !SS to begin transaction.
130 j=cmddata[0];//Backup address.
132 cmddata[i]=ccspitrans8(cmddata[i]);
133 SETSS; //Raise !SS to end transaction.
134 cmddata[0]=j&~0x40;//Restore address.
135 txdata(app,verb,len);
143 //Has there been an overflow?
145 //debugstr("Clearing overflow");
147 ccspitrans8(0x08); //SFLUSHRX
153 //Wait for completion.
158 ccspitrans8(CCSPI_RXFIFO | 0x40);
159 //ccspitrans8(0x3F|0x40);
160 cmddata[0]=0xff; //to be replaced with length
161 for(i=0;i<cmddata[0]+2;i++)
162 cmddata[i]=ccspitrans8(0xde);
167 ccspitrans8(0x08); //SFLUSHRX
171 //Only should transmit length of one more than the reported
172 // length of the frame, which holds the length byte:
173 txdata(app,verb,cmddata[0]+1);
179 debugstr("Can't RX a packet with SFD and FIFOP definitions.");
186 ccspitrans8(CCSPI_SFLUSHRX);
193 #if defined(FIFOP) && defined(SFD) && defined(FIFO) && defined(PLED2DIR) && defined(PLED2PIN) && defined(PLED2OUT)
194 //txdata(app,verb,1); //Let the client continue its business.
196 //Wait until a packet is received
198 //Has there been an overflow in the RX buffer?
200 debugstr("Clearing RX overflow");
202 ccspitrans8(0x08); //SFLUSHRX
206 //Turn on LED 2 (green) as signal
207 PLED2DIR |= PLED2PIN;
208 PLED2OUT &= ~PLED2PIN;
210 //Put radio in TX mode
215 //Load the jamming packet.
216 //Note: attempts to preload this actually slowed the jam time down from 7 to 9 bytes.
218 ccspitrans8(CCSPI_TXFIFO);
219 char pkt[15] = {0x0f, 0x01, 0x08, 0x82, 0xff, 0xff, 0xff, 0xff, 0xde, 0xad, 0xbe, 0xef, 0xba, 0xbe, 0xc0};
220 //char pkt[12] = {0x0c, 0x01, 0x08, 0x82, 0xff, 0xff, 0xff, 0xff, 0xde, 0xad, 0xbe, 0xef};
221 for(i=0;i<pkt[0];i++)
225 //Transmit the packet.
227 ccspitrans8(0x04); //STXON
229 msdelay(100); //Instead of waiting for pulse on SFD
232 ccspitrans8(0x09); //SFLUSHTX
235 //Turn off LED 2 (green) as signal
236 PLED2DIR |= PLED2PIN;
237 PLED2OUT |= PLED2PIN;
239 //TODO the firmware stops staying in this mode after a while, and stops jamming... need to find a fix.
242 debugstr("Can't reflexively jam without SFD, FIFO, FIFOP, and P2LEDx definitions - try using telosb platform.");
246 case CCSPI_REFLEX_AUTOACK:
247 #if defined(FIFOP) && defined(SFD) && defined(FIFO) && defined(PLED2DIR) && defined(PLED2PIN) && defined(PLED2OUT)
248 //txdata(app, verb, 1);
252 //Has there been an overflow in the RX buffer?
254 //debugstr("Clearing overflow");
256 ccspitrans8(0x08); //SFLUSHRX
260 //Wait until a packet is received
262 //Turn on LED 2 (green) as signal
263 PLED2DIR |= PLED2PIN;
264 PLED2OUT &= ~PLED2PIN;
266 //Put radio in TX mode
267 //Note: Not doing this slows down jamming, so can't jam short packets.
268 // However, if we do this, it seems to mess up our RXFIFO ability.
272 //Load the jamming packet
274 ccspitrans8(CCSPI_TXFIFO);
275 char pkt[7] = {0x07, 0x01, 0x08, 0xff, 0xff, 0xff, 0xff};
276 for(i=0;i<pkt[0];i++)
279 //Transmit the jamming packet
281 ccspitrans8(0x04); //STXON
283 msdelay(200); //Instead of examining SFD line status
286 ccspitrans8(0x09); //SFLUSHTX
289 //Get the orignally received packet, up to the seqnum field.
291 ccspitrans8(CCSPI_RXFIFO | 0x40);
293 cmddata[i]=ccspitrans8(0xde);
297 ccspitrans8(0x08); //SFLUSHRX
299 //Send the sequence number of the jammed packet back to the client
300 //itoa(cmddata[3], byte, 16);
302 //txdata(app,verb,cmddata[3]);
304 //TODO turn on AUTOCRC for it to apply to the TX???
305 // this may overcome issues of bad crc / length issues?
306 //mdmctrl0 (0x11) register set bit 5 to true.
308 //Create the forged ACK packet
309 cmddata[0] = 6; //length of ack frame plus length
310 cmddata[1] = 0x02; //first byte of FCF
311 cmddata[2] = 0x00; //second byte of FCF
312 //[3] is already filled with the sequence number
316 int q = (crc ^ c) & 15; //Do low-order 4 bits
317 crc = (crc / 16) ^ (q * 4225);
318 q = (crc ^ (c / 16)) & 15; //And high 4 bits
319 crc = (crc / 16) ^ (q * 4225);
321 cmddata[4] = crc & 0xFF;
322 cmddata[5] = (crc >> 8) & 0xFF;
324 for(i=0;i<cmddata[0];i++) {
325 itoa(cmddata[i], byte, 16);
328 //Load the forged ACK packet
330 ccspitrans8(CCSPI_TXFIFO);
331 for(i=0;i<cmddata[0];i++)
332 ccspitrans8(cmddata[i]);
334 //Transmit the forged ACK packet
337 ccspitrans8(0x04); //STXON
339 msdelay(200); //TODO try doing this based on SFD line status instead
342 ccspitrans8(0x09); //SFLUSHTX
345 //TODO disable AUTOCRC here again to go back to promiscous mode
347 //Turn off LED 2 (green) as signal
348 PLED2DIR |= PLED2PIN;
349 PLED2OUT |= PLED2PIN;
351 //TODO the firmware stops staying in this mode after a while, and stops jamming... need to find a fix.
353 debugstr("Can't reflexively jam without SFD, FIFO, FIFOP, and P2LEDx definitions - try using telosb platform.");
361 ccspitrans8(CCSPI_SFLUSHTX);
369 //Wait for last packet to TX.
370 //while(ccspi_status()&BIT3);
374 ccspitrans8(0x09); //SFLUSHTX
380 ccspitrans8(CCSPI_TXFIFO);
381 for(i=0;i<cmddata[0];i++)
382 ccspitrans8(cmddata[i]);
385 //Transmit the packet.
387 ccspitrans8(0x04); //STXON
390 //Wait for the pulse on SFD, after which the packet has been sent.
396 debugstr("Can't TX a packet with SFD and FIFOP definitions.");
401 debugstr("Not yet supported in CCSPI");