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 ) .
36
+
37
+ For device specific commands, see their individual documentation pages.
38
+
39
+ Common commands:
40
+
41
+ ###### Listing available devices
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
55
+ ```
31
56
32
- Requirements: Python, [ PySimpleGUI ] ( https://www.pysimplegui.org ) and optionally [ pillow ] ( https://pillow.readthedocs.io/en/stable/index.html )
57
+ ###### Apply command to single device
33
58
34
- Use ` control.py ` . Either the commandline, see ` control.py --help ` or the graphical version: ` control.py --gui `
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.
35
63
36
64
```
37
- options:
38
- -h, --help show this help message and exit
39
- --bootloader Jump to the bootloader to flash new firmware
40
- --sleep, --no-sleep Simulate the host going to sleep or waking up
41
- --brightness BRIGHTNESS
42
- Adjust the brightness. Value 0-255
43
- --animate, --no-animate
44
- Start/stop vertical scrolling
45
- --pattern {full,lotus,gradient,double-gradient,zigzag,panic,lotus2}
46
- Display a pattern
47
- --image IMAGE Display a PNG or GIF image in black and white only)
48
- --image-grey IMAGE_GREY
49
- Display a PNG or GIF image in greyscale
50
- --percentage PERCENTAGE
51
- Fill a percentage of the screen
52
- --clock Display the current time
53
- --string STRING Display a string or number, like FPS
54
- --symbols SYMBOLS [SYMBOLS ...]
55
- Show symbols (degF, degC, :), snow, cloud, ...)
56
- --gui Launch the graphical version of the program
57
- --blink Blink the current pattern
58
- --breathing Breathing of the current pattern
59
- --eq EQ [EQ ...] Equalizer
60
- --random-eq Random Equalizer
61
- --wpm WPM Demo
62
- --snake Snake
63
- --all-brightnesses Show every pixel in a different brightness
64
- --set-color {white,black,red,green,blue,cyan,yellow,purple}
65
- Set RGB color (C1 Minimal Input Module)
66
- --get-color Get RGB color (C1 Minimal Input Module)
67
- -v, --version Get device version
68
- --serial-dev SERIAL_DEV
69
- Change the serial dev. Probably /dev/ttyACM0 on Linux, COM0 on Windows
65
+ # Example on Linux
66
+ > inputmodule-control --serial-dev /dev/ttyACM0 b1-display --pattern black
67
+
68
+ # Example on Windows
69
+ > inputmodule-control.exe --serial-dev COM5 b1-display --pattern black
70
70
```
71
71
72
- Examples
72
+ ###### Send command when device connects
73
73
74
- ``` sh
75
- # Launch graphical application
76
- ./control.py --gui
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.
77
77
78
- # Show current time and keep updating it
79
- ./control.py --clock
78
+ ```
79
+ > inputmodule-control b1-display --pattern black
80
+ Failed to find serial devivce. Please manually specify with --serial-dev
80
81
81
- # Draw PNG or GIF
82
- ./control.py --image stripe.gif
83
- ./control.py --image stripe.png
82
+ # No failure, waits until the device is connected, sends command and exits
83
+ > inputmodule-control --wait-for-device b1-display --pattern black
84
84
85
- # Change brightness (0-255)
86
- ./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.
87
90
```
88
91
89
- ## Control via Rust binary
92
+ ## Update the Firmware
90
93
91
- Currently have to specify the build target because it's not possible to specify a per package build target.
92
- 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:
93
98
99
+ ``` sh
100
+ inputmodule-control led-matrix --bootloader
101
+ inputmodule-control b1-display --bootloader
102
+ inputmodule-control c1-minimal --bootloader
94
103
```
95
- > cargo build --target x86_64-unknown-linux-gnu -p inputmodule-control
96
- > 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
97
113
```
98
114
99
- ## Building
115
+ ## Building the firmware
100
116
101
117
Dependencies: Rust
102
118
103
- Prepare Rust toolchain:
119
+ Prepare Rust toolchain (once) :
104
120
105
121
``` sh
106
122
rustup target install thumbv6m-none-eabi
@@ -116,36 +132,33 @@ cargo build -p b1display
116
132
cargo build -p c1minimal
117
133
```
118
134
119
- Generate UF2 file:
135
+ Generate the UF2 update file:
120
136
121
137
``` sh
122
138
elf2uf2-rs target/thumbv6m-none-eabi/debug/ledmatrix ledmatrix.uf2
123
139
elf2uf2-rs target/thumbv6m-none-eabi/debug/b1display b1dipslay.uf2
124
- elf2uf2-rs target/thumbv6m-none-eabi/debug/b1display c1minimal.uf2
140
+ elf2uf2-rs target/thumbv6m-none-eabi/debug/c1minimal c1minimal.uf2
125
141
```
126
142
127
- ## Flashing
143
+ ## Building the Application
128
144
129
- First, put the module into bootloader mode, which will expose a filesystem
145
+ Dependencies: Rust, pkg-config, libudev
130
146
131
- 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
132
149
133
- ``` sh
134
- cargo run -p ledmatrix
135
- cargo run -p b1display
136
- cargo run -p c1minimal
137
150
```
138
-
139
- Or by copying the above generated UF2 file to the partition mounted when the
140
- 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
+ ```
141
154
142
155
### Check the firmware version of the device
143
156
144
- ###### In-band using ` control.py `
157
+ ###### In-band using commandline
145
158
146
159
``` sh
147
- > ./ control.py --version
148
- Device version : 0.1.2
160
+ > inputmodule- control b1-display --version
161
+ Device Version : 0.1.3
149
162
```
150
163
151
164
###### By looking at the USB descriptor
@@ -169,30 +182,3 @@ Additionally the panic message is written to flash, which can be read as follows
169
182
sudo picotool save -r 0x15000000 0x15004000 message.bin
170
183
strings message.bin | head
171
184
```
172
-
173
- ## LED Matrix
174
-
175
- It's a 9x34 (306) LED matrix, controlled by RP2040 MCU and IS31FL3741A LED controller.
176
-
177
- Connection to the host system is via USB 2.0 and currently there is a USB Serial API to control it without reflashing.
178
-
179
- ## B1 Display
180
-
181
- ## C1 Minimal Input Module
182
-
183
- It's a very minimal input module. Many GPIO pins are exposed so that headers
184
- can be soldered onto them. Additionally there are pads for a WS2812/Neopixel
185
- compatible RGB LED.
186
-
187
- When booting up this LED is lit in green color.
188
- Its color and brightness can be controlled via the commands:
189
-
190
- ``` sh
191
- > ./control.py --brightness 255
192
- > ./control.py --get-brightness
193
- Current brightness: 255
194
-
195
- > ./control.py --set-color yellow
196
- > ./control.py --get-color
197
- Current color: RGB:(255, 255, 0)
198
- ```
0 commit comments