Bug fixes and new features added to zigduino firmware and client.
authorbx-s <bx-s@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Fri, 29 Mar 2013 14:46:14 +0000 (14:46 +0000)
committerbx-s <bx-s@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Fri, 29 Mar 2013 14:46:14 +0000 (14:46 +0000)
New features include:
- auto checksum support added
- auto checksum can be enabled and diabled
- support for radio's extended operating mode (AACK mode for research purposes, disabled by default)
- client code cleaned up and argument processing simplified

git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@1562 12e2690d-a6be-4b82-a7b7-67c4a43b65c8

client/GoodFETatmel128.py
client/goodfet.zigduino
firmware/apps/radios/atmel_radio.c
firmware/include/atmel_radio.h

index 876725c..903603b 100644 (file)
@@ -1,4 +1,4 @@
-# GoodFET client to interface zigduino/atmel128 radio
+# GoodFETclient to interface zigduino/atmel128 radio
 # forked by bx from code by neighbor Travis Goodspeed
 from GoodFETAVR import GoodFETAVR
 import sys, binascii, os, array, time, glob, struct
@@ -7,96 +7,109 @@ fmt = ("B", "<H", None, "<L")
 
 class GoodFETatmel128rfa1(GoodFETAVR):
     ATMELRADIOAPP = 0x53
+    autocrc = 0
+    verbose = False
+    connected = 0
+    enable_AACK = False
+    def serInit(self, port=None, timeout=2, attemptlimit=None):
+        if port==None:
+            port=os.environ.get("GOODFET");
+        self.pyserInit(port, timeout, attemptlimit)
+
     def pyserInit(self, port, timeout, attemptlimit):
         """Open the serial port"""
-        # Make timeout None to wait forever, 0 for non-blocking mode.
-        import serial;
-
-        if os.name=='nt' and sys.version.find('64 bit')!=-1:
-            print "WARNING: PySerial requires a 32-bit Python build in Windows.";
-
-        if port is None and os.environ.get("GOODFET")!=None:
-            glob_list = glob.glob(os.environ.get("GOODFET"));
-            if len(glob_list) > 0:
-                port = glob_list[0];
-            else:
-                port = os.environ.get("GOODFET");
-        if port is None:
-            glob_list = glob.glob("/dev/tty.usbserial*");
-            if len(glob_list) > 0:
-                port = glob_list[0];
-        if port is None:
-            glob_list = glob.glob("/dev/ttyUSB*");
-            if len(glob_list) > 0:
-                port = glob_list[0];
-        if port is None:
-            glob_list = glob.glob("/dev/ttyU0");
-            if len(glob_list) > 0:
-                port = glob_list[0];
-        if port is None and os.name=='nt':
-            from scanwin32 import winScan;
-            scan=winScan();
-            for order,comport,desc,hwid in sorted(scan.comports()):
-                try:
-                    if hwid.index('FTDI')==0:
-                        port=comport;
-                        #print "Using FTDI port %s" % port
-                except:
-                    #Do nothing.
-                    a=1;
-
-        baud=115200;
-        self.serialport = serial.Serial(
-            port,
-            baud,
-            parity = serial.PARITY_NONE,
-            timeout=timeout
-            )
-
-        self.verb=0;
-        self.data=""
-        attempts=0;
-        connected=0;
-
-        while connected==0:
-            while self.verb!=0x7F or self.data!="http://goodfet.sf.net/":
-                if attemptlimit is not None and attempts >= attemptlimit:
-                    return
-                elif attempts==2 and os.environ.get("board")!='telosb':
-                    print "See the GoodFET FAQ about missing info flash.";
-                    self.serialport.setTimeout(0.2);
-                    #Explicitly set RTS and DTR to halt board.
-                    self.serialport.setRTS(1);
-                    self.serialport.setDTR(1);
-                    #Drop DTR, which is !RST, low to begin the app.
-                    self.serialport.setDTR(0);
-
-                attempts=attempts+1;
-                self.readcmd(); #Read the first command.
-                if self.verbose:
-                    print "Got %02x,%02x:'%s'" % (self.app,self.verb,self.data);
-
-            #Here we have a connection, but maybe not a good one.
-            #print "We have a connection."
-            for foo in range(1,30):
-                time.sleep(1)
-                if not self.monitorecho():
-                    connected = 0
-                    if self.verbose:
-                        print "Comm error on try %i." % (foo)
+        if self.connected == 0:
+            if (not (attemptlimit == None)) and (attemptlimit <= 1):
+                # it always takes at least 2 tries
+                attemptlimit == 2
+
+            # Make timeout None to wait forever, 0 for non-blocking mode.
+            import serial;
+
+            if os.name=='nt' and sys.version.find('64 bit')!=-1:
+                print "WARNING: PySerial requires a 32-bit Python build in Windows.";
+
+            if port is None and os.environ.get("GOODFET")!=None:
+                glob_list = glob.glob(os.environ.get("GOODFET"));
+                if len(glob_list) > 0:
+                    port = glob_list[0];
                 else:
