From: bx-s Date: Fri, 14 Dec 2012 19:54:49 +0000 (+0000) Subject: Added basic firmware and client support for the zigduino/atmel128rfa1. It can now... X-Git-Url: http://git.rot13.org/?p=goodfet;a=commitdiff_plain;h=473345590445f43c3f5dd8e5c3716c8f69b9b1cf Added basic firmware and client support for the zigduino/atmel128rfa1. It can now rx and tx packets. git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@1362 12e2690d-a6be-4b82-a7b7-67c4a43b65c8 --- diff --git a/client/GoodFETatmel128.py b/client/GoodFETatmel128.py new file mode 100644 index 0000000..876725c --- /dev/null +++ b/client/GoodFETatmel128.py @@ -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", " 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 index 0000000..2a84888 --- /dev/null +++ b/client/goodfet.zigduino @@ -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) diff --git a/firmware/Makefile b/firmware/Makefile index 2d87705..19e9976 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -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 index 0000000..c1cd4ab --- /dev/null +++ b/firmware/apps/radios/atmel_radio.c @@ -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 //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; + } + +} diff --git a/firmware/config.mk b/firmware/config.mk index 29a587a..8dc93fe 100644 --- a/firmware/config.mk +++ b/firmware/config.mk @@ -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) diff --git a/firmware/goodfet.c b/firmware/goodfet.c index efe0f8c..08ec8f5 100644 --- a/firmware/goodfet.c +++ b/firmware/goodfet.c @@ -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 index 0000000..b16116e --- /dev/null +++ b/firmware/include/atmel_radio.h @@ -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 diff --git a/firmware/lib/atmega128rfa1.c b/firmware/lib/atmega128rfa1.c index 81dcd2c..e2f5377 100644 --- a/firmware/lib/atmega128rfa1.c +++ b/firmware/lib/atmega128rfa1.c @@ -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(); } - diff --git a/firmware/platforms/zigduino.h b/firmware/platforms/zigduino.h index cc56739..b1231cf 100644 --- a/firmware/platforms/zigduino.h +++ b/firmware/platforms/zigduino.h @@ -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 #include @@ -22,8 +21,6 @@ #include #include -/* 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 @@ -67,10 +65,10 @@ #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 @@ -97,14 +95,13 @@ // 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); -