Added basic firmware and client support for the zigduino/atmel128rfa1. It can now...
authorbx-s <bx-s@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Fri, 14 Dec 2012 19:54:49 +0000 (19:54 +0000)
committerbx-s <bx-s@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Fri, 14 Dec 2012 19:54:49 +0000 (19:54 +0000)
git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@1362 12e2690d-a6be-4b82-a7b7-67c4a43b65c8

client/GoodFETatmel128.py [new file with mode: 0644]
client/goodfet.zigduino [new file with mode: 0755]
firmware/Makefile
firmware/apps/radios/atmel_radio.c [new file with mode: 0644]
firmware/config.mk
firmware/goodfet.c
firmware/include/atmel_radio.h [new file with mode: 0644]
firmware/lib/atmega128rfa1.c
firmware/platforms/zigduino.h

diff --git a/client/GoodFETatmel128.py b/client/GoodFETatmel128.py
new file mode 100644 (file)
index 0000000..876725c
--- /dev/null
@@ -0,0 +1,222 @@
+# GoodFET client 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
+
+fmt = ("B", "<H", None, "<L")
+
+class GoodFETatmel128rfa1(GoodFETAVR):
+    ATMELRADIOAPP = 0x53
+    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)
+                else:
+                    connected = 1
+                    break
+        if self.verbose:
+            print "Connected after %02i attempts." % attempts;
+        self.serialport.setTimeout(12);
+
+
+    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 count > 0:
+            if(isinstance(data,list)):
+                old = data
+                data = []
+                for i in range(0,count):
+                    data += chr(old[i]);
+            outstr=''.join(data);
+
+        #little endian 16-bit length
+            count = len(outstr)
+            self.serialport.write(chr(count&0xFF));
+            self.serialport.write(chr(count>>8));
+            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
+            return out
+        else:
+            return []
+
+    def readcmd(self):
+        """Read a reply from the GoodFET."""
+        app = self.serialport.read(1)
+        if len(app) < 1:
+            self.app = 0
+            self.verb = 0
+            self.count = 0
+            self.data = ""
+            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)
+
+        if self.verbose:
+            print "Rx: ( 0x%02x, 0x%02x, %i )" % ( self.app, self.verb, self.count )
+
+        #Debugging string; print, but wait.
+        if self.app==0xFF:
+            if self.verb==0xFF:
+                print "# DEBUG %s" % self.serialport.read(self.count)
+            elif self.verb==0xFE:
+                print "# DEBUG 0x%x" % struct.unpack(fmt[self.count-1], self.serialport.read(self.count))[0]
+            elif self.verb==0xFD:
+                        #Do nothing, just wait so there's no timeout.
+                print "# NOP.";
+            return ""
+        else:
+            self.data=self.serialport.read(self.count);
+            return self.data;
+
+    def RF_setchannel(self, chan):
+        if (chan < 11) or (chan > 26):
+            print "Channel out of range"
+        else:
+            self.poke(0x8, chan)
+
+    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)
+        self.writecmd(self.ATMELRADIOAPP,0x02,len(data),data);
+        toret=0;
+        #print self.data.encode("hex")
+        if self.data:
+            #for i in range(0,bytes):
+            #    toret=toret|(ord(self.data[i+1])<<(8*i));
+            #return toret;
+            # right now only works with a byte of data
+            return ord(self.data)
+        else:
+            return -1
+
+    def poke(self,reg,val,bytes=-1):
+        """Write an Register."""
+        data=[reg, 0]
+
+        #Automatically calibrate the len.
+        if bytes==-1:
+            bytes=1;
+            #if reg==0x0a or reg==0x0b or reg==0x10: bytes=5;
+        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:
+            print "Warning, failed to set r%02x=%02x, got %02x." %(
+                reg,
+                val,
+                self.peek(reg,bytes));
+
+        return;
+
+
+    def RF_setup(self):
+        self.writecmd(self.ATMELRADIOAPP, 0x10, 0, None)
+
+    def RF_rxpacket(self):
+        """Get a packet from the radio.  Returns None if none is waiting."""
+        #doto: check if packet has arrived, flush if not new
+        self.writecmd(self.ATMELRADIOAPP, 0x80, 0, None)
+        data=self.data;
+        self.packetlen = len(data)
+        if (self.packetlen > 0):
+            return data;
+        else:
+            return None
+
+    def RX_txpacket(self, payload):
+        self.writecmd(self.ATMELRADIOAPP, 0x81, len(payload)+1,chr(len(payload))+payload)
diff --git a/client/goodfet.zigduino b/client/goodfet.zigduino
new file mode 100755 (executable)
index 0000000..2a84888
--- /dev/null
@@ -0,0 +1,72 @@
+#!/usr/bin/env python
+#GoodFET zigduino client
+#forked from code by neighbor Travis Goodspeed by bx
+
+import sys, binascii, os, array, time, glob
+
+from GoodFETatmel128 import GoodFETatmel128rfa1
+from intelhex import IntelHex;
+
+
+def printpacket(packet):
+    s="";
+    i=0;
+    for foo in packet:
+        i=i+1;
+        if i>client.packetlen: break;
+        s="%s %02x" % (s,ord(foo));
+    print "%s" % s;
+
+
+mskbstring="";
+oldseq=-1;
+
+#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();
+
+
+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();
+
+#Initialize FET and set baud rate
+client=GoodFETatmel128rfa1()
+#client.verbose = True
+client.serInit()
+
+#if(sys.argv[1ce]=="info"):
+#    printconfig();
+
+if(sys.argv[1]=="sniff"):
+    client.RF_setup()
+    if len(sys.argv)>2:
+        print "Set channel to %s" % sys.argv[2];
+        client.RF_setchannel(int(sys.argv[2]));
+    #Now we're ready to get packets.
+
+    while 1:
+        packet=None;
+        while packet==None:
+            packet=client.RF_rxpacket();
+            time.sleep(0.4)
+        printpacket(packet);
+        sys.stdout.flush();
+
+if (sys.argv[1]=="beaconreq"):
+    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"
+    while 1:
+        client.RX_txpacket(packet)
+        time.sleep(1)
index 2d87705..19e9976 100644 (file)
@@ -52,9 +52,10 @@ CC =$(GCC) -Wall -O1 -fno-strict-aliasing -g   $(CCEXTRA)
 # pic -- PIC24H/dsPIC33F debugger
 # adc -- ADC10 (still specific to x2274, GoodFET32)
 
