2 # GoodFET SPI Flash Client
4 # (C) 2012 Travis Goodspeed <travis at radiantmachines.com>
8 # 1) getting hot reads on frequency
9 # 2) allow sniffing in "normal" mode to get ack bits
10 # --check if that's whats causing error flags in board-to-board transmission
17 import csv, time, argparse;
20 from random import randrange
21 from GoodFETMCPCAN import GoodFETMCPCAN;
22 from intelhex import IntelHex;
25 class GoodFETMCPCANCommunication:
27 def __init__(self, dataLocation):
28 self.client=GoodFETMCPCAN(); """ Communication with the bus"""
30 self.client.MCPsetup();
31 #self.DATA_LOCATION = "../../contrib/ThayerData/"
32 self.DATA_LOCATION = dataLocation; """ Stores file data location. This is the root folder where basic sniffs will be stored"""
33 self.INJECT_DATA_LOCATION = self.DATA_LOCATION+"InjectedData/" """ stores the sub folder path where injected data will be stored"""
38 """ This method will print information about the board to the termina. It is usefull for diagnostics"""
39 self.client.MCPreqstatConfiguration();
41 print "MCP2515 Info:\n\n";
43 print "Mode: %s" % self.client.MCPcanstatstr();
44 print "Read Status: %02x" % self.client.MCPreadstatus();
45 print "Rx Status: %02x" % self.client.MCPrxstatus();
46 print "Error Flags: %02x" % self.client.peek8(0x2D);
47 print "Tx Errors: %3d" % self.client.peek8(0x1c);
48 print "Rx Errors: %3d\n" % self.client.peek8(0x1d);
51 print "CNF1: %02x" %self.client.peek8(0x2a);
52 print "CNF2: %02x" %self.client.peek8(0x29);
53 print "CNF3: %02x\n" %self.client.peek8(0x28);
54 print "RXB0 CTRL: %02x" %self.client.peek8(0x60);
55 print "RXB1 CTRL: %02x" %self.client.peek8(0x70);
58 print "RXB0: %02x" %self.client.peek8(0x60);
59 print "RXB1: %02x" %self.client.peek8(0x70);
60 print "RXB0 masks: %02x, %02x, %02x, %02x" %(self.client.peek8(0x20), self.client.peek8(0x21), self.client.peek8(0x22), self.client.peek8(0x23));
61 print "RXB1 masks: %02x, %02x, %02x, %02x" %(self.client.peek8(0x24), self.client.peek8(0x25), self.client.peek8(0x26), self.client.peek8(0x27));
65 packet0=self.client.readrxbuffer(0);
66 packet1=self.client.readrxbuffer(1);
67 for foo in [packet0, packet1]:
68 print self.client.packet2str(foo);
74 self.client.MCPsetup();
77 ##########################
79 ##########################
81 def sniff(self,freq,duration,description, verbose=True, comment=None, filename=None, standardid=None, debug=False, faster=False, parsed=True, data = None,writeToFile=True):
85 #reset eveything on the chip
89 #### ON-CHIP FILTERING
90 if(standardid != None):
93 self.client.MCPreqstatConfiguration();
94 self.client.poke8(0x60,0x26); # set RXB0 CTRL register to ONLY accept STANDARD messages with filter match (RXM1=0, RMX0=1, BUKT=1)
95 self.client.poke8(0x20,0xFF); #set buffer 0 mask 1 (SID 10:3) to FF
96 self.client.poke8(0x21,0xE0); #set buffer 0 mask 2 bits 7:5 (SID 2:0) to 1s
97 if(len(standardid)>2):
98 self.client.poke8(0x70,0x20); # set RXB1 CTRL register to ONLY accept STANDARD messages with filter match (RXM1=0, RMX0=1)
99 self.client.poke8(0x24,0xFF); #set buffer 1 mask 1 (SID 10:3) to FF
100 self.client.poke8(0x25,0xE0); #set buffer 1 mask 2 bits 7:5 (SID 2:0) to 1s
102 for filter,ID in enumerate(standardid):
123 #### split SID into different regs
124 SIDlow = (ID & 0x07) << 5; # get SID bits 2:0, rotate them to bits 7:5
125 SIDhigh = (ID >> 3) & 0xFF; # get SID bits 10:3, rotate them to bits 7:0
128 self.client.poke8(RXFSIDH,SIDhigh);
129 self.client.poke8(RXFSIDL, SIDlow);
131 if (verbose == True):
132 print "Filtering for SID %d (0x%02xh) with filter #%d"%(ID, ID, filter);
133 comment += ("f%d" %(ID))
136 self.client.MCPsetrate(freq);
138 # This will handle the files so that we do not loose them. each day we will create a new csv file
139 if( filename==None and writeToFile == True):
140 #get folder information (based on today's date)
141 now = datetime.datetime.now()
142 datestr = now.strftime("%Y%m%d")
143 path = self.DATA_LOCATION+datestr+".csv"
146 if( writeToFile == True):
147 outfile = open(filename,'a');
148 dataWriter = csv.writer(outfile,delimiter=',');
149 dataWriter.writerow(['# Time Error Bytes 1-13']);
150 dataWriter.writerow(['#' + description])
152 self.client.MCPreqstatNormal();
153 print "Listening...";
155 starttime = time.time();
157 while((time.time()-starttime < duration)):
160 packet=self.client.fastrxpacket();
162 packet=self.client.rxpacket();
164 #add the data to list if the pointer was included
165 if(data != None and packet != None):
166 #data.append(self.client.packet2parsedstr(packet))
167 packetParsed = self.client.packet2parsed(packet)
168 packetParsed["time"] =time.time()
169 data.put(packetParsed)
172 MCPstatusReg = self.client.MCPrxstatus();
173 messagestat=MCPstatusReg&0xC0;
174 messagetype=MCPstatusReg&0x18;
175 if(messagestat == 0xC0):
176 print "Message in both buffers; message type is %02x (0x00 is standard data, 0x08 is standard remote)." %messagetype
177 elif(messagestat == 0x80):
178 print "Message in RXB1; message type is %02x (0x00 is standard data, 0x08 is standard remote)." %messagetype
179 elif(messagestat == 0x40):
180 print "Message in RXB0; message type is %02x (0x00 is standard data, 0x08 is standard remote)." %messagetype
181 elif(messagestat == 0x00):
182 print "No messages in buffers."
183 #check to see if there was a packet
186 if (packet!=None and writeToFile == True):
189 row.append("%f"%time.time());
192 #if we want to print a parsed message
194 packetParsed = self.client.packet2parsed(packet)
195 sId = packetParsed.get('sID')
196 msg = "sID: %04d" %sId
197 if( packetParsed.get('eID')):
198 msg += " eID: %d" %packetParsed.get('eID')
199 msg += " rtr: %d"%packetParsed['rtr']
200 length = packetParsed['length']
201 msg += " length: %d"%length
203 for i in range(0,length):
205 msg +=" %03d"% ord(packetParsed[dbidx])
206 #msg = self.client.packet2parsedstr(packet)
208 # if we want to print just the message as it is read off the chip
210 print self.client.packet2str(packet)
215 MCPeflgReg=self.client.peek8(0x2D);
216 print"EFLG register equals: %x" %MCPeflgReg;
217 if((MCPeflgReg & 0xC0)==0xC0):
218 print "WARNING: BOTH overflow flags set. Missed a packet. Clearing and proceeding."
219 elif(MCPeflgReg & 0x80):
220 print "WARNING: RXB1 overflow flag set. A packet has been missed. Clearing and proceeding."
221 elif(MCPeflgReg & 0x40):
222 print "WARNING: RXB0 overflow flag set. A packet has been missed. Clearing and proceeding."
223 self.client.MCPbitmodify(0x2D,0xC0,0x00);
224 print"EFLG register set to: %x" % self.client.peek(0x2D);
227 if (self.client.peek8(0x2C) & 0x80):
228 self.client.MCPbitmodify(0x2C,0x80,0x00);
229 print "ERROR: Malformed packet recieved: " + self.client.packet2str(packet);
234 row.append(0); #since we don't check for errors if we're not in debug mode...
237 #how long the sniff was for
239 #boolean that tells us if there was filtering. 0 == no filters, 1 == filters
240 if(standardid != None):
244 #write packet to file
246 row.append("%02x"%ord(byte));
247 dataWriter.writerow(row);
248 if(writeToFile == True):
250 print "Listened for %d seconds, captured %d packets." %(duration,packetcount);
254 # def filterStdSweep(self, freq, low, high, time = 5):
256 # self.client.serInit()
257 # self.client.MCPsetup()
258 # for i in range(low, high+1, 6):
259 # print "sniffing id: %d, %d, %d, %d, %d, %d" % (i,i+1,i+2,i+3,i+4,i+5)
260 # comment= "sweepFilter: "
261 # #comment = "sweepFilter_%d_%d_%d_%d_%d_%d" % (i,i+1,i+2,i+3,i+4,i+5)
262 # description = "Running a sweep filer for all the possible standard IDs. This run filters for: %d, %d, %d, %d, %d, %d" % (i,i+1,i+2,i+3,i+4,i+5)
263 # count = self.sniff(freq=freq, duration = time, description = description,comment = comment, standardid = [i, i+1, i+2, i+3, i+4, i+5])
265 # for j in range(i,i+5):
266 # comment = "sweepFilter: "
267 # #comment = "sweepFilter: %d" % (j)
268 # description = "Running a sweep filer for all the possible standard IDs. This run filters for: %d " % j
269 # count = self.sniff(freq=freq, duration = time, description = description,comment = comment, standardid = [j, j, j, j])
274 # def sweepRandom(self, freq, number = 5, time = 200):
277 # self.client.serInit()
278 # self.client.MCPsetup()
279 # for i in range(0,number+1,6):
281 # comment = "sweepFilter: "
282 # for j in range(0,6,1):
283 # id = randrange(2047)
284 # #comment += "_%d" % id
288 # description = "Running a sweep filer for all the possible standard IDs. This runs the following : " + comment
289 # count = self.sniff(freq=freq, duration=time, description=description, comment = comment, standardid = idsTemp)
291 # for element in idsTemp:
292 # #comment = "sweepFilter: %d" % (element)
293 # comment="sweepFilter: "
294 # description = "Running a sweep filer for all the possible standard IDs. This run filters for: %d " % element
295 # count = self.sniff(freq=freq, duration = time, description = description,comment = comment, standardid = [element, element, element])
300 def sniffTest(self, freq):
304 print "Calling MCPsetrate for %i." %rate;
305 self.client.MCPsetrate(rate);
306 self.client.MCPreqstatNormal();
308 print "Mode: %s" % self.client.MCPcanstatstr();
309 print "CNF1: %02x" %self.client.peek8(0x2a);
310 print "CNF2: %02x" %self.client.peek8(0x29);
311 print "CNF3: %02x\n" %self.client.peek8(0x28);
314 packet=self.client.rxpacket();
317 if (self.client.peek8(0x2C) & 0x80):
318 self.client.MCPbitmodify(0x2C,0x80,0x00);
319 print "malformed packet recieved: "+ self.client.packet2str(packet);
321 print "properly formatted packet recieved" + self.client.packet2str(packet);
324 def freqtest(self,freq):
326 self.client.MCPsetup();
328 self.client.MCPsetrate(freq);
329 self.client.MCPreqstatListenOnly();
331 print "CAN Freq Test: %3d kHz" %freq;
336 starttime = time.time();
337 while((time.time()-starttime < args.time)):
338 packet=self.client.rxpacket();
342 if (self.client.peek8(0x2C) & 0x80):
343 print "malformed packet recieved"
345 self.client.MCPbitmodify(0x2C,0x80,0x00);
347 print self.client.packet2str(packet);
349 print "Results for %3.1d kHz: recieved %3d packets, registered %3d RX errors." %(freq, x, errors);
352 def isniff(self,freq):
353 """ An intelligent sniffer, decodes message format """
354 """ More features to be added soon """
356 self.client.MCPsetrate(freq);
357 self.client.MCPreqstatListenOnly();
359 packet=self.client.rxpacket();
368 print "\nArbID: " + self.client.packet2str(arbid);
369 print "EID: " + self.client.packet2str(eid);
370 print "DLC: " + self.client.packet2str(dlc);
371 print "Data: " + self.client.packet2str(data);
374 """ This will perform a test on the GOODTHOPTER10. Diagnostic messages will be printed
378 print "Just reset..."
379 print "EFLG register: %02x" % self.client.peek8(0x2d);
380 print "Tx Errors: %3d" % self.client.peek8(0x1c);
381 print "Rx Errors: %3d" % self.client.peek8(0x1d);
382 print "CANINTF: %02x" %self.client.peek8(0x2C);
383 self.client.MCPreqstatConfiguration();
384 self.client.poke8(0x60,0x66);
385 self.client.MCPsetrate(500);
386 self.client.MCPreqstatNormal();
387 print "In normal mode now"
388 print "EFLG register: %02x" % self.client.peek8(0x2d);
389 print "Tx Errors: %3d" % self.client.peek8(0x1c);
390 print "Rx Errors: %3d" % self.client.peek8(0x1d);
391 print "CANINTF: %02x" %self.client.peek8(0x2C);
392 print "Waiting on packets.";
396 packet=self.client.rxpacket();
398 print "Message recieved: %s" % self.client.packet2str(packet);
400 checkcount=checkcount+1;
401 if (checkcount%30==0):
402 print "EFLG register: %02x" % self.client.peek8(0x2d);
403 print "Tx Errors: %3d" % self.client.peek8(0x1c);
404 print "Rx Errors: %3d" % self.client.peek8(0x1d);
405 print "CANINTF: %02x" %self.client.peek8(0x2C);
410 def addFilter(self,standardid, verbose= True):
411 """ This method will configure filters on the board. Filters are positive filters meaning that they will only
412 store messages that match the ids provided in the list of standardid. Since there are 2 buffers and due to the configuration
413 of how the filtering works (see MCP2515 documentation), at least 3 filters must be set to guarentee you do not get any
414 unwanted messages. However even with only 1 filter set you should get all messages from that ID but the other buffer will store
415 any additional messages.
416 @type standardid: list of integers
417 @param standardid: List of standard ids that need to be set. There can be at most 6 filters set.
418 @type verbose: Boolean
419 @param verbose: If true it will print out messages and diagnostics to terminal.
422 @return: This method does not return anything
425 ### ON-CHIP FILTERING
426 if(standardid != None):
427 self.client.MCPreqstatConfiguration();
428 self.client.poke8(0x60,0x26); # set RXB0 CTRL register to ONLY accept STANDARD messages with filter match (RXM1=0, RMX0=1, BUKT=1)
429 self.client.poke8(0x20,0xFF); #set buffer 0 mask 1 (SID 10:3) to FF
430 self.client.poke8(0x21,0xE0); #set buffer 0 mask 2 bits 7:5 (SID 2:0) to 1s
431 if(len(standardid)>2):
432 self.client.poke8(0x70,0x20); # set RXB1 CTRL register to ONLY accept STANDARD messages with filter match (RXM1=0, RMX0=1)
433 self.client.poke8(0x24,0xFF); #set buffer 1 mask 1 (SID 10:3) to FF
434 self.client.poke8(0x25,0xE0); #set buffer 1 mask 2 bits 7:5 (SID 2:0) to 1s
436 for filter,ID in enumerate(standardid):
457 #### split SID into different regs
458 SIDlow = (ID & 0x07) << 5; # get SID bits 2:0, rotate them to bits 7:5
459 SIDhigh = (ID >> 3) & 0xFF; # get SID bits 10:3, rotate them to bits 7:0
462 self.client.poke8(RXFSIDH,SIDhigh);
463 self.client.poke8(RXFSIDL, SIDlow);
465 if (verbose == True):
466 print "Filtering for SID %d (0x%02xh) with filter #%d"%(ID, ID, filter);
468 self.client.MCPreqstatNormal();
473 def spitSetup(self,freq):
475 This method sets up the chip for transmitting messages, but does not transmit anything itself.
478 self.client.MCPsetrate(freq);
479 self.client.MCPreqstatNormal();
482 def spitSingle(self,freq, standardid, repeat,writes, period = None, debug = False, packet = None):
484 This method will spit a single message onto the bus. If there is no packet information provided then the
485 message will be sent as a remote transmission request (RTR). The packet length is assumed to be 8 bytes The message can be repeated a given number of times with
486 a gap of period (milliseconds) between each message. This will continue for the the number of times specified in the writes input.
487 This method will setup the bus and call the spit method, L{spit}. This method includes a bus reset and initialization.
490 @param freq: The frequency of the bus
492 @type standardid: list of integer
493 @param standardid: This is a single length list with one integer elment that corresponds to the standard id you wish to write to
495 @type repeat: Boolean
496 @param repeat: If true the message will be repeatedly injected. if not the message will only be injected 1 time
498 @type writes: Integer
499 @param writes: Number of writes of the packet
501 @type period: Integer
502 @param period: Time delay between injections of the packet in Milliseconds
505 @param debug: When true debug status messages will be printed to the terminal
508 @param packet: Contains the data bytes for the packet which is assumed to be of length 8. Each byte is stored as
509 an integer and can range from 0 to 255 (8 bits). If packet == None then an RTR will be sent on the given
513 self.spitSetup(freq);
514 spit(self,freq, standardid, repeat,writes, period, debug , packet)
516 def spit(self,freq, standardid, repeat,writes, period = None, debug = False, packet = None):
518 This method will spit a single message onto the bus. If there is no packet information provided then the
519 message will be sent as a remote transmission request (RTR). The packet length is assumed to be 8 bytes The message can be repeated a given number of times with
520 a gap of period (milliseconds) between each message. This will continue for the the number of times specified in the writes input.
521 This method does not include bus setup, it must be done before the method call.
525 @param freq: The frequency of the bus
527 @type standardid: list of integer
528 @param standardid: This is a single length list with one integer elment that corresponds to the standard id you wish to write to
530 @type repeat: Boolean
531 @param repeat: If true the message will be repeatedly injected. if not the message will only be injected 1 time
533 @type writes: Integer
534 @param writes: Number of writes of the packet
536 @type period: Integer
537 @param period: Time delay between injections of the packet in Milliseconds
540 @param debug: When true debug status messages will be printed to the terminal
543 @param packet: Contains the data bytes for the packet which is assumed to be of length 8. Each byte is stored as
544 an integer and can range from 0 to 255 (8 bits). If packet == None then an RTR will be sent on the given
549 #### split SID into different regs
550 SIDlow = (standardid[0] & 0x07) << 5; # get SID bits 2:0, rotate them to bits 7:5
551 SIDhigh = (standardid[0] >> 3) & 0xFF; # get SID bits 10:3, rotate them to bits 7:0
555 # if no packet, RTR for inputted arbID
556 # so packet to transmit is SID + padding out EID registers + RTR request (set bit 6, clear lower nibble of DLC register)
557 packet = [SIDhigh, SIDlow, 0x00,0x00,0x40]
562 # if we do have a packet, packet is SID + padding out EID registers + DLC of 8 + packet
564 """@todo: allow for variable-length packets"""
565 # TODO: allow for variable-length packets
567 packet = [SIDhigh, SIDlow, 0x00,0x00, # pad out EID regs
568 0x08, # bit 6 must be set to 0 for data frame (1 for RTR)
569 # lower nibble is DLC
570 packet[0],packet[1],packet[2],packet[3],packet[4],packet[5],packet[6],packet[7]]
574 if self.client.MCPcanstat()>>5!=0:
575 print "Warning: currently in %s mode. NOT in normal mode! May not transmit.\n" %self.client.MCPcanstatstr();
576 print "\nInitial state:"
577 print "Tx Errors: %3d" % self.client.peek8(0x1c);
578 print "Rx Errors: %3d" % self.client.peek8(0x1d);
579 print "Error Flags: %02x\n" % self.client.peek8(0x2d);
580 print "TXB0CTRL: %02x" %self.client.peek8(0x30);
581 print "CANINTF: %02x\n" %self.client.peek8(0x2C);
582 print "\n\nATTEMPTING TRANSMISSION!!!"
585 print "Transmitting packet: "
586 #print self.client.packet2str(packet)
588 self.client.txpacket(packet);
591 """@todo: the repeat variable is no longer needed and can be removed """
592 print "\nNow looping on transmit. "
594 for i in range(0,writes):
595 self.client.MCPrts(TXB0=True);
597 time.sleep(period/1000) # pause for period ms before sending again
598 #print time.time()-tic
599 #starttime = time.time();
600 #while((time.time()-starttime < duration)):
601 # self.client.MCPrts(TXB0=True);
602 # print "MSG printed"
604 for i in range(0,writes):
605 self.client.MCPrts(TXB0=True);
606 print "messages injected"
611 TXB0CTRL = self.client.peek8(0x30);
613 print "Tx Errors: %3d" % self.client.peek8(0x1c);
614 print "Rx Errors: %3d" % self.client.peek8(0x1d);
615 print "EFLG register: %02x" % self.client.peek8(0x2d);
616 print "TXB0CTRL: %02x" %TXB0CTRL;
617 print "CANINTF: %02x\n" %self.client.peek8(0x2C);
619 while(TXB0CTRL | 0x00 != 0x00):
621 TXB0CTRL = self.client.peek8(0x30);
622 if (checkcount %30 ==0):
623 print "Tx Errors: %3d" % self.client.peek8(0x1c);
624 print "Rx Errors: %3d" % self.client.peek8(0x1d);
625 print "EFLG register: %02x" % self.client.peek8(0x2d);
626 print "TXB0CTRL: %02x" %TXB0CTRL;
627 print "CANINTF: %02x\n" %self.client.peek8(0x2C);
630 def setRate(self,freq):
632 This method will reset the frequency that the MCP2515 expects the CAN bus to be on.
635 @param freq: Frequency of the CAN bus
637 self.client.MCPsetrate(freq);
640 # This will write the data provided in the packets which is expected to be a list of lists
641 # of the following form:
642 # for a given row = packets[i]
643 # row[0] time delay relative to the last packet. if 0 or empty there will be no delay
644 # row[1] = Standard ID (integer)
645 # row[2] = Data Length (0-8) (if it is zero we assume an Remote Transmit Request)
646 # row[3] = Data Byte 0
647 # row[4] = Data Byte 1
648 # .... up to Data Byte 8 ( THIS ASSUMES A PACKET OF LENGTH 8!!!
649 def writeData(self,packets,freq):
650 self.client.serInit()
653 if( row[0] != 0 and row[0] != ""):
656 #### split SID into different regs
657 SIDlow = (sID & 0x07) << 5; # get SID bits 2:0, rotate them to bits 7:5
658 SIDhigh = (sID >> 3) & 0xFF; # get SID bits 10:3, rotate them to bits 7:0
659 packet = [SIDhigh,SIDlow,0x00,0x00,0x08]
662 for i in range(3,dlc+3):
663 packet.append(row[i])
665 self.client.txpacket(packet)
671 if __name__ == "__main__":
673 parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,description='''\
675 Run commands on the MCP2515. Valid commands are:
679 peek 0x(start) [0x(stop)]
689 parser.add_argument('verb', choices=['info', 'test','peek', 'reset', 'sniff', 'freqtest','snifftest', 'spit']);
690 parser.add_argument('-f', '--freq', type=int, default=500, help='The desired frequency (kHz)', choices=[100, 125, 250, 500, 1000]);
691 parser.add_argument('-t','--time', type=int, default=15, help='The duration to run the command (s)');
692 parser.add_argument('-o', '--output', default=None,help='Output file');
693 parser.add_argument("-d", "--description", help='Description of experiment (included in the output file)', default="");
694 parser.add_argument('-v',"--verbose",action='store_false',help='-v will stop packet output to terminal', default=True);
695 parser.add_argument('-c','--comment', help='Comment attached to ech packet uploaded',default=None);
696 parser.add_argument('-b', '--debug', action='store_true', help='-b will turn on debug mode, printing packet status', default=False);
697 parser.add_argument('-a', '--standardid', type=int, action='append', help='Standard ID to accept with filter 0 [1, 2, 3, 4, 5]', default=None);
698 parser.add_argument('-x', '--faster', action='store_true', help='-x will use "fast packet recieve," which may duplicate packets and/or cause other weird behavior.', default=False);
699 parser.add_argument('-r', '--repeat', action='store_true', help='-r with "spit" will continuously send the inputted packet. This will put the GoodTHOPTHER into an infinite loop.', default=False);
702 args = parser.parse_args();
705 filename = args.output
706 description = args.description
707 verbose = args.verbose
708 comments = args.comment
710 standardid = args.standardid
714 comm = GoodFETMCPCANCommunication();
716 ##########################
718 ##########################
720 # Prints MCP state info
722 if(args.verb=="info"):
726 ##########################
728 ##########################
732 if(args.verb=="reset"):
735 ##########################
737 ##########################
739 # runs in ListenOnly mode
740 # utility function to pull info off the car's CAN bus
743 if(args.verb=="sniff"):
744 comm.sniff(freq=freq,duration=duration,description=description,verbose=verbose,comment=comments,filename=filename, standardid=standardid, debug=debug, faster=faster)
746 ##########################
748 ##########################
750 # runs in NORMAL mode
751 # intended for NETWORKED MCP chips to verify proper operation
754 if(args.verb=="snifftest"):
755 comm.sniffTest(freq=freq)
758 ##########################
760 ##########################
762 # runs in LISTEN ONLY mode
763 # tests bus for desired frequency --> sniffs bus for specified length of time and reports
764 # if packets were properly formatted
768 if(args.verb=="freqtest"):
769 comm.freqtest(freq=freq)
773 ##########################
775 ##########################
777 # """ An intelligent sniffer, decodes message format """
778 # """ More features to be added soon """
779 if(args.verb=="isniff"):
780 comm.isniff(freq=freq)
783 ##########################
785 ##########################
787 # Runs in LOOPBACK mode
788 # self-check diagnostic
789 # wasn't working before due to improperly formatted packet
791 # ...add automatic packet check rather than making user verify successful packet
792 if(args.verb=="test"):
795 if(args.verb=="peek"):
798 start=int(sys.argv[2],16);
801 stop=int(sys.argv[3],16);
802 print "Peeking from %04x to %04x." % (start,stop);
804 print "%04x: %02x" % (start,client.peek8(start));
807 ##########################
809 ##########################
811 # Basic packet transmission
812 # runs in NORMAL MODE!
814 # checking TX error flags--> currently throwing error flags on every
815 # transmission (travis thinks this is because we're sniffing in listen-only
816 # and thus not generating an ack bit on the recieving board)
817 if(args.verb=="spit"):
818 comm.spitSingle(freq=freq, standardid=standardid,duration=duration, repeat=repeat, debug=debug)