예제 #1
0
def reset_cortex(port, ctx=proscli.utils.State()):
    click.echo('Resetting cortex...', nl=False)
    configure_port(port, serial.PARITY_NONE)
    debug('RESET CORTEX. PORT CFG: {}'.format(repr(port)), ctx)
    port.flush()
    port.read(port.in_waiting)
    port.write([20])
    port.flush()
    click.echo('complete')
    time.sleep(0.01)
예제 #2
0
def reset_cortex(port, ctx=proscli.utils.State()):
    click.echo('Resetting cortex...', nl=False)
    configure_port(port, serial.PARITY_NONE)
    debug('RESET CORTEX. PORT CFG: {}'.format(repr(port)), ctx)
    port.flush()
    port.read(port.in_waiting)
    port.write([20])
    port.flush()
    click.echo('complete')
    time.sleep(0.01)
예제 #3
0
def reset_cortex(port, ctx=proscli.utils.State()):
    click.echo('Resetting cortex... ', nl=False)
    debug('RESET CORTEX. PORT CFG: {}'.format(repr(port)), ctx)
    port.parity = serial.PARITY_NONE
    port.flush()
    port.read_all()
    time.sleep(0.1)
    port.write([0xc9, 0x36, 0xb8, 0x47, 0x20])
    port.flush()
    port.write([0x14])
    click.echo('complete')
    time.sleep(0.01)
예제 #4
0
def send_go_command(port, address):
    click.echo('Executing binary...', nl=False)
    address = compute_address_commandable(address)
    debug('Executing binary at {}'.format(adr_to_str(address)))

    response = send_bootloader_command(port, 0x21, 1)
    if response is None or response[0] != ACK:
        click.echo('failed (execute command not accepted)')
        return False
    port.write(address)
    port.flush()
    click.echo('complete')
    return True
예제 #5
0
def expose_bootloader(port, ctx=proscli.utils.State()):
    click.echo('Exposing bootloader... ', nl=False)
    bootloader_bits = [0xc9, 0x36, 0xb8, 0x47, 0x25]
    port.flush()
    debug('EXPOSE BL BITS: {}  PORT CFG: {}'.format(bytes_to_str(bootloader_bits), repr(port)), ctx)
    port.read_all()
    time.sleep(0.1)
    for _ in itertools.repeat(None, 5):
        port.write(bootloader_bits)
        time.sleep(0.1)
    time.sleep(0.3)  # time delay to allow shift to download mode
    click.echo('complete')
    return True
예제 #6
0
def send_go_command(port, address):
    click.echo("Executing binary...", nl=False)
    address = compute_address_commandable(address)
    debug("Executing binary at {}".format(adr_to_str(address)))

    response = send_bootloader_command(port, 0x21, 1)
    if response is None or response[0] != ACK:
        click.echo("failed (execute command not accepted)")
        return False
    port.write(address)
    port.flush()
    click.echo("complete")
    return True
예제 #7
0
def expose_bootloader(port, ctx=proscli.utils.State()):
    click.echo('Exposing bootloader... ', nl=False)
    bootloader_bits = [0xc9, 0x36, 0xb8, 0x47, 0x25]
    configure_port(port, serial.PARITY_NONE)
    port.flush()
    debug('EXPOSE BL BITS: {}  PORT CFG: {}'.format(bytes_to_str(bootloader_bits), repr(port)), ctx)
    port.read(port.in_waiting)
    for _ in itertools.repeat(None, 5):
        port.write(bootloader_bits)
        port.flush()
    configure_port(port, serial.PARITY_NONE)
    time.sleep(0.3)  # time delay to allow shift to download mode
    click.echo('complete')
    return True
예제 #8
0
def write_flash(port, start_address, data, retry=2, is_wireless=False):
    data = bytearray(data)
    if len(data) > 256:
        click.echo('Tried writing too much data at once! ({} bytes)'.format(
            len(data)))
        return False
    port.read_all()
    c_addr = compute_address_commandable(start_address)
    debug('Writing {} bytes to {}'.format(len(data), adr_to_str(c_addr)))
    response = send_bootloader_command(port, 0x31)
    if response is None or len(response) < 1 or response[0] != ACK:
        if retry > 0:
            debug('RETRYING PACKET AT COMMAND')
            return write_flash(port, start_address, data, retry=retry - 1)
        else:
            click.echo('failed (write command not accepted)')
            return False
    port.write(c_addr)
    port.flush()
    time.sleep(0.005 if is_wireless else 0.002)
    response = port.read(1)
    debug_response(adr_to_str(c_addr), response)
    if response is None or len(response) < 1 or response[0] != ACK:
        if retry > 0:
            debug('RETRYING PACKET AT ADDRESS')
            return write_flash(port, start_address, data, retry=retry - 1)
        else:
            click.echo('failed (address not accepted)')
            return False
    checksum = len(data) - 1
    for x in data:
        checksum ^= x
    send_data = data[:]
    send_data.insert(0, len(send_data) - 1)
    send_data.append(checksum)
    port.write(send_data)
    port.flush()
    time.sleep(0.007 if is_wireless else 0.002)
    response = port.read(1)
    debug('STM BL RESPONSE TO WRITE: {}'.format(response))
    if response is None or len(response) < 1 or response[0] != ACK:
        if retry > 0:
            debug('RETRYING PACKET AT WRITE')
            return write_flash(port, start_address, data, retry=retry - 1)
        else:
            click.echo('failed (could not complete upload)')
            return False
    port.flush()
    port.reset_input_buffer()
    return True
