From df5b67509d2b27114695d5bb3d32da22f9d0a0ef Mon Sep 17 00:00:00 2001
From: ClockSelect <mrrraow@gmail.com>
Date: Sun, 21 Aug 2016 05:44:39 +0200
Subject: [PATCH 1/7] 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 <mrrraow@gmail.com>
Date: Sun, 21 Aug 2016 06:27:00 +0200
Subject: [PATCH 2/7] 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 <mrrraow@gmail.com>
Date: Sun, 21 Aug 2016 06:30:41 +0200
Subject: [PATCH 3/7] 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 <mrrraow@gmail.com>
Date: Sun, 21 Aug 2016 06:37:22 +0200
Subject: [PATCH 4/7] 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 <mrrraow@gmail.com>
Date: Sun, 4 Sep 2016 10:53:51 +0200
Subject: [PATCH 5/7] 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 <mrrraow@gmail.com>
Date: Wed, 7 Sep 2016 13:05:44 +0200
Subject: [PATCH 6/7] 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 <mrrraow@gmail.com>
Date: Sat, 8 Oct 2016 05:03:12 +0200
Subject: [PATCH 7/7] 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.