1
1
# Lotus Input Module Firmware
2
2
3
- See below sections for LED Matrix, LCD Display and C1 Minimal module details.
3
+ This repository contains both the firmware for the Lotus input modules, as well
4
+ as the tool to control them.
4
5
5
- Rust project setup based off of: https://github.com/rp-rs/rp2040-project-template
6
+ Rust firmware project setup based off of: https://github.com/rp-rs/rp2040-project-template
6
7
7
- ## Features
8
+ ## Modules
8
9
9
- - Reset into bootloader when firmware crashes/panics
10
+ See pages of the individual modules for details about how they work and how
11
+ they're controlled.
12
+
13
+ - [ LED Matrix] ( ledmatrix/README.md )
14
+ - [ 2nd Display] ( b1display/README.md )
15
+ - [ Minimal C1 Input Module] ( c1minimal/README.md )
16
+
17
+ ## Generic Features
18
+
19
+ All modules are built with an RP2040 microcontroller
20
+ Features that all modules share
21
+
22
+ - Firmware written in bare-metal Rust
23
+ - Reset into RP2040 bootloader when firmware crashes/panics
24
+ - Sleep Mode to save power
10
25
- API over USB ACM Serial Port - Requires no Drivers on Windows and Linux
11
- - Display various pre-programmed patterns
12
- - Light up a percentage of the screen
13
- - Change brightness
14
- - Send a black/white image to the display
15
- - Send a greyscale image to the display
16
26
- Go to sleep
17
27
- Reset into bootloader
18
- - Scroll and loop the display content vertically
19
- - A commandline script and graphical application to control it
20
- - Sleep Mode
21
- - Transition slowly turns off/on the LEDs
22
- - Current hardware does not have the SLEEP# GPIO connected, can't sleep automatically
28
+ - Control and read module state (brightness, displayed image, ...)
23
29
24
- Future features:
30
+ ## Control from the host
25
31
26
- - API
27
- - Send a greyscale image to display
28
- - Read current system state (brightness, sleeping, ...)
32
+ To build your own application see the: [ API command documentation] ( commands.md )
29
33
30
- ## Control from the host
34
+ Or use our ` inputmodule-control ` app. Optionally there are is also a
35
+ [ Python script] ( python.md ) .
31
36
32
- See: [ API command documentation ] ( commands.md )
37
+ For device specific commands, see their individual documentation pages.
33
38
34
- Requirements: Python, [ PySimpleGUI ] ( https://www.pysimplegui.org ) and optionally [ pillow ] ( https://pillow.readthedocs.io/en/stable/index.html )
39
+ Common commands:
35
40
36
- Use ` control.py ` . Either the commandline, see ` control.py --help ` or the graphical version: ` control.py --gui `
41
+ ###### Listing available devices
37
42
43
+ ``` sh
44
+ > inputmodule-control --list
45
+ /dev/ttyACM0
46
+ VID 0x32AC
47
+ PID 0x0020
48
+ SN FRAKDEAM0020110001
49
+ Product Lotus_LED_Matrix
50
+ /dev/ttyACM1
51
+ VID 0x32AC
52
+ PID 0x0021
53
+ SN FRAKDEAM0000000000
54
+ Product Lotus_B1_Display
38
55
```
39
- options:
40
- -h, --help show this help message and exit
41
- --bootloader Jump to the bootloader to flash new firmware
42
- --sleep, --no-sleep Simulate the host going to sleep or waking up
43
- --brightness BRIGHTNESS
44
- Adjust the brightness. Value 0-255
45
- --animate, --no-animate
46
- Start/stop vertical scrolling
47
- --pattern {full,lotus,gradient,double-gradient,zigzag,panic,lotus2}
48
- Display a pattern
49
- --image IMAGE Display a PNG or GIF image in black and white only)
50
- --image-grey IMAGE_GREY
51
- Display a PNG or GIF image in greyscale
52
- --percentage PERCENTAGE
53
- Fill a percentage of the screen
54
- --clock Display the current time
55
- --string STRING Display a string or number, like FPS
56
- --symbols SYMBOLS [SYMBOLS ...]
57
- Show symbols (degF, degC, :), snow, cloud, ...)
58
- --gui Launch the graphical version of the program
59
- --blink Blink the current pattern
60
- --breathing Breathing of the current pattern
61
- --eq EQ [EQ ...] Equalizer
62
- --random-eq Random Equalizer
63
- --wpm WPM Demo
64
- --snake Snake
65
- --all-brightnesses Show every pixel in a different brightness
66
- --set-color {white,black,red,green,blue,cyan,yellow,purple}
67
- Set RGB color (C1 Minimal Input Module)
68
- --get-color Get RGB color (C1 Minimal Input Module)
69
- -v, --version Get device version
70
- --serial-dev SERIAL_DEV
71
- Change the serial dev. Probably /dev/ttyACM0 on Linux, COM0 on Windows
56
+
57
+ ###### Apply command to single device
58
+
59
+ By default a command will be sent to all devices that can be found, to apply it
60
+ to a single device, specify the COM port.
61
+ In this example the command is targeted at ` b1-display ` , so it will only apply
62
+ to this module type.
63
+
72
64
```
65
+ # Example on Linux
66
+ > inputmodule-control --serial-dev /dev/ttyACM0 b1-display --pattern black
73
67
74
- Examples
68
+ # Example on Windows
69
+ > inputmodule-control.exe --serial-dev COM5 b1-display --pattern black
70
+ ```
75
71
76
- ``` sh
77
- # Launch graphical application
78
- ./control.py --gui
72
+ ###### Send command when device connects
79
73
80
- # Show current time and keep updating it
81
- ./control.py --clock
74
+ By default the app tries to connect with the device and aborts if it can't
75
+ connect. But you might want to start the app, have it wait until the device is
76
+ connected and then send the command.
82
77
83
- # Draw PNG or GIF
84
- ./control.py --image stripe.gif
85
- ./control.py --image stripe.png
78
+ ```
79
+ > inputmodule-control b1-display --pattern black
80
+ Failed to find serial devivce. Please manually specify with --serial-dev
81
+
82
+ # No failure, waits until the device is connected, sends command and exits
83
+ > inputmodule-control --wait-for-device b1-display --pattern black
86
84
87
- # Change brightness (0-255)
88
- ./control.py --brightness 50
85
+ # If the device is already connected, it does nothing, just wait 1s.
86
+ # This means you can run this command by a system service and restart it when
87
+ # it finishes. Then it will only ever do anything if the device reconnects.
88
+ > inputmodule-control --wait-for-device b1-display --pattern black
89
+ Device already present. No need to wait. Not executing command.
89
90
```
90
91
91
- ## Control via Rust binary
92
+ ## Update the Firmware
92
93
93
- Currently have to specify the build target because it's not possible to specify a per package build target.
94
- Tracking issue: https://github.com/rust-lang/cargo/issues/9406
94
+ First, put the module into bootloader mode.
95
+
96
+ This can be done either by pressing the bootsel button while plugging it in or
97
+ by using one of the following commands:
95
98
99
+ ``` sh
100
+ inputmodule-control led-matrix --bootloader
101
+ inputmodule-control b1-display --bootloader
102
+ inputmodule-control c1-minimal --bootloader
96
103
```
97
- > cargo build --target x86_64-unknown-linux-gnu -p inputmodule-control
98
- > cargo run --target x86_64-unknown-linux-gnu -p inputmodule-control
104
+
105
+ Then the module will present itself in the same way as a USB thumb drive.
106
+ Copy the UF2 firmware file onto it and the device will flash and reset automatically.
107
+ Alternatively when building from source, run one of the following commands:
108
+
109
+ ``` sh
110
+ cargo run -p ledmatrix
111
+ cargo run -p b1display
112
+ cargo run -p c1minimal
99
113
```
100
114
101
- ## Building
115
+ ## Building the firmware
102
116
103
117
Dependencies: Rust
104
118
105
- Prepare Rust toolchain:
119
+ Prepare Rust toolchain (once) :
106
120
107
121
``` sh
108
122
rustup target install thumbv6m-none-eabi
@@ -118,36 +132,33 @@ cargo build -p b1display
118
132
cargo build -p c1minimal
119
133
```
120
134
121
- Generate UF2 file:
135
+ Generate the UF2 update file:
122
136
123
137
``` sh
124
138
elf2uf2-rs target/thumbv6m-none-eabi/debug/ledmatrix ledmatrix.uf2
125
139
elf2uf2-rs target/thumbv6m-none-eabi/debug/b1display b1dipslay.uf2
126
- elf2uf2-rs target/thumbv6m-none-eabi/debug/b1display c1minimal.uf2
140
+ elf2uf2-rs target/thumbv6m-none-eabi/debug/c1minimal c1minimal.uf2
127
141
```
128
142
129
- ## Flashing
143
+ ## Building the Application
130
144
131
- First, put the module into bootloader mode, which will expose a filesystem
145
+ Dependencies: Rust, pkg-config, libudev
132
146
133
- This can be done by pressing the bootsel button while plugging it in.
147
+ Currently have to specify the build target because it's not possible to specify a per package build target.
148
+ Tracking issue: https://github.com/rust-lang/cargo/issues/9406
134
149
135
- ``` sh
136
- cargo run -p ledmatrix
137
- cargo run -p b1display
138
- cargo run -p c1minimal
139
150
```
140
-
141
- Or by copying the above generated UF2 file to the partition mounted when the
142
- module is in the bootloder.
151
+ > cargo build --target x86_64-unknown-linux-gnu -p inputmodule-control
152
+ > cargo run --target x86_64-unknown-linux-gnu -p inputmodule-control
153
+ ```
143
154
144
155
### Check the firmware version of the device
145
156
146
- ###### In-band using ` control.py `
157
+ ###### In-band using commandline
147
158
148
159
``` sh
149
- > ./ control.py --version
150
- Device version : 0.1.2
160
+ > inputmodule- control b1-display --version
161
+ Device Version : 0.1.3
151
162
```
152
163
153
164
###### By looking at the USB descriptor
@@ -171,30 +182,3 @@ Additionally the panic message is written to flash, which can be read as follows
171
182
sudo picotool save -r 0x15000000 0x15004000 message.bin
172
183
strings message.bin | head
173
184
```
174
-
175
- ## LED Matrix
176
-
177
- It's a 9x34 (306) LED matrix, controlled by RP2040 MCU and IS31FL3741A LED controller.
178
-
179
- Connection to the host system is via USB 2.0 and currently there is a USB Serial API to control it without reflashing.
180
-
181
- ## B1 Display
182
-
183
- ## C1 Minimal Input Module
184
-
185
- It's a very minimal input module. Many GPIO pins are exposed so that headers
186
- can be soldered onto them. Additionally there are pads for a WS2812/Neopixel
187
- compatible RGB LED.
188
-
189
- When booting up this LED is lit in green color.
190
- Its color and brightness can be controlled via the commands:
191
-
192
- ``` sh
193
- > ./control.py --brightness 255
194
- > ./control.py --get-brightness
195
- Current brightness: 255
196
-
197
- > ./control.py --set-color yellow
198
- > ./control.py --get-color
199
- Current color: RGB:(255, 255, 0)
200
- ```
0 commit comments