From df5b67509d2b27114695d5bb3d32da22f9d0a0ef Mon Sep 17 00:00:00 2001 From: ClockSelect Date: Sun, 21 Aug 2016 05:44:39 +0200 Subject: [PATCH 01/11] New commands for myevic --- README.rst | 30 +++++++++ evic/cli.py | 164 +++++++++++++++++++++++++++++++++++++--------- evic/dataflash.py | 7 ++ evic/device.py | 88 +++++++++++++++++-------- 4 files changed, 230 insertions(+), 59 deletions(-) diff --git a/README.rst b/README.rst index 344ddbf..fec0c37 100644 --- a/README.rst +++ b/README.rst @@ -124,3 +124,33 @@ Use ``--no-verify`` to disable verification for APROM or data flash. To disable :: $ evic-usb upload --no-verify aprom --no-verify dataflash firmware.bin + +Reset the device: + +:: + + $ evic-usb reset + +Dump any part of the flash memory: + +:: + + $ evic-usb fmc-read -o out.bin -s startaddr -l length + +Example to read the parameters flash memory: + +:: + + $ evic-usb fmc-read -o out.bin -s 122880 -l 4096 + +Setup date and time of the device to the current time: + +:: + + $ evic-usb time + +Take a screenshot of the device display: + +:: + + $ evic-usb screenshot -o outfile.[png|jpg|...] diff --git a/evic/cli.py b/evic/cli.py index 9d81038..8d0acdc 100644 --- a/evic/cli.py +++ b/evic/cli.py @@ -24,12 +24,13 @@ import struct from time import sleep from contextlib import contextmanager +from datetime import datetime +from PIL import Image import click import evic -from .device import DeviceInfo @contextmanager def handle_exceptions(*exceptions): @@ -108,17 +109,39 @@ def read_dataflash(dev, verify): return dataflash -def print_device_info(device_info, dataflash): +def fmc_read(dev, start, len): + """Reads the device data flash. + + Args: + dev: evic.HIDTransfer object. + + Returns: + evic.DataFlash object containing the device data flash. + """ + + # Read the data flash + with handle_exceptions(IOError): + click.echo("Reading data flash...", nl=False) + fmemory = dev.fmc_read(start, len) + + return fmemory + + +def print_device_info(dev, dataflash): """Prints the device information found from data flash. Args: - device_info: device.DeviceInfo tuple. + dev: evic.HIDTransfer object. dataflash: evic.DataFlash object. """ + # Find the product name + product_name = dev.product_names.get(dataflash.product_id, + "Unknown device") + # Print out the information click.echo("\tDevice name: ", nl=False) - click.secho(device_info.name, bold=True) + click.secho(product_name, bold=True) click.echo("\tFirmware version: ", nl=False) click.secho("{0:.2f}".format(dataflash.fw_version / 100.0), bold=True) click.echo("\tHardware version: ", nl=False) @@ -167,12 +190,8 @@ def upload(inputfile, encrypted, dataflashfile, noverify): dataflash = read_dataflash(dev, verify) dataflash_original = copy.deepcopy(dataflash) - # Get the device info - device_info = dev.devices.get(dataflash.product_id, - DeviceInfo("Unknown device", None, None)) - # Print the device information - print_device_info(device_info, dataflash) + print_device_info(dev, dataflash) # Read the APROM image aprom = evic.APROM(inputfile.read()) @@ -183,12 +202,9 @@ def upload(inputfile, encrypted, dataflashfile, noverify): if 'aprom' not in noverify: with handle_exceptions(evic.APROMError): click.echo("Verifying APROM...", nl=False) - - supported_product_ids = [dataflash.product_id] - if device_info.supported_product_ids: - supported_product_ids.extend(device_info.supported_product_ids) - - aprom.verify(supported_product_ids, dataflash.hw_version) + aprom.verify( + dev.supported_product_ids[dataflash.product_id], + dataflash.hw_version) # Are we using a data flash file? if dataflashfile: @@ -237,6 +253,53 @@ def upload(inputfile, encrypted, dataflashfile, noverify): dev.write_aprom(aprom) +@usb.command('reset') +def reset(): + """Resets the device.""" + + dev = evic.HIDTransfer() + + # Connect the device + connect(dev) + + # Restart + click.echo("Restarting the device...", nl=False) + dev.reset() + sleep(2) + click.secho("OK", fg='green', nl=False, bold=True) + + +@usb.command('time') +def time(): + """Sets the device date/time to now.""" + + dev = evic.HIDTransfer() + + # Connect the device + connect(dev) + + # Read the data flash + dataflash = read_dataflash(dev, 1) + + # Print the device information + print_device_info(dev, dataflash) + + dt = datetime.now() + dataflash.df_year = dt.year + dataflash.df_month = dt.month + dataflash.df_day = dt.day + dataflash.df_hour = dt.hour + dataflash.df_minute = dt.minute + dataflash.df_second = dt.second + + # Write data flash to the device + with handle_exceptions(IOError): + click.echo("Writing data flash...", nl=False) + sleep(0.1) + dev.write_dataflash(dataflash) + click.secho("OK", fg='green', bold=True) + + @usb.command('upload-logo') @click.argument('inputfile', type=click.File('rb')) @click.option('--invert', '-i', is_flag=True, @@ -258,27 +321,22 @@ def uploadlogo(inputfile, invert, noverify): dataflash = read_dataflash(dev, noverify) dataflash_original = copy.deepcopy(dataflash) - # Get the device info - device_info = dev.devices.get(dataflash.product_id, - DeviceInfo("Unknown device", None, None)) - # Print the device information - print_device_info(device_info, dataflash) + print_device_info(dev, dataflash) # Convert the image with handle_exceptions(evic.LogoConversionError): click.echo("Converting logo...", nl=False) - - # Check supported logo dimensions - logo_dimensions = device_info.logo_dimensions - if not logo_dimensions: + # Check supported logo size + try: + logosize = dev.supported_logo_size[dataflash.product_id] + except KeyError: raise evic.LogoConversionError("Device doesn't support logos.") - # Perform the actual conversion logo = evic.logo.fromimage(inputfile, invert) - if (logo.width, logo.height) != logo_dimensions: + if (logo.width, logo.height) != logosize: raise evic.LogoConversionError("Device only supports {}x{} logos." - .format(*logo_dimensions)) + .format(*logosize)) # We want to boot to LDROM on restart if not dev.ldrom: @@ -325,12 +383,8 @@ def dumpdataflash(output, noverify): # Read the data flash dataflash = read_dataflash(dev, noverify) - # Get the device info - device_info = dev.devices.get(dataflash.product_id, - DeviceInfo("Unknown device", None, None)) - # Print the device information - print_device_info(device_info, dataflash) + print_device_info(dev, dataflash) # Write the data flash to the file with handle_exceptions(IOError): @@ -338,6 +392,52 @@ def dumpdataflash(output, noverify): output.write(dataflash.array) +@usb.command('fmcread') +@click.option('--output', '-o', type=click.File('wb'), required=True) +@click.option('--start', '-s', type=click.INT, required=True) +@click.option('--length', '-l', type=click.INT, required=True) +def fmcread(output, start, length): + """Write device flash memory to a file.""" + + dev = evic.HIDTransfer() + + # Connect the device + connect(dev) + + # Print the USB info of the device + print_usb_info(dev) + + # Read the data flash + fmemory = fmc_read(dev, start, length) + + # Write the data flash to the file + with handle_exceptions(IOError): + click.echo("Writing flash memory to the file...", nl=False) + output.write(fmemory) + + +@usb.command('screenshot') +@click.option('--output', '-o', type=click.File('wb'), required=True) +def screenshot(output): + """Take a screenshot.""" + + dev = evic.HIDTransfer() + + # Connect the device + connect(dev) + + # Read the screen data + data = dev.read_screen() + + # create the image from screen data + im = Image.fromstring("1",(64,128),bytes(data)) + + # Write the image to the file + with handle_exceptions(IOError): + click.echo("Writing image to the file...", nl=False) + im.save(output,"PNG") + + @usb.command('reset-dataflash') def resetdataflash(): """Reset device data flash.""" diff --git a/evic/dataflash.py b/evic/dataflash.py index 31abb2a..0c61651 100644 --- a/evic/dataflash.py +++ b/evic/dataflash.py @@ -46,6 +46,13 @@ class DataFlash(binstruct.StructTemplate): fw_version = binstruct.Int32Field(256) ldrom_version = binstruct.Int32Field(260) + df_year = binstruct.Int16Field(320) + df_month = binstruct.Int8Field(322) + df_day = binstruct.Int8Field(323) + df_hour = binstruct.Int8Field(324) + df_minute = binstruct.Int8Field(325) + df_second = binstruct.Int8Field(326) + def verify(self, checksum): """Verifies the data flash against given checksum. diff --git a/evic/device.py b/evic/device.py index 0d94545..a5be4af 100644 --- a/evic/device.py +++ b/evic/device.py @@ -18,7 +18,6 @@ """ import struct -from collections import namedtuple try: import hid @@ -28,8 +27,6 @@ from .dataflash import DataFlash -DeviceInfo = namedtuple('DeviceInfo', - 'name supported_product_ids logo_dimensions') class HIDTransfer(object): """Generic Nuvoton HID Transfer device class. @@ -37,7 +34,13 @@ class HIDTransfer(object): Attributes: vid: USB vendor ID. pid: USB product ID. - devices: A dictionary mapping product IDs to DeviceInfo tuples. + product_names: A dictionary mapping product IDs to + product name strings. + supported_product_ids: A dictionary mapping product ID to a list of + strings containing the IDs of the products + with compatible firmware. + supported_logo_size: A dictionary mapping product ID to the allowed + logo resolution as a (width, height) tuple. hid_signature: A bytearray containing the HID command signature (4 bytes). device: A HIDAPI device. @@ -49,29 +52,32 @@ class HIDTransfer(object): vid = 0x0416 pid = 0x5020 - devices = {'E043': DeviceInfo("eVic VTwo", None, (64, 40)), - 'E052': DeviceInfo("eVic-VTC Mini", ['W007'], (64, 40)), - 'E056': DeviceInfo("CUBOID MINI", None, (64, 40)), - 'E060': DeviceInfo("Cuboid", None, (64, 40)), - 'E083': DeviceInfo("eGrip II", None, (64, 40)), - 'E092': DeviceInfo("eVic AIO", None, (64, 40)), - 'E115': DeviceInfo("eVic VTwo mini", None, (64, 40)), - 'E150': DeviceInfo("eVic Basic", None, (64, 40)), - 'M011': DeviceInfo("iStick TC100W", None, None), - 'M037': DeviceInfo("ASTER", None, (96, 16)), - 'M041': DeviceInfo("iStick Pico", None, (96, 16)), - 'M045': DeviceInfo("iStick Pico Mega", None, (96, 16)), - 'M046': DeviceInfo("iPower", None, (96, 16)), - 'W007': DeviceInfo("Presa TC75W", ['E052'], None), - 'W010': DeviceInfo("Classic", None, None), - 'W011': DeviceInfo("Lite", None, None), - 'W013': DeviceInfo("Stout", None, None), - 'W014': DeviceInfo("Reuleaux RX200", None, None), - 'W016': DeviceInfo("CENTURION", None, None), - 'W018': DeviceInfo("Reuleaux RX2/3", None, (64, 48)), - 'W033': DeviceInfo("Reuleaux RX200S", None, None) - } - + product_names = {'E052': "eVic-VTC Mini", + 'E056': "CUBOID MINI", + 'E060': "Cuboid", + 'E083': "eGrip II", + 'M011': "iStick TC100W", + 'M041': "iStick Pico", + 'W007': "Presa TC75W", + 'W010': "Classic", + 'W011': "Lite", + 'W013': "Stout", + 'W014': "Reuleaux RX200"} + supported_product_ids = {'E052': ['E052', 'W007'], + 'E056': ['E056'], + 'E060': ['E060'], + 'M011': ['M011'], + 'M041': ['M041'], + 'W007': ['W007', 'E052'], + 'W010': ['W010'], + 'W011': ['W011'], + 'W013': ['W013'], + 'W014': ['W014']} + supported_logo_size = {'E052': (64, 40), + 'E056': (64, 40), + 'E060': (64, 40), + 'E083': (64, 40), + 'M041': (96, 16)} # 0x43444948 hid_signature = bytearray(b'HIDC') @@ -161,6 +167,34 @@ def read_dataflash(self): return (dataflash, checksum) + def fmc_read(self, start, length): + """Reads the device flash memory. + + Returns: + An array containing the data flash memory content. + """ + + # Send the command for reading the data flash + self.send_command(0xC0, start, length) + + # Read the dataflash + buf = self.read(length) + return (buf) + + def read_screen(self): + """Reads the screen memory. + + Returns: + An array containing the screen. + """ + + # Send the command for reading the screen buffer + self.send_command(0xC1, 0, 0x400) + + # Read the data + buf = self.read(0x400) + return (buf) + def write(self, data): """Writes data to the device. From 1cf91b1cd8165b86df373d6feb273ec37ec19141 Mon Sep 17 00:00:00 2001 From: ClockSelect Date: Sun, 21 Aug 2016 06:27:00 +0200 Subject: [PATCH 02/11] Integrated changes from master --- evic/cli.py | 52 +++++++++++++++++++++++++++++--------------- evic/device.py | 59 ++++++++++++++++++++++---------------------------- 2 files changed, 60 insertions(+), 51 deletions(-) diff --git a/evic/cli.py b/evic/cli.py index 8d0acdc..b613bfb 100644 --- a/evic/cli.py +++ b/evic/cli.py @@ -30,6 +30,7 @@ import click import evic +from .device import DeviceInfo @contextmanager @@ -127,21 +128,17 @@ def fmc_read(dev, start, len): return fmemory -def print_device_info(dev, dataflash): +def print_device_info(device_info, dataflash): """Prints the device information found from data flash. Args: - dev: evic.HIDTransfer object. + device_info: device.DeviceInfo tuple. dataflash: evic.DataFlash object. """ - # Find the product name - product_name = dev.product_names.get(dataflash.product_id, - "Unknown device") - # Print out the information click.echo("\tDevice name: ", nl=False) - click.secho(product_name, bold=True) + click.secho(device_info.name, bold=True) click.echo("\tFirmware version: ", nl=False) click.secho("{0:.2f}".format(dataflash.fw_version / 100.0), bold=True) click.echo("\tHardware version: ", nl=False) @@ -190,8 +187,12 @@ def upload(inputfile, encrypted, dataflashfile, noverify): dataflash = read_dataflash(dev, verify) dataflash_original = copy.deepcopy(dataflash) + # Get the device info + device_info = dev.devices.get(dataflash.product_id, + DeviceInfo("Unknown device", None, None)) + # Print the device information - print_device_info(dev, dataflash) + print_device_info(device_info, dataflash) # Read the APROM image aprom = evic.APROM(inputfile.read()) @@ -202,9 +203,12 @@ def upload(inputfile, encrypted, dataflashfile, noverify): if 'aprom' not in noverify: with handle_exceptions(evic.APROMError): click.echo("Verifying APROM...", nl=False) - aprom.verify( - dev.supported_product_ids[dataflash.product_id], - dataflash.hw_version) + + supported_product_ids = [dataflash.product_id] + if device_info.supported_product_ids: + supported_product_ids.extend(device_info.supported_product_ids) + + aprom.verify(supported_product_ids, dataflash.hw_version) # Are we using a data flash file? if dataflashfile: @@ -281,8 +285,12 @@ def time(): # Read the data flash dataflash = read_dataflash(dev, 1) + # Get the device info + device_info = dev.devices.get(dataflash.product_id, + DeviceInfo("Unknown device", None, None)) + # Print the device information - print_device_info(dev, dataflash) + print_device_info(device_info, dataflash) dt = datetime.now() dataflash.df_year = dt.year @@ -321,22 +329,25 @@ def uploadlogo(inputfile, invert, noverify): dataflash = read_dataflash(dev, noverify) dataflash_original = copy.deepcopy(dataflash) + # Get the device info + device_info = dev.devices.get(dataflash.product_id, + DeviceInfo("Unknown device", None, None)) + # Print the device information - print_device_info(dev, dataflash) + print_device_info(device_info, dataflash) # Convert the image with handle_exceptions(evic.LogoConversionError): click.echo("Converting logo...", nl=False) # Check supported logo size - try: - logosize = dev.supported_logo_size[dataflash.product_id] - except KeyError: + logo_dimensions = device_info.logo_dimensions + if not logo_dimensions: raise evic.LogoConversionError("Device doesn't support logos.") # Perform the actual conversion logo = evic.logo.fromimage(inputfile, invert) if (logo.width, logo.height) != logosize: raise evic.LogoConversionError("Device only supports {}x{} logos." - .format(*logosize)) + .format(*logo_dimensions)) # We want to boot to LDROM on restart if not dev.ldrom: @@ -383,8 +394,13 @@ def dumpdataflash(output, noverify): # Read the data flash dataflash = read_dataflash(dev, noverify) + # Get the device info + device_info = dev.devices.get(dataflash.product_id, + DeviceInfo("Unknown device", None, None)) + + # Print the device information - print_device_info(dev, dataflash) + print_device_info(device_info, dataflash) # Write the data flash to the file with handle_exceptions(IOError): diff --git a/evic/device.py b/evic/device.py index a5be4af..e3f6a7c 100644 --- a/evic/device.py +++ b/evic/device.py @@ -18,6 +18,7 @@ """ import struct +from collections import namedtuple try: import hid @@ -27,6 +28,8 @@ from .dataflash import DataFlash +DeviceInfo = namedtuple('DeviceInfo', + 'name supported_product_ids logo_dimensions') class HIDTransfer(object): """Generic Nuvoton HID Transfer device class. @@ -34,13 +37,7 @@ class HIDTransfer(object): Attributes: vid: USB vendor ID. pid: USB product ID. - product_names: A dictionary mapping product IDs to - product name strings. - supported_product_ids: A dictionary mapping product ID to a list of - strings containing the IDs of the products - with compatible firmware. - supported_logo_size: A dictionary mapping product ID to the allowed - logo resolution as a (width, height) tuple. + devices: A dictionary mapping product IDs to DeviceInfo tuples. hid_signature: A bytearray containing the HID command signature (4 bytes). device: A HIDAPI device. @@ -52,32 +49,28 @@ class HIDTransfer(object): vid = 0x0416 pid = 0x5020 - product_names = {'E052': "eVic-VTC Mini", - 'E056': "CUBOID MINI", - 'E060': "Cuboid", - 'E083': "eGrip II", - 'M011': "iStick TC100W", - 'M041': "iStick Pico", - 'W007': "Presa TC75W", - 'W010': "Classic", - 'W011': "Lite", - 'W013': "Stout", - 'W014': "Reuleaux RX200"} - supported_product_ids = {'E052': ['E052', 'W007'], - 'E056': ['E056'], - 'E060': ['E060'], - 'M011': ['M011'], - 'M041': ['M041'], - 'W007': ['W007', 'E052'], - 'W010': ['W010'], - 'W011': ['W011'], - 'W013': ['W013'], - 'W014': ['W014']} - supported_logo_size = {'E052': (64, 40), - 'E056': (64, 40), - 'E060': (64, 40), - 'E083': (64, 40), - 'M041': (96, 16)} + devices = {'E043': DeviceInfo("eVic VTwo", None, (64, 40)), + 'E052': DeviceInfo("eVic-VTC Mini", ['W007'], (64, 40)), + 'E056': DeviceInfo("CUBOID MINI", None, (64, 40)), + 'E060': DeviceInfo("Cuboid", None, (64, 40)), + 'E083': DeviceInfo("eGrip II", None, (64, 40)), + 'E092': DeviceInfo("eVic AIO", None, (64, 40)), + 'E115': DeviceInfo("eVic VTwo mini", None, (64, 40)), + 'E150': DeviceInfo("eVic Basic", None, (64, 40)), + 'M011': DeviceInfo("iStick TC100W", None, None), + 'M037': DeviceInfo("ASTER", None, (96, 16)), + 'M041': DeviceInfo("iStick Pico", None, (96, 16)), + 'M045': DeviceInfo("iStick Pico Mega", None, (96, 16)), + 'M046': DeviceInfo("iPower", None, (96, 16)), + 'W007': DeviceInfo("Presa TC75W", ['E052'], None), + 'W010': DeviceInfo("Classic", None, None), + 'W011': DeviceInfo("Lite", None, None), + 'W013': DeviceInfo("Stout", None, None), + 'W014': DeviceInfo("Reuleaux RX200", None, None), + 'W016': DeviceInfo("CENTURION", None, None), + 'W018': DeviceInfo("Reuleaux RX2/3", None, (64, 48)), + 'W033': DeviceInfo("Reuleaux RX200S", None, None) + } # 0x43444948 hid_signature = bytearray(b'HIDC') From 87dc7d1b6c32bfa1c9edb7a5db055a78190a5178 Mon Sep 17 00:00:00 2001 From: ClockSelect Date: Sun, 21 Aug 2016 06:30:41 +0200 Subject: [PATCH 03/11] Blanks cleanup --- evic/cli.py | 38 +++++++++++++++++++------------------- evic/device.py | 4 ++-- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/evic/cli.py b/evic/cli.py index b613bfb..dc4c84a 100644 --- a/evic/cli.py +++ b/evic/cli.py @@ -188,9 +188,9 @@ def upload(inputfile, encrypted, dataflashfile, noverify): dataflash_original = copy.deepcopy(dataflash) # Get the device info - device_info = dev.devices.get(dataflash.product_id, - DeviceInfo("Unknown device", None, None)) - + device_info = dev.devices.get(dataflash.product_id, + DeviceInfo("Unknown device", None, None)) + # Print the device information print_device_info(device_info, dataflash) @@ -207,7 +207,7 @@ def upload(inputfile, encrypted, dataflashfile, noverify): supported_product_ids = [dataflash.product_id] if device_info.supported_product_ids: supported_product_ids.extend(device_info.supported_product_ids) - + aprom.verify(supported_product_ids, dataflash.hw_version) # Are we using a data flash file? @@ -278,20 +278,20 @@ def time(): """Sets the device date/time to now.""" dev = evic.HIDTransfer() - + # Connect the device connect(dev) - + # Read the data flash dataflash = read_dataflash(dev, 1) - + # Get the device info - device_info = dev.devices.get(dataflash.product_id, - DeviceInfo("Unknown device", None, None)) - + device_info = dev.devices.get(dataflash.product_id, + DeviceInfo("Unknown device", None, None)) + # Print the device information print_device_info(device_info, dataflash) - + dt = datetime.now() dataflash.df_year = dt.year dataflash.df_month = dt.month @@ -329,9 +329,9 @@ def uploadlogo(inputfile, invert, noverify): dataflash = read_dataflash(dev, noverify) dataflash_original = copy.deepcopy(dataflash) - # Get the device info - device_info = dev.devices.get(dataflash.product_id, - DeviceInfo("Unknown device", None, None)) + # Get the device info + device_info = dev.devices.get(dataflash.product_id, + DeviceInfo("Unknown device", None, None)) # Print the device information print_device_info(device_info, dataflash) @@ -394,10 +394,10 @@ def dumpdataflash(output, noverify): # Read the data flash dataflash = read_dataflash(dev, noverify) - # Get the device info - device_info = dev.devices.get(dataflash.product_id, - DeviceInfo("Unknown device", None, None)) - + # Get the device info + device_info = dev.devices.get(dataflash.product_id, + DeviceInfo("Unknown device", None, None)) + # Print the device information print_device_info(device_info, dataflash) @@ -447,7 +447,7 @@ def screenshot(output): # create the image from screen data im = Image.fromstring("1",(64,128),bytes(data)) - + # Write the image to the file with handle_exceptions(IOError): click.echo("Writing image to the file...", nl=False) diff --git a/evic/device.py b/evic/device.py index e3f6a7c..2e0f425 100644 --- a/evic/device.py +++ b/evic/device.py @@ -28,7 +28,7 @@ from .dataflash import DataFlash -DeviceInfo = namedtuple('DeviceInfo', +DeviceInfo = namedtuple('DeviceInfo', 'name supported_product_ids logo_dimensions') class HIDTransfer(object): @@ -37,7 +37,7 @@ class HIDTransfer(object): Attributes: vid: USB vendor ID. pid: USB product ID. - devices: A dictionary mapping product IDs to DeviceInfo tuples. + devices: A dictionary mapping product IDs to DeviceInfo tuples. hid_signature: A bytearray containing the HID command signature (4 bytes). device: A HIDAPI device. From 46d35c0c7d2b554ab4a80cea7d7dafacc7f5078a Mon Sep 17 00:00:00 2001 From: ClockSelect Date: Sun, 21 Aug 2016 06:37:22 +0200 Subject: [PATCH 04/11] Cleanup --- evic/cli.py | 7 +++++-- evic/device.py | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/evic/cli.py b/evic/cli.py index dc4c84a..95d02c0 100644 --- a/evic/cli.py +++ b/evic/cli.py @@ -30,6 +30,7 @@ import click import evic + from .device import DeviceInfo @@ -339,13 +340,15 @@ def uploadlogo(inputfile, invert, noverify): # Convert the image with handle_exceptions(evic.LogoConversionError): click.echo("Converting logo...", nl=False) - # Check supported logo size + + # Check supported logo dimensions logo_dimensions = device_info.logo_dimensions if not logo_dimensions: raise evic.LogoConversionError("Device doesn't support logos.") + # Perform the actual conversion logo = evic.logo.fromimage(inputfile, invert) - if (logo.width, logo.height) != logosize: + if (logo.width, logo.height) != logo_dimensions: raise evic.LogoConversionError("Device only supports {}x{} logos." .format(*logo_dimensions)) diff --git a/evic/device.py b/evic/device.py index 2e0f425..6ba39a4 100644 --- a/evic/device.py +++ b/evic/device.py @@ -71,6 +71,7 @@ class HIDTransfer(object): 'W018': DeviceInfo("Reuleaux RX2/3", None, (64, 48)), 'W033': DeviceInfo("Reuleaux RX200S", None, None) } + # 0x43444948 hid_signature = bytearray(b'HIDC') From 136dfd166e87be79bef453e57abbfec8191c3c41 Mon Sep 17 00:00:00 2001 From: ClockSelect Date: Sun, 4 Sep 2016 10:53:51 +0200 Subject: [PATCH 05/11] Logo dimensions for Presa 75 running myevic firmware --- evic/device.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evic/device.py b/evic/device.py index 6ba39a4..33be1b5 100644 --- a/evic/device.py +++ b/evic/device.py @@ -62,7 +62,7 @@ class HIDTransfer(object): 'M041': DeviceInfo("iStick Pico", None, (96, 16)), 'M045': DeviceInfo("iStick Pico Mega", None, (96, 16)), 'M046': DeviceInfo("iPower", None, (96, 16)), - 'W007': DeviceInfo("Presa TC75W", ['E052'], None), + 'W007': DeviceInfo("Presa TC75W", ['E052'], (64,40)), 'W010': DeviceInfo("Classic", None, None), 'W011': DeviceInfo("Lite", None, None), 'W013': DeviceInfo("Stout", None, None), From c5235517ae27390175838b3baa65e416a7b21c36 Mon Sep 17 00:00:00 2001 From: ClockSelect Date: Wed, 7 Sep 2016 13:05:44 +0200 Subject: [PATCH 06/11] Fix time accuracy --- evic/cli.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/evic/cli.py b/evic/cli.py index 95d02c0..9d774bd 100644 --- a/evic/cli.py +++ b/evic/cli.py @@ -293,18 +293,17 @@ def time(): # Print the device information print_device_info(device_info, dataflash) - dt = datetime.now() - dataflash.df_year = dt.year - dataflash.df_month = dt.month - dataflash.df_day = dt.day - dataflash.df_hour = dt.hour - dataflash.df_minute = dt.minute - dataflash.df_second = dt.second - # Write data flash to the device with handle_exceptions(IOError): click.echo("Writing data flash...", nl=False) sleep(0.1) + dt = datetime.now() + dataflash.df_year = dt.year + dataflash.df_month = dt.month + dataflash.df_day = dt.day + dataflash.df_hour = dt.hour + dataflash.df_minute = dt.minute + dataflash.df_second = dt.second dev.write_dataflash(dataflash) click.secho("OK", fg='green', bold=True) From fa55dda4ea5d3337e4ee4c45ac6f52cd09b58c0e Mon Sep 17 00:00:00 2001 From: ClockSelect Date: Sat, 8 Oct 2016 05:03:12 +0200 Subject: [PATCH 07/11] Generic HID input command and LDROM update feature --- evic/cli.py | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++ evic/device.py | 34 ++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/evic/cli.py b/evic/cli.py index 9d774bd..607e97d 100644 --- a/evic/cli.py +++ b/evic/cli.py @@ -129,6 +129,24 @@ def fmc_read(dev, start, len): return fmemory +def hid_command(dev, cmd, start, len): + """Sends a HID command. + + Args: + dev: evic.HIDTransfer object. + + Returns: + evic.DataFlash object containing the device data flash. + """ + + # Send the command + with handle_exceptions(IOError): + click.echo("Sending command...", nl=False) + fmemory = dev.hid_command(cmd, start, len) + + return fmemory + + def print_device_info(device_info, dataflash): """Prints the device information found from data flash. @@ -258,6 +276,39 @@ def upload(inputfile, encrypted, dataflashfile, noverify): dev.write_aprom(aprom) +@usb.command('upload-ldrom') +@click.argument('inputfile', type=click.File('rb')) +def upload_ldrom(inputfile): + """Upload an LDROM image to the device.""" + + dev = evic.HIDTransfer() + + # Connect the device + connect(dev) + + # Print the USB info of the device + print_usb_info(dev) + + # Read the data flash + dataflash = read_dataflash(dev, False) + + # Get the device info + device_info = dev.devices.get(dataflash.product_id, + DeviceInfo("Unknown device", None, None)) + + # Print the device information + print_device_info(device_info, dataflash) + + # Read the LDROM image + ldrom = evic.APROM(inputfile.read()) + + # Write data flash to the device + with handle_exceptions(IOError): + # Write LDROM to the device + click.echo("Writing LDROM...", nl=False) + dev.write_ldrom(ldrom) + + @usb.command('reset') def reset(): """Resets the device.""" @@ -434,6 +485,31 @@ def fmcread(output, start, length): output.write(fmemory) +@usb.command('hidcmd') +@click.option('--output', '-o', type=click.File('wb'), required=True) +@click.option('--command', '-c', type=click.INT, required=True) +@click.option('--start', '-s', type=click.INT, required=True) +@click.option('--length', '-l', type=click.INT, required=True) +def hidcmd(command, output, start, length): + """Send a HID command to the device.""" + + dev = evic.HIDTransfer() + + # Connect the device + connect(dev) + + # Print the USB info of the device + print_usb_info(dev) + + # Send the command + response = hid_command(dev, command, start, length) + + # Write the data flash to the file + with handle_exceptions(IOError): + click.echo("Writing command response to the file...", nl=False) + output.write(response) + + @usb.command('screenshot') @click.option('--output', '-o', type=click.File('wb'), required=True) def screenshot(output): diff --git a/evic/device.py b/evic/device.py index 33be1b5..7f27e8f 100644 --- a/evic/device.py +++ b/evic/device.py @@ -175,6 +175,20 @@ def fmc_read(self, start, length): buf = self.read(length) return (buf) + def hid_command(self, cmd, start, length): + """Send a HID command to the device. + + Returns: + An array containing command response. + """ + + # Send the command for reading the data flash + self.send_command(cmd, start, length) + + # Read the response + buf = self.read(length) + return (buf) + def read_screen(self): """Reads the screen memory. @@ -294,6 +308,17 @@ def write_flash(self, data, start): self.write(data) + def write_ldflash(self, data): + """Writes data to the flash memory. + """ + + end = len(data) + + # Send the command for writing the data + self.send_command(0x3C, 0x100000, end) + + self.write(data) + def write_aprom(self, aprom): """Writes the APROM to the device. @@ -303,6 +328,15 @@ def write_aprom(self, aprom): self.write_flash(aprom.data, 0) + def write_ldrom(self, ldrom): + """Writes the LDROM to the device. + + Args: + aprom: A BinFile object containing an unencrypted LDROM image. + """ + + self.write_ldflash(ldrom.data) + def write_logo(self, logo): """Writes the logo to the the device. From 49378534d0c543b102358ebda65ef28d1a7f438f Mon Sep 17 00:00:00 2001 From: Timofey Titovets Date: Sun, 22 Jan 2017 16:02:35 +0300 Subject: [PATCH 08/11] Notes about autosync time on device Signed-off-by: Timofey Titovets --- README.rst | 5 +++++ scripts/evic-usb-rtc-sync.service | 6 ++++++ udev/99-nuvoton-hid.rules | 3 +++ 3 files changed, 14 insertions(+) create mode 100644 scripts/evic-usb-rtc-sync.service diff --git a/README.rst b/README.rst index fec0c37..bf89cfe 100644 --- a/README.rst +++ b/README.rst @@ -78,6 +78,11 @@ Allowing non-root access to the device The file ``udev/99-nuvoton-hid.rules`` contains an example set of rules for setting the device permissions to ``0666``. Copy the file to the directory ``/etc/udev/rules.d/`` to use it. +Autosync time when device connected +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The file ``scripts/evic-usb-rtc-sync.service`` + ``udev/99-nuvoton-hid.rules`` is a example of how to auto sync time + Usage ------- See ``--help`` for more information on a given command. diff --git a/scripts/evic-usb-rtc-sync.service b/scripts/evic-usb-rtc-sync.service new file mode 100644 index 0000000..c92766f --- /dev/null +++ b/scripts/evic-usb-rtc-sync.service @@ -0,0 +1,6 @@ +[Unit] +Description=Evic RTC sync + +[Service] +ExecStart=/usr/bin/evic-usb time +RemainAfterExit=yes diff --git a/udev/99-nuvoton-hid.rules b/udev/99-nuvoton-hid.rules index 0ee1b6f..b7b6117 100644 --- a/udev/99-nuvoton-hid.rules +++ b/udev/99-nuvoton-hid.rules @@ -3,3 +3,6 @@ SUBSYSTEM=="usb", ATTRS{idVendor}=="0416", ATTRS{idProduct}=="5020", MODE="0666" # HIDAPI/hidraw KERNEL=="hidraw*", ATTRS{busnum}=="1", ATTRS{idVendor}=="0416", ATTRS{idProduct}=="5020", MODE="0666" + +# HIDAPI/libusb RTC Sync +ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="0416", ATTRS{idProduct}=="5020", RUN+="/usr/bin/systemctl restart evic-usb-rtc-sync'" From 379715687a07691ffda5c4732057b36fd47564d8 Mon Sep 17 00:00:00 2001 From: Timofey Titovets Date: Mon, 23 Jan 2017 19:42:52 +0300 Subject: [PATCH 09/11] Fix typo in udev rules Signed-off-by: Timofey Titovets --- udev/99-nuvoton-hid.rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev/99-nuvoton-hid.rules b/udev/99-nuvoton-hid.rules index b7b6117..6c6a9bb 100644 --- a/udev/99-nuvoton-hid.rules +++ b/udev/99-nuvoton-hid.rules @@ -5,4 +5,4 @@ SUBSYSTEM=="usb", ATTRS{idVendor}=="0416", ATTRS{idProduct}=="5020", MODE="0666" KERNEL=="hidraw*", ATTRS{busnum}=="1", ATTRS{idVendor}=="0416", ATTRS{idProduct}=="5020", MODE="0666" # HIDAPI/libusb RTC Sync -ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="0416", ATTRS{idProduct}=="5020", RUN+="/usr/bin/systemctl restart evic-usb-rtc-sync'" +ACTION=="add", SUBSYSTEM=="usb", ATTRS{idVendor}=="0416", ATTRS{idProduct}=="5020", RUN+="/usr/bin/systemctl restart evic-usb-rtc-sync" From ffc54582ca16f231b32dd882cbfcca21132d8a1f Mon Sep 17 00:00:00 2001 From: Timofey Date: Wed, 25 Jan 2017 14:33:20 +0200 Subject: [PATCH 10/11] Added: check for usb device 0416:5020 in systemd service (#3) Signed-off-by: Timofey Titovets --- scripts/evic-usb-rtc-sync.service | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/evic-usb-rtc-sync.service b/scripts/evic-usb-rtc-sync.service index c92766f..e756dd2 100644 --- a/scripts/evic-usb-rtc-sync.service +++ b/scripts/evic-usb-rtc-sync.service @@ -2,5 +2,5 @@ Description=Evic RTC sync [Service] -ExecStart=/usr/bin/evic-usb time +ExecStart=/bin/bash -c 'lsusb -d 0416:5020 && evic-usb time' RemainAfterExit=yes From 45b2eb90a23f034a2f76908f2d37e512d04dae43 Mon Sep 17 00:00:00 2001 From: ClockSelect Date: Mon, 24 Jul 2017 22:40:25 +0200 Subject: [PATCH 11/11] Add devices VTC Dual & Primo Mini --- evic/device.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/evic/device.py b/evic/device.py index 7f27e8f..a5764b7 100644 --- a/evic/device.py +++ b/evic/device.py @@ -56,7 +56,9 @@ class HIDTransfer(object): 'E083': DeviceInfo("eGrip II", None, (64, 40)), 'E092': DeviceInfo("eVic AIO", None, (64, 40)), 'E115': DeviceInfo("eVic VTwo mini", None, (64, 40)), + 'E079': DeviceInfo("eVic VTC Dual", None, (64, 40)), 'E150': DeviceInfo("eVic Basic", None, (64, 40)), + 'E196': DeviceInfo("eVic Primo Mini", None, (64, 40)), 'M011': DeviceInfo("iStick TC100W", None, None), 'M037': DeviceInfo("ASTER", None, (96, 16)), 'M041': DeviceInfo("iStick Pico", None, (96, 16)),