#!/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()]