-                    connected = 1
-                    break
-        if self.verbose:
-            print "Connected after %02i attempts." % attempts;
-        self.serialport.setTimeout(12);
+                    port = os.environ.get("GOODFET");
+            if port is None:
+                glob_list = glob.glob("/dev/tty.usbserial*");
+                if len(glob_list) > 0:
+                    port = glob_list[0];
+            if port is None:
+                glob_list = glob.glob("/dev/ttyUSB*");
+                if len(glob_list) > 0:
+                    port = glob_list[0];
+            if port is None:
+                glob_list = glob.glob("/dev/ttyU0");
+                if len(glob_list) > 0:
+                    port = glob_list[0];
+            if port is None and os.name=='nt':
+                from scanwin32 import winScan;
+                scan=winScan();
+                for order,comport,desc,hwid in sorted(scan.comports()):
+                    try:
+                        if hwid.index('FTDI')==0:
+                            port=comport;
+                            #print "Using FTDI port %s" % port
+                    except:
+                        #Do nothing.
+                        a=1;
+
+            baud=115200;
+
+            self.serialport = serial.Serial(
+                port,
+                baud,
+                parity = serial.PARITY_NONE,
+                timeout=timeout
+                )
+
+            self.verb=0;
+            self.data=""
+            attempts=0;
+            self.connected=0;
+
+            while self.connected==0:
+                self.serialport.setDTR(False)
+                while self.verb!=0x7F or self.data!="http://goodfet.sf.net/":
+                    if attemptlimit is not None and attempts >= attemptlimit:
+                        return
+
+                    attempts=attempts+1;
+                    self.readcmd(); #Read the first command.
+                    if self.verbose:
+                        print "Got %02x,%02x:'%s'" % (self.app,self.verb,self.data);
+
+                #Here we have a connection, but maybe not a good one.
+                #print "We have a connection."
+                for foo in range(1,30):
+                    time.sleep(1)
+                    if not self.monitorecho():
+                        self.connected = 0
+                        if self.verbose:
+                            print "Comm error on try %i." % (foo)
+                    else:
+                        self.connected = 1
+                        break
+            if self.verbose:
+                print "Connected after %02i attempts." % attempts;
+            self.serialport.setTimeout(12);
+
+    def serClose(self):
+        self.connected = 0
+        self.serialport.close()
 
 
     def writecmd(self, app, verb, count=0, data=[]):
         """Write a command and some data to the GoodFET."""
         self.serialport.write(chr(app));
         self.serialport.write(chr(verb));
-
+        if self.verbose:
+            print "Tx: ( 0x%02x, 0x%02x, %d )" % ( app, verb, count )
         if count > 0:
             if(isinstance(data,list)):
                 old = data
@@ -107,29 +120,31 @@ class GoodFETatmel128rfa1(GoodFETAVR):
 
         #little endian 16-bit length
             count = len(outstr)
-            self.serialport.write(chr(count&0xFF));
-            self.serialport.write(chr(count>>8));
+        self.serialport.write(chr(count&0xFF));
+        self.serialport.write(chr(count>>8));
+        if count > 0:
             if self.verbose:
-                print "Tx: ( 0x%02x, 0x%02x, %d )" % ( app, verb, count )
                 print "sending: %s" %outstr.encode("hex")
-
             self.serialport.write(outstr);
-        else: # count == 0
-            self.serialport.write("\x00")
-            self.serialport.write("\x00")
+
 
         if not self.besilent:
             out = self.readcmd()
