[{"element_type":"text","content":"\n        \u003cp\u003eCircuitPython 9.2.5 adds a new property to the supervisor Runtime object, \u003ca href=\"https://docs.circuitpython.org/en/latest/shared-bindings/supervisor/index.html#supervisor.Runtime.display\"\u003e\u003ccode\u003edisplay\u003c/code\u003e\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eIf your board has a built in display that is automatically configured by the CircuitPython core (e.g., boards like the \u003ca href=\"https://www.adafruit.com/product/5691\"\u003eFeather ESP32-S3 Reverse TFT\u003c/a\u003e), then this display is available as \u003ccode\u003esupervisor.runtime.display\u003c/code\u003e in addition to \u003ccode\u003eboard.DISPLAY\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eSo what's different about the new \u003ccode\u003esupervisor.runtime.display\u003c/code\u003e?\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eThis property is available on all boards that support \u003ccode\u003edisplayio\u003c/code\u003e, not just boards with built in displays\u003c/li\u003e\n\u003cli\u003eUnlike \u003ccode\u003eboard.DISPLAY\u003c/code\u003e, this property is settable, and remembers its value after your code file finishes running. This means you can set this property once in \u003cstrong\u003eboot.py\u003c/strong\u003e and then use the display each time your \u003ccode\u003ecode.py\u003c/code\u003e runs, or re-use a display set by a previous run of \u003cstrong\u003ecode.py\u003c/strong\u003e.\u003c/li\u003e\n\u003cli\u003eDue to technical limitations in CircuitPython, when a display is released, \u003ccode\u003eboard.DISPLAY\u003c/code\u003e becomes a \"None-like object\": one that prints as \u003ccode\u003eNone\u003c/code\u003e but fails the check\u0026nbsp;\u003ccode\u003eboard.DISPLAY is None\u003c/code\u003e.\u0026nbsp;\u003ccode\u003esupervisor.runtime.display is None\u003c/code\u003e works correctly to check whether a default display is configured.\u003c/li\u003e\n\u003c/ul\u003e\n      ","metadata":{}},{"element_type":"text","content":"\n  \n        \u003ch2\u003eSetting \u003ccode\u003esupervisor.runtime.display\u003c/code\u003e\n\u003c/h2\u003e\n\u003cp\u003eThere are two approaches:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eDo it unconditionally in\u0026nbsp;\u003cstrong\u003eboot.py\u003c/strong\u003e and depend on this in \u003cstrong\u003ecode.py\u003c/strong\u003e\n\u003c/li\u003e\n\u003cli\u003eDo it conditionally in \u003cstrong\u003ecode.py\u003c/strong\u003e, if \u003ccode\u003esupervisor.runtime.display is None\u003c/code\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3\u003e... in \u003cstrong\u003eboot.py\u003c/strong\u003e\n\u003c/h3\u003e\n\u003cp\u003eHere's a code snippet that shows configuring a \u003ca href=\"https://www.adafruit.com/product/3787\"\u003e240x240 ST7789 display\u003c/a\u003e connected to an \u003ca href=\"https://www.adafruit.com/product/5772\"\u003eEyeSpi BFF\u003c/a\u003e on a QT Py board like the \u003ca href=\"https://www.adafruit.com/product/4900\"\u003eQT Py RP2040\u003c/a\u003e:\u003c/p\u003e\n      \n","metadata":{}},{"element_type":"code","content":"# Place in boot.py and then hard-reset your board\nimport board\nimport displayio\nimport fourwire\nimport supervisor\n\nfrom adafruit_st7789 import ST7789\n\ndisplayio.release_displays()\n\nspi = board.SPI()\ntft_cs = board.TX\ntft_dc = board.RX\n\ndisplay_bus = fourwire.FourWire(\n    spi, command=tft_dc, chip_select=tft_cs, reset=None\n)\n\nsupervisor.runtime.display = ST7789(display_bus, width=240, height=240, rowstart=80)","metadata":{"language":"python","linenums":false}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eThen, in your code.py, fetch the already-configured display like so:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"code","content":"import supervisor\n\ndisplay = supervisor.runtime.display","metadata":{"language":"python","linenums":false}},{"element_type":"text","content":"\n  \n  \n  \n  \n        \u003ch3\u003e... in \u003cstrong\u003ecode.py\u003c/strong\u003e\n\u003c/h3\u003e\n\u003cp\u003eThe first time through, the check \u003ccode\u003esupervisor.runtime.display is None\u003c/code\u003e will succeed, and the code inside the if-block will be run. When it finishes, it sets \u003ccode\u003esupervisor.runtime.display\u003c/code\u003e to the newly-created display.\u003c/p\u003e\n\u003cp\u003eOn the next run of \u003cstrong\u003ecode.py\u003c/strong\u003e, that block will be skipped, because \u003ccode\u003esupervisor.runtime.display\u003c/code\u003e will be the previously configured display, not \u003ccode\u003eNone\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eEither way, on the last line, the value of \u003ccode\u003esupervisor.runtime.display\u003c/code\u003e is grabbed and assigned to the \u003ccode\u003edisplay\u003c/code\u003e variable for use as normal.\u003c/p\u003e\n      \n\n\n\n","metadata":{}},{"element_type":"code","content":"import board\nimport displayio\nimport fourwire\nimport supervisor\n\nfrom adafruit_st7789 import ST7789\n\nif supervisor.runtime.display is None:\n    displayio.release_displays()\n\n    spi = board.SPI()\n    tft_cs = board.TX\n    tft_dc = board.RX\n\n    display_bus = fourwire.FourWire(\n        spi, command=tft_dc, chip_select=tft_cs, reset=None\n    )\n\n    supervisor.runtime.display = ST7789(display_bus, width=240, height=240, rowstart=80)\n    \ndisplay = supervisor.runtime.display","metadata":{"language":"auto","linenums":false}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eWith this variant, an existing display will be used if it is configured; otherwise, the display will be set up and assigned to the \u003ccode\u003esupervisor.runtime.display\u003c/code\u003e property so that on the next run it can be used without configuration.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n        \u003ch2\u003eCaveats\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eSetting \u003ccode\u003esupervisor.runtime.display\u003c/code\u003e in \u003cstrong\u003eboot.py\u003c/strong\u003e interacts poorly with fake deep sleep (\u003ca href=\"https://github.com/adafruit/circuitpython/issues/10070\"\u003e#10070\u003c/a\u003e)\u003c/li\u003e\n\u003c/ul\u003e\n      \n\n\n","metadata":{}}]