-#  Radios:
+#  Radions:
 # nrf -- Nordic RF SPI
 # ccspi -- Chipcon SPI
+# atmel_radio -- Atmel radio
 
 # Miscelaneous:
 # glitch -- Glitch research tool
@@ -266,6 +267,12 @@ ifeq ($(filter nrf, $(config)), nrf)
        hdrs+= nrf.h
 endif
 
+# include atmel_radio app
+ifeq ($(filter atmel_radio, $(config)), atmel_radio)
+       apps+= apps/radios/atmel_radio.o
+       hdrs+= atmel_radio.h
+endif
+
 # include glitch app
 ifeq ($(filter glitch, $(config)), glitch)
        apps+= apps/glitch/glitch.o
@@ -316,7 +323,11 @@ run:
 
 avrinstall: $(app).hex
        #to be merged
+ifdef AVR_PLATFORM
+       avrdude -V -F -c stk500v1 -p $(AVR_PLATFORM) -b 57600 -P $(GOODFET) -U flash:w:$(app).hex
+else
        avrdude -V -F -c stk500v1 -p m328p -b 57600 -P $(GOODFET) -U flash:w:$(app).hex
+endif
 
 ifeq ($(platform),tilaunchpad)
 install: $(app).hex
diff --git a/firmware/apps/radios/atmel_radio.c b/firmware/apps/radios/atmel_radio.c
new file mode 100644 (file)
index 0000000..c1cd4ab
--- /dev/null
@@ -0,0 +1,234 @@
+/*! \file atmel_radio.c
+  \author bx forked from neighbor Travis Goodspeed
+  \brief Atmel Radio Register Interface
+
+*/
+
+//Higher level left to client application.
+
+#include "platform.h"
+#include "command.h"
+#include <stdlib.h> //added for itoa
+
+#include "atmel_radio.h"
+#include "spi.h"
+
+//! Handles a Chipcon SPI command.
+void atmel_radio_handle_fn( uint8_t const app,
+                            uint8_t const verb,
+                            uint32_t const len);
+
+// define the atmel_radio app's app_t
+app_t const atmel_radio_app = {
+
+  /* app number */
+  ATMEL_RADIO,
+
+  /* handle fn */
+  atmel_radio_handle_fn,
+
+  /* name */
+  "ATMEL_RADIO",
+
+  /* desc */
+  "\tThe ATMEL_RADIO app adds support for the atmel radio.\n"
+};
+
+#define TRX_REGISTER_BASEADDR 0x140
+inline void reg_write(u16 addr, u8 val)
+{
+  *(u8*)(TRX_REGISTER_BASEADDR + addr) = val;
+}
+
+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;
+  mask = ~(1 << pos);
+  old = reg_read(addr) & ~mask; //bits to keep
+  old = old | (value << pos); //bit to add
+  reg_write(addr, old); //write byte
+}
+
+
+void atmel_radio_set_state(u8 state) //based on zigduino-radio, radio_rfa.c
+{
+  u8 cmd, retries;
+  /* ensure not in state transition */
+  while (STATE_TRANSITION_IN_PROGRESS == (STATE_TRANSITION_IN_PROGRESS &TRX_STATE)) {}
+  switch(state) {
+  case TRX_OFF:
+    cmd = CMD_TRX_OFF;
+    break;
+  case PLL_ON:
+    cmd = CMD_PLL_ON;
+    break;
+  case BUSY_TX:
+    cmd = CMD_TX_START;
+    break;
+  default: //doesn't exist
+    cmd = CMD_RX_ON;
+    break;
+  }
+
+  TRX_STATE = cmd;
+  retries = 140; /* enough to receive ongoing frame */
+  do {
+    if (state == (state & TRX_STATUS)) {
+      break;
+    }
+    retries--;
+    _delay_ms(32);
+  } while (retries);
+}
+
+void atmel_radiosetup(){
+  u8 status;
+  /* initialize transceiver
+     code based on zigduino-radio
+  */
+  //TRX_RESET_LOW
+  TRXPR &= ~(1 << TRXRST);
+
+  //TRX_SLPTR_LOW.  Make sure radio isn't sleeping
+  TRXPR  &= ~(1 << SLPTR);
+
+  _delay_ms(6/1000.0);
+  //TRX_RESET_HIGH
+  TRXPR |= (1 << TRXRST);
+
+  /* disable IRQ and clear any pending IRQs */
+  {
+    IRQ_MASK = 0;
+    /* clear IRQ history by reading status*/
+    status = IRQ_STATUS;
+  }
+
+  // unset auto crc
+  TRX_CTRL_1 &= 0xDF & ~(1 << TX_AUTO_CRC_ON);
+
+  /* enter TRX_OFF state */
+  atmel_radio_set_state(TRX_OFF);
+
+  /* enter RX_ON state */
+  atmel_radio_set_state(RX_ON);
+
+}
+
+
+void atmel_radio_pokebyte(u16 addr, u8 data) {
+  reg_write(addr, data);
+}
+
+u8 atmel_radio_peekbyte(u16 addr) {
+  return reg_read(addr);
+}
+
+//! Writes bytes into the Atmel's ram
+void atmel_radio_pokeram(u16 addr, u8 *data, u16 len){
+  u16 i;
+  for (i = 0; i < len; i++ ) {
+    atmel_radio_pokebyte(addr+i, data[i]);
+  }
+}
+
+//! Read bytes from the Atmel's RAM.
+void atmel_radio_peekram(u16 addr, u8 *data, u16 len){
+  u16 i;
+  //Data goes here.
+  for (i = 0; i < len; i++){
+    *data++=atmel_radio_peekbyte(addr+i);
+  }
+}
+
+int atmel_radio_is_frame_buffer_empty() {
+  return TRXFBST == 0;
+}
+
+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;
+
+  switch(verb){
+  case PEEK:
+
+  case READ:
+    length=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);
+    break;
+  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
+    break;
+  case SETUP:
+    atmel_radiosetup();
+    txdata(app,verb,0);
+    break;
+
+  case ATMEL_RADIO_RX:
+
+    // set 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);
+      }
+    }else{
+      // didn't recieve anything new
+      txdata(app,verb,0);
+    }
+    // receive packets again
+    atmel_radio_set_state(RX_ON);
+
+    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;
+    }
+
+    memcpy((void *) &TRXFBST, cmddata, cmddata[0]+1); //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);
+
+    break;
+
+  case ATMEL_RADIO_RX_FLUSH:
+  case ATMEL_RADIO_TX_FLUSH:
+  default:
+    debugstr("Not yet supported in ATMEL_RADIO");
+    txdata(app,verb,-1);
+    break;
+  }
+
+}
index 29a587a..8dc93fe 100644 (file)
@@ -153,7 +153,8 @@ CC := avr-gcc
 mcu ?= atmega128rfa1
 platform = zigduino
 CFLAGS=$(DEBUG) -Iinclude -mmcu=$(mcu) -W -Os -mcall-prologues -Wall -Wextra -Wuninitialized -fpack-struct -fshort-enums -funsigned-bitfields
