Skip to content
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

Rebase all open pull requests on recent master branch #38

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
26 changes: 13 additions & 13 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
env:
- TOXENV=py34
- TOXENV=py33
- TOXENV=py27
- TOXENV=py26
- TOXENV=pypy

install: pip install -U tox

language: python

cache:
directories:
- .tox
- $HOME/.cache/pip

matrix:
include:
- python: 2.7
env: TOXENV=py27
- python: 3.4
env: TOXENV=py34
- python: 3.5
env: TOXENV=py35
- python: 3.6
env: TOXENV=py36

install: pip install -U tox

script: tox
cache:
directories:
- .tox
- $HOME/.cache/pip

deploy:
provider: pypi
Expand Down
88 changes: 69 additions & 19 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,43 @@ Evic is a USB programmer for devices based on the Joyetech Evic VTC Mini.
Supported devices
---------------------

* eVic VTwo*
* Evic VTC Mini
* Cuboid Mini
* Cuboid
* eVic VTC Dual*
* eGrip II*
* eVic AIO*
* eVic VTwo mini*
* eVic Basic*
* iStick TC100W*
* ASTER*
* iStick Pico
* iStick Pico Mega*
* iPower*
* Presa TC75W*
* Joyetech eVic VTwo*
* Joyetech eVic VTwo mini
* Joyetech evic VTC Mini
* Joyetech eVic VTC Dual*
* Joyetech eVic AIO*
* Joyetech eVic Basic*
* Joyetech eVic Primo*
* Joyetech eVic Primo Mini*
* Joyetech eVic Primo 2.0*
* Joyetech Cuboid
* Joyetech Cuboid Mini
* Joyetech Cuboid 200*
* Joyetech eGrip II*
* Eleaf iStick QC 200W*
* Eleaf iStick TC100W*
* Eleaf iStick TC200W*
* Eleaf iStick Pico
* Eleaf iStick Pico RDTA*
* Eleaf iStick Pico Mega*
* Eleaf iStick Pico Dual*
* Eleaf iStick Power*
* Eleaf ASTER*
* Wismec Presa TC75W
* Wismec Presa TC100W*
* Wismec Reuleaux RX2/3
* Wismec Reuleaux RX200*
* Wismec Reuleaux RX200S*
* Wismec Reuleaux RX75
* Wismec Reuleaux RX300*
* Wismec Reuleaux RXmini*
* Wismec Predator 228
* Vaporflask Classic*
* Vaporflask Lite*
* Vaporflask Stout*
* Reuleaux RX200*
* CENTURION*
* Reuleaux RX2/3*
* Reuleaux RX200S*
* Beyondvape Centurion*
* Vaponaute La Petit Box*
* Vapor Shark SwitchBox RX*

\*Untested

Expand Down Expand Up @@ -79,6 +94,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 @@ -125,3 +145,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 (May not work with all firmwares):

::

$ 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 (For firmwares supporting clock display):

::

$ evic-usb time

Take a screenshot of the device display (May not work with all firmwares):

::

$ evic-usb screenshot -o outfile.[png|jpg|...]
197 changes: 197 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,92 @@ 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.
Works only with devices and/or firmwares
supporting a clock-screen on the display.
"""

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 +454,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 +464,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
Loading