Skip to content

Commit 4c023a7

Browse files
Thomas Griffithspelwell
authored andcommitted
splashasm: Added splashasm
Small tool to compile .splash files that describe i2c & spi dumps for spitting out during start.elf Squished commits
1 parent 12ac746 commit 4c023a7

12 files changed

Lines changed: 1543 additions & 0 deletions

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ add_subdirectory(rpi-gpu-usage)
2121
add_subdirectory(vcgencmd)
2222
add_subdirectory(vclog)
2323
add_subdirectory(vcmailbox)
24+
add_subdirectory(splashasm)
2425

2526
# Only build rpifwcrypto if GnuTLS is available
2627
include(CheckIncludeFile)

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ A collection of scripts and simple applications
2929
secure-boot provisioner.
3030
* [rpi-gpu-usage](rpi-gpu-usage/) - A tool for showing the per-process usage of the V3D GPU
3131
on Raspberry Pi 4 and 5.
32+
* [splashasm](splashasm/) - A tool for writing spi & i2c dumps for fast display at boot
3233
* [vcgencmd](vcgencmd/) - A tool to send commands to the VideoCore firmware and
3334
display the results.
3435
* [vclog](vclog/) - A tool to get VideoCore 'assert' or 'msg' logs

splashasm/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
cmake_minimum_required(VERSION 3.10...3.27)
2+
3+
include(GNUInstallDirs)
4+
5+
#set project name
6+
project(splashasm)
7+
8+
add_subdirectory(parser)
9+
10+
install(PROGRAMS splash_assembler.py DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME splash-assembler)

