74dde4fbfb8225a0b501a322dde8e889a9df2402
[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
50 #define RADIOACTIVE CLRCE
51 #define RADIOPASSIVE SETCE
52
53 //! Set up the pins for CCSPI mode.
54 void ccspisetup(){
55   SPIDIR&=~MISO;
56   SPIDIR|=MOSI+SCK;
57   DIRSS;
58   DIRCE;
59   
60   //Telos B Radio VReg Enable
61   P4DIR|=BIT5+BIT2+BIT6+BIT7;
62   P4OUT|=BIT5+BIT7;
63   P4OUT&=~(BIT6+BIT2);
64   
65   //Begin a new transaction.
66   CLRSS; 
67   SETSS;
68 }
69
70 //! Read and write an CCSPI byte.
71 u8 ccspitrans8(u8 byte){
72   register unsigned int bit;
73   //This function came from the CCSPI Wikipedia article.
74   //Minor alterations.
75   
76   for (bit = 0; bit < 8; bit++) {
77     /* write MOSI on trailing edge of previous clock */
78     if (byte & 0x80)
79       SETMOSI;
80     else
81       CLRMOSI;
82     byte <<= 1;
83  
84     SETCLK;
85   
86     /* read MISO on trailing edge */
87     byte |= READMISO;
88     CLRCLK;
89   }
90   
91   return byte;
92 }
93
94
95 //! Writes a register
96 u8 ccspi_regwrite(u8 reg, const u8 *buf, int len){
97   CLRSS;
98   
99   reg=ccspitrans8(reg);
100   while(len--)
101     ccspitrans8(*buf++);
102   
103   SETSS;
104   return reg;//status
105 }
106 //! Reads a register
107 u8 ccspi_regread(u8 reg, u8 *buf, int len){
108   CLRSS;
109   
110   reg=ccspitrans8(reg);
111   while(len--)
112     *buf++=ccspitrans8(0);
113   
114   SETSS;
115   return reg;//status
116 }
117
118 //! Handles a Chipcon SPI command.
119 void ccspi_handle_fn( uint8_t const app,
120                       uint8_t const verb,
121                       uint32_t const len){
122   unsigned long i;
123   
124   //debugstr("Chipcon SPI handler.");
125   
126   switch(verb){
127   case READ:
128   case WRITE:
129     CLRSS; //Drop !SS to begin transaction.
130     for(i=0;i<len;i++)
131       cmddata[i]=ccspitrans8(cmddata[i]);
132     SETSS;  //Raise !SS to end transaction.
133     txdata(app,verb,len);
134     break;
135
136   case PEEK://Grab CCSPI Register
137     CLRSS; //Drop !SS to begin transaction.
138     cmddata[0]=ccspitrans8(/*CCSPI_R_REGISTER |*/ cmddata[0]); //000A AAAA
139     for(i=1;i<len;i++)
140       cmddata[i]=ccspitrans8(cmddata[i]);
141     SETSS;  //Raise !SS to end transaction.
142     txdata(app,verb,len);
143     break;
144     
145   case POKE://Poke CCSPI Register
146     CLRSS; //Drop !SS to begin transaction.
147     cmddata[0]=ccspitrans8(/* CCSPI_W_REGISTER |*/ 0x40 | cmddata[0]); //02AA AAAA
148     for(i=1;i<len;i++)
149       cmddata[i]=ccspitrans8(cmddata[i]);
150     SETSS;  //Raise !SS to end transaction.
151     txdata(app,verb,len);
152     break;
153   case SETUP:
154     ccspisetup();
155     txdata(app,verb,0);
156     break;
157   case CCSPI_RX:
158     //Get the packet.
159     CLRSS;
160     ccspitrans8(CCSPI_RXFIFO);
161     for(i=0;i<32;i++)
162       cmddata[i]=ccspitrans8(0xde);
163     SETSS;
164     //no break
165     txdata(app,verb,32);
166     break;
167   case CCSPI_RX_FLUSH:
168     //Flush the buffer.
169     CLRSS;
170     ccspitrans8(CCSPI_SFLUSHRX);
171     SETSS;
172     
173     //Return the packet.
174     txdata(app,verb,32);
175     break;
176   case CCSPI_TX:
177   case CCSPI_TX_FLUSH:
178   default:
179     debugstr("Not yet supported.");
180     txdata(app,verb,0);
181     break;
182   }
183   
184
185 }