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