ccspi application reflexive jamming and reflexive jamming returning the jammed frame...
[goodfet] / firmware / apps / radios / ccspi.c
1 /*! \file ccspi.c
2   \author Travis Goodspeed
3   \brief Chipcon SPI Register Interface
4   
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.
9 */
10
11 //Higher level left to client application.
12
13 #include "platform.h"
14 #include "command.h"
15 #include <stdlib.h> //added for itoa
16 #include <signal.h>
17 #include <io.h>
18 #include <iomacros.h>
19
20 #include "ccspi.h"
21 #include "spi.h"
22
23 //! Handles a Chipcon SPI command.
24 void ccspi_handle_fn( uint8_t const app,
25                                           uint8_t const verb,
26                                           uint32_t const len);
27
28 // define the ccspi app's app_t
29 app_t const ccspi_app = {
30
31         /* app number */
32         CCSPI,
33
34         /* handle fn */
35         ccspi_handle_fn,
36
37         /* name */
38         "CCSPI",
39
40         /* desc */
41         "\tThe CCSPI app adds support for the Chipcon SPI register\n"
42         "\tinterface. Unfortunately, there is very little similarity\n"
43         "\tbetween the CC2420 and the CC2500, to name just two of the\n"
44         "\tmyriad of Chipcon SPI radios.  Auto-detection will be a bit\n"
45         "\tdifficult, but more to the point, all high level functionality\n"
46         "\tmust be moved into the client.\n"
47 };
48
49 //! Set up the pins for CCSPI mode.
50 void ccspisetup(){
51   SPIDIR&=~MISO;
52   SPIDIR|=MOSI+SCK;
53   DIRSS;
54   DIRCE;
55   
56   P4OUT|=BIT5; //activate CC2420 voltage regulator
57   msdelay(100);
58   
59   //Reset the CC2420.
60   P4OUT&=~BIT6;
61   P4OUT|=BIT6;
62   
63   //Begin a new transaction.
64   CLRSS;
65   SETSS;
66 }
67
68 //! Read and write an CCSPI byte.
69 u8 ccspitrans8(u8 byte){
70   register unsigned int bit;
71   //This function came from the CCSPI Wikipedia article.
72   //Minor alterations.
73   
74   for (bit = 0; bit < 8; bit++) {
75     /* write MOSI on trailing edge of previous clock */
76     if (byte & 0x80)
77       SETMOSI;
78     else
79       CLRMOSI;
80     byte <<= 1;
81  
82     SETCLK;
83   
84     /* read MISO on trailing edge */
85     byte |= READMISO;
86     CLRCLK;
87   }
88   
89   return byte;
90 }
91
92
93 //! Writes a register
94 u8 ccspi_regwrite(u8 reg, const u8 *buf, int len){
95   CLRSS;
96   
97   reg=ccspitrans8(reg);
98   while(len--)
99     ccspitrans8(*buf++);
100   
101   SETSS;
102   return reg;//status
103 }
104 //! Reads a register
105 u8 ccspi_regread(u8 reg, u8 *buf, int len){
106   CLRSS;
107   
108   reg=ccspitrans8(reg);
109   while(len--)
110     *buf++=ccspitrans8(0);
111   
112   SETSS;
113   return reg;//status
114 }
115
116 //! Handles a Chipcon SPI command.
117 void ccspi_handle_fn( uint8_t const app,
118                       uint8_t const verb,
119                       uint32_t const len){
120   unsigned long i;
121   
122   //debugstr("Chipcon SPI handler.");
123   
124   switch(verb){
125   case PEEK:
126     cmddata[0]|=0x40; //Set the read bit.
127     //DO NOT BREAK HERE.
128   case READ:
129   case WRITE:
130   case POKE:
131     CLRSS; //Drop !SS to begin transaction.
132     for(i=0;i<len;i++)
133       cmddata[i]=ccspitrans8(cmddata[i]);
134     SETSS;  //Raise !SS to end transaction.
135     txdata(app,verb,len);
136     break;
137   case SETUP:
138     ccspisetup();
139     txdata(app,verb,0);
140     break;
141   case CCSPI_RX:
142 #ifdef FIFOP
143     //Has there been an overflow?
144     if((!FIFO)&&FIFOP){
145       debugstr("Clearing overflow");
146       CLRSS;
147       ccspitrans8(0x08); //SFLUSHRX
148       SETSS;
149     }
150     
151     //Is there a packet?
152     if(FIFOP&&FIFO){
153       //Wait for completion.
154       while(SFD);
155       
156       //Get the packet.
157       CLRSS;
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);
163       SETSS;
164       
165       //Flush buffer.
166       CLRSS;
167       ccspitrans8(0x08); //SFLUSHRX
168       SETSS;
169       //Only should transmit length of one more than the reported
170       // length of the frame, which holds the length byte:
171       txdata(app,verb,cmddata[0]+1);
172     }else{
173       //No packet.
174       txdata(app,verb,0);
175     }
176 #else
177     debugstr("Can't RX a packet with SFD and FIFOP definitions.");
178     txdata(app,NOK,0);
179 #endif
180     break;
181   case CCSPI_RX_FLUSH:
182     //Flush the buffer.
183     CLRSS;
184     ccspitrans8(CCSPI_SFLUSHRX);
185     SETSS;
186     
187     txdata(app,verb,0);
188     break;
189
190   case CCSPI_REFLEX:
191     txdata(app,verb,1);  //Just sending some response back to client
192     while(1) {
193         //Wait until a packet is received
194         while(!SFD);
195         //Turn on LED 2 (green) as signal
196             PLED2DIR |= PLED2PIN;
197             PLED2OUT &= ~PLED2PIN;
198
199         //Put radio in TX mode
200         CLRSS;
201         ccspitrans8(0x04);
202         SETSS;
203
204         //Load the jamming packet.
205         //TODO try to preload this to get faster effects
206         CLRSS;
207         ccspitrans8(CCSPI_TXFIFO);
208         char pkt[15] = {0x0f, 0x01, 0x08, 0x82, 0xff, 0xff, 0xff, 0xff, 0xde, 0xad, 0xbe, 0xef, 0xba, 0xbe, 0xc0};
209         //char pkt[12] = {0x0c, 0x01, 0x08, 0x82, 0xff, 0xff, 0xff, 0xff, 0xde, 0xad, 0xbe, 0xef};
210         for(i=0;i<pkt[0];i++)
211           ccspitrans8(pkt[i]);
212         SETSS;
213
214         //Transmit the packet.
215         CLRSS;
216         ccspitrans8(0x04); //STXON
217         SETSS;
218         msdelay(100);      //Instead of waiting for pulse on SFD
219         //Flush TX buffer.
220         CLRSS;
221         ccspitrans8(0x09); //SFLUSHTX
222         SETSS;
223
224         //Turn off LED 2 (green) as signal
225             PLED2DIR |= PLED2PIN;
226             PLED2OUT |= PLED2PIN;
227     }
228     //TODO the firmware stops staying in this mode after a while, and stops jamming... need to find a fix.
229     break;
230
231   case CCSPI_REFLEX_SEQNUM:
232     //char byte[4];
233     while(1) {
234         //Has there been an overflow in the RX buffer?
235         //TODO do we really need to check this??
236         if((!FIFO)&&FIFOP){
237           //debugstr("Clearing overflow");
238           CLRSS;
239           ccspitrans8(0x08); //SFLUSHRX
240           SETSS;
241         }
242
243         //Wait until a packet is received
244         while(!SFD);
245         //Turn on LED 2 (green) as signal
246             PLED2DIR |= PLED2PIN;
247             PLED2OUT &= ~PLED2PIN;
248
249         //Get the orignally received packet, up to the seqnum field.
250         CLRSS;
251         ccspitrans8(CCSPI_RXFIFO | 0x40);
252         for(i=0;i<4;i++)
253             cmddata[i]=ccspitrans8(0xde);
254         SETSS;
255         //Flush RX buffer.
256         CLRSS;
257         ccspitrans8(0x08); //SFLUSHRX
258         SETSS;
259         //Send the sequence number of the jammed packet back to the client
260         //itoa(cmddata[3], byte, 16);
261         //debugstr(byte);
262         txdata(app,verb,cmddata[3]);
263
264         //Put radio in TX mode
265         CLRSS;
266         ccspitrans8(0x04);
267         SETSS;
268
269         //Load the packet.
270         CLRSS;
271         ccspitrans8(CCSPI_TXFIFO);
272         char pkt[12] = {0x0c, 0x01, 0x08, 0x82, 0xff, 0xff, 0xff, 0xff, 0xde, 0xad, 0xbe, 0xef};
273         for(i=0;i<pkt[0];i++)
274           ccspitrans8(pkt[i]);
275         SETSS;
276
277         //Transmit the packet.
278         CLRSS;
279         ccspitrans8(0x04);  //STXON
280         SETSS;
281         msdelay(200);       //Instead of examining SFD line status
282         //Flush TX buffer.
283         CLRSS;
284         ccspitrans8(0x09);  //SFLUSHTX
285         SETSS;
286
287         //Turn off LED 2 (green) as signal
288             PLED2DIR |= PLED2PIN;
289             PLED2OUT |= PLED2PIN;
290     }
291     //TODO the firmware stops staying in this mode after a while, and stops jamming... need to find a fix.
292     break;
293
294   case CCSPI_TX_FLUSH:
295     //Flush the buffer.
296     CLRSS;
297     ccspitrans8(CCSPI_SFLUSHTX);
298     SETSS;
299     
300     txdata(app,verb,0);
301     break;
302   case CCSPI_TX:
303 #ifdef FIFOP
304     
305     //Wait for last packet to TX.
306     //while(ccspi_status()&BIT3);
307     
308     //Load the packet.
309     CLRSS;
310     ccspitrans8(CCSPI_TXFIFO);
311     for(i=0;i<cmddata[0];i++)
312       ccspitrans8(cmddata[i]);
313     SETSS;
314     
315     //Transmit the packet.
316     CLRSS;
317     ccspitrans8(0x04); //STXON
318     SETSS;
319     
320     //Wait for the pulse on SFD, after which the packet has been sent.
321     while(!SFD);
322     while(SFD);
323     
324     //Flush TX buffer.
325     CLRSS;
326     ccspitrans8(0x09); //SFLUSHTX
327     SETSS;
328     
329     txdata(app,verb,0);
330 #else
331     debugstr("Can't TX a packet with SFD and FIFOP definitions.");
332     txdata(app,NOK,0);
333 #endif
334     break;
335   default:
336     debugstr("Not yet supported in CCSPI");
337     txdata(app,verb,0);
338     break;
339   }
340
341 }