-            #if out:
-            #    print "read: " + out
+            if out and self.verbose:
+                print "read: " + out.encode("hex")
             return out
         else:
-            return []
+            return None
 
     def readcmd(self):
+
         """Read a reply from the GoodFET."""
         app = self.serialport.read(1)
+
         if len(app) < 1:
+            if self.verbose:
+                print "Rx: None"
+
             self.app = 0
             self.verb = 0
             self.count = 0
@@ -137,10 +152,19 @@ class GoodFETatmel128rfa1(GoodFETAVR):
             return
 
         self.app=ord(app);
-        self.verb=ord(self.serialport.read(1));
-
-        self.count= ord(self.serialport.read(1)) + (ord(self.serialport.read(1))<<8)
 
+        v = self.serialport.read(1);
+        if v:
+            self.verb = ord(v)
+        else:
+            self.verb = 0
+            
+        c1 = self.serialport.read(1)
+        c2 = self.serialport.read(1)
+        if (c1 and c2):
+            self.count= ord(c1) + (ord(c2)<<8)
+        else:
+            self.count = 0
         if self.verbose:
             print "Rx: ( 0x%02x, 0x%02x, %i )" % ( self.app, self.verb, self.count )
 
@@ -164,13 +188,14 @@ class GoodFETatmel128rfa1(GoodFETAVR):
         else:
             self.poke(0x8, chan)
 
-    def peek(self,reg,bytes=-1):
+    def peek(self,reg,bytes=1):
         """Read a Register. """
         #Automatically calibrate the len.
-        if bytes==-1:
-            bytes=1;
-            #if reg==0x0a or reg==0x0b or reg==0x10: bytes=5;
-        data = [reg, 0, bytes%255, bytes>>8] + ([0]*bytes)
+        if bytes != 1:
+            print "Warning, currently cannot poke more than 1 byte"
+            bytes = 1
+        data = [reg, 0, bytes%255, bytes>>8] #+ ([0]*bytes)
+        self.data = None
         self.writecmd(self.ATMELRADIOAPP,0x02,len(data),data);
         toret=0;
         #print self.data.encode("hex")
@@ -183,26 +208,28 @@ class GoodFETatmel128rfa1(GoodFETAVR):
         else:
             return -1
 
-    def poke(self,reg,val,bytes=-1):
+    def poke(self,reg,val,bytes=1): # todo, support >1 byte
         """Write an Register."""
+        data = [reg, 0] #+ ([0]*bytes)
         data=[reg, 0]
-
-        #Automatically calibrate the len.
-        if bytes==-1:
-            bytes=1;
-            #if reg==0x0a or reg==0x0b or reg==0x10: bytes=5;
+        if bytes != 1:
+            print "Warning, currently cannot poke more than 1 byte"
+            bytes = 1
         for i in range(0,bytes):
             data=data+[(val>>(8*i))&0xFF];
 
         self.writecmd(self.ATMELRADIOAPP,0x03,len(data),data);
-        if self.peek(reg,bytes)!=val:
+        newval = self.peek(reg,bytes)
+        if newval!=val:
             print "Warning, failed to set r%02x=%02x, got %02x." %(
                 reg,
                 val,
-                self.peek(reg,bytes));
+                newval);
 
         return;
 
+    def setup(self):
+        self.RF_setup()
 
     def RF_setup(self):
         self.writecmd(self.ATMELRADIOAPP, 0x10, 0, None)
@@ -218,5 +245,37 @@ class GoodFETatmel128rfa1(GoodFETAVR):
         else:
             return None
 
