Skip to content

New commands for myevic #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -124,3 +129,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:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add that fmc-read, time and screenshot are specific to your FW. reset is good.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree.


::

$ 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|...]
194 changes: 194 additions & 0 deletions evic/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,16 @@
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):
"""Context for handling exceptions."""
Expand Down Expand Up @@ -108,6 +111,42 @@ def read_dataflash(dev, verify):
return 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 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.

Expand Down Expand Up @@ -237,6 +276,89 @@ 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."""

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)

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

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


@usb.command('upload-logo')
@click.argument('inputfile', type=click.File('rb'))
@click.option('--invert', '-i', is_flag=True,
Expand Down Expand Up @@ -329,6 +451,7 @@ def dumpdataflash(output, noverify):
device_info = dev.devices.get(dataflash.product_id,
DeviceInfo("Unknown device", None, None))


# Print the device information
print_device_info(device_info, dataflash)

Expand All @@ -338,6 +461,77 @@ 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('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):
"""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."""
Expand Down
7 changes: 7 additions & 0 deletions evic/dataflash.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
66 changes: 65 additions & 1 deletion evic/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,15 @@ 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)),
'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),
Expand Down Expand Up @@ -161,6 +163,48 @@ def read_dataflash(self):

return (dataflash, checksum)

def fmc_read(self, start, length):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add a small note to the docstring, mentioning fmc_read and read_screen are specific to your FW.

"""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 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.

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.

Expand Down Expand Up @@ -266,6 +310,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.

Expand All @@ -275,6 +330,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.

Expand Down
Loading