radios/ccspi firmware fixed off-by-one error on packet rx; GoodFET.py added serInit...
[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
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   case CCSPI_REFLEX:
190     debugstr("Coming soon.");
191     txdata(app,verb,0);
192     break;
193   case CCSPI_TX_FLUSH:
194      //Flush the buffer.
195     CLRSS;
196     ccspitrans8(CCSPI_SFLUSHTX);
197     SETSS;
198     
199     txdata(app,verb,0);
200     break;
201   case CCSPI_TX:
202 #ifdef FIFOP
203     
204     //Wait for last packet to TX.
205     //while(ccspi_status()&BIT3);
206     
207     //Load the packet.
208     CLRSS;
209     ccspitrans8(CCSPI_TXFIFO);
210     for(i=0;i<cmddata[0];i++)
211       ccspitrans8(cmddata[i]);
212     SETSS;
213     
214     //Transmit the packet.
215     CLRSS;
216     ccspitrans8(0x04); //STXON
217     SETSS;
218     
219     //Wait for the pulse on SFD, after which the packet has been sent.
220     while(!SFD);
221     while(SFD);
222     
223     //Flush TX buffer.
224     CLRSS;
225     ccspitrans8(0x09); //SFLUSHTX
226     SETSS;
227     
228     txdata(app,verb,0);
229 #else
230     debugstr("Can't TX a packet with SFD and FIFOP definitions.");
231     txdata(app,NOK,0);
232 #endif
233     break;
234   default:
235     debugstr("Not yet supported in CCSPI");
236     txdata(app,verb,0);
237     break;
238   }
239   
240
241 }