aboutsummaryrefslogtreecommitdiff
path: root/usb-control/telaviv.py
blob: d28113f67097f27ef535b8b607c422cf4b77d984 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#!/usr/bin/env python
"""Controls power button and BIOS Disable of the Haikou Baseboard
"""

__copyright__ = 'Copyright (C) 2017 Theobroma Systems Design und Consulting GmbH'
__license__ = 'MIT'

import argparse
import usb.core
import usb.util
import sys
import time

VENDOR_ID               = 0x10c4
PRODUCT_ID              = 0xea60
PRODUCT_STRING          = "Tel-Aviv"
REQTYPE_HOST_TO_DEVICE  = 0x40
REQTYPE_DEVICE_TO_HOST  = 0xc0
CP210X_VENDOR_SPECIFIC  = 0xFF
CP210X_WRITE_LATCH      = 0x37E1
CP210X_READ_LATCH       = 0x00C2
CP210X_GET_MDMSTS       = 0x8

def send_gpio_command(gpio,value):
    data = 0
    # the latch register has 16 bit. the upper 8 bits are the gpio value,
    # the lower 8 bit are the write mask.
    data = (value << (8+gpio)) | (1 << gpio);
    dev.ctrl_transfer(REQTYPE_HOST_TO_DEVICE, CP210X_VENDOR_SPECIFIC, \
            CP210X_WRITE_LATCH, data, 0)

def toggle_power():
    send_gpio_command(0,1)
    time.sleep(0.3)
    send_gpio_command(0,0)

def get_powerstate():
    data = dev.ctrl_transfer(REQTYPE_DEVICE_TO_HOST, CP210X_GET_MDMSTS,0,0,1);
    return not ((data[0] >> 4) & 1)

parser = argparse.ArgumentParser(description='Controls power button and BIOS \
        Disable of the Haikou baseboard')
subparser = parser.add_subparsers(title='subcommands', dest='subcommand', \
        description='valid subcommands', \
        help='call with -h for additional parameters')
parser_list = subparser.add_parser('list', help='lists serial numbers of  \
        attached Haikou Baseboards')
parser_power = subparser.add_parser('power', help='control the power state')
parser_power.add_argument('power_cmd', choices=['on','off','reset','status'], \
        help='set or get the power status of the baseboard')
parser_power.add_argument('--serial','-s', action='store', dest='serialnumber', \
        type=str, help='defines the serialnumber to use')
parsergroup_bootmode = parser_power.add_mutually_exclusive_group()
parsergroup_bootmode.add_argument('--bios-disable','-b',action='store_true', \
        dest='bios_disable', help='activate BIOS Disable')
parsergroup_bootmode.add_argument('--normal-boot','-n',action='store_true', \
        dest='normal_boot', help='activate Normal Boot')
args = parser.parse_args()

if args.subcommand == 'list':
    try:
        dev = list(usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID, \
                product=PRODUCT_STRING, find_all=True))

    except ValueError, e:
        if 'langid' in e.message:
            raise usb.core.USBError(e.message + "\n" +
                    "This may be a permission issue. See: \n"+
                    "https://github.com/walac/pyusb/issues/139")
    print "Found %d Baseboard%s:" % (len(dev),"s"[len(dev)==1:])
    for idx,cfg in enumerate(dev):
        print "%d: %s" % (idx, cfg.serial_number)
    sys.exit()

if args.subcommand == 'power':
    if args.serialnumber:
        dev = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID, \
                serial_number=args.serialnumber)
    else:
        dev = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID)

    if dev is None:
        print "Device not found"
        sys.exit()

    if args.bios_disable:
        send_gpio_command(1,1)

    if args.normal_boot:
        send_gpio_command(1,0)

    if args.power_cmd == 'on':
        if not get_powerstate(): toggle_power()

    elif args.power_cmd == 'off':
        if get_powerstate(): toggle_power()

    elif args.power_cmd == 'reset':
        if get_powerstate():
            toggle_power()
            time.sleep(0.5)
        toggle_power()

    elif args.power_cmd == 'status':
        print "Board is %s" % ("OFF","ON")[get_powerstate()]