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