def main(): commands = {'scan': print_chain_info, 'svf': play_svf_file} # Set up a simple argument parser. parser = GreatFETArgumentParser( description="Utility for working with JTAG devices") parser.add_argument('command', choices=commands, help='the operation to complete') parser.add_argument('filename', metavar="[filename]", nargs='?', help='the filename to read from, for SVF playback') args = parser.parse_args() device = parser.find_specified_device() if args.command == 'scan': args.verbose = True elif args.filename == "-": args.verbose = False # Grab our log functions. log_function, log_error = parser.get_log_functions() # Execute the relevant command. command = commands[args.command] command(device.jtag, log_function, log_error, args)
def main(): from greatfet.utils import GreatFETArgumentParser # Set up a simple argument parser. parser = GreatFETArgumentParser(description="utility for reading from the GreatFET's ADC") parser.add_argument('-f', '--format', dest='format', type=str, default='voltage', choices=['voltage', 'raw'], help="Format to output in.\nVoltage string, or raw fraction returned by the ADC.") parser.add_argument('-m', '--machine-readable', dest='machine_readable', action='store_true', default=False, help="Don't output unit suffixes.") parser.add_argument('-n', '--samples', dest='sample_count', type=int, default=1, help="The number of samples to read. (default: 1)") parser.add_argument('-o', '--output', dest='output', type=argparse.FileType('w'), default='-', help="File to output to. Specify - to output to stdout (default).") args = parser.parse_args() log_function = parser.get_log_function() device = parser.find_specified_device() if not device.supports_api('adc'): sys.stderr.write("This device doesn't seem to support an ADC. Perhaps your firmware needs to be upgraded?\n") sys.exit(0) samples = device.adc.read_samples(args.sample_count) for sample in samples: output_sample(sample, args) args.output.close()
def main(): from greatfet.utils import GreatFETArgumentParser # Set up a simple argument parser. parser = GreatFETArgumentParser( description="Utility for experimenting with GreatFET's DAC") parser.add_argument('-S', '--set', nargs=1, type=int, help="DAC value to set on ADC0_0 (0-1023)") args = parser.parse_args() log_function = log_verbose if args.verbose else log_silent try: log_function("Trying to find a GreatFET device...") device = GreatFET(serial_number=args.serial) log_function("{} found. (Serial number: {})".format( device.board_name(), device.serial_number())) except greatfet.errors.DeviceNotFoundError: if args.serial: print("No GreatFET board found matching serial '{}'.".format( args.serial), file=sys.stderr) else: print("No GreatFET board found!", file=sys.stderr) sys.exit(errno.ENODEV) if args.set: set(device, args.set[0])
def main(): # Set up a simple argument parser. parser = GreatFETArgumentParser( description= "Utility for loading runtime extensions on to a GreatFET board.") parser.add_argument( '--m0', dest="m0", type=argparse.FileType('rb'), metavar='<filename>', help="loads the provided loadable file to run on the GreatFET's m0 core" ) args = parser.parse_args() log_function = parser.get_log_function() device = parser.find_specified_device() if not args.m0: parser.print_help() sys.exit(-1) if args.m0: data = args.m0.read() log_function( "Loading {} byte loadable onto the M0 coprocessor.\n".format( len(data))) device.m0.run_loadable(data)
def main(): logfile = 'log.bin' # logfile = '/tmp/fifo' from greatfet.utils import GreatFETArgumentParser # Set up a simple argument parser. parser = GreatFETArgumentParser(description="Utility for experimenting with GreatFET's ADC") parser.add_argument('-f', dest='filename', metavar='<filename>', type=str, help="Write data to file", default=logfile) parser.add_argument('-a', dest='adc', action='store_true', help="Use internal ADC") args = parser.parse_args() log_function = parser.get_log_function() device = parser.find_specified_device() if args.adc: device.comms._vendor_request_out(vendor_requests.ADC_INIT) else: device.comms._vendor_request_out(vendor_requests.SDIR_RX_START) time.sleep(1) print(device.comms.device) with open(args.filename, 'wb') as f: try: while True: d = device.comms.device.read(0x81, 0x4000, 1000) # print(d) f.write(d) except KeyboardInterrupt: pass if not args.adc: device.comms._vendor_request_out(vendor_requests.SDIR_RX_STOP)
def main(): # Set up a simple argument parser. parser = GreatFETArgumentParser( description="Convenience shell for working with GreatFET devices.") parser.add_argument('-e', '--exec', metavar="code", type=str, help="Executes the provided code as though it were passed" + "to a greatfet shell, and then terminates.", dest="code") args = parser.parse_args() gf = parser.find_specified_device() # Handle any inline execution. if args.code: # Replace any ;'s with newlines, so we can execute more than one statement. code = re.sub(";\s*", "\n", args.code) lines = code.split("\n") # And execute the code. for line in lines: result = repr(eval(line)) # Print the last result and return. print(result) sys.exit(0) # Break into IPython for the shell. print("Spwaning an IPython shell for easy access to your GreatFET.") print("Like normal python, you can use help(object) to get help for that object.") print("Try help(gf.apis.example) to see the documentation for the example API.\n") print("A GreatFET object has been created for you as 'gf'. Have fun!\n") IPython.start_ipython(user_ns={"gf": gf}, display_banner=False, argv=[])
def main(): parser = GreatFETArgumentParser( description="Convenience shell for working with GreatFET devices.") parser.add_argument('-n', '--length', dest='length', metavar='<bytes>', type=int, help="maximum amount of data to read (default: 4096)", default=4096) args = parser.parse_args() args = parser.parse_args() gf = parser.find_specified_device() log_function = parser.get_log_function() #Read and print the logs logs = gf.read_debug_ring(args.length) log_function("Ring buffer contained {} bytes of data:\n".format(len(logs))) print(logs)
def main(): from greatfet.utils import GreatFETArgumentParser # Set up a simple argument parser. parser = GreatFETArgumentParser( description="Utility for I2C communication via GreatFET") parser.add_argument( '-a', '--address', nargs=1, type=ast.literal_eval, help="7-bit address for communication over the I2C Bus") parser.add_argument( '-r', '--read', default=0, help="Number of bytes expecting to receive from the I2C Bus") parser.add_argument('-w', '--write', nargs='*', type=ast.literal_eval, default=[], help="Bytes to send over the I2C Bus") parser.add_argument('-z', '--scan', action='store_true', help="Scan all possible i2c addresses") args = parser.parse_args() log_function = log_verbose if args.verbose else log_silent try: log_function("Trying to find a GreatFET device...") device = GreatFET(serial_number=args.serial) log_function("{} found. (Serial number: {})".format( device.board_name(), device.serial_number())) except greatfet.errors.DeviceNotFoundError: if args.serial: print("No GreatFET board found matching serial '{}'.".format( args.serial), file=sys.stderr) else: print("No GreatFET board found!", file=sys.stderr) sys.exit(errno.ENODEV) if args.scan: scan(device, log_function) if args.write: write(device, args.address[0], args.write, log_function) if args.read: read(device, args.address[0], int(args.read), log_function)
def main(): parser = GreatFETArgumentParser( description="Convenience shell for working with GreatFET devices.") parser.add_argument('-n', '--length', dest='length', metavar='<bytes>', type=int, help="maximum amount of data to read (default: 4096)", default=4096) args = parser.parse_args() args = parser.parse_args() gf = parser.find_specified_device() log_function = parser.get_log_function() if not gf.supports_api('debug'): print("ERROR: This board doesn't appear to support the debug API -- was its firmware built without it?") return if not gf.apis.debug.supports_verb('read_dmesg'): print("ERROR: This board doesn't appear to support debug logging. Was its firmware built with logging or the ringbuffer off?") return #Read and print the dmesg log. logs = gf.read_debug_ring(args.length) log_function("Ring buffer contained {} bytes of data:\n".format(len(logs))) print(logs)
def main(): from greatfet.utils import GreatFETArgumentParser supported_interfaces = {'spi': lambda d: d.spi, 'i2c': lambda d: d.i2c} supported_interface_string = ', '.join(supported_interfaces) # Set up a simple argument parser. parser = GreatFETArgumentParser( description="bus pirate emulation utility for GreatFET", verbose_by_default=True) parser.add_argument( 'interface', nargs='?', help= "The type of interface to use for our commands. Currently supported: {}" .format(supported_interface_string)) parser.add_argument('commands', nargs='*', default=[], help="Bus pirate command to execute.") args = parser.parse_args() log_function, log_error = parser.get_log_functions() device = parser.find_specified_device() # By default, if we have a command on the command line, run non-interactively. if args.commands: interface = supported_interfaces[args.interface](device) commands = ' '.join(args.commands) # Print the executed commands, and their results. log_function("> {}".format(commands)) run_batch(interface, commands, log_function) else: if args.interface: interface = supported_interfaces[args.interface](device) else: interface = None # FIXME: remove this when we support proper mode-switching log_error( "Mode-switching currently not supported from interactive mode. Specify a mode on the command line." ) sys.exit(-1) run_interactive(interface, print, args.commands)
def main(): from greatfet.utils import GreatFETArgumentParser # Set up a simple argument parser. parser = GreatFETArgumentParser( description="Utility for LED configuration on GreatFET") parser.add_argument('-t', '--toggle', nargs='*', type=ast.literal_eval, default=[], help="LED numbers to toggle (0-3)") parser.add_argument('--on', nargs='*', type=ast.literal_eval, default=[], help="LED numbers to turn on (0-3)") parser.add_argument('--off', nargs='*', type=ast.literal_eval, default=[], help="LED numbers to turn off (0-3)") args = parser.parse_args() log_function = log_verbose if args.verbose else log_silent try: log_function("Trying to find a GreatFET device...") device = GreatFET(serial_number=args.serial) log_function("{} found. (Serial number: {})".format( device.board_name(), device.serial_number())) except greatfet.errors.DeviceNotFoundError: if args.serial: print("No GreatFET board found matching serial '{}'.".format( args.serial), file=sys.stderr) else: print("No GreatFET board found!", file=sys.stderr) sys.exit(errno.ENODEV) if args.toggle: toggle(device, args.toggle, log_function) if args.on: on(device, args.on, log_function) if args.off: off(device, args.off, log_function)
def main(): # Set up a simple argument parser. parser = GreatFETArgumentParser(description="""Utility for chipcon debugging via GreatFET (See /firmware/common/swra.c for pin mappings)""", verbose_by_default=True) parser.add_argument('--chip-id', action='store_true', # Short options (one dash) should always be one letter help="Print the chip ID of the connected device.") parser.add_argument('-a', '--address', dest='address', metavar='<n>', type=int_auto_base, help="Starting address (default: 0)", default=0) parser.add_argument('-l', '--length', dest='length', metavar='<n>', type=int_auto_base, help="Length of data to read") parser.add_argument('-r', '--read', metavar='<filename>', type=argparse.FileType('wb'), help="Read data into file") parser.add_argument('--no-erase', dest='erase', default=True, action='store_false', help="Do not erase the flash before performing a write operation") parser.add_argument('--no-verify', dest='verify', action='store_false', default=True, help="Do not verify the flash after performing a write operation") parser.add_argument('-E', '--mass-erase', action='store_true', help="Erase the entire flash memory") parser.add_argument('-w', '--write', metavar='<filename>', type=argparse.FileType('rb'), help="Write data from file") args = parser.parse_args() log_function = log_verbose if args.verbose else log_silent device = parser.find_specified_device() chipcon = device.create_programmer('chipcon') chipcon.debug_init() if args.chip_id: chip_id(chipcon) if args.read: if not args.length: parser.error("argument -s/--length: expected one argument") read_flash(chipcon, args.read, args.address, args.length, log_function) if args.mass_erase: mass_erase_flash(chipcon, log_function) if args.write: program_flash(chipcon, args.write, args.address, args.erase, args.verify, log_function)
def main(): from greatfet.utils import GreatFETArgumentParser # Set up a simple argument parser. parser = GreatFETArgumentParser( description="Utility for experimenting with GreatFET's DAC", verbose_by_default=True) parser.add_argument( '-f', '--format', dest='format', type=str, default='voltage', choices=['voltage', 'raw'], help= "Format for the input.\nVoltage string, or binary value to be loaded into the DAC." ) parser.add_argument( 'value', metavar='[value]', type=float, help= "The desired voltage (default) or raw value to load into DAC (with -f raw)." ) args = parser.parse_args() log_function = parser.get_log_function() device = parser.find_specified_device() device.apis.dac.initialize() if args.format == "voltage": # Voltage must be passed to the device in millivolts, so * 1000. device.apis.dac.set_voltage(int(args.value * 1000)) log_function("DAC set to {} volts".format(args.value)) else: device.apis.dac.set_value(int(args.value)) log_function("DAC set to {}".format(int(args.value)))
def main(): from greatfet.utils import GreatFETArgumentParser # Set up a simple argument parser. parser = GreatFETArgumentParser(description="Periodically print temperature from DS18B20 sensor") parser.add_argument('-S', dest='s20', action='store_true', help='DS18S20') args = parser.parse_args() log_function = parser.get_log_function() device = parser.find_specified_device() while True: data = device.vendor_request_in(vendor_requests.DS18B20_READ, length=2, timeout=2000) # temperature data is 16 bit signed temp = struct.unpack('<h', data)[0] if args.s20: temp /= 2.0 else: temp /= 16.0 print(time.strftime("%H:%M:%S"), temp, '{:.01f}'.format(temp * 9 / 5 + 32)) time.sleep(1)
def main(): # Set up a simple argument parser. parser = GreatFETArgumentParser( dfu=True, description="Utility for flashing firmware on GreatFET boards") parser.add_argument('-a', '--address', metavar='<n>', type=int, help="starting address (default: 0)", default=0) parser.add_argument( '-l', '--length', metavar='<n>', type=int, help="number of bytes to read (default: {})".format(MAX_FLASH_LENGTH), default=MAX_FLASH_LENGTH) parser.add_argument('-r', '--read', dest='read', metavar='<filename>', type=str, help="Read data into file", default='') parser.add_argument('-w', '--write', dest='write', metavar='<filename>', type=str, help="Write data from file", default='') parser.add_argument( '-R', '--reset', dest='reset', action='store_true', help="Reset GreatFET after performing other operations.") args = parser.parse_args() # Validate our options. # If we don't have an option, print our usage. if not any(( args.read, args.write, args.reset, )): parser.print_help() sys.exit(0) # Determine whether we're going to log to the stdout, or not at all. log_function = parser.get_log_function() # If we're supposed to install firmware via a DFU stub, install it first. if args.dfu: try: load_dfu_stub(args) except DeviceNotFoundError: print("Couldn't find a GreatFET-compatible board in DFU mode!", file=sys.stderr) sys.exit(errno.ENODEV) # Create our GreatFET connection. log_function("Trying to find a GreatFET device...") device = parser.find_specified_device() log_function("{} found. (Serial number: {})".format( device.board_name(), device.serial_number())) # Ensure that the device supports an onboard SPI flash. try: device.onboard_flash except AttributeError: print( "The attached GreatFET ({}) doesn't appear to have an SPI flash to program!" .format(device.board_name()), file=sys.stderr) sys.exit(errno.ENOSYS) # If we have a write command, write first, to match the behavior of hackrf_spiflash. if args.write: log_function("Writing data to SPI flash...") spi_flash_write(device, args.write, args.address, log_function) log_function("Write complete!") if not (args.reset or args.dfu): log_function( "Reset not specified; new firmware will not start until next reset." ) # Handle any read commands. if args.read: log_function("Reading data from SPI flash...") spi_flash_read(device, args.read, args.address, args.length, log_function) log_function("Read complete!") # Finally, reset the target if args.reset or args.dfu: log_function("Resetting GreatFET...") device.reset(reconnect=False) log_function("Reset complete!")
def main(): # Simple type-arguments for parsing. int_from_msps = lambda x: from_eng_notation( x, units=['Hz', 'SPS'], to_type=int) # Set up our argument parser. parser = GreatFETArgumentParser( description="Logic analyzer implementation for GreatFET", verbose_by_default=True) parser.add_argument( '-o', '-b', '--binary', dest='binary', metavar='<filename>', type=str, help="Write the raw samples captured to a file with the provided name." ) parser.add_argument( '-p', '--pulseview', '--sigrok', dest='pulseview', metavar="<filename>", type=str, help= "Generate a Sigrok/PulseView session file, and write it to the provided filename." ) parser.add_argument('-f', '--samplerate', metavar='samples_per_second', type=int_from_msps, default=17000000, dest='sample_rate', help='samples to capture per second') parser.add_argument('-n', '--num-channels', metavar='channels', type=int, default=8, dest='bus_width', help='the number of channels to capture') parser.add_argument( '-B', '--second-bank', action='store_const', const=8, default=0, dest='first_pin', help= "Provide this option to capture from SGPIO8 up, rather than from SGPIO0 up." ) parser.add_argument( '-O', '--stdout', dest='write_to_stdout', action='store_true', help= 'Provide this option to write the raw binary samples to the standard out. Implies -q.' ) parser.add_argument( '--rhododendron', dest='rhododendron', action='store_true', help= 'Capture raw packets for e.g. low or full speed USB using the Rhodadendon neighbor.' ) parser.add_argument( '--raw-usb', dest='raw_usb', action='store_true', help= 'Capture raw packets for e.g. low or full speed USB on SGPIO0 and SGPIO1.' ) parser.add_argument( '--debug-sgpio', dest='debug_sgpio', action='store_true', help= 'Developer option for debugging; dumps the SGPIO configuration before starting.' ) parser.add_argument( '--stats', dest='print_stats', action='store_true', help='Print capture statistics after the transfer is complete.') # And grab our GreatFET. args = parser.parse_args() # If we're writing binary samples directly to stdout, don't emit logs to stdout; otherwise, honor the # --quiet flag. if args.write_to_stdout: log_function = log_silent else: log_function = parser.get_log_function() # Ensure we have at least one write operation. if not (args.pulseview or args.binary or args.write_to_stdout): parser.print_help() sys.exit(-1) # Capture a few of the arguments. sample_rate = args.sample_rate bus_width = args.bus_width channel_names = None # If we have one of the raw-usb options, apply their settings. if args.raw_usb or args.rhododendron: sample_rate = int(51e6) bus_width = 2 channel_names = {0: 'D-', 1: 'D+'} if args.rhododendron: args.first_pin = 8 # Find our GreatFET. device = parser.find_specified_device() # Configure which locations we're using for SGPIO8/9. device.apis.logic_analyzer.configure_alt_mappings(args.rhododendron) # Set the first pin in our capture according to our bank setting. device.apis.logic_analyzer.change_first_pin(args.first_pin) # Replace the sample rate with the actual achieved sample rate. sample_rate, buffer_size, endpoint = device.apis.logic_analyzer.configure( sample_rate, bus_width) # If we've been asked to dump SGPIO debug info, do so. if args.debug_sgpio: device.apis.logic_analyzer.dump_sgpio_configuration(False) print(device.read_debug_ring(), file=sys.stderr) sys.stderr.flush() # Print what we're doing and our status. log_function("Sampling {} channels at {}Hz.".format( bus_width, eng_notation(sample_rate))) log_function("Press Ctrl+C to stop reading data from device.") # If we have a target binary file, open the target filename and use that to store samples. if args.binary: bin_file = open(args.binary, 'wb') bin_file_name = args.binary # Otherwise, create an temporary file and use that. (It's automatically destroyed on close, which is fancy.) elif args.pulseview: try: holding_dir = os.path.dirname(os.path.abspath(args.pulseview)) except: holding_dir = None bin_file = tempfile.NamedTemporaryFile(dir=holding_dir) bin_file_name = bin_file.name # Create queues of transfer objects that we'll use as a producer/consumer interface for our comm thread. empty_buffers = [] full_buffers = [] # Allocate a set of transfer buffers, so we don't have to continuously allocate them. for _ in range(DEFAULT_PREALLOCATED_BUFFERS): empty_buffers.append(allocate_transfer_buffer(buffer_size)) # Finally, spawn the thread that will handle our data processing and output. termination_request = threading.Event() thread_arguments = (termination_request, args, bus_width, bin_file, empty_buffers, full_buffers) data_thread = threading.Thread(target=background_process_data, args=thread_arguments) # Now that we're done with all of that setup, perform our actual sampling, in a tight loop, data_thread.start() device.apis.logic_analyzer.start() start_time = time.time() try: while True: # Grab a transfer buffer from the empty list... try: transfer_buffer = empty_buffers.pop() except IndexError: # If we don't have a buffer to fill, allocate a new one. It'll wind up in our buffer pool shortly. transfer_buffer = allocate_transfer_buffer(buffer_size) # Capture data from the device, and unpack it. device.comms.device.read(endpoint, transfer_buffer, 3000) # ... and pop it into the to-be-processed queue. full_buffers.append(transfer_buffer) except KeyboardInterrupt: pass except usb.core.USBError as e: log_error("") if e.errno == 32: log_error( "ERROR: Couldn't pull data from the device fast enough! Aborting." ) log_error( "(Lowering the sample rate may help. Sometimes, switching to another USB bus / port may help.)" ) else: log_error( "ERROR: Communications failure -- check the connection to -- and state of -- the GreatFET. " ) log_error( "(More debug information may be available if you run 'gf dmesg')." ) log_error(e) finally: elapsed_time = time.time() - start_time # No matter what, once we're done stop the device from sampling. device.apis.logic_analyzer.stop() # Signal to our data processing thread that it's time to terminate. termination_request.set() # Wait for our data processing thread to complete. log_function('') log_function( 'Capture terminated -- waiting for data processing to complete.') data_thread.join() # Flush whatever data we've read to disk, so it can be correctly read by subsequent operations. if args.pulseview: bin_file.flush() # Finally, generate our output. if args.binary: log_function("Binary data written to file '{}'.".format(args.binary)) if args.pulseview: emit_sigrok_file(args.pulseview, bin_file_name, bus_width, sample_rate, args.first_pin, channel_names) log_function( "Sigrok/PulseView compatible session file created: '{}'.".format( args.pulseview)) # Print how long we sampled for, as a nicety. log_function("Sampled for {} seconds.".format(round(elapsed_time, 4)))
def main(): # Set up a simple argument parser. parser = GreatFETArgumentParser( description="Convenience shell for working with GreatFET devices.") parser.add_argument( '-e', '--exec', metavar="code", type=str, help="Executes the provided code as though it were passed" + "to a greatfet shell, and then terminates.", dest="code") args = parser.parse_args() gf = parser.find_specified_device() # Handle any inline execution. if args.code: # Replace any ;'s with newlines, so we can execute more than one statement. code = re.sub(";\s*", "\n", args.code) lines = code.split("\n") # And execute the code. for line in lines: result = repr(eval(line)) # Print the last result and return. print(result) sys.exit(0) # Break into IPython for the shell. #print("Spwaning an IPython shell for easy access to your GreatFET.") #print("Like normal python, you can use help(object) to get help for that object.") #print("Try help(gf.apis.example) to see the documentation for the example API.\n") #print("A GreatFET object has been created for you as 'gf'. Have fun!\n") #IPython.start_ipython(user_ns={"gf": gf}, display_banner=False, argv=[]) #set up GPIO pins as outputs pin_clk = gf.gpio.get_pin('J1_P16') pin_sleep = gf.gpio.get_pin('J1_P8') #pin_cmode = gf.gpio.get_pin('J1_P14') #pin_mode = gf.gpio.get_pin('J1_P19') pin0 = gf.gpio.get_pin('J1_P15') #LSB pin1 = gf.gpio.get_pin('J1_P18') pin2 = gf.gpio.get_pin('J1_P17') pin3 = gf.gpio.get_pin('J1_P20') pin4 = gf.gpio.get_pin('J1_P22') pin5 = gf.gpio.get_pin('J1_P21') pin6 = gf.gpio.get_pin('J1_P26') pin7 = gf.gpio.get_pin('J1_P25') #MSB pin_clk.set_direction(1) pin_sleep.set_direction(1) #pin_cmode.set_direction(1) #pin_mode.set_direction(1) pin0.set_direction(1) pin1.set_direction(1) pin2.set_direction(1) pin3.set_direction(1) pin4.set_direction(1) pin5.set_direction(1) pin6.set_direction(1) pin7.set_direction(1) #initialize pins pin_sleep.write(0) pin_clk.write(0) #pin_cmode.write(0) #pin_mode.write(0) val = 0 pin0.write(val) pin1.write(val) pin2.write(val) pin3.write(val) pin4.write(val) pin5.write(val) pin6.write(val) pin7.write(val) #clock pulse function def clock_pulse(): pin_clk.write(0) #time.sleep(0.1) pin_clk.write(1) #time.sleep(0.1) pin_clk.write(0) def write_pin(pin, value): pin.write(value) #why do we need two clock pulses to get correct output? There can be a reset button between pulses and it stills works afterwards write_pin(pin7, 0) clock_pulse() clock_pulse() while False: pin7.write(1) clock_pulse() time.sleep(2) pin7.write(0) clock_pulse() time.sleep(2)
def main(): # Grab any GreatFET assets that should have shipped with the tool. dfu_stub_path = find_greatfet_asset('flash_stub.bin') auto_firmware_path = find_greatfet_asset("greatfet_usb.bin") # Set up a simple argument parser.- parser = GreatFETArgumentParser( dfu=True, verbose_by_default=True, description="Utility for flashing firmware on GreatFET boards") parser.add_argument('-a', '--address', metavar='<n>', type=int, help="starting address (default: 0)", default=0) parser.add_argument( '-l', '--length', metavar='<n>', type=int, default=None, help= "number of bytes to read; if not specified, we try to read the programmed sections" ) parser.add_argument('-r', '--read', dest='read', metavar='<filename>', type=str, help="Read data into file", default='') parser.add_argument('-w', '--write', dest='write', metavar='<filename>', type=str, help="Write data from file", default='') parser.add_argument( '-R', '--reset', dest='reset', action='store_true', help="Reset GreatFET after performing other operations.") parser.add_argument( '-V', '--volatile-upload', dest='volatile', metavar="<filename>", type=str, help= "Uploads a GreatFET firmware image to RAM via DFU mode. Firmware is not flashed." ) # If we have the ability to automatically install firmware, provide that as an option. if auto_firmware_path: parser.add_argument( '--autoflash', action='store_true', dest='autoflash', help= "Automatically flash the attached board with the firmware corresponding to the installed tools." ) parser.add_argument( '-U', '--volatile-upload-auto', dest='volatile_auto', action='store_true', help= "Automatically upload the tools' firmware via DFU mode. Firmware is not flashed." ) args = parser.parse_args() # If we're trying to automatically flash the given firmware, set the relevant options accordingly. try: if not args.write and args.autoflash: args.write = auto_firmware_path args.reset = True except AttributeError: pass try: if not args.volatile and args.volatile_auto: args.volatile = auto_firmware_path except AttributeError: pass # Validate our options. # If we don't have an option, print our usage. if not any((args.read, args.write, args.reset, args.volatile)): parser.print_help() sys.exit(0) # Determine whether we're going to log to the stdout, or not at all. log_function = parser.get_log_function() if args.dfu_stub: dfu_stub_path = args.dfu_stub # If we're uploading a file via DFU for a "volatile" flash, do so and abort. if args.volatile: try: device = LPC43xxTarget() except BoardNotFoundError: print("Couldn't find a GreatFET-compatible board in DFU mode!", file=sys.stderr) sys.exit(errno.ENODEV) log_function("Uploading data to RAM...\n") dfu_upload(device, args.volatile, log_function) sys.exit(0) # If we're supposed to install firmware via a DFU stub, install it first. if args.dfu: try: load_dfu_stub(dfu_stub_path) except DeviceNotFoundError: print("Couldn't find a GreatFET-compatible board in DFU mode!", file=sys.stderr) sys.exit(errno.ENODEV) # Create our GreatFET connection. log_function("Trying to find a GreatFET device...") device = parser.find_specified_device() log_function("{} found. (Serial number: {})".format( device.board_name(), device.serial_number())) # Ensure that the device supports an onboard SPI flash. try: device.onboard_flash except AttributeError: print( "The attached GreatFET ({}) doesn't appear to have an SPI flash to program!" .format(device.board_name()), file=sys.stderr) sys.exit(errno.ENOSYS) # If we have a write command, write first, to match the behavior of hackrf_spiflash. if args.write: log_function("Writing data to SPI flash...\n") spi_flash_write(device, args.write, args.address, log_function) log_function("Write complete!") if not (args.reset or args.dfu): log_function( "Reset not specified; new firmware will not start until next reset." ) # Handle any read commands. if args.read: log_function("Reading data from SPI flash...\n") spi_flash_read(device, args.read, args.address, args.length, log_function) log_function("Read complete!") # Finally, reset the target if args.reset or args.dfu: log_function("Resetting GreatFET...") device.reset(reconnect=False, is_post_firmware_flash=bool(args.write)) log_function("Reset complete!")
def main(): # Start off with a default packet state. current_packet_type = None current_packet_data = array.array('B') current_packet_remaining = 0 next_data_packet_emit_after = [] next_data_packet_timestamp = None current_usb_data = array.array('B') def emit_usb_packet(packet_data): """ Emits a raw USB packet to the target format. """ print("Packet: [{}]".format(packet_data)) def is_valid_pid_byte(byte): """ Returns true iff the given byte could be a valid PID. """ pid = byte & 0xf inverse = byte >> 4 return (pid ^ inverse) == 0xf def hack_smoothe_out_jitter(packet_data, emit_point): """ XXX Horrorhack intended to "smoothe" over a missing firmware piece until it's implemented. """ try: print("next PID would be {} -- valid: {}".format( packet_data[emit_point], is_valid_pid_byte(packet_data[emit_point]))) # If the next byte is a valid PID, there's no need to hack anything. # Move along.. if is_valid_pid_byte(packet_data[emit_point]): return 0 except IndexError: pass print("trying to smoothe out a bit of jitter:") try: print("trying delta -1 [{}] -- {}".format( packet_data[emit_point - 1], is_valid_pid_byte(packet_data[emit_point - 1]))) # Otherwise, if the previous byte was a valid PID, move back to it. if is_valid_pid_byte(packet_data[emit_point - 1]): return -1 except IndexError: pass try: print("trying delta +1 [{}] -- {}".format( packet_data[emit_point + 1], is_valid_pid_byte(packet_data[emit_point + 1]))) # Otherwise, if the previous byte was a valid PID, move back to it. if is_valid_pid_byte(packet_data[emit_point + 1]): return 1 except IndexError: pass return 0 def handle_capture_packet(packet_type, packet_data): """ Handles a received full packet from the analyzer. """ nonlocal current_packet_type, current_packet_data, current_packet_remaining nonlocal next_data_packet_emit_after, next_data_packet_timestamp, current_usb_data # If this is an "end event" packet, grab the point at which # we're supposed to emit the packet. if packet_type == PACKET_TYPE_EVENT_END_OK: if (not next_data_packet_emit_after) or ( next_data_packet_emit_after[-1] != packet_data[0]): next_data_packet_emit_after.append(packet_data[0]) # If this is start packet, grab the timestamp from it. elif packet_type == PACKET_TYPE_EVENT_START: # FIXME: implement pass # If this is a USB data packet, handle it. elif packet_type == PACKET_TYPE_USB_DATA: print("got {} bytes of USB data [{}] <emit at: {}>".format( len(packet_data), packet_data, next_data_packet_emit_after)) existing_packet_length = len(current_usb_data) # Add the data to the current packet. current_usb_data.extend(packet_data) # Store that we're handled 0 bytes into the current packet. position_in_packet = 0 # If this packet ends a USB packet, emit the completed usb packet. while next_data_packet_emit_after: emit_after_bytes = next_data_packet_emit_after.pop( 0) - position_in_packet + 1 print("emit after: {} bytes [data: {}]".format( emit_after_bytes, current_usb_data)) # Emit the USB packet up until this point... emit_point = existing_packet_length + emit_after_bytes # XXX: Temporary hack to smoothe out single-byte event offsets until # the firmware properly has NXT and DIR tied to an SCT counter. delta = hack_smoothe_out_jitter(current_usb_data, emit_point) emit_point += delta emit_after_bytes += delta emit_usb_packet(current_usb_data[0:emit_point]) # ... and mark ourselves as already having emitted the relevant bytes, so # the future "emit afters" can be scaled properly. position_in_packet += emit_after_bytes # ... and remove those packets from the buffer. del current_usb_data[0:emit_point] next_data_packet_emit_after = [] def parse_capture_packets(samples, args, bin_file): """ Parses a set of packets coming from a USB capture device. """ nonlocal current_packet_type, current_packet_data, current_packet_remaining nonlocal next_data_packet_emit_after, next_data_packet_timestamp, current_usb_data # Parse all of the samples we have in our buffer. while samples: sample = samples.pop(0) #print("sample: {} / current_packet_remaining: {}".format(sample, current_packet_remaining)) # If we have data remaining in our packet, parse this sample as data. if current_packet_remaining: current_packet_data.append(sample) current_packet_remaining -= 1 # If we just completed a given packet, handle it. if current_packet_remaining == 0: handle_capture_packet(current_packet_type, current_packet_data) # Clear out our packet state. del current_packet_data[:] # Otherwise, handle this as a new packet. elif (current_packet_remaining == 0) and (sample in PACKET_SIZES): current_packet_type = sample current_packet_remaining = PACKET_SIZES[current_packet_type] - 1 else: raise IOError( "unknown packet type {}! stream error?\n".format(sample)) # Set up our argument parser. parser = GreatFETArgumentParser( description="Simple Rhododendron capture utility for GreatFET.", verbose_by_default=True) parser.add_argument( '-o', '-b', '--binary', dest='binary', metavar='<filename>', type=str, help="Write the raw samples captured to a file with the provided name." ) parser.add_argument( '--m0', dest="m0", type=argparse.FileType('rb'), metavar='<filename>', help= "loads the specific m0 coprocessor 'loadable' instead of the default Rhododendron one" ) parser.add_argument('-F', '--full-speed', dest='speed', action='store_const', const=SPEED_FULL, default=SPEED_HIGH, help="Capture full-speed data.") parser.add_argument('-L', '--low-speed', dest='speed', action='store_const', const=SPEED_LOW, default=SPEED_HIGH, help="Capture low-speed data.") parser.add_argument('-H', '--high-speed', dest='speed', action='store_const', const=SPEED_HIGH, help="Capture high-speed data. The default.") parser.add_argument( '-O', '--stdout', dest='write_to_stdout', action='store_true', help= 'Provide this option to log the received data to the stdout.. Implies -q.' ) # And grab our GreatFET. args = parser.parse_args() # If we're writing binary samples directly to stdout, don't emit logs to stdout; otherwise, honor the # --quiet flag. if args.write_to_stdout: log_function = log_silent else: log_function = parser.get_log_function() # Ensure we have at least one write operation. if not (args.binary or args.write_to_stdout): parser.print_help() sys.exit(-1) # Find our GreatFET. device = parser.find_specified_device() # Bring our Rhododendron board online; and capture communication parameters. buffer_size, endpoint = device.apis.usb_analyzer.initialize( args.speed, timeout=10000, comms_timeout=10000) # $Load the Rhododendron firmware loadable into memory... try: if args.m0: data = args.m0.read() else: data = read_rhododendron_m0_loadable() except (OSError, TypeError): log_error("Can't find a Rhododendron m0 program to load!") log_error("We can't run without one.") sys.exit(-1) # Debug only: setup a pin to track when we're handling SGPIO data. debug_pin = device.gpio.get_pin('J1_P3') debug_pin.set_direction(debug_pin.DIRECTION_OUT) # ... and then run it on our m0 coprocessor. device.m0.run_loadable(data) # Print what we're doing and our status. log_function("Reading raw {}-speed USB data!\n".format( SPEED_NAMES[args.speed])) log_function("Press Ctrl+C to stop reading data from device.") # If we have a target binary file, open the target filename and use that to store samples. bin_file = None if args.binary: bin_file = open(args.binary, 'wb') bin_file_name = args.binary # Now that we're done with all of that setup, perform our actual sampling, in a tight loop, device.apis.usb_analyzer.start_capture() transfer_buffer = allocate_transfer_buffer(buffer_size) total_captured = 0 try: while True: # Capture data from the device, and unpack it. try: new_samples = device.comms.device.read( endpoint, transfer_buffer, SAMPLE_DELIVERY_TIMEOUT_MS) samples = transfer_buffer[0:new_samples - 1] total_captured += new_samples log_function("Captured {} bytes.".format(total_captured), end="\r") parse_capture_packets(samples, args, bin_file) except usb.core.USBError as e: if e.errno != errno.ETIMEDOUT: raise except KeyboardInterrupt: pass except usb.core.USBError as e: log_error("") if e.errno == 32: log_error( "ERROR: Couldn't pull data from the device fast enough! Aborting." ) else: log_error( "ERROR: Communications failure -- check the connection to -- and state of -- the GreatFET. " ) log_error( "(More debug information may be available if you run 'gf dmesg')." ) log_error(e) finally: # No matter what, once we're done stop the device from sampling. device.apis.usb_analyzer.stop_capture() if args.binary: log_function("Binary data written to file '{}'.".format( args.binary))
def main(): commands = { 'info': print_flash_info, 'erase': erase_chip, 'read': dump_chip, 'write': program_chip } # Set up a simple argument parser. parser = GreatFETArgumentParser( description="Utility for programming and dumping SPI flash chips", verbose_by_default=True) parser.add_argument('command', choices=commands, help='the operation to complete') parser.add_argument( 'filename', metavar="[filename]", nargs='?', help='the filename to read or write to, for read/write operations') parser.add_argument('-a', '--address', metavar='<addr>', default=0, type=from_eng_notation, help="Starting offset in the given flash memory.") parser.add_argument('-l', '--length', metavar='<length>', type=from_eng_notation, default=None, help="number of bytes to read (default: flash size)") parser.add_argument( '-E', '--no-autoerase', action='store_false', dest='autoerase', help= "If provided, the target flash will not be erased before a write operation." ) parser.add_argument( '-C', '--cautious', '--cowardly', action='store_true', dest='cowardly', help="Refuses to do anything that might overwrite or lose chip data.") parser.add_argument( '-S', '--no-spdf', dest='autodetect', action='store_false', help="Don't attempt to use SPDF to autodetect flash parameters.") parser.add_argument( '-R', '--require-spdf', dest='allow_fallback', action='store_false', help="Only use SPDF; ignore any argument provided as fall-back options." ) parser.add_argument( '-T', '--auto-truncate', dest='truncate', action='store_true', help= "If provided, any read operations will truncate trailing unprogrammed words (0xFFs)." ) parser.add_argument( '--page-size', metavar='<bytes>', type=int, default=256, help= "manually specify the page size of the target flash; for use with -S") parser.add_argument( '--flash-size', metavar='<bytes>', type=int, default=8192, help= "manually specify the capacity of the target flash; for use with -S") parser.add_argument( '-J', '--allow-null-jedec-id', dest='bypass_jedec', action='store_true', help= "Allow the device to work even if it doesn't appear to support a JEDEC ID." ) args = parser.parse_args() device = parser.find_specified_device() if args.command == 'info': args.verbose = True elif args.filename == "-": args.verbose = False # Grab our log functions. log_function, log_error = parser.get_log_functions() try: # TODO: use a GreatFET method to automatically instantiate spi_flash # Figure out the "override" page and flash size for any arguments provided. # If autodetection is enabled and works, these aren't used. maximum_address = args.flash_size - 1 num_pages = (args.flash_size + (args.page_size - 1)) // args.page_size # Create a SPI flash object. spi_flash = device.create_programmer( 'spi_flash', args.autodetect, args.allow_fallback, page_size=args.page_size, maximum_address=maximum_address, allow_null_jedec=args.bypass_jedec) # If we have a device that's ancient enough to not speak JEDEC, notify the user. Pithily. if args.bypass_jedec and spi_flash.manufacturer_id == 0xff and spi_flash.part_id == 0xffff: log_function( "I... really can't see an SPI flash here. I'll trust you.") except CommandFailureError: log_error("This device doesn't appear to support identifying itself.") log_error(" You'll need to specify the page and flash size manually.") sys.exit(-1) except IOError as e: log_error(str(e)) log_error("If you believe you have a device properly connected, you") log_error(" may want to try again with --allow-null-jedec-id.") log_error("") sys.exit(-2) command = commands[args.command] command(spi_flash, log_function, log_error, args)
def main(): """ Core command. """ global input_thread, termination_request, console parity_modes = { 'none': UART.PARITY_NONE, 'odd': UART.PARITY_ODD, 'even': UART.PARITY_EVEN, 'one': UART.PARITY_STUCK_AT_ONE, 'zero': UART.PARITY_STUCK_AT_ZERO } # Set up a simple argument parser. # TODO: support configurations such as '8n1' parser = GreatFETArgumentParser( description="Simple GreatFET UART monitor.") parser.add_argument( 'baud', nargs='?', type=from_eng_notation, default=115200, help="Baud rate; in symbols/second. Defaults to 115200.") parser.add_argument('-d', '--data', type=int, default=8, help="The number of data bits per frame.") parser.add_argument('-S', '--stop', type=int, default=1, help="The number of stop bits per frame.") parser.add_argument('-P', '--parity', choices=parity_modes, default=0, help="The type of parity to use.") parser.add_argument('-E', '--echo', action='store_true', help="If provided, local echo will be enabled.") parser.add_argument( '-N', '--no-newline-translation', action='store_false', dest='tr_newlines', help="Provide this option to disable newline translation.") args = parser.parse_args() device = parser.find_specified_device() # Grab our log functions. log_function, log_error = parser.get_log_functions() # Configure our UART. if not hasattr(device, 'uart'): log_error( "This device doesn't appear to support the UART API. Perhaps it needs a firmware upgrade?" ) sys.exit(-1) # Notify the user that we're entering monitor mode. log_function( "Entering monitor mode. To terminate, type CTRL+A, then CTRL+C.") # Create a console object. console = Console() console.setup() # Create a thread to capture input data into a locally-processed queue. input_queue = queue.Queue() termination_request = threading.Event() input_thread = threading.Thread(target=input_handler, args=(console, input_queue, termination_request)) input_thread.start() # Configure our UART parameters. device.uart.update_parameters(baud=args.baud, data_bits=args.data, stop_bits=args.stop, parity=args.parity) # Generate our UART monitor. while True: # Grab any data from the serial port, and print it to the screen. data = device.uart.read() # If we're preforming newline translation, prepend a "\r" to any newline. if args.tr_newlines and (data == b"\n"): console.write_bytes(b"\r") # Stick the UART data onscreen. console.write_bytes(data) # Grab any data from the user, and send it via serial. try: new_key = input_queue.get_nowait() handle_special_functions(new_key) # If local echo is on, print the character to our local console. if args.echo: sys.stdout.buffer.write(new_key) if args.tr_newlines and (new_key == b"\n"): device.uart.write(b"\r") device.uart.write(new_key) except queue.Empty: pass
def main(): from greatfet.utils import GreatFETArgumentParser # Set up a simple argument parser. parser = GreatFETArgumentParser( description="JTAG debug utility for MSP430") parser.add_argument('-I', '--identify', dest='ident', action='store_true', help="Show target identification") parser.add_argument('-e', '--erase', dest='erase', action='store_true', help="Erase target flash") parser.add_argument('-E', '--erase_info', dest='erase_info', action='store_true', help="Erase target info flash") parser.add_argument('-f', '--flash', dest='flash', type=str, metavar='<filename>', help="Write target flash") parser.add_argument('-V', '--verify', dest='verify', type=str, metavar='<filename>', help="Verify target flash") parser.add_argument('-d', '--dump', dest='dump', type=str, metavar='<filename>', help="Dump target flash") parser.add_argument('-r', '--run', dest='run', action='store_true', help="Run target device") parser.add_argument('-R', '--peek', dest='peek', action='store_true', help="Read from memory location") parser.add_argument('-W', '--poke', dest='poke', type=ast.literal_eval, metavar='<value>', help="Write to memory location") parser.add_argument( '-a', '--address', dest='address', default=0, type=ast.literal_eval, metavar='<address>', help="Address for peek/poke/flash/dump/verify actions (default 0x00)") parser.add_argument('-l', '--length', dest='length', type=ast.literal_eval, metavar='<length>', help="Length for peek/dump actions in bytes") parser.add_argument('-t', '--test', dest='test', action='store_true', help="Test MSP430 JTAG functions (destructive)") args = parser.parse_args() log_function = log_verbose if args.verbose else log_silent try: log_function("Trying to find a GreatFET device...") device = GreatFET(serial_number=args.serial) log_function("{} found. (Serial number: {})".format( device.board_name(), device.serial_number())) except greatfet.errors.DeviceNotFoundError: if args.serial: print("No GreatFET board found matching serial '{}'.".format( args.serial), file=sys.stderr) else: print("No GreatFET board found!", file=sys.stderr) sys.exit(errno.ENODEV) jtag = msp430_jtag.JTAG_MSP430(device) jtag_id = jtag.start() if jtag_id in (0x89, 0x91): log_function("Target dentified as 0x%02x." % jtag_id) else: print("Error, misidentified as 0x%02x." % jtag_id) print("Check wiring, as this should be 0x89 or 0x91.") sys.exit(errno.ENODEV) if args.ident: print("Identifies as %s (0x%04x)" % (jtag.ident_string(), jtag.ident())) if args.dump: if args.length: end = args.address + args.length else: end = 0xffff log_function("Dumping from 0x%04x to 0x%04x to %s." % (args.address, end, args.dump)) with open(args.dump, 'wb') as f: address = args.address while address < end: data = jtag.peek_block(address) f.write(data) address += len(data) if args.erase: log_function("Erasing main flash memory.") jtag.erase_flash() if args.erase_info: log_function("Erasing info flash.") jtag.erase_info() if args.flash: with open(args.flash, 'rb') as f: address = args.address if args.length: end = address + args.length else: end = address + f.seek(0, 2) f.seek(0) log_function("Writing %d bytes of %s to 0x%04x." % (end - address, args.flash, address)) while address < end: if end - address < 0x400: block_size = end - address else: block_size = 0x400 data = f.read(block_size) result = jtag.poke_flash_block(address, data) address += block_size else: log_function("Flash contents written.") if args.verify: with open(args.verify, 'rb') as f: address = args.address if args.length: end = address + args.length else: end = address + f.seek(0, 2) f.seek(0) log_function("Verifying %d bytes of %s from 0x%04x." % (end - address, args.verify, address)) while address < end: if end - address < 0x400: block_size = end - address else: block_size = 0x400 data = jtag.peek_block(address, block_size) buffer = f.read(len(data)) if data != buffer: print("File does not match flash.") break address += len(data) else: print("Flash contents verified.") if args.poke: log_function("Writing 0x%04x to 0x%04x." % (args.poke, args.address)) written = jtag.poke(args.address, args.poke) if written != args.poke: print("Failed to write 0x%04x to 0x%04x" % (args.poke, args.address)) if args.peek: if args.length: length = args.length if length % 2: length += 1 else: length = 2 log_function("Reading %d bytes from 0x%04x." % (length, args.address)) values = jtag.peek(args.address, length) for i, v in enumerate(values): print("%04x: %04x" % (args.address + i * 2, v)) if args.run: log_function("Resuming target execution.") jtag.run() if args.test: log_function("Running test.") msp430_test(jtag)
def main(): # Simple type-arguments for parsing. int_from_msps = lambda x: from_eng_notation( x, units=['Hz', 'SPS'], to_type=int) int_from_eng = lambda x: from_eng_notation(x, to_type=int) # Set up our argument parser. parser = GreatFETArgumentParser( description="Logic analyzer implementation for GreatFET", verbose_by_default=True) parser.add_argument( 'command', choices=commands, help='the pattern shape to generate, or command to execute') parser.add_argument( '-n', '--samples', metavar='samples', type=int_from_eng, default=64, dest='samples', help='the number of samples to generate of the given pattern, up to 32K' ) parser.add_argument( '-w', '--width', metavar='bus_width', type=int, default=8, dest='bus_width', help='the width of the bus, in bits; up to 16 [default: 8]') parser.add_argument( '-f', '--samplerate', metavar='samples_per_second', type=int_from_msps, default=1000000, dest='sample_rate', help='samples to emit per second; up to 204MSPS [default: 1MSPS]') parser.add_argument( '--oneshot', dest='repeat', action='store_false', help='If provided, the given pattern will be shifted out only once.') parser.add_argument( '--debug-sgpio', dest='debug_sgpio', action='store_true', help= 'Developer option for debugging; dumps the SGPIO configuration after starting.' ) args = parser.parse_args() log_function, log_error = parser.get_log_functions() # Find our GreatFET. device = parser.find_specified_device() # Ensure the GreatFET supports our API. if not device.supports_api('pattern_generator'): log_error( "The connected GreatFET doesn't seem to support pattern generation. A firmware upgrade may help." ) # Create our pattern generator object. pattern_generator = PatternGenerator(device, sample_rate=args.sample_rate, bus_width=args.bus_width) # TODO: truncate things to the pattern generator object's limits # Figure out how the user wants their samples generated (or what the want done, in general). command_to_execute = commands[args.command] # Execute the core command, which usually generates samples. samples = command_to_execute(args, pattern_generator) # If the generator has generated samples, scan them out. if samples: pattern_generator.scan_out_pattern(samples, args.repeat) # If we've been asked to dump our SGPIO configuration, do so. if args.debug_sgpio: log_error(pattern_generator.dump_sgpio_config()) # Log what we've done to the user. if samples: log_function("Scanning out {} samples at {}.".format( len(samples), eng_notation(args.sample_rate, unit='SPS'))) log_function("Run '{} stop' to halt generation.".format(sys.argv[0])) log_function("")
def main(): # Set up a simple argument parser. parser = GreatFETArgumentParser( description="Convenience shell for working with GreatFET devices.") parser.add_argument( '-e', '--exec', metavar="code", type=str, help="Executes the provided code as though it were passed " + "to a greatfet shell, and then terminates.", dest="code") parser.add_argument( '-E', '--pre-exec', metavar="code", type=str, help="Executes the provided code as though it were passed " + "to a greatfet shell, but does not explicitly terminate.", dest="prelude") parser.add_argument( '-f', '--file', metavar="file", type=str, help="Executes the relevant file before starting the given shell.") parser.add_argument( '-M', '--automagic', dest="automagic", action='store_true', help="Enable automagic, so lazy developers don't have to type %%.") parser.add_argument( '-P', '--avoid-parens', dest="avoidparens", action='store_true', help= "Enable full autocall, so bare methods are executed, rather than printed." ) parser.add_argument( '-A', '--autoreload', dest="autoreload", action='store_true', help= "Attempts to reload python modules automatically as they change; so current objects import new functionality. This may sometimes break your shell." ) parser.add_argument( '-S', '--singleton', dest="singleton", action='store_true', help= "Connect via a singleton that persists across device reconnects. Note: device state is not preserved." ) args = parser.parse_args() if args.singleton: connect_function = parser.get_singleton_for_specified_device else: connect_function = parser.find_specified_device gf = connect_function() # Break into IPython for the shell. if not args.code: print( "Spawning an IPython shell for easy access to your GreatFET board." ) print( "Like normal python, you can use help(object) to get help for that object.\n" ) print( "Try help(gf.gpio) to see the documentation for the GreatFET GPIO;" ) print( "try dir(gf) to see a list of properties on the GreatFET object, and" ) print( "try gf.available_interfaces() and gf.available_programmers() to see" ) print( "the interfaces you can work with, and the programmers you can create.\n" ) print( "This GreatFET shell is *magical*. Try some of our IPython magics:\n" ) print("\t %dmesg -- prints the GreatFET's debug ring (log)") print("\t %reconnect -- tries to reconnect to the current GreatFET") print( "\t %makeflash -- when run from a firmware build dir, builds and flashes your GreatFET" ) print( "\t %reload -- tries to reload your host python code; useful with $PYTHONPATH" ) print( "\t %refet -- (not %reset) resets and reconnects to the current GreatFET" ) print("\t [hey, %reset was taken!]\n\n") singleton_text = "singleton " if args.singleton else "" print( "A GreatFET {}object has been created for you as 'gf'. Have fun!\n" .format(singleton_text)) # Create a new shell, and give it access to our created GreatFET object. shell = TerminalInteractiveShell() shell.push('gf') # Create nice aliases for our primary interfaces. i2c = gf.i2c spi = gf.spi adc = gf.adc uart = gf.uart gpio = gf.gpio shell.push(( 'i2c', 'spi', 'adc', 'uart', 'gpio', )) # Make the autoreload extension available. shell.extension_manager.load_extension('autoreload') # Add our magic commands, to make execution more 'fun'. shell.register_magics(GreatFETShellMagics) # If the user has requested automagic, let them have their automagic. if args.automagic: shell.automagic = True # If we're in avoid parenthesis mode if args.avoidparens: shell.autocall = 2 # If we're using autoreload, enable that. if args.autoreload: shell.run_cell('%autoreload 2') print( "Heads up: you've enabled autoreload. Things make break in unexpected ways as your code changes." ) print( "You can fix this by adjusting your expectations regarding breakage.\n" ) # Handle any inline execution requested. if args.code or args.prelude: # Replace any ;'s with newlines, so we can execute more than one statement. code = args.code or args.prelude code = re.sub(r";\s*", "\n", code) lines = code.split("\n") # If we're in execute-and-quit mode, do so. for line in lines: shell.run_cell(line, shell_futures=True) # If we're to exit after running the relevant code, do so. if args.code: sys.exit(0) # If we have a file to execute, execute it. if args.file: shell.safe_execfile_ipy(args.file, shell_futures=True, raise_exceptions=True) # Run the shell itself. shell.connect_function = connect_function shell.mainloop()