예제 #9
0
 def reader(self):
     try:
         while self.alive and self._reader_alive:
             data = self.serial.read(self.serial.in_waiting or 1)
             if data:
                 if self.output_raw:
                     self.console.write_bytes(data)
                 else:
                     text = data.decode('utf-8', 'ignore')
                     for transformation in self.transformations:
                         text = transformation(text)
                     self.console.write(text)
     except serial.SerialException as e:
         debug(e)
         self.alive = False
예제 #10
0
def stop_user_code(port, ctx=proscli.utils.State()):
    click.echo('Stopping user code... ', nl=False)
    stopbits = [0x0f, 0x0f, 0x21, 0xde, 0x08, 0x00, 0x00, 0x00, 0x08, 0xf1, 0x04]
    debug(bytes_to_str(stopbits), ctx)
    if not port.is_open:
        port.open()
    port.flush()
    port.read(port.in_waiting)
    for stopbit in stopbits:
        port.write([stopbit])
    port.flush()
    response = port.read_all()
    debug(bytes_to_str(response), ctx)
    port.parity = serial.PARITY_NONE
    click.echo('complete')
예제 #11
0
def stop_user_code(port, ctx=proscli.utils.State()):
    click.echo('Stopping user code... ', nl=False)
    stopbits = [0x0f, 0x0f, 0x21, 0xde, 0x08, 0x00, 0x00, 0x00, 0x08, 0xf1, 0x04]
    debug(bytes_to_str(stopbits), ctx)
    if not port.is_open:
        port.open()
    port.flush()
    port.read(port.in_waiting)
    for stopbit in stopbits:
        port.write([stopbit])
    port.flush()
    response = port.read_all()
    debug(bytes_to_str(response), ctx)
    port.parity = serial.PARITY_NONE
    click.echo('complete')
예제 #12
0
 def reader(self):
     start_time = time.clock
     try:
         while self.alive and self._reader_alive:
             data = self.serial.read(self.serial.in_waiting or 1)
             if data:
                 if self.output_raw:
                     self.console.write_bytes(data)
                 else:
                     text = data.decode('utf-8', 'ignore')
                     for transformation in self.transformations:
                         text = transformation(text)
                     self.console.write(text)
     except serial.SerialException as e:
         debug(e)
         self.alive = False
예제 #13
0
 def transmitter(self):
     try:
         while self.alive and self._transmitter_alive:
             try:
                 c = self.console.getkey()
             except KeyboardInterrupt:
                 c = '\x03'
             if not self.alive:
                 break
             if c == '\x03' or not self.no_sigint:
                 self.stop()
                 break
             else:
                 self.serial.write(c.encode('utf-8'))
                 self.console.write(c)
     except Exception as e:
         debug(e)
         self.alive = False
예제 #14
0
def send_to_download_channel(port, ctx=proscli.utils.State()):
    click.echo('Sending to download channel... ', nl=False)
    download_ch_bits = [0xc9, 0x36, 0xb8, 0x47, 0x35]
    configure_port(port, serial.PARITY_EVEN)
    debug('DL CH BITS: {}  PORT CFG: {}'.format(bytes_to_str(download_ch_bits), repr(port)), ctx)
    for _ in itertools.repeat(None, 5):
        port.read(port.in_waiting)
        port.write(download_ch_bits)
        port.flush()
        time.sleep(0.25)
        response = port.read_all()
        debug('DB CH RESPONSE: {}'.format(bytes_to_str(response)), ctx)
        response = response[-1:]
        if response is not None and len(response) > 0 and response[0] == ACK:
            click.echo('complete')
            return True
    click.echo('failed')
    return False
예제 #15
0
 def transmitter(self):
     try:
         while self.alive and self._transmitter_alive:
             try:
                 c = self.console.getkey()
             except KeyboardInterrupt:
                 c = '\x03'
             if not self.alive:
                 break
             if c == '\x03' or not self.no_sigint:
                 self.stop()
                 break
             else:
                 self.serial.write(c.encode('utf-8'))
                 self.console.write(c)
     except Exception as e:
         debug(e)
         self.alive = False
