telosb reflexive jamming, beta version, confirmed works in some testing, improvements...
[goodfet] / firmware / apps / radios / ccspi.c
index e1cb9bb..83dfa37 100644 (file)
@@ -1,6 +1,11 @@
 /*! \file ccspi.c
   \author Travis Goodspeed
   \brief Chipcon SPI Register Interface
+  
+  Unfortunately, there is very little similarity between the CC2420
+  and the CC2500, to name just two of the myriad of Chipcon SPI
+  radios.  Auto-detection will be a bit difficult, but more to the
+  point, all high level functionality must be moved into the client.
 */
 
 //Higher level left to client application.
 #include "ccspi.h"
 #include "spi.h"
 
+//! Handles a Chipcon SPI command.
+void ccspi_handle_fn( uint8_t const app,
+                                         uint8_t const verb,
+                                         uint32_t const len);
+
+// define the ccspi app's app_t
+app_t const ccspi_app = {
+
+       /* app number */
+       CCSPI,
 
-#define RADIOACTIVE SETCE
-#define RADIOPASSIVE CLRCE
+       /* handle fn */
+       ccspi_handle_fn,
+
+       /* name */
+       "CCSPI",
+
+       /* desc */
+       "\tThe CCSPI app adds support for the Chipcon SPI register\n"
+       "\tinterface. Unfortunately, there is very little similarity\n"
+       "\tbetween the CC2420 and the CC2500, to name just two of the\n"
+       "\tmyriad of Chipcon SPI radios.  Auto-detection will be a bit\n"
+       "\tdifficult, but more to the point, all high level functionality\n"
+       "\tmust be moved into the client.\n"
+};
 
 //! Set up the pins for CCSPI mode.
 void ccspisetup(){
-  SETSS;
-  P5DIR&=~MISO;
-  P5DIR|=MOSI+SCK;
+  SPIDIR&=~MISO;
+  SPIDIR|=MOSI+SCK;
   DIRSS;
   DIRCE;
   
+  P4OUT|=BIT5; //activate CC2420 voltage regulator
+  msdelay(100);
+  
+  //Reset the CC2420.
+  P4OUT&=~BIT6;
+  P4OUT|=BIT6;
+  
   //Begin a new transaction.
-  CLRSS; 
+  CLRSS;
   SETSS;
 }
 
@@ -81,78 +114,173 @@ u8 ccspi_regread(u8 reg, u8 *buf, int len){
 }
 
 //! Handles a Chipcon SPI command.
