Esempio n. 1
0
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()
Esempio n. 2
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)
Esempio n. 4
0
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)))
Esempio n. 5
0
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)
Esempio n. 6
0
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():
    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():
    # 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!")
Esempio n. 9
0
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)))
Esempio n. 10
0
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))
Esempio n. 11
0
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!")