-
Notifications
You must be signed in to change notification settings - Fork 40
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
Generalized interface for different display models #54
Generalized interface for different display models #54
Conversation
I'm also getting a HD44780 matrix display, I'm curious how that one works and if I can generalize the API further to get it working. |
I think it's better if incorporating the matrix LCD display is a separate PR (and has lower priority), so this PR would be fully implemented now. |
I will need some help with updating the other examples, as I can't get them to attempt building, nor do I have the hardware |
Yeah, I'm not sure how to handle that since I don't have a bunch of HD44780s setup anymore either. It might make sense to remove the examples for now and open issues to re-add them from those who have the hardware setup so we can get your work here merged. |
I've ordered a few Arduino and Pi Pico boards now and can add examples for these and ESP32 on the weekend. I think that should cover the most common MCUs. Apart from that, the code is gonna be very similar for others. It's probably fine if we wait until I added the examples before merging, there's no need to rush things. |
In the end, it was just a bad connection. It is interesting to note that ESP32 did not have this issue and that the RP2040 HAL did not give me an error if the I2C connection failed. |
I've added all examples that I planned on adding for this PR. I only added 4-bit and 8-bit examples for ESP32, because I noticed that I would have needed a logic level converter to avoid sinking 5V into 3.3V logic pins. This could have damaged my MCUs. For I2C, I was able to modify the backpacks by desoldering the builtin pullup resistors and instead pulled the I2C lines only to 3.3V, which worked. I could add the remaining examples to the other MCUs once I have logic level converters. All examples that I added were tested on hardware. @JohnDoneth I feel like this PR is ready for review now. I've also added basic (for now) implementations for |
Sorry that this has become so huge, I'll keep my other PRs smaller |
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.
All of the changes look really good. Excellent work
This is only a draft for now, because this is not finished. Though, I would like to get some feedback on what I'm trying to do here as these are some major changes (though mostly API compatible or very similar).
The changes I've made are moving the initialization logic into a separate module and incorporates a building pattern (example below). I've also added the concept of Charsets, because different displays support different characters/glyphs and this would also allow users to define their own (e.g. for custom characters/glyphs, which could be added latter. rel. #8) or if they have a display with a completely different Charset. It's also possible to detect whether a character is supported or not. I've added the
Fallback<C: Charset, const FB: u8>
struct to easily specify which character to use instead, defaulting to space.Both the Charset and the DisplayMemoryMap are encoded as a generic parameter that are automatically inferred through the builder. The abstracted DisplayMemoryMap is respecting the scrollable margin of lines, allowing to set the cursor there. It's also possible to get the columns that one specific row has including the scrollable margin. This is for example important for 16x4 displays, as only the last 2 rows can scroll there.
Example
My Display is using the A00 Charset, which is some ASCII combined with Japanese Katakana. Currently, this library is just converting a string from UTF8 into raw bytes and sends that to the LCD. The LCD, however, doesn't speak UTF8, it only understands its own Charset. The added Charset trait is used for converting UTF8 into whatever the LCD speaks.
This allows me to render Japanese UTF8 strings directly onto the display:
ESP32 Code
Hardware Testing
So far, I only have my 16x2 display, but I have ordered a few different models to test on.
Changes
(Eight|Four)BitBusPins
instead of 10 or 6 arguments. This also improves the destroy function signature and clippy no longer needs to be suppressed.destroy
function for all Buses and the driver itself allows recovering pins and buses.new
function on the driver that returns all pins on error for better error handling. This function generically takes any options struct (DisplayOptions(8Bit|4Bit|I2C)
, one for each bus type). All setup logic has been moved out oflib.rs
intosetup.rs
.Copy
unless pins/bus were configured. This allows copying a single configuration for multiple displays.DisplayMemoryMap
trait was added to abstract the way display memory works internally. It maps 2D coordinates to contiguous slices in the display memory (start address + columns/length). It also allows addressing off-screen characters (scrollable area) where this library would have error'ed previously.Contiguous1RMemoryMap
).get_position
function in favor ofDisplayMemoryMap
.Charset
trait was added to abstract the internal character set that a display may support. It maps unicode characters to optional bytes to be sent to the display. TheCharsetWithFallback
trait andFallback
struct implementing it always return a byte. There areCharsetUniversal
which covers the ASCII character subset that is supported by most/all displays,CharsetA00
andCharsetA02
.set_cursor_pos
implementations were different, I chose the one that non_blocking used as there is no coordinate mangling involved.set_cursor_xy
was not implemented for non blocking..await
in documentation examples.