-    def RX_txpacket(self, payload):
-        self.writecmd(self.ATMELRADIOAPP, 0x81, len(payload)+1,chr(len(payload))+payload)
+    def RF_txpacket(self, payload):
+        if type(payload) == list: #convert to string
+            import array
+            payload = array.array('B', payload).tostring()
+        self.writecmd(self.ATMELRADIOAPP, 0x81, len(payload), payload)
+
+
+    def RF_getrssi(self):
+        """Returns the received signal strength"""
+        base = -90
+        val = self.peek(0x7) & 0x7f # read rssi bits
+        if val == 0:
+            return base - 1
+        elif val < 0x53:
+            return val + base
+        else:
+            return 0x53 + base
+
+    def RF_enable_AACK(self, enable = True):
+        if (enable and (not self.enable_AACK)):
+            self.enable_AACK = True
+            self.writecmd(self.ATMELRADIOAPP, 0x84)
+        elif ((not enable) and self.enable_AACK):
+            self.enable_AACK = False
+            self.writecmd(self.ATMELRADIOAPP, 0x85)
+
+
+    def RF_autocrc(self, autocrc=1):
+        self.autocrc = autocrc
+        if autocrc:
+            self.writecmd(self.ATMELRADIOAPP, 0x86)
+        else:
+            self.writecmd(self.ATMELRADIOAPP, 0x87)
+
index 2a84888..ca5ed35 100755 (executable)
@@ -2,7 +2,7 @@
 #GoodFET zigduino client
 #forked from code by neighbor Travis Goodspeed by bx
 
-import sys, binascii, os, array, time, glob
+import sys, binascii, os, array, time, glob, argparse
 
 from GoodFETatmel128 import GoodFETatmel128rfa1
 from intelhex import IntelHex;
@@ -18,55 +18,60 @@ def printpacket(packet):
     print "%s" % s;
 
 
-mskbstring="";
-oldseq=-1;
+commands=["sniff", "beaconreq"]
+parser = argparse.ArgumentParser(description="Simple GoodFET running on Zigduino tools.")
+subparsers = parser.add_subparsers(help='sub-command help')
+p_sniff = subparsers.add_parser('sniff', help='Sniff for packets')
+p_sniff.add_argument("-f", action="store", dest="channel", help="channel")
+p_sniff.add_argument("-i", action="store", dest="interface", 
+                    default="/dev/ttyUSB0", help="interface (ie. /dev/ttyUSB0")
+p_sniff.set_defaults(name="sniff")
+p_br = subparsers.add_parser('beaconreq', help= 'Send out beacon requests')
+p_br.add_argument("-f", action="store", dest="channel", help="channel")
+p_br.add_argument("-c", action="store_true", dest="autocrc", help="Sends beacon requests with autocrc enabled.")
+p_br.add_argument("-i", action="store", dest="interface", 
+                    default="/dev/ttyUSB0", help="interface (ie. /dev/ttyUSB0")
 
-#def printconfig():
-#    print "Encoding %s" % client.RF_getenc();
-#    print "Freq    %10i MHz" % (client.RF_getfreq()/10**6);
-#    print "Rate    %10i kbps" % (client.RF_getrate()/1000);
-#    print "PacketLen %02i bytes" % client.RF_getpacketlen();
-#    #print "MacLen    %2i bytes" % client.RF_getmaclen();
-#    print "SMAC  0x%010x" % client.RF_getsmac();
-#    print "TMAC  0x%010x" % client.RF_gettmac();
+p_br.set_defaults(name="beaconreq")
 
-
-if(len(sys.argv)==1):
-    print "Usage: %s verb [objects]\n" % sys.argv[0];
-    #print "%s info" % sys.argv[0];
-    print "%s sniff [channel]\n\tSniffs packets." % sys.argv[0];
-    print "%s beaconreq [channel]\n\tSends out beacons requests" % sys.argv[0];
-    sys.exit();
+args = parser.parse_args()
 
 #Initialize FET and set baud rate
 client=GoodFETatmel128rfa1()
 #client.verbose = True
-client.serInit()
+client.serInit(args.interface)
 
 #if(sys.argv[1ce]=="info"):
 #    printconfig();
 
-if(sys.argv[1]=="sniff"):
+if(args.name=="sniff"):
     client.RF_setup()
-    if len(sys.argv)>2:
-        print "Set channel to %s" % sys.argv[2];
-        client.RF_setchannel(int(sys.argv[2]));
+    if args.channel:
+        print "Set channel to %s" % args.channel
+        client.RF_setchannel(int(args.channel))
     #Now we're ready to get packets.
-
     while 1:
         packet=None;
         while packet==None:
             packet=client.RF_rxpacket();
-            time.sleep(0.4)
+            time.sleep(.5)
         printpacket(packet);
         sys.stdout.flush();
 
-if (sys.argv[1]=="beaconreq"):
+if (args.name=="beaconreq"):
+    if (args.autocrc):
+        autocrc = 1
+    else:
+        autocrc = 0
     client.RF_setup()
