-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Auto-configure display on some RP2350 boards #10028
Conversation
This should be considered an RFC. Some bits should probably be moved to common code & tidied up. If connected to a HDMI monitor, an eeprom will be on the i2c bus with address 0x50. When it's found, configure the display to 320x240x16 (default), or to user settings. Invalid user settings cause a safe mode with a misleading error: "Heap allocation when VM not running." This is because common_hal_picodvi_framebuffer_construct throws an exception for invalid parameters (width, height, and color depth), but the circuitpy VM is not running. With the default framebuffer configuration, about 256KiB is left for the CircuitPython VM. When a display is configured (whether picodvi or not), board.DISPLAY exits and can be retrieved. When there's no display (including after `release_displays()`), accessing `board.DISPLAY` raises an AttributeError. This behavior should maybe adapted everywhere, but I'm not sure how much flash size it takes.
ping @ladyada |
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.
Thanks for working on this! I'm very excited for a CP computer.
Is this ready now? Would love to add it to the metro and fruit jam too. |
Let's see if this works out in terms of code space.
There's only an implementation for RP2350 right now, as it's not used/needed on RP2040.
and auto-set height and support rotation similar to how it's done on some of those dot clock display espressif boards
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.
Just a couple of things in addition to the build failing.
.. some boards need MODULE_ATTR_DELEGATION for other reasons than displayio.
I threw an artifact onto a pimoroni_pico_dv_base_w board using the CIRCUITPY_PICODVI_ENABLE="always" setting and the display didn't come up. A dir(board.DISPLAY) just returned When the new artifacts come up I'll try again with the non-w version (and a feather-dvi just to be sure I know how it's supposed to work). |
The code is only enabled on a few boards and it's not available at all on rp2040 at all right now. I updated the initial comment to explain this more. Do I need to clarify the docs? It lists the specific boards that are supported. |
(I do like the idea that boards with defined video pins but no guaranteed i2c pull-ups could still take an "always" setting via settings.toml and I would like to support more boards .. but that's not part of this PR) |
The way |
Sorry, no, I just jumped the gun before looking close enough. Checking for the existence of board.DISPLAY was a way of determining whether a builtin display was available, but I guess I can check the type now as board.DISPLAY is a Nonetype on boards that the new code is not enabled on. An interesting observation though is that if you create a picodvi instance to bring up a display on a board not supported the board.DISPLAY object type changes to FramebufferDisplay. That's a pretty cool feature 😁 |
I appreciate the comments, it's a chance to figure out if there's more to say in documenting this. Yes, it's true that libraries/helpers/bitmapsaver/adafruit_bitmapsaver.py: if not hasattr(board, "DISPLAY"):
libraries/helpers/displayio_layout/adafruit_displayio_layout/layouts/tab_layout.py: if hasattr(board, "DISPLAY"): |
|
Your opening comment is clear enough regarding the supported boards, I just got excited when I saw all the DISPLAY entries being dropped from pins.c on other boards, I thought there may have been a scope change. I should have looked closer and realized that none of the board.c files were updated so any existing display initializations would still be in effect. |
Historically, boards with no built-in display have not had a `board.DISPLAY` property. Soon, with adafruit/circuitpython#10028, any board with displayio will have a `board.DISPLAY` property. This property will be `None` if no display is configured, or a truthy non-`None` value if a display is configured (including dynamically at runtime). This revised check will work on both old and new circuitpython versions.
Historically, boards with no built-in display have not had a `board.DISPLAY` property. Soon, with adafruit/circuitpython#10028, any board with displayio will have a `board.DISPLAY` property. This property will be `None` if no display is configured, or a truthy non-`None` value if a display is configured (including dynamically at runtime). This revised check will work on both old and new circuitpython versions.
The schematic shows pull ups are present on the pico dv base so it would be a candidate for enabling the auto-dvi code. |
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.
One small thing plus changing board.DISPLAY
presence on some boards.
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.
A couple small things. Otherwise this looks right! Thank you.
@@ -204,6 +207,39 @@ MP_PROPERTY_GETSET(supervisor_runtime_rgb_status_brightness_obj, | |||
(mp_obj_t)&supervisor_runtime_get_rgb_status_brightness_obj, | |||
(mp_obj_t)&supervisor_runtime_set_rgb_status_brightness_obj); | |||
|
|||
#if CIRCUITPY_DISPLAYIO | |||
//| display: Any | |||
//| """The primary configured displayio display, if any. Read-only. |
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.
//| """The primary configured displayio display, if any. Read-only. | |
//| """The primary configured displayio display, if any. |
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.
yes, good catch.
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { | ||
if (i == primary_display_number) { |
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.
I think this is what you want.
if (i == primary_display_number) { | |
if (keep_primary && i == primary_display_number) { |
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.
That's originally what I had, but I changed it. Here's my logic: If !keep_primary
, then primary_display_number
was updated just above and will always be -1
here. -1 will never be equal to the loop counter.
Closing in favor of rebased version |
If a board has a HSTX or DVI connector, and it has I2C pull-ups built in, it's possible to auto-configure the display.
This is implemented for 2 boards: feather rp2350 & metro rp2350. It's expected to be added to fruit jam when that board definition is added.
It can't be applied to rp2040 boards right now because a particular routine to check if a video mode is valid is not yet implemented there.
it can't be applied to general rp2040/rp2350 boards because without i2c pull-ups, attempting to instantiate the i2c bus would throw an exception. This'll land you in safe mode.
The default resolution is 320x240@16bpp but this can be set via settings.toml (as can display rotation, in case you want a portrait hdmi display)
An earlier iteration of this PR changed how
board.DISPLAY
worked, but this is no longer the case. Instead, there's a newsupervisor.runtime.display
property that persists across soft resets. Ifboard_init
sets up a display, then that display is also set up there (in addition to appearing asboard.DISPLAY
). Otherwise, the property can be set by boot.py or code.py. This is a partial implementation of #8675, excluding the incompatible change of resetting "non-default displays" at the end of a code run, and excluding the idea of allocating SPI & I2C buses outside the GC heap.