예제 #16
0
def send_to_download_channel(port, ctx=proscli.utils.State()):
    click.echo('Sending to download channel... ', nl=False)
    download_ch_bits = [0xc9, 0x36, 0xb8, 0x47, 0x35]
    configure_port(port, serial.PARITY_EVEN)
    debug('DL CH BITS: {}  PORT CFG: {}'.format(bytes_to_str(download_ch_bits), repr(port)), ctx)
    for _ in itertools.repeat(None, 5):
        port.read(port.in_waiting)
        port.write(download_ch_bits)
        port.flush()
        time.sleep(0.25)
        response = port.read_all()
        debug('DB CH RESPONSE: {}'.format(bytes_to_str(response)), ctx)
        response = response[-1:]
        if response is not None and len(response) > 0 and response[0] == ACK:
            click.echo('complete')
            return True
    click.echo('failed')
    return False
예제 #17
0
def send_to_download_channel(port, ctx=proscli.utils.State()):
    click.echo('Sending to download channel (this may take a while)... ', nl=False)
    download_ch_bits = [0xc9, 0x36, 0xb8, 0x47, 0x35]
    debug('DL CH BITS: {}  PORT CFG: {}'.format(bytes_to_str(download_ch_bits), repr(port)), ctx)
    for _ in itertools.repeat(None, 5):
        port.read_all()
        time.sleep(0.1)
        port.write(download_ch_bits)
        port.flush()
        time.sleep(3)
        response = port.read_all()
        debug('DB CH RESPONSE: {}'.format(bytes_to_str(response)), ctx)
        response = response[-1:]
        sys_info = ask_sys_info(port, ctx, silent=True)
        if (sys_info is not None and sys_info.connection_type == ConnectionType.serial_vexnet2_dl) or (response is not None and len(response) > 0 and response[0] == ACK):
            click.echo('complete')
            return True
    click.echo('failed')
    return False
예제 #18
0
def ask_sys_info(port, ctx=proscli.utils.State(), silent=False):
    if not silent:
        click.echo('Asking for system information... ', nl=False)
    sys_info_bits = [0xc9, 0x36, 0xb8, 0x47, 0x21]
    if not port.is_open:
        port.open()
    debug('SYS INFO BITS: {}  PORT CFG: {}'.format(bytes_to_str(sys_info_bits), repr(port)), ctx)
    for _ in itertools.repeat(None, 10):
        port.read_all()
        port.write(sys_info_bits)
        port.flush()
        time.sleep(0.1)
        response = port.read_all()
        debug('SYS INFO RESPONSE: {}'.format(bytes_to_str(response)), ctx)
        if len(response) > 14:
            response = response[:14]
        if len(response) == 14 and response[0] == 0xaa and response[1] == 0x55\
                and response[2] == 0x21 and response[3] == 0xa:  # synchronization matched
            sys_info = SystemInfo()
            sys_info.device = port.name
            sys_info.joystick_firmware = '{}.{}'.format(response[4], response[5])
            sys_info.cortex_firmware = '{}.{}'.format(response[6], response[7])
            if response[8] > 5:  # anything smaller than 5 is probably garbage from ADC
                sys_info.joystick_battery = response[8] * 0.059
            if response[9] > 5:  # anything smaller than 5 is probably garbage from ADC
                sys_info.cortex_battery = response[9] * 0.059
            if response[10] > 5:  # anything smaller than 5 is probably garbage from ADC
                sys_info.backup_battery = response[10] * 0.059
            try:
                # Mask FCS bits out of response[11]
                sys_info.connection_type = ConnectionType(response[11] & 0b00110111)
            except ValueError:
                sys_info.connection_type = ConnectionType.unknown
            sys_info.previous_polls = response[13]
            sys_info.byte_representation = response
            if not silent:
                click.echo('complete')
            return sys_info
        time.sleep(0.15)
    return None
예제 #19
0
def send_go_command(port, address, retry=3):
    click.echo('Executing user code... ', nl=False)
    c_addr = compute_address_commandable(address)
    debug('Executing binary at {}'.format(adr_to_str(c_addr)))

    response = send_bootloader_command(port, 0x21, 1)
    debug_response(0x21, response)
    if response is None or len(response) < 1 or response[0] != ACK:
        click.echo('failed (execute command not accepted)')
        return False
    time.sleep(0.01)
    port.write(c_addr)
    time.sleep(0.01)
    response = port.read(1)
    debug_response(adr_to_str(c_addr), response)
    if response is None or len(response) < 1 or response[0] != ACK:
        click.echo(
            'user code might not have started properly. May need to restart Cortex'
        )
    else:
        click.echo('complete')
    return True
