#!/usr/bin/env python # GoodFET SPI Flash Client # # (C) 2012 Travis Goodspeed # # This code is being rewritten and refactored. You've been warned! import sys; import binascii; import array; from GoodFETMCPCAN import GoodFETMCPCAN; from intelhex import IntelHex; if(len(sys.argv)==1): print "Usage: %s verb [objects]\n" % sys.argv[0]; print "%s info" % sys.argv[0]; print "%s test" % sys.argv[0]; print "%s peek 0x$start [0x$stop]" % sys.argv[0]; #print "%s poke 0x$adr 0x$val" % sys.argv[0]; print "\n%s sniff [kHz]" % sys.argv[0]; print "\n%s isniff [kHz]" % sys.argv[0]; print "\n%s spit [kHz]" % sys.argv[0]; print "\nSupported rates: 83.3, 100, 125, 250, 500, 1000 kHz."; sys.exit(); #Initialize FET and set baud rate client=GoodFETMCPCAN(); client.serInit() client.MCPsetup(); #Dummy read. #Might read as all ones if chip has a startup delay. if(sys.argv[1]=="info"): print "MCP2515 Info:\n\n"; print "Mode: %s" % client.MCPcanstatstr(); print "Read Status: %02x" % client.MCPreadstatus(); print "Rx Status: %02x" % client.MCPrxstatus(); print "Tx Errors: %3d" % client.peek8(0x1c); print "Rx Errors: %3d\n" % client.peek8(0x1d); print "Timing Info:"; print "CNF1: %02x" %client.peek8(0x2a); print "CNF2: %02x" %client.peek8(0x29); print "CNF3: %02x\n" %client.peek8(0x28); print "RXB0 CTRL: %02x" %client.peek8(0x60); print "RXB1 CTRL: %02x" %client.peek8(0x70); print "RX Buffers:" packet0=client.readrxbuffer(0); packet1=client.readrxbuffer(1); for foo in [packet0, packet1]: print client.packet2str(foo); if(sys.argv[1]=="sniff"): if len(sys.argv)>2: rate=float(sys.argv[2]); print "Calling MCPsetrate for %i." %rate; client.MCPsetrate(rate); client.MCPreqstatListenOnly(); print "Mode: %s" % client.MCPcanstatstr(); print "CNF1: %02x" %client.peek8(0x2a); print "CNF2: %02x" %client.peek8(0x29); print "CNF3: %02x\n" %client.peek8(0x28); while(1): packet=client.rxpacket(); if packet!=None: print client.packet2str(packet); if (client.peek8(0x2C) & 0x80): client.MCPbitmodify(0x2C,0x80,0x00); print"...malformed packet recieved"; if(sys.argv[1]=="snifftest"): freqrange=[10.4, 41.6, 83.3, 100, 125, 250, 500, 1000]; for rate in freqrange: print "CAN Freq Test: %3d kHz" %rate; client.MCPsetrate(rate); #print "CNF1/2/3: %02x %02x %02x" %(client.peek8(0x2a), client.peek8(0x29),client.peek8(0x28)); client.MCPreqstatListenOnly(); print "Mode: %s" % client.MCPcanstatstr(); x = 0; errors = 0; for n in range(0,400): packet=client.rxpacket(); if packet!=None: print client.packet2str(packet); x+=1; if (client.peek8(0x2C) & 0x80): errors+=1; client.MCPbitmodify(0x2C,0x80,0x00); if x==0: print "No packets sniffed for %3d kHz" %rate; else: percenterror = float(errors/x); print "Results for %3.1 kHz: recieved %3d packets, registered %3d RX errors, for a %3.3f percent error rate." %(rate, x, errors, percenterrors); client.MCPreset(); if(sys.argv[1]=="isniff"): """ An intelligent sniffer, decodes message format """ """ More features to be added soon """ if len(sys.argv)>2: rate=float(sys.argv[2]); client.MCPsetrate(rate); client.MCPreqstatListenOnly(); while 1: packet=client.rxpacket(); if packet!=None: plist=[]; for byte in packet: plist.append(byte); arbid=plist[0:2]; eid=plist[2:4]; dlc=plist[4:5]; data=plist[5:13]; print "\nArbID: " + client.packet2str(arbid); print "EID: " + client.packet2str(eid); print "DLC: " + client.packet2str(dlc); print "Data: " + client.packet2str(data); if(sys.argv[1]=="test"): print "\nMCP2515 Self Test:"; #Switch to config mode and try to rewrite TEC. client.MCPreqstatConfiguration(); client.poke8(0x00,0xde); if client.peek8(0x00)!=0xde: print "ERROR: Poke to TEC failed."; else: print "SUCCESS: Register read/write."; #Switch to Loopback mode and try to catch our own packet. client.MCPreqstatLoopback(); packet1 = [0x00, 0x08, # LOWER nibble must be 8 or greater to set EXTENDED ID 0x00, 0x00, 0x08, # UPPER nibble must be 0 to set RTR bit for DATA FRAME # LOWER nibble is DLC 0x01,0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xFF] client.txpacket(packet1); client.txpacket(packet1); print "Waiting on loopback packets."; packet=None; while(1): packet=client.rxpacket(); if packet!=None: print "Message recieved: %s" % client.packet2str(packet); if(sys.argv[1]=="peek"): start=0x0000; if(len(sys.argv)>2): start=int(sys.argv[2],16); stop=start; if(len(sys.argv)>3): stop=int(sys.argv[3],16); print "Peeking from %04x to %04x." % (start,stop); while start<=stop: print "%04x: %02x" % (start,client.peek8(start)); start=start+1; # AWWW YEAAAA CODIN THAT SHIT # as written, this should if(sys.argv[1]=="spit"): if len(sys.argv)>2: rate=float(sys.argv[2]); print "Calling MCPsetrate for %i." %rate; client.MCPsetrate(rate); client.MCPreqstatNormal(); packet = [0x00, 0x08, # LOWER nibble must be 8 or greater to set EXTENDED ID 0x00, 0x00, 0x08, # UPPER nibble must be 0 to set RTR bit for DATA FRAME # LOWER nibble is DLC 0x01,0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0xFF] client.txpacket(packet); data = client.peek8(0x30); while (data&0x08)==0: print "waiting..."; data=client.peek8(0x30); print "message successfully sent!"; if(sys.argv[1]=="setbitrate"): if len(sys.argv)>2: rate=float(sys.argv[2]); print "Calling MCPsetrate for %i." %rate; client.MCPsetrate(rate);