-
Notifications
You must be signed in to change notification settings - Fork 97
splashasm: Added splashasm to utils for compiling splash files for i2c & spi dumps at boot #205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| cmake_minimum_required(VERSION 3.10...3.27) | ||
|
|
||
| include(GNUInstallDirs) | ||
|
|
||
| #set project name | ||
| project(splashasm) | ||
|
|
||
| add_subdirectory(parser) | ||
|
|
||
| install(PROGRAMS splash_assembler.py DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME splash-assembler) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,241 @@ | ||
| # Splash Asm | ||
|
|
||
| ## Introduction | ||
|
|
||
| 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. | ||
|
|
||
| ## Usage | ||
|
|
||
| 1. Clone this repository | ||
|
|
||
| 2. Write a .splash file, or use one of the examples | ||
|
|
||
| 3. Run ```python3 splash_assembler.py <input>.splash -o output.bin``` | ||
|
|
||
| 4. Either already be on or mount a bootable Raspberry Pi drive | ||
|
|
||
| 5. Copy this output.bin file into ```/boot/firmware/``` | ||
|
|
||
| 6. Edit ```/boot/firmware/config.txt```, adding a line ```splash_screen=output.bin``` anywhere in the file | ||
|
|
||
| ## Tips | ||
|
|
||
| * 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 | ||
| * 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 | ||
|
|
||
| ## The langauge | ||
|
|
||
| There are five kinds of instructions you can write | ||
|
|
||
| - ```define``` | ||
| - ```command``` - this is not a keyword, you write the command name as defined in define to invoke it | ||
| - ```const``` | ||
| - ```delay``` | ||
| - ```import``` | ||
|
|
||
| the syntax is as follows | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "The syntax is as follows:" |
||
|
|
||
| ```bnf | ||
| <define> ::= "define" <command-name> <protocol> <params> | ||
| <protocol> ::= "spi" | "i2c" | ||
|
|
||
|
|
||
| <command> ::= <command-name> <params> <opt-data> | ||
| <opt-data> ::= <data> <opt-data> | <data> | ||
|
|
||
| <const> ::= "const" <const-name> "extern" | const <const-name> <data> | ||
|
|
||
| <delay> ::= "delay" <params> <int> | ||
|
|
||
| <import> ::= "import" <filename> | ||
|
|
||
|
|
||
| <params> ::= "[" <key> <value> "]" | "[" <flag> "]" | ||
| <data> ::= <hex-value> | <const-name> | ||
| ``` | ||
|
|
||
| Newlines and whitespaces are treated the same, the only sperator is either a newline or a whitespace, and one newline or whitespace is the same as n newlines andor whitespace | ||
|
|
||
| What are valid params for each instruction are better defined in the binary docs, I always learn best from examples, so I reccomend having a look through those | ||
|
|
||
| ## The binary | ||
|
|
||
| ``` | ||
| ----------------------------------------------------------------------- | ||
| 1. FILE HEADER - 16 bytes | ||
|
|
||
| 0 1 2 3 | ||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've just noticed that your network-protocol-style structure diagrams don't work so well in little-endian - the bits are numbered backwards. Would it be cleaner to number the bytes? |
||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| | | | ||
| : : | ||
| | "SPLASH ASM" | | ||
| : +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| | | 0x00 | 0x00 | | ||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| | 0x00 | 0x00 | 0x00 | Version | | ||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
|
|
||
| Magic : ASCII "SPLASH ASM" followed by five 0x00 pad bytes (15 B) | ||
| Version : format version, currently 0x01 | ||
|
|
||
| Everything after byte 15 is a stream of instructions, each | ||
| beginning with a one-byte opcode: | ||
|
|
||
| 0x00 DELAY | ||
| 0x01 SETUP | ||
| 0x10 COMMAND | ||
|
|
||
|
|
||
|
|
||
| ----------------------------------------------------------------------- | ||
| 2. DELAY (0x00) - 5 bytes | ||
|
|
||
| 0 | ||
| 0 1 2 3 4 5 6 7 | ||
| +-+-+-+-+-+-+-+-+ | ||
| | Opcode 0x00 | | ||
| +-+-+-+-+-+-+-+-+ | ||
|
|
||
|
|
||
| 0 1 2 3 | ||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| | Delay | | ||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
|
|
||
| Delay : microseconds to wait (source [US]/[MS]/[S] | ||
| units are multiplied out by the assembler) | ||
|
|
||
|
|
||
|
|
||
| ----------------------------------------------------------------------- | ||
| 3. DEFINE (0x01) - 9-byte header + #Size Parameters | ||
|
|
||
| 0 | ||
| 0 1 2 3 4 5 6 7 | ||
| +-+-+-+-+-+-+-+-+ | ||
| | Opcode 0x01 | | ||
| +-+-+-+-+-+-+-+-+ | ||
|
|
||
|
|
||
| 0 1 2 3 | ||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| | Protocol four cc | | ||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| | Size | Reserved | | ||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| | : | ||
| : Parameters : | ||
| : | | ||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
|
|
||
| Protocol : A four cc code, currently either "SPI " or "I2C " | ||
| Size : length in bytes of the parameters block that follows. | ||
| This is unique to a four cc and file version | ||
| Reserved : three pad bytes (struct alignment after Size), always 0x00 | ||
|
|
||
| Defines are implicitly numbered: the index used later by | ||
| COMMAND's "Out idx" field is just the order in which DEFINE | ||
| instructions appear in the stream (0, 1, 2, ...). | ||
|
|
||
| The shape of the N-byte param block depends on Protocol: | ||
|
|
||
| 3a. I2C Parameter block (8 bytes) | ||
|
|
||
| 0 1 2 3 | ||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| | SDA pin | SCL pin | ADDR | Reserved | | ||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| | Frequency | | ||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
|
|
||
| ADDR : The I2C address of the endpoint | ||
|
|
||
| 3b. SPI Parameter block (12 bytes) | ||
|
|
||
| 0 1 2 3 | ||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| | COPI pin | CIPO pin | SCLK pin | CS pin | | ||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| | DC pin | CPOL | CPHA | CSPOL | | ||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| | Frequency | | ||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
|
|
||
| CPOL/CPHA : SPI mode bits (default mode 0) | ||
| CPOL : clock polarity, if 1 the data is transmitted on | ||
| rising edges, if 2 the data is transmitted on | ||
| falling edges (default 1) | ||
| CSPOL : chip-select polarity active-low is 1 | ||
| active high is 2, (default 1) | ||
| CPHA : clock phase, if 1 the clock transitions in the | ||
| middle of bits, if 2, the data transitions are in | ||
| phase with the clock | ||
|
|
||
|
|
||
|
|
||
| ----------------------------------------------------------------------- | ||
| 4. COMMAND (0x10) - 5-byte header + #Size data | ||
|
|
||
| 0 | ||
| 0 1 2 3 4 5 6 7 | ||
| +-+-+-+-+-+-+-+-+ | ||
| | Opcode 0x10 | | ||
| +-+-+-+-+-+-+-+-+ | ||
|
|
||
| 0 1 2 3 | ||
| 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| | Out idx | Flags | Size | | ||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
| | : | ||
| : Data (Size bytes) : | ||
| : | | ||
| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
|
|
||
| Out idx : which DEFINE this command targets, by definition order | ||
| Flags : 8-bit bitmask, only bit 0 is currently defined: | ||
| Data : raw bytes to shift out over the target bus | ||
|
|
||
| 4a. SPI Flag bitmask | ||
|
|
||
| 0 1 2 3 4 5 6 7 | ||
| +-+-+-+-+-+-+-+-+ | ||
| |S| Reserved |D| | ||
| +-+-+-+-+-+-+-+-+ | ||
|
|
||
| bit 0 (D), DATA_ONLY : If this is 1 then the DC pin always | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is where I noticed that the bit numbering is backwards. Whichever way you do choose to number them (and I vote 0 for LSB), either the diagram or the description has to change. |
||
| indicates data in the command, if 0, | ||
| the DC pin indicates the first byte | ||
| as a command | ||
| bit 8 (S), SWALLOW_ERRORS : If this is 1 then we don't finish | ||
| the splash on a transaction error | ||
| (mainly caused by nacked i2c) | ||
|
|
||
| 4b. I2C Flag bitmask | ||
|
|
||
| 0 1 2 3 4 5 6 7 | ||
| +-+-+-+-+-+-+-+-+ | ||
| |S| Reserved |R| | ||
| +-+-+-+-+-+-+-+-+ | ||
|
|
||
| bit 0 (R), READ : Indicates an I2C read if 1, indicates an | ||
| I2C write if 0 (default) | ||
| bit 8 (S), SWALLOW_ERRORS : If this is 1 then we don't finish | ||
| the splash on a transaction error | ||
| (mainly caused by nacked i2c) | ||
| ----------------------------------------------------------------------- | ||
| ``` | ||
| *(inspired by https://www.ietf.org/rfc/rfc793.html)* | ||
|
|
||
| ## Limitations | ||
|
|
||
| - This is incompatible with the Pi 5 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. currently |
||
| - You can only have a maximum of 4 SPI defines | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can drop the "only"s here |
||
| - You can only have a maximum of 10 I2C defines | ||
| - The delays are blocking and therefore a long splash description will slow down a boot | ||
| - The only timing garuntee 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 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo - guarantee |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Single backticks are sufficient for in-line code formatting