-    if len(sys.argv)>2:
-        print "Set channel to %s" % sys.argv[2];
-        client.RF_setchannel(int(sys.argv[2]));
-    packet="\x03\x08\x46\xff\xff\xff\xff\x07\x13\x33"
+    if args.channel:
+        print "Set channel to %s" % args.channel
+        client.RF_setchannel(int(args.channel))
+    client.RF_autocrc(autocrc)
+    if autocrc:
+        packet="\x03\x08\x46\xff\xff\xff\xff\x07\x00\x00"        
+    else:
+        packet="\x03\x08\x46\xff\xff\xff\xff\x07\x13\x33"
     while 1:
-        client.RX_txpacket(packet)
+        client.RF_txpacket(chr(len(packet))+packet)
         time.sleep(1)
index c1cd4ab..a81ccdf 100644 (file)
@@ -8,15 +8,16 @@
 
 #include "platform.h"
 #include "command.h"
-#include <stdlib.h> //added for itoa
 
 #include "atmel_radio.h"
 #include "spi.h"
 
+uint8_t AACK_enabled;
+
 //! Handles a Chipcon SPI command.
 void atmel_radio_handle_fn( uint8_t const app,
                             uint8_t const verb,
-                            uint32_t const len);
+                            uint32_t const datalen32);
 
 // define the atmel_radio app's app_t
 app_t const atmel_radio_app = {
@@ -44,6 +45,7 @@ inline u8 reg_read(u16 addr)
 {
   return *(u8*)(TRX_REGISTER_BASEADDR + addr);
 }
+
 inline void reg_bit_write(u16 addr, u8 pos, u8 value)
 {
   u8 old, mask;
@@ -53,8 +55,12 @@ inline void reg_bit_write(u16 addr, u8 pos, u8 value)
   reg_write(addr, old); //write byte
 }
 
+void atmel_radio_clear_frame_buffer() {
+  TRXFBST = 0; //reset the frame buffer pointer to signal it was read (resets the PHR - length value)
+}
+
 
-void atmel_radio_set_state(u8 state) //based on zigduino-radio, radio_rfa.c
+u16 atmel_radio_set_state(u8 state) //based on zigduino-radio, radio_rfa.c
 {
   u8 cmd, retries;
   /* ensure not in state transition */
@@ -69,13 +75,19 @@ void atmel_radio_set_state(u8 state) //based on zigduino-radio, radio_rfa.c
   case BUSY_TX:
     cmd = CMD_TX_START;
     break;
-  default: //doesn't exist
-    cmd = CMD_RX_ON;
+  case RX_ON:
+  default: 
+    if (AACK_enabled) {
+      cmd =  CMD_RX_AACK_ON;
+      state = RX_AACK_ON;
+    } else {
+      cmd = CMD_RX_ON;
+    }
     break;
   }
 
   TRX_STATE = cmd;
-  retries = 140; /* enough to receive ongoing frame */
+  retries = 180; // enough to receive ongoing frame
   do {
     if (state == (state & TRX_STATUS)) {
       break;
@@ -83,10 +95,15 @@ void atmel_radio_set_state(u8 state) //based on zigduino-radio, radio_rfa.c
     retries--;
     _delay_ms(32);
   } while (retries);
+  if (state != (state & TRX_STATUS)) {
+    return (state & TRX_STATUS);
+  }else{
+    return 0;
+  }
 }
 
-void atmel_radiosetup(){
-  u8 status;
+u16 atmel_radiosetup(){
+  u16 status;
   /* initialize transceiver
      code based on zigduino-radio
   */
@@ -106,15 +123,36 @@ void atmel_radiosetup(){
     /* clear IRQ history by reading status*/
     status = IRQ_STATUS;
   }
+  atmel_radio_set_state(TRX_OFF);
+
+  /* setup options for extended operating sniffing mode */
+  
+  // disable auto ack
+  CSMA_SEED_1 &= 0xEF & ~(1 << AACK_DIS_ACK); 
+  
+  // disable filtering of reserved frame types and reserve frame type processing
+  XAH_CTRL_1 &= 0xDF & ~(1 << AACK_FLTR_RES_FT);
+  XAH_CTRL_1 &= 0xEF & ~(1 << AACK_UPLD_RES_FT);
+  
+  // enable promiscuous mode
+  XAH_CTRL_1 |= 1 << AACK_PROM_MODE;
+
+  
+  // disable frame protection
+  TRX_CTRL_2 &= 0x7F &  ~(1 << RX_SAFE_MODE);
 
   // unset auto crc
   TRX_CTRL_1 &= 0xDF & ~(1 << TX_AUTO_CRC_ON);
 
-  /* enter TRX_OFF state */
-  atmel_radio_set_state(TRX_OFF);
+
+  atmel_radio_clear_frame_buffer();
+
+  // extended operation mode disabled by default
+  AACK_enabled = 0;
+
 
   /* enter RX_ON state */
-  atmel_radio_set_state(RX_ON);
+  return atmel_radio_set_state(RX_ON);
 
 }
 
@@ -145,86 +183,121 @@ void atmel_radio_peekram(u16 addr, u8 *data, u16 len){
 }
 
 int atmel_radio_is_frame_buffer_empty() {
-  return TRXFBST == 0;
+  return 0 == TRXFBST;
 }
 
-void atmel_radio_clear_frame_buffer() {
-  TRXFBST = 0; //reset the frame buffer pointer to signal it was read
-}
 
-//! Handles a Chipcon SPI command.
 void atmel_radio_handle_fn( uint8_t const app,
                             uint8_t const verb,
-                            uint32_t const len){
-
-  u16 length;
-  u8  len8;
-
+                            uint32_t const datalen32){
+
+  // cmddata -> byte
+  // cmddataword -> int
+  // cmddatalong -> long
+  u16 readlen16;
+  u16 ret;
+  u8 retries;
+  uint8_t framelen8;
   switch(verb){
   case PEEK:
-
-  case READ:
-    length=cmddataword[1]; // Backup length. Second byte
+    //case READ:
+    readlen16 = cmddataword[1]; // Backup length. Second byte
     atmel_radio_peekram(cmddataword[0], // First word is address
                         cmddata, // Return in same buffer
-                        length);
-    txdata(app,verb,length);
+                       readlen16); // length
+    txdata(app,verb,readlen16);
     break;
-  case WRITE:
+    //case WRITE:
   case POKE:
     atmel_radio_pokeram(cmddataword[0], // First word is address
                         cmddata+2,  // Remainder of buffer is data
-                        len-2); //Length implied by packet length
-    txdata(app,verb,len-2); //return number of poked bytes
+                        (u16) datalen32-2); //Length implied by packet length
+    txdata(app,verb, datalen32-2); //return number of poked bytes
     break;
   case SETUP:
-    atmel_radiosetup();
-    txdata(app,verb,0);
+    ret = atmel_radiosetup();
+    txdata(app, verb, ret);
     break;
 
   case ATMEL_RADIO_RX:
-
-    // set to PLL_ON so frame buffer isn't clobbered
+    // ensure radio is not in the middle or receiving a packet
+    atmel_radio_set_state(RX_ON);
+    // set state to PLL_ON so frame buffer isn't clobbered
     atmel_radio_set_state(PLL_ON);
-    len8 = 8;
+
     if (!atmel_radio_is_frame_buffer_empty()) { //only if we recieved something new
-      len8 = TST_RX_LENGTH; //register contains frame length
-
-      if  ((len8 > 0x80) ) { //frame too big
-        txdata(app,verb,0);
-      } else {
-        memcpy(cmddata, (void *) &TRXFBST, len8); //return in same buffer
-        atmel_radio_clear_frame_buffer();
-        txdata(app, verb, len8);
+      framelen8 = TST_RX_LENGTH; //register contains frame length
+      if  ((framelen8 > 127) ) { //frame too big
+       framelen8 = 127;
       }
-    }else{
-      // didn't recieve anything new
-      txdata(app,verb,0);
+      memcpy(cmddata, (void *) &TRXFBST, framelen8); //return in same buffer
+      atmel_radio_clear_frame_buffer();
+    } else {
+      framelen8 = 0; //didn't receive anything new
     }
     // receive packets again
     atmel_radio_set_state(RX_ON);
 
+    txdata(app, verb, framelen8);
     break;
   case ATMEL_RADIO_TX:
     //prevent radio from recieving new packets
     atmel_radio_set_state(PLL_ON);
-    if (cmddata[0] > 127) { //truncate too long packets
-      cmddata[0] = 127;
+    uint8_t maxlen = 127;
+    if (cmddata[0] > maxlen) { //truncate too long packets
+      cmddata[0] = maxlen;
     }
 
-    memcpy((void *) &TRXFBST, cmddata, cmddata[0]+1); //copy length + packet
+    memcpy((void *) &TRXFBST, cmddata, datalen32); //copy length + packet
     atmel_radio_set_state(BUSY_TX); //send packet
 
+
     while (PLL_ON != (PLL_ON & TRX_STATUS)) {} //wait for TX done
     //reset the frame buffer pointer to signal it was read
     atmel_radio_clear_frame_buffer();
     atmel_radio_set_state(RX_ON);
-    txdata(app, verb, len8);
+    txdata(app, verb, 0);
 
     break;
+  case ATMEL_RADIO_AACK_ON:
+    if (!AACK_enabled) {
+      AACK_enabled = 1;
+      /* enter PLL_ON state */
+      atmel_radio_set_state(PLL_ON);
+      /* enter RX_ON state */
+      atmel_radio_set_state(RX_ON);
+    }
+    txdata(app, verb, 0);
+    break;
+  case ATMEL_RADIO_AACK_OFF:
+    if (AACK_enabled) {
+      AACK_enabled = 0;
+      /* enter PLL_ON state */
+      atmel_radio_set_state(PLL_ON);
+      /* enter RX_ON state */
+      atmel_radio_set_state(RX_ON);
+    }
+    txdata(app, verb, 0);
+    break;
+  case ATMEL_RADIO_AUTOCRC_ON:
+    if (0 == (TRX_CTRL_1 & (1 << TX_AUTO_CRC_ON))) { //not enabled
+      atmel_radio_set_state(TRX_OFF);
+      // can only be safely set in TRX_OFF mode
+      TRX_CTRL_1 |= 1 << TX_AUTO_CRC_ON;
+      atmel_radio_set_state(RX_ON);
+    }
 
-  case ATMEL_RADIO_RX_FLUSH:
-  case ATMEL_RADIO_TX_FLUSH:
+    txdata(app, verb, 0);
+    break;
+  case ATMEL_RADIO_AUTOCRC_OFF:
+    if (TRX_CTRL_1 & (1 << TX_AUTO_CRC_ON)) { //enabled
+      atmel_radio_set_state(TRX_OFF);
+      // can only be safely set in TRX_OFF mode
+      TRX_CTRL_1 &= 0xDF & ~(1 << TX_AUTO_CRC_ON);
+      atmel_radio_set_state(RX_ON);
+    }
+    txdata(app, verb, 0);
+    break;
   default:
     debugstr("Not yet supported in ATMEL_RADIO");
     txdata(app,verb,-1);
index b16116e..d043201 100644 (file)
 #define ATMEL_RADIO_RX_FLUSH 0x82
 //Flush TX
 #define ATMEL_RADIO_TX_FLUSH 0x83
-
-
-//Nordic RF SPI Instructions
-#define ATMEL_RADIO_R_REGISTER   0x00
-#define ATMEL_RADIO_W_REGISTER   0x20
-#define ATMEL_RADIO_R_RX_PAYLOAD 0x61
-#define ATMEL_RADIO_W_TX_PAYLOAD 0xA0
-#define ATMEL_RADIO_FLUSH_TX     0xE1
-#define ATMEL_RADIO_FLUSH_RX     0xE2
-#define ATMEL_RADIO_REUSE_TX_PL  0xE3
-#define ATMEL_RADIO_NOP          0xFF
+//Start sniffing in extented oparating (AACK) mode
+#define ATMEL_RADIO_AACK_ON 0x84
+//Sopt sniffing in extented oparating (AACK) mode, sniff in basic operating mode
+#define ATMEL_RADIO_AACK_OFF 0x85
+// enable auto CRC generation
+#define ATMEL_RADIO_AUTOCRC_ON 0x86
+// diasble auto CRC generation (disabled by default)
+#define ATMEL_RADIO_AUTOCRC_OFF 0x87
 
 
 //ATMEL_RADIO24L01+ Registers