splashasm/README.md

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,230 @@
1+
# Splash Asm
2+
3+
## Introduction
4+
5+
A toy language and binary format for describing SPI & I2C dumps, aimed at putting splash screens on SPI & I2C displays during vc4 boot on Raspberry Pis. This currently only supports non RP1 RPis, i.e. everything but the Pi 5.
6+
7+
## Usage
8+
9+
1. Clone this repository
10+
11+
2. Write a .splash file, or use one of the examples
12+
13+
3. Run `python3 splash_assembler.py <input>.splash -o output.bin` (You need python 3.12 or later)
14+
15+
4. Either already be on or mount a bootable Raspberry Pi drive
16+
17+
5. Copy this output.bin file into `/boot/firmware/`
18+
19+
6. Edit `/boot/firmware/config.txt`, adding a line `splash_screen=output.bin` anywhere in the file
20+
21+
## Tips
22+
23+
* To import an image for splash screens, write a python script to output your image binary in the correct format into a human readable splash file
24+
* Consts are useful, the way I have written this is so that you can structure a generic configuration file for your ic, and then have the actual data in another file. This allows the configuration files to be reused. Use extern consts and expressions like I have in st7789.splash to keep things clean
25+
26+
## The language
27+
28+
There are five kinds of instructions you can write
29+
30+
- `define`
31+
- `command` - this is not a keyword, you write the command name as defined in define to invoke it
32+
- `const`
33+
- `delay`
34+
- `import`
35+
36+
The syntax is as follows:
37+
38+
```bnf
39+
<define> ::= "define" <command-name> <protocol> <params>
40+
<protocol> ::= "spi" | "i2c"
41+
42+
43+
<command> ::= <command-name> <params> <opt-data>
44+
<opt-data> ::= <data> <opt-data> | <data>
45+
46+
<const> ::= "const" <const-name> "extern" | const <const-name> <data>
47+
48+
<delay> ::= "delay" <params> <int>
49+
50+
<import> ::= "import" <filename>
51+
52+
53+
<params> ::= "[" <key> <value> "]" | "[" <flag> "]"
54+
<data> ::= <hex-value> | <const-name>
55+
```
56+
57+
Newlines and whitespaces are treated the same, the only seperator is either a newline or a whitespace, and one newline or whitespace is the same as n newlines and/or whitespace
58+
59+
What are valid params for each instruction are better defined in the binary docs, I always learn best from examples, so I recomend having a look through those
60+
61+
## The binary
62+
63+
```
64+
-----------------------------------------------------------------------
65+
1. FILE HEADER - 16 bytes
66+
67+
0 1 2 3
68+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69+
| |
70+
: :
71+
| "SPLASH ASM" |
72+
: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
73+
| | 0x00 | 0x00 |
74+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
75+
| 0x00 | 0x00 | 0x00 | Version |
76+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
77+
78+
Magic : ASCII "SPLASH ASM" followed by five 0x00 pad bytes (15 B)
79+
Version : format version, currently 0x01
80+
81+
Everything after byte 15 is a stream of instructions, each
82+
beginning with a one-byte opcode:
83+
84+
0x00 DELAY
85+
0x01 SETUP
86+
0x10 COMMAND
87+
88+
89+
90+
-----------------------------------------------------------------------
91+
2. DELAY (0x00) - 5 bytes
92+
93+
94+
+-+-+-+-+-+-+-+-+
95+
| Opcode 0x00 |
96+
+-+-+-+-+-+-+-+-+
97+
98+
99+
0 1 2 3
100+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
101+
| Delay |
102+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
103+
104+
Delay : microseconds to wait (source [US]/[MS]/[S]
105+
units are multiplied out by the assembler)
106+
107+
108+
109+
-----------------------------------------------------------------------
110+
3. DEFINE (0x01) - 9-byte header + #Size Parameters
111+
112+
113+
+-+-+-+-+-+-+-+-+
114+
| Opcode 0x01 |
115+
+-+-+-+-+-+-+-+-+
116+
117+
118+
0 1 2 3
119+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
120+
| Protocol four cc |
121+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
122+
| Size | Reserved |
123+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
124+
| :
125+
: Parameters :
126+
: |
127+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
128+
129+
Protocol : A four cc code, currently either "SPI " or "I2C "
130+
Size : length in bytes of the parameters block that follows.
131+
This is unique to a four cc and file version
132+
Reserved : three pad bytes (struct alignment after Size), always 0x00
133+
134+
Defines are implicitly numbered: the index used later by
135+
COMMAND's "Out idx" field is just the order in which DEFINE
136+
instructions appear in the stream (0, 1, 2, ...).
137+
138+
The shape of the N-byte param block depends on Protocol:
139+
140+
3a. I2C Parameter block (8 bytes)
141+
142+
0 1 2 3
143+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
144+
| SDA pin | SCL pin | ADDR | Reserved |
145+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
146+
| Frequency |
147+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
148+
149+
ADDR : The I2C address of the endpoint
150+
151+
3b. SPI Parameter block (12 bytes)
152+
153+
0 1 2 3
154+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
155+
| COPI pin | CIPO pin | SCLK pin | CS pin |
156+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
157+
| DC pin | CPOL | CPHA | CSPOL |
158+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
159+
| Frequency |
160+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
161+
162+
CPOL/CPHA : SPI mode bits (default mode 0)
163+
CPOL : clock polarity, if 1 the data is transmitted on
164+
rising edges, if 2 the data is transmitted on
165+
falling edges (default 1)
166+
CSPOL : chip-select polarity active-low is 1
167+
active high is 2, (default 1)
168+
CPHA : clock phase, if 1 the clock transitions in the
169+
middle of bits, if 2, the data transitions are in
170+
phase with the clock
171+
172+
173+
174+
-----------------------------------------------------------------------
175+
4. COMMAND (0x10) - 5-byte header + #Size data
176+
177+
178+
+-+-+-+-+-+-+-+-+
179+
| Opcode 0x10 |
180+
+-+-+-+-+-+-+-+-+
181+
182+
0 1 2 3
183+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
184+
| Out idx | Flags | Size |
185+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
186+
| :
187+
: Data (Size bytes) :
188+
: |
189+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
190+
191+
Out idx : which DEFINE this command targets, by definition order
192+
Flags : 8-bit bitmask, only bit 0 is currently defined:
193+
Data : raw bytes to shift out over the target bus
194+
195+
4a. SPI Flag bitmask
196+
197+
+-+-+-+-+-+-+-+-+
198+
|S| Reserved |D|
199+
+-+-+-+-+-+-+-+-+
200+
201+
bit 0 (D), DATA_ONLY : If this is 1 then the DC pin always
202+
indicates data in the command, if 0,
203+
the DC pin indicates the first byte
204+
as a command
205+
bit 7 (S), SWALLOW_ERRORS : If this is 1 then we don't end
206+
the splash on a transaction error
207+
(mainly caused by nacked i2c)
208+
209+
4b. I2C Flag bitmask
210+
211+
+-+-+-+-+-+-+-+-+
212+
|S| Reserved |R|
213+
+-+-+-+-+-+-+-+-+
214+
215+
bit 0 (R), READ : Indicates an I2C read if 1, indicates an
216+
I2C write if 0 (default)
217+
bit 7 (S), SWALLOW_ERRORS : If this is 1 then we don't end
218+
the splash on a transaction error
219+
(mainly caused by nacked i2c)
220+
-----------------------------------------------------------------------
221+
```
222+
*(inspired by https://www.ietf.org/rfc/rfc793.html)*
223+
224+
## Limitations
225+
226+
- This is currently incompatible with the Pi 5
227+
- You can have a maximum of 4 SPI defines
228+
- You can have a maximum of 10 I2C defines
229+
- The delays are blocking and therefore a long splash description will slow down a boot
230+
- The only timing guarantee is that if you write a delay command, there will be a wait strictly greater than your delay command. This is not made for timing sensitive applications, there are further delays due to parsing

splashasm/examples/lcd.splash

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Writes "hello", waits 1 second, then writes "world" on an AQM0802A-FL-YBH
2+
# I2C 8x2 character LCD
3+
# This example was entirely written by claude as I wanted to see if it could work out the langauge
4+
5+
define lcd i2c [sda 2] [scl 3] [addr 0x3e] [freq 100000]
6+
7+
lcd [WRITE] 0x00 0x38
8+
lcd [WRITE] 0x00 0x39
9+
lcd [WRITE] 0x00 0x14
10+
lcd [WRITE] 0x00 0x70
11+
lcd [WRITE] 0x00 0x56
12+
lcd [WRITE] 0x00 0x6c
13+
delay [ms] 200
14+
15+
lcd [WRITE] 0x00 0x38
16+
lcd [WRITE] 0x00 0x0c
17+
lcd [WRITE] 0x00 0x01
18+
delay [ms] 2
19+
lcd [WRITE] 0x00 0x06
20+
21+
lcd [WRITE] 0x40 0x68 0x65 0x6c 0x6c 0x6f
22+
23+
delay [s] 1
24+
25+
lcd [WRITE] 0x00 0x01
26+
delay [ms] 2
27+
lcd [WRITE] 0x40 0x77 0x6f 0x72 0x6c 0x64

0 commit comments

Comments
 (0)