X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=client%2FGoodFETCC.py;h=9c838b19d44582bdaab0619703c2cfb9bfad57a6;hp=afbef534718e400622d295c5aeddb0345d7d7654;hb=dc09fbf0db139aa339f35ec7fa7fb10453d4a6d3;hpb=eab7c3c80313ae0e26ddfb09a3639f7fb2feb46e diff --git a/client/GoodFETCC.py b/client/GoodFETCC.py index afbef53..9c838b1 100644 --- a/client/GoodFETCC.py +++ b/client/GoodFETCC.py @@ -114,7 +114,29 @@ class GoodFETCC(GoodFET): hz=freq*396.728515625; return hz; - + def shellcodefile(self,filename,wait=1): + """Run a fragment of shellcode by name.""" + #FIXME: should identify chip model number, use shellcode for that chip. + file=__file__; + file=file.replace("GoodFETCC.pyc","GoodFETCC.py"); + path=file.replace("client/GoodFETCC.py","shellcode/chipcon/cc1110/"); + #print "File\t%s" % file; + #print "Path\t%s" % path; + filename=path+filename; + #print "Loading shelcode from %s" % filename; + + #Load the shellcode. + h=IntelHex(filename); + for i in h._buf.keys(): + self.CCpokedatabyte(i,h[i]); + + #Execute it. + self.CCdebuginstr([0x02, 0xf0, 0x00]); #ljmp 0xF000 + self.resume(); + while wait>0 and (0==self.CCstatus()&0x20): + time.sleep(0.1); + #print "Waiting for shell code to return."; + return; def shellcode(self,code,wait=1): """Copy a block of code into RAM and execute it.""" i=0; @@ -122,12 +144,12 @@ class GoodFETCC(GoodFET): for byte in code: self.pokebyte(0xF000+i,byte); i=i+1; - print "Code loaded, executing." + #print "Code loaded, executing." self.CCdebuginstr([0x02, 0xf0, 0x00]); #ljmp 0xF000 self.resume(); while wait>0 and (0==self.CCstatus()&0x20): time.sleep(0.1); - print "Waiting for shell code to return."; + #print "Waiting for shell code to return."; return; def CC1110_crystal(self): """Start the main crystal of the CC1110 oscillating, needed for radio use.""" @@ -143,10 +165,93 @@ class GoodFETCC(GoodFET): 0xA5, #HALT ]; self.shellcode(code); + + #Slower to load, but produced from C. + #self.shellcodefile("crystal.ihx"); return; def RF_idle(self): + """Move the radio to its idle state.""" + self.CC_RFST_IDLE(); + return; + + #Chipcon RF strobes. CC1110 specific + RFST_IDLE=0x04; + RFST_RX=0x02; + RFST_TX=0x03; + RFST_CAL=0x01; + def CC_RFST_IDLE(self): + """Switch the radio to idle mode, clearing overflows and errors.""" + self.CC_RFST(self.RFST_IDLE); + def CC_RFST_TX(self): + """Switch the radio to TX mode.""" + self.CC_RFST(self.RFST_TX); + def CC_RFST_RX(self): + """Switch the radio to RX mode.""" + self.CC_RFST(self.RFST_RX); + def CC_RFST_CAL(self): + """Calibrate strobe the radio.""" + self.CC_RFST(self.RFST_CAL); + def CC_RFST(self,state=RFST_IDLE): RFST=0xDFE1 - self.pokebyte(RFST,0x04); #Return to idle state. + self.pokebyte(RFST,state); #Return to idle state. + return; + + def config_simpliciti(self,band="none"): + self.pokebysym("FSCTRL1" , 0x08) # Frequency synthesizer control. + self.pokebysym("FSCTRL0" , 0x00) # Frequency synthesizer control. + + #Don't change these while the radio is active. + self.pokebysym("FSCAL3" , 0xEA) # Frequency synthesizer calibration. + self.pokebysym("FSCAL2" , 0x2A) # Frequency synthesizer calibration. + self.pokebysym("FSCAL1" , 0x00) # Frequency synthesizer calibration. + self.pokebysym("FSCAL0" , 0x1F) # Frequency synthesizer calibration. + + if band=="ismeu" or band=="eu": + self.pokebysym("FREQ2" , 0x21) # Frequency control word, high byte. + self.pokebysym("FREQ1" , 0x71) # Frequency control word, middle byte. + self.pokebysym("FREQ0" , 0x7a) # Frequency control word, low byte. + if band=="ismus" or band=="us": + self.pokebysym("FREQ2" , 0x22) # Frequency control word, high byte. + self.pokebysym("FREQ1" , 0xB1) # Frequency control word, middle byte. + self.pokebysym("FREQ0" , 0x3B) # Frequency control word, low byte. + if band=="ismlf" or band=="lf": + self.pokebysym("FREQ2" , 0x10) # Frequency control word, high byte. + self.pokebysym("FREQ1" , 0xB0) # Frequency control word, middle byte. + self.pokebysym("FREQ0" , 0x71) # Frequency control word, low byte. + + self.pokebysym("MDMCFG4" , 0x7B) # Modem configuration. + self.pokebysym("MDMCFG3" , 0x83) # Modem configuration. + self.pokebysym("MDMCFG2" , 0x13) # Modem configuration. + self.pokebysym("MDMCFG1" , 0x22) # Modem configuration. + self.pokebysym("MDMCFG0" , 0xF8) # Modem configuration. + if band=="ismus" or band=="us": + self.pokebysym("CHANNR" , 20) # Channel number. + else: + self.pokebysym("CHANNR" , 0x00) # Channel number. + self.pokebysym("DEVIATN" , 0x42) # Modem deviation setting (when FSK modulation is enabled). + + self.pokebysym("FREND1" , 0xB6) # Front end RX configuration. + self.pokebysym("FREND0" , 0x10) # Front end RX configuration. + self.pokebysym("MCSM0" , 0x18) # Main Radio Control State Machine configuration. + self.pokebysym("FOCCFG" , 0x1D) # Frequency Offset Compensation Configuration. + self.pokebysym("BSCFG" , 0x1C) # Bit synchronization Configuration. + + self.pokebysym("AGCCTRL2" , 0xC7) # AGC control. + self.pokebysym("AGCCTRL1" , 0x00) # AGC control. + self.pokebysym("AGCCTRL0" , 0xB2) # AGC control. + + self.pokebysym("TEST2" , 0x81) # Various test settings. + self.pokebysym("TEST1" , 0x35) # Various test settings. + self.pokebysym("TEST0" , 0x09) # Various test settings. + #self.pokebysym("PA_TABLE0", 0xC0) # PA output power setting. + self.pokebysym("PKTCTRL1" , 0x04) # Packet automation control. + self.pokebysym("PKTCTRL0" , 0x05) # Packet automation control, w/ checksum. + #self.pokebysym("PKTCTRL0" , 0x01) # Packet automation control, w/o checksum. + self.pokebysym("ADDR" , 0x00) # Device address. + self.pokebysym("PKTLEN" , 0xFF) # Packet length. + + self.pokebysym("SYNC1",0xD3); + self.pokebysym("SYNC0",0x91); def RF_carrier(self): """Hold a carrier wave on the present frequency.""" @@ -161,9 +266,6 @@ class GoodFETCC(GoodFET): RFST=0xDFE1; - #0a00 - #self.pokebysym("FSCTRL1" , 0x12) # Frequency synthesizer control. - #self.pokebysym("FSCTRL0" , 0x00) # Frequency synthesizer control. self.pokebysym("FSCTRL1" , 0x0a) # Frequency synthesizer control. self.pokebysym("FSCTRL0" , 0x00) # Frequency synthesizer control. @@ -173,12 +275,6 @@ class GoodFETCC(GoodFET): self.pokebysym("FSCAL1" , 0x00) # Frequency synthesizer calibration. self.pokebysym("FSCAL0" , 0x11) # Frequency synthesizer calibration. - #Ossmann's settings, not yet sure how they differ. - #self.pokebysym("FSCAL3" , 0xEA) # Frequency synthesizer calibration. - #self.pokebysym("FSCAL2" , 0x2A) # Frequency synthesizer calibration. - #self.pokebysym("FSCAL1" , 0x00) # Frequency synthesizer calibration. - #self.pokebysym("FSCAL0" , 0x1F) # Frequency synthesizer calibration. - #self.pokebysym("FREQ2" , 0x10) # Frequency control word, high byte. #self.pokebysym("FREQ1" , 0xEC) # Frequency control word, middle byte. @@ -201,11 +297,6 @@ class GoodFETCC(GoodFET): self.pokebysym("AGCCTRL1" , 0x40) # AGC control. self.pokebysym("AGCCTRL0" , 0x91) # AGC control. - - - - - self.pokebysym("TEST2" , 0x88) # Various test settings. self.pokebysym("TEST1" , 0x31) # Various test settings. self.pokebysym("TEST0" , 0x09) # Various test settings. @@ -219,7 +310,7 @@ class GoodFETCC(GoodFET): self.pokebysym("SYNC0",0xAA); - + #while ((MARCSTATE & MARCSTATE_MARC_STATE) != MARC_STATE_TX); state=0; @@ -227,7 +318,7 @@ class GoodFETCC(GoodFET): self.pokebyte(RFST,0x03); #RFST=RFST_STX time.sleep(0.1); state=self.peekbysym("MARCSTATE")&0x1F; - print "state=%02x" % state; + #print "state=%02x" % state; print "Holding a carrier on %f MHz." % (self.RF_getfreq()/10**6); #Not needed, radio works when CPU is halted. @@ -235,12 +326,45 @@ class GoodFETCC(GoodFET): return; - + def RF_getsmac(self): + """Return the source MAC address.""" + + #Register 0A is RX_ADDR_P0, five bytes. + mac=self.peekbysym("ADDR"); + return mac; + def RF_setsmac(self,mac): + """Set the source MAC address.""" + self.pokebysym("ADDR",mac); + return 0; + def RF_gettmac(self): + """Return the target MAC address.""" + return 0; + def RF_settmac(self,mac): + """Set the target MAC address.""" + return 0; + def RF_rxpacket(self): + """Get a packet from the radio. Returns None if none is waiting.""" + #RFST=0xDFE1 + #self.pokebyte(RFST,0x01); #SCAL + #self.pokebyte(RFST,0x02); #SRX + + self.shellcodefile("rxpacket.ihx"); + #time.sleep(1); + self.halt(); + len=self.peek8(0xFE00,"xdata"); + #print "Grabbing %i bytes." %len; + return self.peekblock(0xFE00,len,"data"); + def RF_txpacket(self,payload): + """Transmit a packet. Untested.""" + + print "FIXME, Chipcon packet transmission is not yet implemented."; + return; + def RF_getrssi(self): """Returns the received signal strenght, with a weird offset.""" try: rssireg=self.symbols.get("RSSI"); - return self.CCpeekdatabyte(rssireg); + return self.CCpeekdatabyte(rssireg)^0x80; except: if self.verbose>0: print "RSSI reg doesn't exist."; try: @@ -254,7 +378,8 @@ class GoodFETCC(GoodFET): if self.verbose>0: print "RSSIL/RSSIH regs don't exist."; return 0; - + + def SRF_loadsymbols(self): ident=self.CCident(); @@ -409,12 +534,12 @@ class GoodFETCC(GoodFET): def CCdebuginstr(self,instr): self.writecmd(self.APP,0x88,len(instr),instr); return ord(self.data[0]); - def peekblock(self,adr,length,memory="vn"): - """Return a block of data.""" - data=[adr&0xff, (adr&0xff00)>>8, - length&0xFF,(length&0xFF00)>>8]; - self.writecmd(self.APP,0x91,4,data); - return [ord(x) for x in self.data] + #def peekblock(self,adr,length,memory="vn"): + # """Return a block of data, broken""" + # data=[adr&0xff, (adr&0xff00)>>8, + # length&0xFF,(length&0xFF00)>>8]; + # self.writecmd(self.APP,0x91,4,data); + # return [ord(x) for x in self.data] def peek8(self,address, memory="code"): if(memory=="code" or memory=="flash" or memory=="vn"): return self.CCpeekcodebyte(address);