5a3d5d67494bde6c5dfa864dc92af24b33b58eed
[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     
144      //Has there been an overflow?
145     if((!FIFO)&&FIFOP){
146       debugstr("Clearing overflow");
147       CLRSS;
148       ccspitrans8(0x08); //SFLUSHRX
149       SETSS;
150     }
151     
152     //Is there a packet?
153     if(FIFOP&&FIFO){
154       //Wait for completion.
155       while(SFD);
156       
157       //Get the packet.
158       CLRSS;
159       ccspitrans8(CCSPI_RXFIFO | 0x40);
160       //ccspitrans8(0x3F|0x40);
161       cmddata[0]=0xff; //to be replaced with length
162       for(i=0;i<cmddata[0];i++)
163         cmddata[i]=ccspitrans8(0xde);
164       SETSS;
165       
166       //Flush buffer.
167       CLRSS;
168       ccspitrans8(0x08); //SFLUSHRX
169       SETSS;
170       txdata(app,verb,i);
171     }else{
172       //No packet.
173       txdata(app,verb,0);
174     }
175     #else
176     debugstr("Can't RX a packet with SFD and FIFOP definitions.");
177     txdata(app,NOK,0);
178     #endif
179     break;
180   case CCSPI_RX_FLUSH:
181     //Flush the buffer.
182     CLRSS;
183     ccspitrans8(CCSPI_SFLUSHRX);
184     SETSS;
185     
186     txdata(app,verb,0);
187     break;
188   case CCSPI_REFLEX:
189     debugstr("Coming soon.");
190     txdata(app,verb,0);
191     break;
192   case CCSPI_TX_FLUSH:
193      //Flush the buffer.
194     CLRSS;
195     ccspitrans8(CCSPI_SFLUSHTX);
196     SETSS;
197     
198     txdata(app,verb,0);
199     break;
200   case CCSPI_TX:
201   default:
202     debugstr("Not yet supported.");
203     txdata(app,verb,0);
204     break;
205   }
206   
207
208 }