6fdea296507834198874d34ee64a7b8ae2ab947a
[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
24 #define RADIOACTIVE SETCE
25 #define RADIOPASSIVE CLRCE
26
27 //! Set up the pins for CCSPI mode.
28 void ccspisetup(){
29   SETSS;
30   P5DIR&=~MISO;
31   P5DIR|=MOSI+SCK;
32   DIRSS;
33   DIRCE;
34   
35   //Begin a new transaction.
36   CLRSS; 
37   SETSS;
38 }
39
40 //! Read and write an CCSPI byte.
41 u8 ccspitrans8(u8 byte){
42   register unsigned int bit;
43   //This function came from the CCSPI Wikipedia article.
44   //Minor alterations.
45   
46   for (bit = 0; bit < 8; bit++) {
47     /* write MOSI on trailing edge of previous clock */
48     if (byte & 0x80)
49       SETMOSI;
50     else
51       CLRMOSI;
52     byte <<= 1;
53  
54     SETCLK;
55   
56     /* read MISO on trailing edge */
57     byte |= READMISO;
58     CLRCLK;
59   }
60   
61   return byte;
62 }
63
64
65 //! Writes a register
66 u8 ccspi_regwrite(u8 reg, const u8 *buf, int len){
67   CLRSS;
68   
69   reg=ccspitrans8(reg);
70   while(len--)
71     ccspitrans8(*buf++);
72   
73   SETSS;
74   return reg;//status
75 }
76 //! Reads a register
77 u8 ccspi_regread(u8 reg, u8 *buf, int len){
78   CLRSS;
79   
80   reg=ccspitrans8(reg);
81   while(len--)
82     *buf++=ccspitrans8(0);
83   
84   SETSS;
85   return reg;//status
86 }
87
88 //! Handles a Chipcon SPI command.
89 void ccspihandle(unsigned char app,
90                unsigned char verb,
91                unsigned long len){
92   unsigned long i;
93   
94   //Drop CE to passify radio.
95   RADIOPASSIVE;
96   //Raise !SS to end transaction, just in case we forgot.
97   SETSS;
98   ccspisetup();
99   
100   switch(verb){
101     //PEEK and POKE might come later.
102   case READ:  
103   case WRITE:
104     CLRSS; //Drop !SS to begin transaction.
105     for(i=0;i<len;i++)
106       cmddata[i]=ccspitrans8(cmddata[i]);
107     SETSS;  //Raise !SS to end transaction.
108     txdata(app,verb,len);
109     break;
110
111   case PEEK://Grab CCSPI Register
112     CLRSS; //Drop !SS to begin transaction.
113     ccspitrans8(CCSPI_R_REGISTER | cmddata[0]); //000A AAAA
114     for(i=1;i<len;i++)
115       cmddata[i]=ccspitrans8(cmddata[i]);
116     SETSS;  //Raise !SS to end transaction.
117     txdata(app,verb,len);
118     break;
119     
120   case POKE://Poke CCSPI Register
121     CLRSS; //Drop !SS to begin transaction.
122     ccspitrans8(CCSPI_W_REGISTER | cmddata[0]); //001A AAAA
123     for(i=1;i<len;i++)
124       cmddata[i]=ccspitrans8(cmddata[i]);
125     SETSS;  //Raise !SS to end transaction.
126     txdata(app,verb,len);
127     break;
128   case SETUP:
129     ccspisetup();
130     txdata(app,verb,0);
131     break;
132   case CCSPI_RX:
133     RADIOPASSIVE;
134     //Get the packet.
135     CLRSS;
136     ccspitrans8(CCSPI_RXFIFO);
137     for(i=0;i<32;i++)
138       cmddata[i]=ccspitrans8(0xde);
139     SETSS;
140     //no break
141     txdata(app,verb,32);
142     break;
143   case CCSPI_RX_FLUSH:
144     //Flush the buffer.
145     CLRSS;
146     ccspitrans8(CCSPI_SFLUSHRX);
147     SETSS;
148     
149     //Return the packet.
150     txdata(app,verb,32);
151     break;
152   case CCSPI_TX:
153   case CCSPI_TX_FLUSH:
154   default:
155     debugstr("Not yet supported.");
156     txdata(app,verb,0);
157     break;
158   }
159   
160
161   SETSS;//End session
162   RADIOACTIVE;
163 }