aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Schulz <quentin.schulz@theobroma-systems.com>2023-08-03 18:03:07 +0200
committerQuentin Schulz <quentin.schulz@theobroma-systems.com>2023-08-04 09:05:02 +0000
commit90bc12ae347916b0314f42d5cf67c05317811bb9 (patch)
treec66a9bd6a4d365b14ad0435a95339a31b2aaf061
parent525b4e46965cc03db69ae9184ece2a3b6ce48778 (diff)
usb-control: add script to control Jaguar
SBC-RK3588-AMR Jaguar is controllable over CP2102 both for its main power and BIOS DISABLE lines, so let's add a wrapper script to make it easier to control the BIOS Disable line state as well as control power reset via USB. Signed-off-by: Quentin Schulz <quentin.schulz@theobroma-systems.com>
-rw-r--r--usb-control/README.md33
-rw-r--r--usb-control/cp2102_jaguar.py133
-rwxr-xr-xusb-control/jaguar.py15
3 files changed, 179 insertions, 2 deletions
diff --git a/usb-control/README.md b/usb-control/README.md
index 48e0172..bf04e52 100644
--- a/usb-control/README.md
+++ b/usb-control/README.md
@@ -1,4 +1,4 @@
-# Haikou USB Control
+# Theobroma Systems baseboards and SBCs USB Control
This tool allows to control the **BIOS disable** signal and
**power** state via USB.
@@ -13,7 +13,7 @@ This tool allows to control the **BIOS disable** signal and
apt install python-usb
```
-# Usage
+## Usage (Haikou baseboard)
To manipulate **BIOS disable** via USB the slider has to be in the **normal
boot** position.
@@ -42,3 +42,32 @@ For more features use the built-in help:
haikou.py --help
+## Usage (SBC-RK3588-AMR Jaguar)
+
+The **BIOS** button forces BIOS Disable signal so please do not press it while
+controlling the SBC via USB.
+
+To list connected Jaguar SBCs:
+
+ jaguar.py list
+
+To power cycle the board:
+
+ jaguar.py cycle
+
+To select a specific board with given serial number (can be fetched via 'list'):
+
+ jaguar.py --serial SERIALNUMBER
+
+To enable the BIOS disable signal:
+
+ jaguar.py biosdisable
+
+To switch back to normal boot:
+
+ jaguar.py normalboot
+
+For more features use the built-in help:
+
+ jaguar.py --help
+
diff --git a/usb-control/cp2102_jaguar.py b/usb-control/cp2102_jaguar.py
new file mode 100644
index 0000000..96f7cc7
--- /dev/null
+++ b/usb-control/cp2102_jaguar.py
@@ -0,0 +1,133 @@
+#!/usr/bin/env python3
+
+"""
+Abstraction layer for SBC-RK3588-AMR Jaguar control circuits.
+The Jaguar circuit offers to control the status of the main power regulator
+via GPIO.0 in order to toggle the power state, to control the BIOS disable
+(maskrom) signal via GPIO.1, and to read the current power state via CTS line
+(modem status).
+"""
+
+__copyright__ = 'Copyright (C) 2023 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_ON = 0
+VALUE_POWER_OFF = 1
+
+# BIOS disable GPIO
+GPIO_BIOS = 1
+VALUE_BIOS_NORMAL = 0
+VALUE_BIOS_DISABLE = 1
+
+# Power state
+POWERSTATE_ON = 0
+POWERSTATE_OFF = 1
+
+
+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 VCC_3V3_S3, 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 to 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 BIOS button being pressed.
+ # 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 BIOS button)")))
+
+
+def do_normalboot(dev):
+ set_bootmode(dev, VALUE_BIOS_NORMAL)
+
+
+def do_biosdisable(dev):
+ set_bootmode(dev, VALUE_BIOS_DISABLE)
+
+
+def do_on(dev):
+ cp210x_controller.set_gpio(dev, GPIO_POWER, VALUE_POWER_ON)
+
+
+def do_off(dev):
+ cp210x_controller.set_gpio(dev, GPIO_POWER, VALUE_POWER_OFF)
+
+
+def do_cycle(dev):
+ do_off(dev)
+ time.sleep(0.3)
+ do_on(dev)
+ time.sleep(0.3)
+
+
+def do_cycle_to_normal(dev):
+ do_off(dev)
+ # Disable maskrom mode
+ set_bootmode(dev, VALUE_BIOS_NORMAL)
+ time.sleep(0.3)
+ do_on(dev)
+
+
+def do_cycle_to_maskrom(dev):
+ do_off(dev)
+ # Enable maskrom mode
+ set_bootmode(dev, VALUE_BIOS_DISABLE)
+ time.sleep(0.3)
+ do_on(dev)
+ # Disable maskrom mode again
+ time.sleep(0.1)
+ set_bootmode(dev, VALUE_BIOS_NORMAL)
+
+
+def main(product_string):
+ command_dict = {
+ 'status': (do_status,
+ 'show status of attached Jaguar SBCs'),
+ 'normalboot': (do_normalboot,
+ 'set bootmode to normal boot'),
+ 'biosdisable': (do_biosdisable,
+ 'set bootmode to BIOS disabled'),
+ 'on': (do_on,
+ 'turn on attached Jaguar SBCs'),
+ 'off': (do_off,
+ 'turn off attached Jaguar SBCs'),
+ 'cycle': (do_cycle,
+ 'power cycle attached Jaguar SBCs'),
+ '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()
diff --git a/usb-control/jaguar.py b/usb-control/jaguar.py
new file mode 100755
index 0000000..4f462d1
--- /dev/null
+++ b/usb-control/jaguar.py
@@ -0,0 +1,15 @@
+#!/usr/bin/env python3
+
+"""
+Controls power and BIOS Disable signal on the SBC-RK3588-AMR Jaguar.
+"""
+
+__copyright__ = 'Copyright (C) 2023 Theobroma Systems Design und Consulting GmbH'
+__license__ = 'MIT'
+
+import cp2102_jaguar
+
+PRODUCT_STRING = "Jaguar"
+
+if __name__ == '__main__':
+ cp2102_jaguar.main(PRODUCT_STRING)