示例#1
0
    def resetDeviceHandler(self, device_path):
        device = self.tryOpenDevicePath(device_path)
        if device == None: return

        if is_keyplus_device(device):
            protocol.reset_device(device)
        elif is_xusb_bootloader_device(device):
            xusb_boot.reset(device)
        elif is_nrf24lu1p_bootloader_device(device):
            print("TODO: reset: ", device_path, file=sys.stderr)
        else:
            print("Can't reset device: ", device_path, file=sys.stderr)
示例#2
0
    def programDeviceHandler(self, device_path):
        target_device = self.tryOpenDevicePath(device_path)

        if target_device == None:
            self.abort_update(target_device)
            return

        programmingMode = self.fileSelectorWidget.getProgramingInfo()

        if is_bootloader_device(
                target_device
        ) and programmingMode != FileSelector.ScopeFirmware:
            error_msg_box(
                "Can only upload firmware while bootloader is running. "
                "Either reset it, or upload a firmware hex instead")
            self.abort_update(target_device)
            return

        if programmingMode == FileSelector.ScopeLayout:
            self.statusBar().showMessage("Started updating layout",
                                         timeout=STATUS_BAR_TIMEOUT)

            layout_file = self.fileSelectorWidget.getLayoutFile()

            if layout_file == '':
                error_msg_box("No layout file given.")
                self.abort_update(target_device)
                return
            else:
                pass

            layout_json_obj = None
            with open(layout_file) as file_obj:
                try:
                    layout_json_obj = yaml.safe_load(file_obj.read())
                except Exception as err:
                    error_msg_box("Syntax error in yaml file: " + str(err))
                    self.abort_update(target_device)
                    return

            device_info = protocol.get_device_info(target_device)
            layout_data, settings_data = self.process_layout(
                layout_json_obj, layout_file, device_info.id)
            if layout_data == None or settings_data == None:
                return

            protocol.update_layout_section(target_device, layout_data)
            protocol.update_settings_section(target_device,
                                             settings_data,
                                             keep_rf=True)
            protocol.reset_device(target_device)

            self.statusBar().showMessage("Finished updating layout",
                                         timeout=STATUS_BAR_TIMEOUT)
        elif programmingMode == FileSelector.ScopeDevice:
            layout_file = self.fileSelectorWidget.getRFLayoutFile()
            rf_file = self.fileSelectorWidget.getRFFile()
            target_id = self.fileSelectorWidget.getTargetID()

            self.statusBar().showMessage("Started updating RF settings",
                                         timeout=STATUS_BAR_TIMEOUT)

            if layout_file == '':
                error_msg_box("No layout file given.")
                self.abort_update(target_device)
                return
            elif rf_file == '':
                error_msg_box("No RF settings file given.")
                self.abort_update(target_device)
                return
            elif target_id == None:
                error_msg_box("No device id file given.")
                self.abort_update(target_device)
                return

            layout_json_obj = None
            rf_json_obj = None
            with open(layout_file) as file_obj:
                try:
                    layout_json_obj = yaml.safe_load(file_obj.read())
                except Exception as err:
                    error_msg_box("Syntax error in yaml file: " + str(err))
                    self.abort_update(target_device)
                    return
            with open(rf_file) as file_obj:
                try:
                    rf_json_obj = yaml.safe_load(file_obj.read())
                except Exception as err:
                    error_msg_box("Syntax error in yaml file: " + str(err))
                    self.abort_update(target_device)
                    return

            try:
                settings_gen = layout.parser.SettingsGenerator(
                    layout_json_obj, rf_json_obj)
            except ParseError as err:
                error_msg_box("Error Generating RF settings data: " + str(err))
                self.abort_update(target_device)
                return

            layout_data = settings_gen.gen_layout_section(target_id)
            settings_data = settings_gen.gen_settings_section(target_id)

            protocol.update_settings_section(target_device, settings_data)
            protocol.update_layout_section(target_device, layout_data)
            protocol.reset_device(target_device)

            self.statusBar().showMessage("Finished updating RF settings",
                                         timeout=STATUS_BAR_TIMEOUT)

        elif programmingMode == FileSelector.ScopeFirmware:
            fw_file = self.fileSelectorWidget.getFirmwareFile()

            self.statusBar().showMessage("Starting update firmware",
                                         timeout=STATUS_BAR_TIMEOUT)

            if fw_file == '':
                error_msg_box("No firmware file given.")
            else:

                if is_xusb_bootloader_device(target_device):
                    self.program_xusb_boot_firmware_hex(target_device, fw_file)
                elif is_keyplus_device(target_device):
                    try:
                        serial_num = target_device.serial_number
                        boot_vid, boot_pid = protocol.enter_bootloader(
                            target_device)

                        self.bootloaderProgramTimer = QTimer()
                        self.bootloaderProgramTimer.setInterval(3000)
                        self.bootloaderProgramTimer.setSingleShot(True)
                        self.bootloaderProgramTimer.timeout.connect(
                            lambda: self.programFirmwareHex(
                                boot_vid, boot_pid, serial_num, fw_file))
                        self.bootloaderProgramTimer.start()
                    except (easyhid.HIDException,
                            protocol.KBProtocolException):
                        error_msg_box(
                            "Programming hex file failed: '{}'".format(
                                fw_file))
        else:
            try:
                target_device.close()
            except:
                pass
            raise Exception("Unimplementend programming mode")
