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