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)
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)
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
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
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
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
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
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
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')
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
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
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
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
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
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
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
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
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
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))
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))