예제 #20
0
def write_flash(port, start_address, data):
    data = bytearray(data)
    if len(data) > 256:
        click.echo('Tried writing too much data at once! ({} bytes)'.format(
            len(data)))
        return False
    port.read_all()
    start_address = compute_address_commandable(start_address)
    debug('Writing {} bytes to {}'.format(len(data),
                                          adr_to_str(start_address)))
    response = send_bootloader_command(port, 0x31)
    if response is None or response[0] != ACK:
        click.echo('failed (write command not accepted)')
        return False
    port.write(start_address)
    port.flush()
    response = port.read(1)
    debug_response(adr_to_str(start_address), response)
    if response is None or response[0] != ACK:
        click.echo('failed (address not accepted)')
        return False
    checksum = len(data) - 1
    for x in data:
        checksum ^= x
    data.insert(0, len(data) - 1)
    data.append(checksum)
    port.write(data)
    time.sleep(0.005)
    response = port.read(1)
    if response is None or response[0] != ACK:
        port.write(data)
        time.sleep(20)
        response = port.read(1)
        if response is None or response[0] != ACK:
            click.echo('failed (could not complete upload)')
            return False
    port.flush()
    port.reset_input_buffer()
    return True
예제 #21
0
def ask_sys_info(port, ctx=proscli.utils.State()):
    click.echo('Asking for system information... ', nl=False)
    sys_info_bits = [0xc9, 0x36, 0xb8, 0x47, 0x21]
    if not port.is_open:
        port.open()
    configure_port(port, serial.PARITY_NONE)
    debug('SYS INFO BITS: {}  PORT CFG: {}'.format(bytes_to_str(sys_info_bits), repr(port)), ctx)
    for _ in itertools.repeat(None, 10):
        port.read(port.in_waiting)
        port.write(sys_info_bits)
        port.flush()
        time.sleep(0.1)
        response = port.read_all()
        debug('SYS INFO RESPONSE: {}'.format(bytes_to_str(response)), ctx)
        if len(response) > 14:
            response = response[:14]
        if len(response) == 14 and response[0] == 0xaa and response[1] == 0x55\
                and response[2] == 0x21 and response[3] == 0xa:  # synchronization matched
            sys_info = SystemInfo()
            sys_info.device = port.name
            sys_info.joystick_firmware = '{}.{}'.format(response[4], response[5])
            sys_info.cortex_firmware = '{}.{}'.format(response[6], response[7])
            if response[8] > 5:  # anything smaller than 5 is probably garbage from ADC
                sys_info.joystick_battery = response[8] * 0.059
            if response[9] > 5:  # anything smaller than 5 is probably garbage from ADC
                sys_info.cortex_battery = response[9] * 0.059
            if response[10] > 5:  # anything smaller than 5 is probably garbage from ADC
                sys_info.backup_battery = response[10] * 0.059
            try:
                sys_info.connection_type = ConnectionType(response[11])
            except ValueError:
                sys_info.connection_type = ConnectionType.unknown
            sys_info.previous_polls = response[13]
            sys_info.byte_representation = response
            click.echo('complete')
            return sys_info
        time.sleep(0.15)
    return None
예제 #22
0
def write_flash(port, start_address, data):
    data = bytearray(data)
    if len(data) > 256:
        click.echo("Tried writing too much data at once! ({} bytes)".format(len(data)))
        return False
    port.read_all()
    start_address = compute_address_commandable(start_address)
    debug("Writing {} bytes to {}".format(len(data), adr_to_str(start_address)))
    response = send_bootloader_command(port, 0x31)
    if response is None or response[0] != ACK:
        click.echo("failed (write command not accepted)")
        return False
    port.write(start_address)
    port.flush()
    response = port.read(1)
    debug_response(adr_to_str(start_address), response)
    if response is None or response[0] != ACK:
        click.echo("failed (address not accepted)")
        return False
    checksum = len(data) - 1
    for x in data:
        checksum ^= x
    data.insert(0, len(data) - 1)
    data.append(checksum)
    port.write(data)
    time.sleep(0.005)
    response = port.read(1)
    if response is None or response[0] != ACK:
        port.write(data)
        time.sleep(20)
        response = port.read(1)
        if response is None or response[0] != ACK:
            click.echo("failed (could not complete upload)")
            return False
    port.flush()
    port.reset_input_buffer()
    return True
예제 #23
0
def debug_response(command, response, fmt="STM BL RESPONSE TO 0x{}: {}"):
    if not isinstance(command, str):
        command = bytes_to_str(command)
    if not isinstance(response, str):
        response = bytes_to_str(response)
    debug(fmt.format(command, response))
예제 #24
0
def debug_response(command, response, fmt='STM BL RESPONSE TO 0x{}: {}'):
    if not isinstance(command, str):
        command = bytes_to_str(command)
    if not isinstance(response, str):
        response = bytes_to_str(response)
    debug(fmt.format(command, response))