Skip to content

Commit d2e2200

Browse files
committed
README!
Signed-off-by: Daniel Schaefer <[email protected]>
1 parent 99e842a commit d2e2200

File tree

5 files changed

+347
-115
lines changed

5 files changed

+347
-115
lines changed

README.md

Lines changed: 99 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,122 @@
11
# Lotus Input Module Firmware
22

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.
45

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
67

7-
## Features
8+
## Modules
89

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
1025
- 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
1626
- Go to sleep
1727
- 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, ...)
2329

24-
Future features:
30+
## Control from the host
2531

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)
2933

30-
## Control from the host
34+
Or use our `inputmodule-control` app. Optionally there are is also a
35+
[Python script](python.md).
3136

32-
See: [API command documentation](commands.md)
37+
For device specific commands, see their individual documentation pages.
3338

34-
Requirements: Python, [PySimpleGUI](https://www.pysimplegui.org) and optionally [pillow](https://pillow.readthedocs.io/en/stable/index.html)
39+
Common commands:
3540

36-
Use `control.py`. Either the commandline, see `control.py --help` or the graphical version: `control.py --gui`
41+
###### Listing available devices
3742

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
3855
```
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+
7264
```
65+
# Example on Linux
66+
> inputmodule-control --serial-dev /dev/ttyACM0 b1-display --pattern black
7367
74-
Examples
68+
# Example on Windows
69+
> inputmodule-control.exe --serial-dev COM5 b1-display --pattern black
70+
```
7571

76-
```sh
77-
# Launch graphical application
78-
./control.py --gui
72+
###### Send command when device connects
7973

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.
8277

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
8684
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.
8990
```
9091

91-
## Control via Rust binary
92+
## Update the Firmware
9293

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:
9598

99+
```sh
100+
inputmodule-control led-matrix --bootloader
101+
inputmodule-control b1-display --bootloader
102+
inputmodule-control c1-minimal --bootloader
96103
```
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
99113
```
100114

101-
## Building
115+
## Building the firmware
102116

103117
Dependencies: Rust
104118

105-
Prepare Rust toolchain:
119+
Prepare Rust toolchain (once):
106120

107121
```sh
108122
rustup target install thumbv6m-none-eabi
@@ -118,36 +132,33 @@ cargo build -p b1display
118132
cargo build -p c1minimal
119133
```
120134

121-
Generate UF2 file:
135+
Generate the UF2 update file:
122136

123137
```sh
124138
elf2uf2-rs target/thumbv6m-none-eabi/debug/ledmatrix ledmatrix.uf2
125139
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
127141
```
128142

129-
## Flashing
143+
## Building the Application
130144

131-
First, put the module into bootloader mode, which will expose a filesystem
145+
Dependencies: Rust, pkg-config, libudev
132146

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
134149

135-
```sh
136-
cargo run -p ledmatrix
137-
cargo run -p b1display
138-
cargo run -p c1minimal
139150
```
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+
```
143154

144155
### Check the firmware version of the device
145156

146-
###### In-band using `control.py`
157+
###### In-band using commandline
147158

148159
```sh
149-
> ./control.py --version
150-
Device version: 0.1.2
160+
> inputmodule-control b1-display --version
161+
Device Version: 0.1.3
151162
```
152163

153164
###### By looking at the USB descriptor
@@ -171,30 +182,3 @@ Additionally the panic message is written to flash, which can be read as follows
171182
sudo picotool save -r 0x15000000 0x15004000 message.bin
172183
strings message.bin | head
173184
```
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-
```

b1display/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
## B1 Display

c1minimal/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
## C1 Minimal Input Module
2+
3+
It's a very minimal input module. Many GPIO pins are exposed so that headers
4+
can be soldered onto them. Additionally there are pads for a WS2812/Neopixel
5+
compatible RGB LED.
6+
7+
When booting up this LED is lit in green color.
8+
Its color and brightness can be controlled via the commands:
9+
10+
```sh
11+
> ./control.py --brightness 255
12+
> ./control.py --get-brightness
13+
Current brightness: 255
14+
15+
> ./control.py --set-color yellow
16+
> ./control.py --get-color
17+
Current color: RGB:(255, 255, 0)
18+
```

0 commit comments

Comments
 (0)