-config := monitor #avr spi
+config := monitor atmel_radio #avr spi
+AVR_PLATFORM := m128rfa1
 endif
 
 
@@ -180,7 +181,7 @@ $(error Please define board, as explained in the README)
 endif
 #platform := $(board)
 
-AVAILABLE_APPS = monitor spi jtag sbw jtag430 jtag430x2 i2c jtagarm7 ejtag jtagxscale openocd chipcon avr pic adc nrf ccspi glitch smartcard ps2 slc2  maxusb
+AVAILABLE_APPS = monitor spi jtag sbw jtag430 jtag430x2 i2c jtagarm7 ejtag jtagxscale openocd chipcon avr pic adc nrf ccspi glitch smartcard ps2 slc2  maxusb atmel_radio
 
 # defaults
 CONFIG_monitor    ?= y
@@ -205,6 +206,7 @@ CONFIG_glitch     ?= n
 CONFIG_smartcard  ?= n
 CONFIG_ps2        ?= n
 CONFIG_slc2       ?= n
+CONFIG_atmel_radio ?=n
 
 #The CONFIG_foo vars are only interpreted if $(config) is "unset".
 ifeq ($(config),undef)
index efe0f8c..08ec8f5 100644 (file)
@@ -108,6 +108,9 @@ int main(void){
 #if (platform == donbfet)
   extern void donbfet_reboot(void);
   void (*reboot_function)(void) = donbfet_reboot;
+#elif (platform == zigduino)
+  extern void zigduino_reboot(void);
+  void (*reboot_function)(void) = zigduino_reboot;
 #else
   void (*reboot_function)(void) = (void *) 0xFFFE;
 #endif
diff --git a/firmware/include/atmel_radio.h b/firmware/include/atmel_radio.h
new file mode 100644 (file)
index 0000000..b16116e
--- /dev/null
@@ -0,0 +1,69 @@
+/*! \file atmel_radio.h
+  \author bx but forked from neighbor Travis Goodspeed
+  \brief Constants for ATMEL_RADIO Driver
+*/
+
+#ifndef ATMEL_RADIO_H
+#define ATMEL_RADIO_H
+
+#include "app.h"
+
+#define ATMEL_RADIO   0x53
+
+//Nordic RF Commands
+
+//Grab a packet, if one is available.
+#define ATMEL_RADIO_RX 0x80
+//Send a packet.
+#define ATMEL_RADIO_TX 0x81
+//Flush RX
+#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
+
+
+//ATMEL_RADIO24L01+ Registers
+//These aren't yet used, but are included for later
+//translation to XML.
+#define ATMEL_RADIO_CONFIG      0x00
+#define ATMEL_RADIO_EN_AA       0x01
+#define ATMEL_RADIO_EN_RXADDR   0x02
+#define ATMEL_RADIO_SETUP_AW    0x03
+#define ATMEL_RADIO_SETUP_RETR  0x04
+#define ATMEL_RADIO_RF_CH       0x05
+#define ATMEL_RADIO_RF_SETUP    0x06
+#define ATMEL_RADIO_STATUS      0x07
+#define ATMEL_RADIO_OBSERVE_TX  0x08
+#define ATMEL_RADIO_RPD         0x09
+#define ATMEL_RADIO_RX_ADDR_P0  0x0A
+#define ATMEL_RADIO_RX_ADDR_P1  0x0B
+#define ATMEL_RADIO_RX_ADDR_P2  0x0C
+#define ATMEL_RADIO_RX_ADDR_P3  0x0D
+#define ATMEL_RADIO_RX_ADDR_P4  0x0E
+#define ATMEL_RADIO_RX_ADDR_P5  0x0F
+#define ATMEL_RADIO_TX_ADDR     0x10
+#define ATMEL_RADIO_RX_PW_P0    0x11
+#define ATMEL_RADIO_RX_PW_P1    0x12
+#define ATMEL_RADIO_RX_PW_P2    0x13
+#define ATMEL_RADIO_RX_PW_P3    0x14
+#define ATMEL_RADIO_RX_PW_P4    0x15
+#define ATMEL_RADIO_RX_PW_P5    0x16
+#define ATMEL_RADIO_FIFO_STATUS 0x17
+#define ATMEL_RADIO_DYNPD       0x1C
+//Also 32-byte buffers for ACK_PLD, TX_PLD, and RX_PLD.
+//Separate SPI commands.
+
+extern app_t const atmel_radio_app;
+
+#endif // ATMEL_RADIO_H
index 81dcd2c..e2f5377 100644 (file)
@@ -9,10 +9,6 @@ unsigned char serial0_rx(){
   return UDR0;
 }
 
-//! Receive a byte.
-unsigned char serial1_rx(){
-  return 0;
-}
 
 //! Transmit a byte.
 void serial0_tx(unsigned char x){
@@ -20,52 +16,44 @@ void serial0_tx(unsigned char x){
   UDR0 = x;
 }
 
-//! Transmit a byte on the second UART.
-void serial1_tx(unsigned char x){
-}
 
 //! Set the baud rate.
 void setbaud0(unsigned char rate){
-        /* disable briefly */
-        UCSR0B = 0;
-
-        UBRR0L = 4;   /* 500,000 baud at 20MHz */
-        //UBRR0L = 1;   /* 500,000 baud at 8MHz */
-        //UBRR0L = 103; /* 9600 baud */
-        // XXX UBRR0L = 8;     /* 115200 baud ERROR RATE TOO HIGH */
-        UBRR0H = 0;
-
-        UCSR0A = (1 << U2X0);   /* double the baud rate */
-        UCSR0C = (3 << UCSZ00); /* 8N1 */
-
-        /* enabling rx/tx must be done after frame/baud setup */
-        UCSR0B = ((1 << TXEN0) | (1 << RXEN0));
-
-  return;
-  
-}
+  /* disable everything briefly */
+  UCSR0B = 0;
 
-//! Set the baud rate of the second uart.
-void setbaud1(unsigned char rate){
-  //http://mspgcc.sourceforge.net/baudrate.html
+  int32_t r;
   switch(rate){
   case 1://9600 baud
-    
+    r = 9600;
     break;
   case 2://19200 baud
-    
+    r = 19200;
     break;
   case 3://38400 baud
-    
+    r = 38400;
     break;
   case 4://57600 baud
-    
+    r = 57600;
     break;
+
   default:
   case 5://115200 baud
-    
+    r = 115200;
     break;
   }
+
+  /* enabling rx/tx must be done before frame/baud setup */
+  UCSR0B = ((1 << TXEN0) | (1 << RXEN0));
+
+  UCSR0A = (1 << U2X0);   /* double the baud rate */
+  UCSR0C = (3 << UCSZ00); /* 8N1 */
+
+  UBRR0L = (int8_t) (F_CPU/(r*8L)-1);
+  UBRR0H = (F_CPU/(r*8L)-1) >> 8;
+
+  return;
+
 }
 
 
@@ -75,97 +63,87 @@ void zigduino_init_uart0(){
 }
 
 void led_init(){
-  
+
+  PLEDDIR |= (1 << PLEDPIN);
 }
 
 void  led_on() {
-       PLEDOUT |= (1 << PLEDPIN);
+  PLEDOUT |= (1 << PLEDPIN);
 }
 
 void led_off() {
-       PLEDOUT &= ~(1 << PLEDPIN);
+  PLEDOUT &= ~(1 << PLEDPIN);
 }
 
 void zigduino_init(){
-        uint8_t x;
-
-        /* explicitly clear interrupts */
-        cli();
-
-        /* move the vectors */
-
-        /* move interrupts from boot flash section */
-        /* NB */
-        /* you MUST use a variable during this process. even highly optimized,
-         * masking the bit, shifting, ANDing, and setting MCUCR will exceed
-         * 4 CPU cycles! set a variable with the desired value for MCUCR and
-         * then set the register once IVCE is enabled
-         */
-        x = MCUCR & ~(1 << IVSEL);
-
-        /* enable change of interrupt vectors */
-        /* NOTE: setting IVCE disables interrupts until the bit is auto-unset 
-         * 4 cycles after being set or after IVSEL is written
-         */
-        MCUCR |= (1 << IVCE);
-        MCUCR = x;
-
-        /* disable the watchdog timer; this macro will disable interrupts for us */
-        /* NOTE: ensure that the WDRF flag is unset in the MCUSR or we will spinlock
-         * when the watchdog times out
-         */
-        MCUSR &= ~(1 << WDRF);
-        wdt_disable();
-
-        /* init the USART */
-        zigduino_init_uart0();
-
-       /* set the LED as an output */
-       PLEDDIR |= (1 << PLEDPIN);
-       PLEDOUT |= (1 << PLEDPIN);
-
-        /* explicitly enable interrupts */
-        sei();
-}
+  uint8_t x;
 
-void
-zigduino_reboot()
-{
-       MCUSR &= ~(1 << WDRF);
-       wdt_enable(WDTO_15MS);
-       while(1)
-               _delay_ms(127);
-}
+  /* explicitly clear interrupts */
+  cli();
+
+  /* move the vectors */
+
+  /* move interrupts from boot flash section */
+  /* NB */
+  /* you MUST use a variable during this process. even highly optimized,
+   * masking the bit, shifting, ANDing, and setting MCUCR will exceed
+   * 4 CPU cycles! set a variable with the desired value for MCUCR and
+   * then set the register once IVCE is enabled
+   */
+  x = MCUCR & ~(1 << IVSEL);
+
+  /* enable change of interrupt vectors */
+  /* NOTE: setting IVCE disables interrupts until the bit is auto-unset
+   * 4 cycles after being set or after IVSEL is written
+   */
+  MCUCR |= (1 << IVCE);
+  MCUCR = x;
+
+  /* disable the watchdog timer; this macro will disable interrupts for us */
+  /* NOTE: ensure that the WDRF flag is unset in the MCUSR or we will spinlock
+   * when the watchdog times out
+   */
+  MCUSR &= ~(1 << WDRF);
+  wdt_disable();
+
+  /* init the USART */
+  zigduino_init_uart0();
+
+  /* set the LED as an output */
+  led_init();
+
+  /* enable internal internal pull-up resister
+        in order to supress line noise that prevents
+        bootloader from timing out */
+  SPIDIR &= ~(1 << SPIPIN);
+  SPIOUT |= (1 << SPIPIN);
+
+  /* explicitly enable interrupts */
+  sei();
 
-void zigduino_init_uart1(){
 }
 
-uint8_t
-zigduino_get_byte(uint16_t v)
+void
+zigduino_reboot()
 {
-       /* NB */
-       /* we are only passed in a 16bit word. should 
-        * be increased to 32bit if we want to handle
-        * far reads as well
-        */
-/* XXX should be far on the 1284P, but there are bugs with flash reads using _far */
-/* XXX until the bugs are figured out (probably my fault?) use _near */
-       return pgm_read_byte_near(v);
+  MCUSR &= ~(1 << WDRF);
+  wdt_enable(WDTO_15MS);
+  while(1)
+    _delay_ms(127);
 }
 
-int * 
+int *
 zigduino_ramend(void)
 {
-       /* NB */
-       /* ATmega1284P has 16K SRAM */
-       return (int * )0x4000; 
+  /* NB */
+  /* ATmega128rfa1 has 16K SRAM */
+  return (int * )0x4000;
 }
 
 void
 led_toggle(void)
 {
-       led_on();
-       _delay_ms(30);
-       led_off();
+  led_on();
+  _delay_ms(30);
+  led_off();
 }
-
index cc56739..b1231cf 100644 (file)
@@ -1,11 +1,10 @@
-/*! \file donbfet.h
-  \author Don A. Bailey
-  \brief Port descriptions for the DonbFET platform.
+/*! \file zigduino.h
+  \author bx, forked from donbfet.h by Don A. Bailey
+  \brief Port descriptions for the Zigduino platform.
 */
 
 /* NB: define default CPU frequency */
-//XXX #define F_CPU 8000000UL
-#define F_CPU 20000000UL
+#define F_CPU 16000000UL
 
 #include <avr/io.h>
 #include <avr/wdt.h>
@@ -22,8 +21,6 @@
 #include <stdio.h>
 #include <ctype.h>
 
-/* all AVR SRAM starts after I/O mapped memory and registers */
-#define RAMSTART 0x100
 
 #ifndef PB0
 # define PB0 PORTB0
@@ -50,7 +47,8 @@
 //LED on P1.0
 #define PLEDOUT PORTB
 #define PLEDDIR DDRB
-#define PLEDPIN PB0
+#define PLEDPIN PINB1
+//#define LEDPIN PINB
 
 //Use P3 instead of P5 for target I/O on chips without P5.
 #ifdef msp430f2274
 #else
 
 # if (platform == zigduino)
-#  define SPIOUT PORTA
-#  define SPIDIR DDRA
-#  define SPIIN  PINA
-//# define SPIREN P5REN
+#  define SPIOUT PORTE
+#  define SPIDIR DDRE
+#  define SPIIN  PINE
+#  define SPIPIN PINE0
 # endif
 #endif
 
 
 // network byte order converters
 #define htons(x) ((((uint16_t)(x) & 0xFF00) >> 8) | \
-                                (((uint16_t)(x) & 0x00FF) << 8))
+                  (((uint16_t)(x) & 0x00FF) << 8))
 #define htonl(x) ((((uint32_t)(x) & 0xFF000000) >> 24) | \
-                                 (((uint32_t)(x) & 0x00FF0000) >> 8) | \
-                                 (((uint32_t)(x) & 0x0000FF00) << 8) | \
-                                 (((uint32_t)(x) & 0x000000FF) << 24))
+  (((uint32_t)(x) & 0x00FF0000) >> 8) | \
+  (((uint32_t)(x) & 0x0000FF00) << 8) | \
+                  (((uint32_t)(x) & 0x000000FF) << 24))
 
 #define ntohs htons
 #define ntohl htonl
-
+#define INITCHIP zigduino_init();
 extern uint8_t zigduino_get_byte(uint16_t);
-