-void ccspihandle(unsigned char app,
-              unsigned char verb,
-              unsigned long len){
+void ccspi_handle_fn( uint8_t const app,
+                     uint8_t const verb,
+                     uint32_t const len){
   unsigned long i;
   
-  //Drop CE to passify radio.
-  RADIOPASSIVE;
-  //Raise !SS to end transaction, just in case we forgot.
-  SETSS;
-  ccspisetup();
+  //debugstr("Chipcon SPI handler.");
   
   switch(verb){
-    //PEEK and POKE might come later.
-  case READ:  
+  case PEEK:
+    cmddata[0]|=0x40; //Set the read bit.
+    //DO NOT BREAK HERE.
+  case READ:
   case WRITE:
+  case POKE:
     CLRSS; //Drop !SS to begin transaction.
     for(i=0;i<len;i++)
       cmddata[i]=ccspitrans8(cmddata[i]);
     SETSS;  //Raise !SS to end transaction.
     txdata(app,verb,len);
     break;
-
-  case PEEK://Grab CCSPI Register
-    CLRSS; //Drop !SS to begin transaction.
-    ccspitrans8(CCSPI_R_REGISTER | cmddata[0]); //000A AAAA
-    for(i=1;i<len;i++)
-      cmddata[i]=ccspitrans8(cmddata[i]);
-    SETSS;  //Raise !SS to end transaction.
-    txdata(app,verb,len);
-    break;
-    
-  case POKE://Poke CCSPI Register
-    CLRSS; //Drop !SS to begin transaction.
-    ccspitrans8(CCSPI_W_REGISTER | cmddata[0]); //001A AAAA
-    for(i=1;i<len;i++)
-      cmddata[i]=ccspitrans8(cmddata[i]);
-    SETSS;  //Raise !SS to end transaction.
-    txdata(app,verb,len);
-    break;
   case SETUP:
     ccspisetup();
     txdata(app,verb,0);
     break;
   case CCSPI_RX:
-    RADIOPASSIVE;
-    //Get the packet.
+#ifdef FIFOP
+    //Has there been an overflow?
+    if((!FIFO)&&FIFOP){
+      debugstr("Clearing overflow");
+      CLRSS;
+      ccspitrans8(0x08); //SFLUSHRX
+      SETSS;
+    }
+    
+    //Is there a packet?
+    if(FIFOP&&FIFO){
+      //Wait for completion.
+      while(SFD);
+      
+      //Get the packet.
+      CLRSS;
+      ccspitrans8(CCSPI_RXFIFO | 0x40);
+      //ccspitrans8(0x3F|0x40);
+      cmddata[0]=0xff; //to be replaced with length
+      for(i=0;i<cmddata[0]+2;i++)
+        cmddata[i]=ccspitrans8(0xde);
+      SETSS;
+      
+      //Flush buffer.
+      CLRSS;
+      ccspitrans8(0x08); //SFLUSHRX
+      SETSS;
+      //Only should transmit length of one more than the reported
+      // length of the frame, which holds the length byte:
+      txdata(app,verb,cmddata[0]+1);
+    }else{
+      //No packet.
+      txdata(app,verb,0);
+    }
+#else
+    debugstr("Can't RX a packet with SFD and FIFOP definitions.");
+    txdata(app,NOK,0);
+#endif
+    break;
+  case CCSPI_RX_FLUSH:
+    //Flush the buffer.
     CLRSS;
-    ccspitrans8(CCSPI_R_RX_PAYLOAD);
-    for(i=0;i<32;i++)
-      cmddata[i]=ccspitrans8(0xde);
+    ccspitrans8(CCSPI_SFLUSHRX);
     SETSS;
-    //no break
-    txdata(app,verb,32);
+    
+    txdata(app,verb,0);
     break;
-  case CCSPI_RX_FLUSH:
+
+  case CCSPI_REFLEX:
+    debugstr("Beta implementation.");
+    cmddata[0] = 1;
+    txdata(app,verb,cmddata[0]+1);
+
+    while(1) {
+        //Wait until a packet is received
+        while(!SFD);
+        //Turn on LED 2 (green) as signal
+           PLED2DIR |= PLED2PIN;
+           PLED2OUT &= ~PLED2PIN;
+
+        //Switch the radio to TX mode
+        CLRSS;  //Drop !SS to begin transaction.
+        ccspitrans8(0x04);
+        SETSS;  //Raise !SS to end transaction.
+        //txdata(app,verb,len);
+
+        //Load the packet.
+        CLRSS;
+        ccspitrans8(CCSPI_TXFIFO);
+        char pkt[15] = {0x0f, 0x01, 0x08, 0x82, 0xff, 0xff, 0xff, 0xff, 0xde, 0xad, 0xbe, 0xef, 0xba, 0xbe, 0xc0};
+        for(i=0;i<pkt[0];i++)
+          ccspitrans8(pkt[i]);
+        SETSS;
+        debugstr("Packet loaded for tx.");
+        //Transmit the packet.
+        CLRSS;
+        ccspitrans8(0x04); //STXON
+        SETSS;
+        //Wait for the pulse on SFD, after which the packet has been sent.
+        //while(!SFD);
+        //while(SFD);
+        msdelay(300);
+        //Flush TX buffer.
+        CLRSS;
+        ccspitrans8(0x09); //SFLUSHTX
+        SETSS;
+
+        //while(SFD);
+        //msdelay(200);
+        //Turn off LED 2 (green) as signal
+           PLED2DIR |= PLED2PIN;
+           PLED2OUT |= PLED2PIN;
+    }
+    //TODO the firmware stops staying in this mode after a while, and stops jamming... need to find a fix!
+    break;
+
+  case CCSPI_TX_FLUSH:
     //Flush the buffer.
     CLRSS;
-    ccspitrans8(CCSPI_FLUSH_RX);
+    ccspitrans8(CCSPI_SFLUSHTX);
     SETSS;
     
-    //Return the packet.
-    txdata(app,verb,32);
+    txdata(app,verb,0);
     break;
   case CCSPI_TX:
-  case CCSPI_TX_FLUSH:
+#ifdef FIFOP
+    
+    //Wait for last packet to TX.
+    //while(ccspi_status()&BIT3);
+    
+    //Load the packet.
+    CLRSS;
+    ccspitrans8(CCSPI_TXFIFO);
+    for(i=0;i<cmddata[0];i++)
+      ccspitrans8(cmddata[i]);
+    SETSS;
+    
+    //Transmit the packet.
+    CLRSS;
+    ccspitrans8(0x04); //STXON
+    SETSS;
+    
+    //Wait for the pulse on SFD, after which the packet has been sent.
+    while(!SFD);
+    while(SFD);
+    
+    //Flush TX buffer.
+    CLRSS;
+    ccspitrans8(0x09); //SFLUSHTX
+    SETSS;
+    
+    txdata(app,verb,0);
+#else
+    debugstr("Can't TX a packet with SFD and FIFOP definitions.");
+    txdata(app,NOK,0);
+#endif
+    break;
   default:
-    debugstr("Not yet supported.");
+    debugstr("Not yet supported in CCSPI");
     txdata(app,verb,0);
     break;
   }
   
 
-  SETSS;//End session
-  RADIOACTIVE;
 }