1 # GoodFET client to interface zigduino/atmel128 radio
2 # forked by bx from code by neighbor Travis Goodspeed
3 from GoodFETAVR import GoodFETAVR
4 import sys, binascii, os, array, time, glob, struct
6 fmt = ("B", "<H", None, "<L")
8 class GoodFETatmel128rfa1(GoodFETAVR):
10 def pyserInit(self, port, timeout, attemptlimit):
11 """Open the serial port"""
12 # Make timeout None to wait forever, 0 for non-blocking mode.
15 if os.name=='nt' and sys.version.find('64 bit')!=-1:
16 print "WARNING: PySerial requires a 32-bit Python build in Windows.";
18 if port is None and os.environ.get("GOODFET")!=None:
19 glob_list = glob.glob(os.environ.get("GOODFET"));
20 if len(glob_list) > 0:
23 port = os.environ.get("GOODFET");
25 glob_list = glob.glob("/dev/tty.usbserial*");
26 if len(glob_list) > 0:
29 glob_list = glob.glob("/dev/ttyUSB*");
30 if len(glob_list) > 0:
33 glob_list = glob.glob("/dev/ttyU0");
34 if len(glob_list) > 0:
36 if port is None and os.name=='nt':
37 from scanwin32 import winScan;
39 for order,comport,desc,hwid in sorted(scan.comports()):
41 if hwid.index('FTDI')==0:
43 #print "Using FTDI port %s" % port
49 self.serialport = serial.Serial(
52 parity = serial.PARITY_NONE,
62 while self.verb!=0x7F or self.data!="http://goodfet.sf.net/":
63 if attemptlimit is not None and attempts >= attemptlimit:
65 elif attempts==2 and os.environ.get("board")!='telosb':
66 print "See the GoodFET FAQ about missing info flash.";
67 self.serialport.setTimeout(0.2);
68 #Explicitly set RTS and DTR to halt board.
69 self.serialport.setRTS(1);
70 self.serialport.setDTR(1);
71 #Drop DTR, which is !RST, low to begin the app.
72 self.serialport.setDTR(0);
75 self.readcmd(); #Read the first command.
77 print "Got %02x,%02x:'%s'" % (self.app,self.verb,self.data);
79 #Here we have a connection, but maybe not a good one.
80 #print "We have a connection."
81 for foo in range(1,30):
83 if not self.monitorecho():
86 print "Comm error on try %i." % (foo)
91 print "Connected after %02i attempts." % attempts;
92 self.serialport.setTimeout(12);
95 def writecmd(self, app, verb, count=0, data=[]):
96 """Write a command and some data to the GoodFET."""
97 self.serialport.write(chr(app));
98 self.serialport.write(chr(verb));
101 if(isinstance(data,list)):
104 for i in range(0,count):
106 outstr=''.join(data);
108 #little endian 16-bit length
110 self.serialport.write(chr(count&0xFF));
111 self.serialport.write(chr(count>>8));
113 print "Tx: ( 0x%02x, 0x%02x, %d )" % ( app, verb, count )
114 print "sending: %s" %outstr.encode("hex")
116 self.serialport.write(outstr);
118 self.serialport.write("\x00")
119 self.serialport.write("\x00")
121 if not self.besilent:
124 # print "read: " + out
130 """Read a reply from the GoodFET."""
131 app = self.serialport.read(1)
140 self.verb=ord(self.serialport.read(1));
142 self.count= ord(self.serialport.read(1)) + (ord(self.serialport.read(1))<<8)
145 print "Rx: ( 0x%02x, 0x%02x, %i )" % ( self.app, self.verb, self.count )
147 #Debugging string; print, but wait.
150 print "# DEBUG %s" % self.serialport.read(self.count)
151 elif self.verb==0xFE:
152 print "# DEBUG 0x%x" % struct.unpack(fmt[self.count-1], self.serialport.read(self.count))[0]
153 elif self.verb==0xFD:
154 #Do nothing, just wait so there's no timeout.
158 self.data=self.serialport.read(self.count);
161 def RF_setchannel(self, chan):
162 if (chan < 11) or (chan > 26):
163 print "Channel out of range"
167 def peek(self,reg,bytes=-1):
168 """Read a Register. """
169 #Automatically calibrate the len.
172 #if reg==0x0a or reg==0x0b or reg==0x10: bytes=5;
173 data = [reg, 0, bytes%255, bytes>>8] + ([0]*bytes)
174 self.writecmd(self.ATMELRADIOAPP,0x02,len(data),data);
176 #print self.data.encode("hex")
178 #for i in range(0,bytes):
179 # toret=toret|(ord(self.data[i+1])<<(8*i));
181 # right now only works with a byte of data
182 return ord(self.data)
186 def poke(self,reg,val,bytes=-1):
187 """Write an Register."""
190 #Automatically calibrate the len.
193 #if reg==0x0a or reg==0x0b or reg==0x10: bytes=5;
194 for i in range(0,bytes):
195 data=data+[(val>>(8*i))&0xFF];
197 self.writecmd(self.ATMELRADIOAPP,0x03,len(data),data);
198 if self.peek(reg,bytes)!=val:
199 print "Warning, failed to set r%02x=%02x, got %02x." %(
202 self.peek(reg,bytes));
208 self.writecmd(self.ATMELRADIOAPP, 0x10, 0, None)
210 def RF_rxpacket(self):
211 """Get a packet from the radio. Returns None if none is waiting."""
212 #doto: check if packet has arrived, flush if not new
213 self.writecmd(self.ATMELRADIOAPP, 0x80, 0, None)
215 self.packetlen = len(data)
216 if (self.packetlen > 0):
221 def RX_txpacket(self, payload):
222 self.writecmd(self.ATMELRADIOAPP, 0x81, len(payload)+1,chr(len(payload))+payload)