示例#3
0
    def task(self, args):
        layout_file = args.layout_file
        rf_file = args.rf_file
        hex_file = args.hex_file
        new_id = args.new_id

        if args.merge_hex:
            if (new_id == None or layout_file == None or rf_file == None or \
                    new_id == None):
                print("Error: To generate a merged hex file, need all settings"
                        " files.", file=sys.stderr)
                exit(EXIT_COMMAND_ERROR)
            if len(args.merge_hex) != 3:
                print("Error: To generate a merged hex file, need to provide "
                      "[settings_addr, layout_addr, layout_size] as arguments",
                      file=sys.stderr)
                exit(EXIT_COMMAND_ERROR)


        if new_id != None and (layout_file == None or rf_file == None):
            print("Error: when providing a new ID, a layout and RF file "
                  "must be provided", file=sys.stderr)
            exit(EXIT_COMMAND_ERROR)

        if layout_file == None and hex_file == None and rf_file == None:
            self.arg_parser.print_help()
            exit(0)


        if not args.merge_hex:
            device = self.find_matching_device(args)

            device.open()
            print("Programing start...")
            print_hid_info(device)
            print_device_info(device)
            print_layout_info(device)
            print("")


        if layout_file != None:
            with open(layout_file) as file_obj:
                try:
                    layout_json_obj = yaml.safe_load(file_obj.read())
                # except yaml.YAMLError as err:
                except Exception as err:
                    print("Error in Layout Settings YAML file: " + str(err), file=sys.stderr)
                    device.close()
                    exit(EXIT_BAD_FILE)
        else:
            layout_json_obj = None

        if rf_file != None:
            with open(rf_file) as file_obj:
                try:
                    rf_json_obj = yaml.safe_load(file_obj.read())
                # except yaml.YAMLError as err:
                except Exception as err:
                    print("Error in RF Settings YAML file: " + str(err), file=sys.stderr)
                    device.close()
                    exit(EXIT_BAD_FILE)
        else:
            rf_json_obj = None

        if layout_file != None:
            print("Parsing files...")

            if not args.merge_hex:
                device_info = protocol.get_device_info(device)

            if new_id == None:
                target_id = device_info.id
            else:
                target_id = new_id

            layout_data, settings_data = self.process_layout(
                layout_json_obj,
                rf_json_obj,
                layout_file,
                target_id
            )
            if layout_data == None or settings_data == None:
                exit(EXIT_BAD_FILE)
            print("Parsing finished...")

        if args.merge_hex:
            # don't want to program the device, instead we want to build a
            # hexfile with the settings preprogrammed
            with open(hex_file) as f:
                fw_hex = intelhex.IntelHex(f)

            settings_addr = args.merge_hex[0]
            layout_addr = args.merge_hex[1]
            layout_size = args.merge_hex[2]

            if len(layout_data) > layout_size:
                print("Error: layout data to large. Got {} bytes, but only "
                      "{} bytes available".format(
                          len(layout_data),
                          layout_size
                      ), file=sys.stderr)
                exit(EXIT_INSUFFICIENT_SPACE)

            settings_hex = intelhex.IntelHex()
            settings_hex.frombytes(
                settings_data,
                offset = settings_addr
            )

            layout_hex = intelhex.IntelHex()
            layout_hex.frombytes(
                layout_data,
                offset = layout_addr
            )


            fw_hex.merge(settings_hex, overlap='replace')

            # first erase anything that is in the layout section
            for i in range(layout_addr, layout_addr+layout_size):
                fw_hex[i] = 0 # dummy, write so del works
                del fw_hex[i]

            fw_hex.merge(layout_hex, overlap='replace')

            if args.outfile:
                with open(args.outfile, 'w') as outfile:
                    fw_hex.write_hex_file(outfile)
            else:
                    fw_hex.write_hex_file(sys.stdout)
            exit(0)
        elif layout_file and not rf_file:
            print("Updating layout only...")
            protocol.update_settings_section(device, settings_data, keep_rf=True)
            protocol.update_layout_section(device, layout_data)
        elif layout_file and rf_file:
            print("Updating layout and rf settings...")
            protocol.update_settings_section(device, settings_data)
            protocol.update_layout_section(device, layout_data)
        elif layout_file and rf_file and hex_file:
            print("TODO: not implemented", file=sys.stderr)
        elif hex_file and not layout_file and not rf_file:
            print("TODO: not implemented", file=sys.stderr)
        else:
            pass

        print("Done!")

        protocol.reset_device(device)
        device.close()
示例#4
0
 def task(self, args):
     device = self.find_matching_device(args)
     device.open()
     protocol.reset_device(device)
     device.close()