X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=client%2FGoodFETEM260.py;h=ef2bf0c6fecbb25d9188a3c85c2feb6b9abc15b6;hp=edee5b2fe1084a8a99c0fcfa37e363a1cd9a44b2;hb=f7fdc48f01ada713d5034763a2f3395fe2a7c51b;hpb=fcc7db4fe655ae58c57a81f390c7b5aaf417ec0f diff --git a/client/GoodFETEM260.py b/client/GoodFETEM260.py index edee5b2..ef2bf0c 100644 --- a/client/GoodFETEM260.py +++ b/client/GoodFETEM260.py @@ -16,31 +16,148 @@ # The delay is mandatory. -import sys, time, string, cStringIO, struct, glob, serial, os; +import sys, time, string, cStringIO, struct, glob, os; from GoodFETSPI import GoodFETSPI; class GoodFETEM260(GoodFETSPI): EM260APP=0x01; + seq=0; + def EM260trans(self,data,retry=1): + """Exchange data by EM260 SPI. (Slightly nonstandard.)""" + + if retry==0: + #Retries exceeded. Send a trivial command to clear error. + data=[0x0A,0xA7]; + self.writecmd(0x01,0x82,len(data),data); + + + try: + reply=ord(self.data[0]); + if(reply==0x00): + #print "Warning: EM260 rebooted."; + return self.EM260trans(data,retry-1); + if(reply==0x02): + #print "Error: Aborted Transaction."; + return self.EM260trans(data,retry-1); + if(reply==0x03): + print "Error: Missing Frame Terminator."; + return self.data; + if(reply==0x04): + print "Error: Reserved Error. (Access denied?)"; + return self.data; + except: + print "Error in EM260trans."; + return self.data; + + def EZSPtrans(self,frame): + """Send an EZSP frame.""" + data=self.EM260trans([0xFE,len(frame)+2, + self.seq&0xFF,0x00, + ]+frame+[ + 0xA7]); + s="EZSP< "; + for foo in data: + s=s+"%02x " % ord(foo); + print s; + + if ord(data[0])!=0xFE: + print "EZSP error: 0x%02x" % ord(data[0]); + if ord(data[4])==0x58: + print "EZSP Invalid Command because 0x%02x" % ord(data[5]); + return data; + if frame[0]!=ord(data[4]): + print "EZSP warning: Command 0x%02x returned type 0x%02x." % ( + frame[0],ord(data[4])); + self.seq=self.seq+1; + return data; + def peek8(self,adr): - """Read a byte from the given address.""" - data=self.SPItrans([0xfe,0x01,0x00, - 0x49, - 0xA7,0,0,0,0,0,0,0,0]); - return ord(data[7]); - def poke8(self,adr, byte): - """Poke a byte to the given address.""" + """Read a byte from the given address. Untested.""" + + data=self.EZSPtrans([0x47,adr&0xFF,10]); + + return ord(data[6]); + def poke8(self,adr,val): + """Poke a value into RAM. Untested""" + self.EZSPtrans([0x46,adr&0xFF,1,val&0xFF]); + return val; + def rand16(self): + """Read a random 16-bit word.""" + + data=self.EZSPtrans([0x49]); + if data==None: + print "Insufficient random data."; + return 0; + return ord(data[6])+(ord(data[7])<<8); + def info(self): """Read the info bytes.""" - data=self.SPItrans([0x0B,0xA7, - 0xFF, - 0xFF,0xFF,0xFF, #00 02 A7 - 0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0 - ]); - for foo in data: - print "%02x" % ord(foo); + print "Ember EM26 Z-Stack SPI Module."; + version=self.EM260spiversion(); + status=self.EM260spistatus(); + print "Version: %i" % (version); + print "Status: %s" % (["dead","alive"][status]); + print "" + self.setVersion(); + print "Node ID: %04x" % (self.getNodeID()); + print "Connected to %2i neighbors." % self.neighborCount(); + def EM260spiversion(self): + """Read the SPI version number from EM260.""" + data=self.EM260trans([0x0A,0xA7]); + version=ord(data[0]); + + if version==0x00: + return self.EM260spiversion(); + if version==0x02: + return self.EM260spiversion(); + if not version&0x80: + print "Version misread."; + return 0; + return version&0x7F; + + def EM260spistatus(self): + """Read the status bit.""" + data=self.EM260trans([0x0B,0xA7]); + status=ord(data[0]); + + if status==0x00: + return self.EM260spistatus(); + if status==0x02: + return self.EM260spistatus(); + if not status&0x80 and status&0x40: + print "Status misread."; + return 0; + return status&1; + + #Everything after here is ZigBee. + + def getNodeID(self): + """Read the EZSP node id.""" + + data=self.EZSPtrans([0x27]); + return ord(data[5])+(ord(data[6])<<8); + def neighborCount(self): + """Read the count of neighbors, used for iterating the neighbor table.""" + + data=self.EZSPtrans([0x7A]); + return ord(data[5]); + def setRadioChannel(self,channel): + """Set the radio channel.""" + + data=self.EZSPtrans([0x9A, channel&xFF]); + return ord(data[5]); + def setVersion(self,version=2): + """Set the requested EZSP protocol version.""" + + data=self.EZSPtrans([0x00, version]); + newversion=ord(data[5]); + if version==newversion: + print "Version set." + print "Protocol %i, stack type %i, Stack Version 0x%02x%02x." % ( + newversion, + ord(data[6]), + ord(data[8]), + ord(data[7])); + else: + self.setVersion(newversion);