aboutsummaryrefslogtreecommitdiff
path: root/usb-control/cp2102_haikou.py
blob: 4b44b3e1affdc0048cfd992a837e5d0418a4c4aa (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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#!/usr/bin/env python

"""
Abstraction layer for Haikou-like control circuits.
The Haikou circuit offers to "press" the power button
via GPIO.0 in order to toggle the power state, controls
the BIOS disable (maskrom) signal via GPIO.1, and
an read the current power state via CTS line
(modem status).
"""

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

import sys
import time
import command_processor
import cp210x_controller

# Power supply GPIO
GPIO_POWER = 0
VALUE_POWER_RELEASE = 0
VALUE_POWER_PRESS = 1

# BIOS disable GPIO
GPIO_BIOS = 1
VALUE_BIOS_NORMAL = 0
VALUE_BIOS_DISABLE = 1

# Power state
POWERSTATE_ON = 0
POWERSTATE_OFF = 1

def toggle_power(dev):
    # We emulate a power button press for 300 ms
    cp210x_controller.set_gpio(dev, GPIO_POWER, VALUE_POWER_PRESS)
    time.sleep(0.3)
    cp210x_controller.set_gpio(dev, GPIO_POWER, VALUE_POWER_RELEASE)
    time.sleep(0.3)

def get_powerstate(dev):
    # Reading the GPIO latch (get_gpio()) is useless, because it
    # does not reflect the real status. However, we have CTS connected
    # to 3V3, which is enabled when the PMIC is active
    # Returns POWERSTATE_ON or POWERSTATE_OFF
    return cp210x_controller.get_modemstatus(dev)

def set_bootmode(dev, state):
    # Set the bootmode state according the given argument.
    # state should be VALUE_BIOS_NORMAL or VALUE_BIOS_DISABLE
    cp210x_controller.set_gpio(dev, GPIO_BIOS, state)

def get_bootmode(dev):
    # We can only check if we pull the line low.
    # This could be overruled with the on-board slider.
    # Returns VALUE_BIOS_NORMAL or VALUE_BIOS_DISABLE
    return cp210x_controller.get_gpio(dev, GPIO_BIOS)



def do_status(dev):
    powerstate = get_powerstate(dev)
    bootmode = get_bootmode(dev)
    print "Board is {} ({})".format(
        ("ON" if powerstate == POWERSTATE_ON else "OFF"),
        ("BIOS disabled" if bootmode == VALUE_BIOS_DISABLE else "Normal boot (if not overruled by on-board switch)"))

def do_normalboot(dev):
    set_bootmode(dev, VALUE_BIOS_NORMAL)

def do_biosdisable(dev):
    set_bootmode(dev, VALUE_BIOS_DISABLE)

def do_powerbutton(dev):
    toggle_power(dev)

def do_on(dev):
    # Turn on if needed
    if get_powerstate(dev) == POWERSTATE_OFF:
        toggle_power(dev)

def do_off(dev):
    # Turn off if needed
    if get_powerstate(dev) == POWERSTATE_ON:
        toggle_power(dev)

def do_cycle(dev):
    # Turn off if needed
    if get_powerstate(dev) == POWERSTATE_ON:
        toggle_power(dev)
    # Turn on board
    toggle_power(dev)

def do_cycle_to_normal(dev):
    # Turn off if needed
    if get_powerstate(dev) == POWERSTATE_ON:
        toggle_power(dev)
    # Disable maskrom mode
    set_bootmode(dev, VALUE_BIOS_NORMAL)
    # Turn on board
    toggle_power(dev)

def do_cycle_to_maskrom(dev):
    # Turn off if needed
    if get_powerstate(dev) == POWERSTATE_ON:
        toggle_power(dev)
    # Enable maskrom mode
    set_bootmode(dev, VALUE_BIOS_DISABLE)
    # Turn on board
    toggle_power(dev)



def main(product_string):
    command_dict = {
        'status': (do_status,
            'show status of attached Haikou Baseboards'),
        'normalboot': (do_normalboot,
            'set bootmode to normal boot'),
        'biosdisable': (do_normalboot,
            'set bootmode to BIOS disabled'),
        'powerbutton': (do_powerbutton,
                'emulate power button press'),
        'on': (do_on,
            'turn on attached Haikou Baseboards'),
        'off': (do_off,
            'turn off attached Haikou Baseboards'),
        'cycle': (do_cycle,
            'power cycle attached Haikou Baseboards'),
        'cycle-to-normal': (do_cycle_to_normal,
            'power cycle with normal boot'),
        'cycle-to-maskrom': (do_cycle_to_maskrom,
            'power cycle with BIOS disabled')
    }

    # Create argparser object
    cp = command_processor.CommandProcessor(product_string, None, command_dict)

    # Valiate command line arguments and commands
    cp.validate_commandline(sys.argv[1:])

    # Start executing the commands
    cp.run()