[{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/651/original/zephyr-display-sample-photo.jpeg?1740871226","metadata":{"caption":""}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n        \u003ch2\u003eOverview\u003c/h2\u003e\n      \n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eAs part of a series on Zephyr with Adafruit hardware, this guide shows how to configure Zephyr to use an ST7789 TFT display with a Feather RP2350. By connecting the display with a breadboard, we can use a logic analyzer to verify that the Zephyr display driver pin configuration agrees with the CircuitPython display driver. This guide is meant for people interested in adding support for Adafruit displays to Zephyr.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eOne of my eventual goals for the Zephyr Quest series of guides is to write a board definition for the Adafruit CLUE board. But, that's too much complexity to tackle all at once. For this guide, I'm aiming for three smaller intermediate goals:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eWalk through a specific example of bringing up an ST7798 TFT display on a board that has convenient SWD debug and UART serial connections. This will include making a pin mapping and translating the CircuitPython ST7789 driver's init sequence\u0026nbsp;\u003ca href=\"https://github.com/adafruit/Adafruit_CircuitPython_ST7789/blob/1.6.4/adafruit_st7789.py#L55-L64\" target=\"_blank\"\u003ebyte array\u003c/a\u003e into Zephyr Devicetree properties.\u003c/li\u003e\n\u003cli\u003eExplain Devicetree concepts that you need to know to configure Zephyr's\u0026nbsp; \u003ca href=\"https://docs.zephyrproject.org/latest/build/dts/api/bindings/display/sitronix%2Cst7789v.html\" target=\"_blank\"\u003esitronix,st7789v\u003c/a\u003e display driver\u003c/li\u003e\n\u003cli\u003eDemonstrate tips and tricks for working through problems that can happen when bringing up a new display in Zephyr. (compare logic analyzer captures, etc.)\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3\u003eOptional Stuff\u003c/h3\u003e\n\u003cp\u003eThis guide describes using a Raspberry Pi Debug Probe, Saleae logic analyzer, and 3D printed display stand. But, those are all optional:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eI like programming Zephyr firmware with \u003ccode\u003ewest flash\u003c/code\u003e and a debug probe. But, if you want, you can program firmware by copying UF2 files using the RP2350's built in USB bootloader.\u003c/li\u003e\n\u003cli\u003eYou don't need to use a Saleae logic analyzer to verify Devicetree pin configurations when bringing up a new display. If you want, you can just use trial and error until you get something that works.\u003c/li\u003e\n\u003cli\u003eI made a 3D printed stand for the breadboard and display because I like having the display at an angle that's easy to read. If you don't want to make a stand, you can skip it.\u003c/li\u003e\n\u003c/ul\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eParts\u003c/h3\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/6000","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/4311","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/5613","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/5462","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/64","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/5153","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/5699","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eTools \u0026amp; Materials\u003c/h3\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/152","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/527","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/1204","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/3174","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/1930","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/2512","metadata":{}},{"element_type":"product","content":"https://www.adafruit.com/product/400","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch2\u003eAssembly\u003c/h2\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n        \u003ch3\u003e3D Printing (optional)\u003c/h3\u003e\n\u003cp\u003eThis is optional. But, if you want to hold the TFT display up at an angle so it's easier to read, I designed a 3D printable stand using Blender. You can download the Blender file or printable STL file using the download buttons below. The download files are both zipped, so you will need to unzip them.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eNote:\u003c/strong\u003e Not all breadboards are the same size. I made this stand to fit a random breadboard I had lying around, and I'm not sure which brand it was. The opening for the breadboard is 84.0 mm wide by 55.2 mm deep. If you need more space, you can edit the .blend file.\u003c/p\u003e\n      \n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/652/original/blender-stand-front.png?1740871503","metadata":{"caption":""}},{"element_type":"button","content":"https://github.com/samblenny/zphqst-02/releases/download/v0.2.1/breadboard-tft-stand.blend.zip","metadata":{"class":"btn btn-large btn-block btn-primary","button_type":"primary","target":"_blank","zip_folder":"false"}},{"element_type":"button","content":"https://github.com/samblenny/zphqst-02/releases/download/v0.2.1/breadboard-tft-stand.stl.zip","metadata":{"class":"btn btn-large btn-block btn-primary","button_type":"primary","target":"_blank","zip_folder":"false"}},{"element_type":"text","content":"\n        \u003cp\u003eIf you want to experiment with the Blender file, there are Blender screenshots in the \u003ca href=\"https://github.com/samblenny/zphqst-02/tree/main/media\" target=\"_blank\"\u003ezphqst-02/media/\u003c/a\u003e directory of the GitHub repo for this guide. The screenshots may help you to understand how I used the boolean difference and bevel modifiers.\u003c/p\u003e\n\u003cp\u003eThe stand's holes for the breadboard and display were made to have 1mm of clearance on all sides, relative to caliper measurements of a random half-sized breadboard I grabbed from my parts pile. The horizontal alignment between the display and breadboard is a few mm away from ideal, so the cable may twist slightly. You can try to fix it in Blender if you want. For me, it was close enough, so I didn't bother making a second print. Before printing this, I recommend comparing caliper measurements of your breadboard to the .blend or .stl file.\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n      ","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eWiring\u003c/h3\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/653/original/Fritzing-diagram-Feather-EYESPI-Display.jpeg?1740871538","metadata":{"caption":""}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003col\u003e\n\u003cli\u003eSolder Feather headers using a\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003ca href=\"https://www.adafruit.com/product/64\" target=\"_blank\"\u003ebreadboard\u003c/a\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003eto hold the pins. If you are unfamiliar with soldering headers, you might want to read:\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://learn.adafruit.com/adafruit-guide-excellent-soldering/tools\" target=\"_blank\"\u003eAdafruit Guide To Excellent Soldering\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://learn.adafruit.com/how-to-solder-headers\" target=\"_blank\"\u003eHow To Solder Headers\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eSolder EYESPI breakout board headers.\u003c/li\u003e\n\u003cli\u003eArrange the feather and EYESPI breakout on a half-size breadboard as shown in the Fritzing diagram above.\u0026nbsp;\u003cstrong\u003eNote:\u003c/strong\u003e If you want to connect a logic analyzer, make sure the EYESPI breakout board is shifted one row above the center of the breadboard, leaving a row of holes open for logic analyzer wires.\u003c/li\u003e\n\u003cli\u003eUse diagonal flush cutters, wire strippers, and \u003cstrong\u003ered hookup wire\u003c/strong\u003e to connect the \u003cstrong\u003eFeather 3.3V\u003c/strong\u003e pin to the \u003cstrong\u003eEYESPI Breakout Vin\u003c/strong\u003e pin. If you are unfamiliar with breadboard wiring, you might want to read:\n\u003cul\u003e\n\u003cli\u003e\n\u003ca href=\"https://learn.adafruit.com/breadboards-for-beginners/diy-jumper-wires\" target=\"_blank\"\u003eBreadboards for Beginners\u003c/a\u003e (\"Jumper Wires\" section)\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eConnect \u003cstrong\u003eFeather GND\u003c/strong\u003e to \u003cstrong\u003eEYESPI Gnd\u003c/strong\u003e with \u003cstrong\u003eblack wire.\u003c/strong\u003e\n\u003c/li\u003e\n\u003cli\u003eConnect \u003cstrong\u003eFeather MO\u003c/strong\u003e\u0026nbsp;to \u003cstrong\u003eEYESPI MOSI\u003c/strong\u003e with a different color of wire (e.g. gray).\u003c/li\u003e\n\u003cli\u003eConnect \u003cstrong\u003eFeather SCK\u003c/strong\u003e to \u003cstrong\u003eEYESPI SCK\u003c/strong\u003e with a different color of wire (e.g. yellow).\u003c/li\u003e\n\u003cli\u003eConnect \u003cstrong\u003eFeather D5\u003c/strong\u003e to \u003cstrong\u003eEYESPI TCS\u003c/strong\u003e with a different color of wire (e.g. orange).\u003c/li\u003e\n\u003cli\u003eConnect \u003cstrong\u003eFeather D6\u003c/strong\u003e to \u003cstrong\u003eEYESPI DC\u003c/strong\u003e with a different color of wire (e.g. green).\u003c/li\u003e\n\u003cli\u003eConnect \u003cstrong\u003eFeather D9\u003c/strong\u003e to \u003cstrong\u003eEYESPI RST\u003c/strong\u003e with a different color of wire (e.g. blue).\u003c/li\u003e\n\u003cli\u003eCarefully flip the \u003cstrong\u003eTFT Display'\u003c/strong\u003es EYESPI connector \u003cstrong\u003eclamp\u003c/strong\u003e to the open position (pointing up) using your fingernail, a spudger, a trimmed chopstick, or whatever. If you are unfamiliar with FPC flex cable connectors, you might want to read:\n\u003cul\u003e\n\u003cli\u003e\n\u003ca href=\"https://learn.adafruit.com/adafruit-eyespi-breakout-board/plugging-in-an-eyespi-cable\" target=\"_blank\"\u003eAdafruit EYESPI Breakout Board\u003c/a\u003e (\"Plugging in an EYESPI Cable\" section)\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eInsert one end of the \u003cstrong\u003e50mm EYESPI flex cable\u003c/strong\u003e in the \u003cstrong\u003e18-pin connector\u003c/strong\u003e with the blue side facing towards you and away from the display's PCB.\u003c/li\u003e\n\u003cli\u003eMake sure the cable is centered, straight, and fully inserted, then carefully \u003cstrong\u003eclose the clamp\u003c/strong\u003e.\u003c/li\u003e\n\u003cli\u003eFlip the display over and connect the \u003cstrong\u003eother end of the EYESPI flex cable\u003c/strong\u003e to the \u003cstrong\u003eEYESPI breakout\u003c/strong\u003e (blue side facing toward you and away from the PCB).\u003c/li\u003e\n\u003cli\u003e(optional) If you 3D printed a stand for the display and breadboard, move the breadboard and TFT display to the stand now.\u003c/li\u003e\n\u003cli\u003eLook at the top of the\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003ca href=\"https://www.adafruit.com/product/5699\" target=\"_blank\"\u003ePi Debug Probe\u003c/a\u003e. On the enclosure lid, above the 3-pin female connectors, you should see the letters \"U\" and \"D\" molded into the plastic.\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003cstrong\u003eU\u003c/strong\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003eis over the\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003cstrong\u003eUART serial port\u003c/strong\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003eand\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003cstrong\u003eD\u003c/strong\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003eis over the\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003cstrong\u003eSWD debug port\u003c/strong\u003e.\u003c/li\u003e\n\u003cli\u003eConnect the probe's\u0026nbsp;\u003cstrong\u003egray cable\u003c/strong\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003efrom its\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003cstrong\u003eD port\u003c/strong\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003eto the\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003cstrong\u003eFeather Debug\u003c/strong\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003e(SWD) connector.\u003c/li\u003e\n\u003cli\u003eConnect the probe's\u0026nbsp;\u003cstrong\u003eOrange/Black/Yellow male header cable\u003c/strong\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003efrom its\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003cstrong\u003eU port\u003c/strong\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003eto the\u0026nbsp;\u003cstrong\u003eFeather serial pins\u003c/strong\u003e:\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003eOrange wire\u003c/strong\u003e: probe serial TX; connects to\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003cstrong\u003eFeather RX\u003c/strong\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eBlack wire\u003c/strong\u003e: probe GND; connects to\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003cstrong\u003eFeather GND\u003c/strong\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eYellow wire\u003c/strong\u003e: probe serial RX; connects to\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003cstrong\u003eFeather TX\u003c/strong\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eConnect the Pi Debug Probe to your computer with a USB A to Micro B data cable, such as the one that came with the Pi Debug Probe (CAUTION: charge-only cables won't work!)\u003c/li\u003e\n\u003cli\u003eConnect the Feather RP2350 to your computer with a\u003cspan\u003e USB C data cable\u003c/span\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003e(CAUTION: charge-only cables won't work!)\u003c/li\u003e\n\u003c/ol\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eLogic Analyzer (optional)\u003c/h3\u003e\n\u003cp\u003eIf you want to connect a logic analyzer, begin by making sure the EYESPI breakout and jumper wires are arranged on your breadboard to leave a row of holes open for connecting logic analyzer wires.\u003c/p\u003e\n\u003cp\u003eUse male-to-male pin headers to connect the Saleae wiring harness to the EYESPI signals like so:\u003c/p\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003ctable\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e\u003cstrong\u003eEYESPI\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003cstrong\u003eSaleae Wire Color\u003c/strong\u003e\u003c/td\u003e\n\u003ctd\u003e\u003cstrong\u003eSaleae Wire #\u003c/strong\u003e\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eSCK\u003c/td\u003e\n\u003ctd\u003eblack\u003c/td\u003e\n\u003ctd\u003e0\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eMOSI\u003c/td\u003e\n\u003ctd\u003ebrown\u003c/td\u003e\n\u003ctd\u003e1\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eMISO\u003c/td\u003e\n\u003ctd\u003ered\u003c/td\u003e\n\u003ctd\u003e2\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eDC\u003c/td\u003e\n\u003ctd\u003eorange\u003c/td\u003e\n\u003ctd\u003e3\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eRST\u003c/td\u003e\n\u003ctd\u003eyellow\u003c/td\u003e\n\u003ctd\u003e4\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eTCS\u003c/td\u003e\n\u003ctd\u003egreen\u003c/td\u003e\n\u003ctd\u003e5\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e\u0026nbsp;\u003c/p\u003e\n\u003cp\u003eAlso connect some of the logic analyzer's black \u003cstrong\u003eground wires\u003c/strong\u003e to the \u003cstrong\u003ebreadboard's ground row\u003c/strong\u003e.\u003c/p\u003e\n\u003cp\u003eIn Saleae's \u003ca href=\"https://www.saleae.com/pages/downloads\" target=\"_blank\"\u003eLogic 2\u003c/a\u003e app, \u003ca href=\"https://support.saleae.com/user-guide/using-logic/navigating-the-software\" target=\"_blank\"\u003econfigure\u003c/a\u003e \u003cstrong\u003echannels 0 through 5 for digital input\u003c/strong\u003e and add an\u0026nbsp;\u003ca href=\"https://support.saleae.com/user-guide/using-logic/using-protocol-analyzers\" target=\"_blank\"\u003eSPI analyzer\u003c/a\u003e with \u003cstrong\u003eSCK\u003c/strong\u003e on \u003cstrong\u003echannel 0\u003c/strong\u003e, \u003cstrong\u003eMOSI\u003c/strong\u003e on \u003cstrong\u003echannel 1\u003c/strong\u003e, and \u003cstrong\u003eMISO\u003c/strong\u003e on \u003cstrong\u003echannel 2\u003c/strong\u003e. If you want, edit the channel labels to match the signal names. For more details on using Saleae's Logic 2 software, check out the \u003ca href=\"https://support.saleae.com/user-guide/using-logic\" target=\"_blank\"\u003eUsing Logic\u003c/a\u003e section of their online manual.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch2\u003eCircuitPython Wiring Test\u003c/h2\u003e\n\u003cp\u003eBefore moving on to the Zephyr stuff, I suggest testing that your hardware modules and wiring are working as expected. To do that:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eInstall CircuitPython\u003c/li\u003e\n\u003cli\u003eInstall the project bundle code which will print a test message to the display\u003c/li\u003e\n\u003cli\u003e(optional) Start a Saleae logic analyzer capture\u003c/li\u003e\n\u003cli\u003ePower up the Feather RP2350 board to run the code and verify that the display works\u003c/li\u003e\n\u003c/ol\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eInstall CircuitPython 9.2.4\u003c/h3\u003e\n\u003cp class=\"p1\"\u003eTo prepare for running the CircuitPython display test code, you need to install CircuitPython 9.2.4. To download the Feather RP2350 CircuitPython 9.2.4 .UF2 file, you can use this direct link to circuitpython.org:\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://downloads.circuitpython.org/bin/adafruit_feather_rp2350/en_US/adafruit-circuitpython-adafruit_feather_rp2350-en_US-9.2.4.uf2\" target=\"_blank\"\u003eAdafruit Feather RP2350\u003c/a\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003e(9.2.4 .UF2 file)\u003c/p\u003e\n\u003cp class=\"p1\"\u003eIf you prefer to try running the latest version of CircuitPython, you can use the .UF2 download button from the board detail page at circuitpython.org:\u003c/p\u003e\n\u003cp class=\"p1\"\u003e\u003ca href=\"https://circuitpython.org/board/adafruit_feather_rp2350/\" target=\"_blank\"\u003eFeather RP2350\u003c/a\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003e(board page)\u003c/p\u003e\n\u003cp class=\"p1\"\u003eOnce you have the .UF2 file, follow the instructions on the \u003ca href=\"https://learn.adafruit.com/adafruit-feather-rp2350/install-circuitpython-2\" target=\"_blank\"\u003eInstall CircuitPython\u003c/a\u003e page of the \"Adafruit Feather RP2350 with HSTX\" Learn Guide to install CircuitPython.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3 class=\"p1\"\u003eInstall Project Bundle\u003c/h3\u003e\n\u003cp class=\"p2\"\u003e\u003cspan class=\"s1\"\u003eTo install the CircuitPython code, copy the project bundle files to your CIRCUITPY drive:\u003c/span\u003e\u003c/p\u003e\n\u003col class=\"ol1\"\u003e\n\u003cli class=\"li3\"\u003e\u003cspan class=\"s1\"\u003eDownload the project bundle .zip file using the \"Download Project Bundle\" button below.\u003c/span\u003e\u003c/li\u003e\n\u003cli class=\"li3\"\u003e\u003cspan class=\"s1\"\u003eExpand the zip file by opening it, or use\u0026nbsp;unzip\u0026nbsp;in a Terminal. The zip archive should expand to a folder. When you open the folder, it should contain a\u0026nbsp;README.txt\u0026nbsp;file and a\u0026nbsp;CircuitPython 9.x\u0026nbsp;folder.\u003c/span\u003e\u003c/li\u003e\n\u003cli class=\"li3\"\u003e\u003cspan class=\"s1\"\u003eOpen the CircuitPython 9.x folder and copy all of its contents to your CIRCUITPY drive.\u003c/span\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp class=\"p2\"\u003e\u003cspan class=\"s1\"\u003eTo learn more about copying libraries to your\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003cstrong\u003eCIRCUITPY\u003c/strong\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003edrive, check out the\u0026nbsp;\u003ca href=\"https://learn.adafruit.com/welcome-to-circuitpython/circuitpython-libraries\" target=\"_blank\"\u003e\u003cspan class=\"s2\"\u003eCircuitPython Libraries\u003c/span\u003e\u003c/a\u003e\u0026nbsp;section of the\u0026nbsp;\u003ca href=\"https://learn.adafruit.com/welcome-to-circuitpython\" target=\"_blank\"\u003e\u003cspan class=\"s2\"\u003eWelcome to CircuitPython!\u003c/span\u003e\u003c/a\u003e learn guide.\u003c/span\u003e\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"button","content":"https://github.com/samblenny/zphqst-02/releases/download/v0.2.1/zphqst-02-b8aee51.zip","metadata":{"class":"btn btn-large btn-block btn-primary","button_type":"primary","target":"_blank","zip_folder":"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  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003e\u003cspan class=\"s1\"\u003eAfter copying the files from the project bundle, your\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003cstrong\u003eCIRCUITPY\u003c/strong\u003e\u003cspan\u003e\u0026nbsp;\u003c/span\u003edrive should contain the files and directories shown in this screenshot:\u003c/span\u003e\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/654/original/CIRCUITPY-drive-screenshot.png?1740871603","metadata":{"caption":""}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eCircuitPython Code\u003c/h3\u003e\n\u003cp\u003eThis is what the code looks like:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"embed","content":"https://github.com/samblenny/zphqst-02/blob/v0.2.1/code.py"},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003ePhoto \u0026amp; Saleae Captures\u003c/h3\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eWhen you run code.py, the display should show a purple background with large text reading, \"CircuitPython Wiring Test: Feather RP2350 + ST7789\", like this:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/655/original/circuitpython-wiring-test.jpeg?1740871659","metadata":{"caption":""}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eThis is how it looked when I took a Saleae logic analyzer capture of powering up the Feather RP2350 with the wiring test firmware:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/658/original/Saleae-CircuitPython-Display-Demo-Capture-1.png?1740872070","metadata":{"caption":""}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eHere is a zoomed in view showing the sequencing of the data/command (DC) and chip select (TCS) pins relative to SCK and MOSI as the CircuitPython ST7789 driver is initializing the display (note how DC is low for the command and high for the command's data parameter... that will be important later):\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/657/original/Saleae-CircuitPython-Display-Demo-Capture-2.png?1740871836","metadata":{"caption":""}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eThe point of taking these captures is to establish a baseline of what the signals should look like for a working display initialization. As I write the Zephyr Devicetree configuration, I will make sure that the Zephyr MIPI display driver is using the pins in the same way (chip select is active low, etc.).\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch2\u003eZephyr Stuff\u003c/h2\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eDev Tool Setup\u003c/h3\u003e\n\u003cp\u003eThis guide builds on top of the same Zephyr workspace and developer tools described in my \u003ca href=\"https://adafruit-playground.com/u/SamBlenny/pages/zephyr-quest-feather-rp2350-board-def\" target=\"_blank\"\u003eZephyr Quest: Feather RP2350 Board Def\u003c/a\u003e guide. To follow along with this guide, you will need:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eZephyr workspace with \u003ccode\u003ewest\u003c/code\u003e and the Zephyr SDK's \u003cspan\u003e\u003ccode\u003earm-zephyr-eabi\u003c/code\u003e toolchain\u003c/span\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003cspan\u003e(optional) The Raspberry Pi version of\u0026nbsp;\u003ccode\u003eopenocd\u003c/code\u003e including their patches for RP2350 support. (alternately, you can program the Feather RP2350 with UF2 files and the factory bootloader)\u003c/span\u003e\u003c/li\u003e\n\u003cli\u003e\u003cspan\u003e(optional) A git cloned copy of my \u003ca href=\"https://github.com/samblenny/zphqst-02\" target=\"_blank\"\u003ezphqst-02\u003c/a\u003e GitHub repo with the EYESPI and TFT display shield definitions described in this guide. (alternately, you can copy and paste the code from this guide)\u003c/span\u003e\u003c/li\u003e\n\u003cli\u003e\u003cspan\u003eFeather RP2350 board definition: you can get this from my zphqst-02 repo or from the \u003ca href=\"https://github.com/adafruit/adafruit-zephyr-support\" target=\"_blank\"\u003eadafruit/adafruit-zephyr-support\u003c/a\u003e GitHub repository\u003c/span\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eHere's an example of what it might look like to clone the zphqst-02 repo into your Zephyr workspace directory using a terminal and bash shell on Debian Linux:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\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":"$ cd ~/code/zephyr-workspace/\n$ source .venv/bin/activate\n(.venv) $ git clone https://github.com/samblenny/zphqst-02.git\n(.venv) $ ls\nadafruit-zephyr-support  modules  tools   zphqst-01\nbootloader               openocd  zephyr  zphqst-02\n(.venv) $ cd zphqst-02\n(.venv) $ ls\nboards   bundle_builder.py    code.py   Makefile  README.md\nboot.py  bundle_manifest.cfg  LICENSES  media\n(.venv) $","metadata":{"language":"terminal","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  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eWhat is a Shield Definition?\u003c/h3\u003e\n\u003cp\u003eZephyr uses adapted versions of the Kconfig and Devicetree systems from the Linux kernel to manage modular configuration of software and hardware. Both systems allow for building up a single data structure that merges fragments of configuration from different sources. This approach allows software features to be structured into modules, where code and related configuration fragments can exist side by side in the same folder. The advantage is, you don't have to navigate though one gigantic configuration file. The disadvantage is, you may need to cross-reference several configuration fragment files to get a clear picture of the actual configuration being used.\u003c/p\u003e\n\u003cp\u003eBoard definitions include configuration files describing what hardware is soldered onto the board and which software modules are necessary to make that hardware function. Shield definitions add configuration to enable support for hardware add-on modules that can be connected to a board, such as Arduino shields or Adafruit FeatherWings.\u003c/p\u003e\n\u003cp\u003eSuppose you have a board, like the Feather RP2350, and that you want to use it with a TFT display which uses the ST7789V controller chip. Zephyr has a MIPI driver for the ST7789V. To use the display, you need to make sure the driver gets compiled in, and you need to configure the display driver with a mapping of which GPIO and SPI pins to use for which signals. You can do those things by creating a shield definition. It's also possible to combine more than one shield.\u003c/p\u003e\n\u003cp\u003eTo use a shield, you can provide an option to \u003ccode\u003ewest build\u003c/code\u003e, such as \u003ccode\u003e--shield NAME_OF_SHIELD\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eTo learn more, you can read the Zephyr project's \u003ca href=\"https://docs.zephyrproject.org/latest/hardware/porting/shields.html\" target=\"_blank\"\u003eShields\u003c/a\u003e documentation page.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eWhat is a GPIO Nexus Node?\u003c/h3\u003e\n\u003cp\u003eTo map pins from a board to a standardized connector such as the Feather header, Zephyr shield definitions use a Devicetree structure called a GPIO nexus node. The Zephyr project's \u003ca href=\"https://docs.zephyrproject.org/latest/hardware/porting/shields.html#gpio-nexus-nodes\" target=\"_blank\"\u003eGPIO nexus nodes\u003c/a\u003e documentation is brief. To understand how nexus nodes work, I found the Devicetree v0.4 Specification's \u003ca href=\"https://github.com/devicetree-org/devicetree-specification/blob/v0.4/source/chapter2-devicetree-basics.rst#nexus-nodes-and-specifier-mapping\" target=\"_blank\"\u003eNexus Nodes and Specifier Mapping\u003c/a\u003e section helpful.\u003c/p\u003e\n\u003cp\u003eWhen you get past the confusing syntax, it turns out that GPIO Nexus Nodes are, more or less, just an implementation of an associative array data structure. There's some subtlety because the nexus node \"specifiers\" sometimes encode pin mode information in their low bits. The\u0026nbsp;\u003ccode\u003e#gpio-cells\u003c/code\u003e, \u003ccode\u003egpio-map-mask\u003c/code\u003e, and \u003ccode\u003egpio-map-pass-thru\u003c/code\u003e settings are part of the mechanism for encoding pin mode information. But, approximately, the nexus nodes function similarly to a Python dictionary literal.\u003c/p\u003e\n\u003cp\u003eFor example, consider this Python REPL example with two dictionary literals:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\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":"\u003e\u003e\u003e feather_header = {6: (6,0,\"SCK\"), 7: (7,0,\"MOSI\"), 8: (8,0,\"MISO\")}\n\u003e\u003e\u003e eyespi = {3: feather_header[6], 4: feather_header[7], 5: feather_header[8]}\n\u003e\u003e\u003e print(eyespi)\n{3: (6, 0, 'SCK'), 4: (7, 0, 'MOSI'), 5: (8, 0, 'MISO')}","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  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003e\u003cspan\u003eThat pin mapping represented by the\u0026nbsp;\u003c/span\u003e\u003ccode\u003eeyespi\u003c/code\u003e\u003cspan\u003e\u0026nbsp;dictionary above is expressing a similar meaning as this Devicetree GPIO nexus node:\u003c/span\u003e\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\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":"/ {\n  eyespi: connector {\n    compatible = \"eyespi\";\n    #gpio-cells = \u003c2\u003e;\n    gpio-map-mask = \u003c0xffffffff 0xffffffc0\u003e;\n    gpio-map-pass-thru = \u003c0 0x3f\u003e;\n    gpio-map =\n      \u003c 3 0  \u0026feather 6 0\u003e,  /* eyespi SCK   = feather SCK  */\n      \u003c 4 0  \u0026feather 7 0\u003e,  /* eyespi MOSI  = feather MOSI */\n      \u003c 5 0  \u0026feather 8 0\u003e;  /* eyespi MISO  = feather MISO */\n  };\n};","metadata":{"language":"cpp","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  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eFeather RP2350 Board Def\u003c/h3\u003e\n\u003cp\u003eThis guide uses an updated version of my \u003ccode\u003efeather_rp2350\u003c/code\u003e board definition from\u0026nbsp;the \u003ca href=\"https://adafruit-playground.com/u/SamBlenny/pages/zephyr-quest-feather-rp2350-board-def\" target=\"_blank\"\u003eZephyr Quest: Feather RP2350 Board Def\u003c/a\u003e guide. The main difference is the improved version includes a \u003ccode\u003efeather_header\u003c/code\u003e pin mapping, which includes a GPIO nexus node.\u003c/p\u003e\n\u003cp\u003eThis is a copy of the \u003ccode\u003efeather_connector.dtsi\u003c/code\u003e file that defines the \u003ccode\u003efeather_header\u003c/code\u003e pin mapping:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"embed","content":"https://github.com/samblenny/zphqst-02/blob/v0.2.1/boards/adafruit/feather_rp2350/feather_connector.dtsi"},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eThere are several other files involved in the board definition. If you're curious you can check out the full set of board definition files in my GitHub repo at:\u0026nbsp;\u003ca href=\"https://github.com/samblenny/zphqst-02/tree/main/boards/adafruit/feather_rp2350\" target=\"_blank\"\u003ezphqst-02/boards/adafruit/feather_rp2350\u003c/a\u003e.\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n        \u003ch3\u003eEYESPI Breakout Shield\u003c/h3\u003e\n\u003cp\u003eThe two files below will make a shield called \u003ccode\u003eeyespi_mipi\u003c/code\u003e if you put them in a \u003ccode\u003eboards/shields/eyespi_mipi\u003c/code\u003e directory. The point of this shield is to translate Feather header pin specifiers into EYESPI pin specifiers. With that translation in place, we can make a second shield that just refers to EYESPI pin specifiers without worrying about what sort of board or shield those connector pins might be wired up to.\u003c/p\u003e\n\u003cp\u003eFor example, in theory, I could make a shield for the \u003ca href=\"https://www.adafruit.com/product/5967\" target=\"_blank\"\u003eAdafruit Proto Tripler PiCowbell\u003c/a\u003e, which includes an EYESPI connector, and reuse the ST7789 display shield from this guide with the Tripler PiCowbell and a Raspberry Pi Pico.\u003c/p\u003e\n\u003cp\u003eThese are the files for the EYESPI Breakout shield:\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eboards/shields/eyespi_mipi/Kconfig.shield:\u003c/strong\u003e\u003c/p\u003e\n      \n\n\n\n","metadata":{}},{"element_type":"embed","content":"https://github.com/samblenny/zphqst-02/blob/v0.2.1/boards/shields/eyespi_mipi/Kconfig.shield"},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003e\u003cstrong\u003eboards/shields/eyespi_mipi/eyespi_mipi.overlay:\u003c/strong\u003e\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"embed","content":"https://github.com/samblenny/zphqst-02/blob/v0.2.1/boards/shields/eyespi_mipi/eyespi_mipi.overlay"},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eCircuitPython Init Sequence\u003c/h3\u003e\n\u003cp\u003eMy goal here is to get the Zephyr display driver working as well as the CircuitPython display driver. So, by looking at how the CircuitPython driver initializes the display we can prepare for configuring the Zephyr driver.\u003c/p\u003e\n\u003cp\u003eCircuitPython's ST7789 driver specifies display initialization using a\u0026nbsp;\u003ca href=\"https://github.com/adafruit/Adafruit_CircuitPython_ST7789/blob/1.6.4/adafruit_st7789.py#L55-L64\" target=\"_blank\"\u003ebyte string\u003c/a\u003e\u003cspan\u003e that holds an encoded\u0026nbsp;\u003c/span\u003esequence of MIPI commands and variable length delays. DisplayIO decodes the byte string and sends the commands to the display with the requested timing.\u003c/p\u003e\n\u003cp\u003eInstead of hand-decoding the byte string, I just ran the code with a Saleae logic analyzer hooked up to the EYESPI pins. To understand what those MIPI display control commands were doing, I cross-referenced the command and data bytes from Saleae's SPI analyzer against the\u0026nbsp;\u003ca href=\"https://newhavendisplay.com/content/datasheets/ST7789V.pdf\" target=\"_blank\"\u003eST7798V datasheet\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eThis screenshot shows the CircuitPython MIPI commands to reset and initialize the display:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/656/original/Saleae-CircuitPython-Init-Sequence.png?1740871799","metadata":{"caption":""}},{"element_type":"markdown","content":"\u003cp\u003eThis table has a transcription of the timing marker annotations from the screenshot, plus some extra notes from the ST7789V datasheet:\u003c/p\u003e\n\n\u003ctable\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003cth\u003eSPI\u003c/th\u003e\n\u003cth\u003eCMD / Data\u003c/th\u003e\n\u003cth\u003eDelay\u003c/th\u003e\n\u003cth\u003eDescription\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003e0x01\u003c/td\u003e\n\u003ctd\u003eSWRESET\u003c/td\u003e\n\u003ctd\u003e150ms\u003c/td\u003e\n\u003ctd\u003esoftware reset\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e0x11\u003c/td\u003e\n\u003ctd\u003eSLPOUT\u003c/td\u003e\n\u003ctd\u003e500ms\u003c/td\u003e\n\u003ctd\u003esleep out\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e0x3A\u003c/td\u003e\n\u003ctd\u003eCOLMOD\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003ctd\u003einterface pixel format\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e0x55\u003c/td\u003e\n\u003ctd\u003e(data)\u003c/td\u003e\n\u003ctd\u003e10ms\u003c/td\u003e\n\u003ctd\u003e65K of RGB data (0b101) at 16bit/pixel (0b101)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e0x36\u003c/td\u003e\n\u003ctd\u003eMADCTL\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003ctd\u003ememory data access control\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e0x08\u003c/td\u003e\n\u003ctd\u003e(data)\u003c/td\u003e\n\u003ctd\u003e10ms\u003c/td\u003e\n\u003ctd\u003eMY: top to bot, MX: L to R, MV: normal, ML: top to bot, RGB: BGR, MH: L to R\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e0x21\u003c/td\u003e\n\u003ctd\u003eINVON\u003c/td\u003e\n\u003ctd\u003e10ms\u003c/td\u003e\n\u003ctd\u003edisplay inversion\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e0x13\u003c/td\u003e\n\u003ctd\u003eNORON\u003c/td\u003e\n\u003ctd\u003e10ms\u003c/td\u003e\n\u003ctd\u003epartial off (normal)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e0x36\u003c/td\u003e\n\u003ctd\u003eMADCTL\u003c/td\u003e\n\u003ctd\u003e\u003c/td\u003e\n\u003ctd\u003ememory data access control\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e0xC0\u003c/td\u003e\n\u003ctd\u003e(data)\u003c/td\u003e\n\u003ctd\u003e10ms\u003c/td\u003e\n\u003ctd\u003eMY: bot to top, MX: R to L, MV: normal, ML: top to bot, RGB: RGB, MH: L to R\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e0x29\u003c/td\u003e\n\u003ctd\u003eDISPON\u003c/td\u003e\n\u003ctd\u003e500ms\u003c/td\u003e\n\u003ctd\u003edisplay on\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003cp\u003e \u003c/p\u003e\n\n\u003cp\u003eSome notes on what those commands are doing:\u003c/p\u003e\n\n\u003cul\u003e\n\u003cli\u003eCOLMOD command specifies framebuffer format is 16-bit RGB565\u003c/li\u003e\n\u003cli\u003eFirst MADCTL command sets top-to-bottom, left-to-right rotation with BGR color order\u003c/li\u003e\n\u003cli\u003eSecond MADCTL command changes to bottom-to-top, right-to-left rotation with RGB color order\u003c/li\u003e\n\u003c/ul\u003e\n","metadata":{"markdown":"This table has a transcription of the timing marker annotations from the screenshot, plus some extra notes from the ST7789V datasheet:\n\n| SPI  | CMD / Data | Delay | Description |\n| ---- | ---------- | ----- | ----------- | \n| 0x01 | SWRESET    | 150ms | software reset |\n| 0x11 | SLPOUT     | 500ms | sleep out |\n| 0x3A | COLMOD     |       | interface pixel format |\n| 0x55 | (data)     |  10ms | 65K of RGB data (0b101) at 16bit/pixel (0b101) |\n| 0x36 | MADCTL     |       | memory data access control |\n| 0x08 | (data)     |  10ms | MY: top to bot, MX: L to R, MV: normal, ML: top to bot, RGB: BGR, MH: L to R |\n| 0x21 | INVON      |  10ms | display inversion |\n| 0x13 | NORON      |  10ms | partial off (normal) |\n| 0x36 | MADCTL     |       | memory data access control |\n| 0xC0 | (data)     |  10ms | MY: bot to top, MX: R to L, MV: normal, ML: top to bot, RGB: RGB, MH: L to R |\n| 0x29 | DISPON     | 500ms | display on |\n\n\u0026amp;nbsp;\n\nSome notes on what those commands are doing:\n- COLMOD command specifies framebuffer format is 16-bit RGB565\n- First MADCTL command sets top-to-bottom, left-to-right rotation with BGR color order\n- Second MADCTL command changes to bottom-to-top, right-to-left rotation with RGB color order\n\n"}},{"element_type":"text","content":"\n  \n  \n  \n        \u003ch3\u003eZephyr sitronix,st7789v Driver\u003c/h3\u003e\n\u003cp\u003eCompared to the CircuitPython ST7789 driver, Zephyr's\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003ca href=\"https://docs.zephyrproject.org/latest/build/dts/api/bindings/display/sitronix%2Cst7789v.html\" target=\"_blank\"\u003esitronix,st7789v\u003c/a\u003e driver takes a different approach. The Zephyr driver requires many display register values to be specified as Devicetree parameters, even if you don't actually need to change the display's defaults. The driver hardcodes a sequence of\u0026nbsp;\u003ca href=\"https://github.com/zephyrproject-rtos/zephyr/blob/v4.1.0-rc3/drivers/display/display_st7789v.c#L403\" target=\"_blank\"\u003edelays and MIPI commands\u003c/a\u003e, but the data parameter values come from Devicetree properties.\u003c/p\u003e\n\u003cp\u003eMany of the required Devicetree properties are not set by the CircuitPython driver, so I had to look up default values in the\u003cspan\u003e\u0026nbsp;\u003c/span\u003e\u003ca href=\"https://newhavendisplay.com/content/datasheets/ST7789V.pdf\" target=\"_blank\"\u003eST7798V datasheet\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eTo keep things organized and assist with cross-referencing, I created a table of Devicetree properties, C struct field names, header file \u003ccode\u003e#define\u003c/code\u003e constants, MIPI command hex values, and default values from the datasheet. The struct fields and defined constants come from \u003ca href=\"https://github.com/zephyrproject-rtos/zephyr/blob/v4.1.0-rc3/drivers/display/display_st7789v.c\" target=\"_blank\"\u003edisplay_st7789v.c\u003c/a\u003e and \u003ca href=\"https://github.com/zephyrproject-rtos/zephyr/blob/v4.1.0-rc3/drivers/display/display_st7789v.h\" target=\"_blank\"\u003edisplay_st7789v.h\u003c/a\u003e in the Zephyr GitHub repository.\u003c/p\u003e\n      \n\n\n","metadata":{}},{"element_type":"markdown","content":"\u003ctable\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003cth\u003eDevicetree\u003c/th\u003e\n\u003cth\u003eStruct\u003c/th\u003e\n\u003cth\u003eDefine\u003c/th\u003e\n\u003cth\u003eHex\u003c/th\u003e\n\u003cth\u003eDatasheet Default\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd\u003evcom\u003c/td\u003e\n\u003ctd\u003e.vcom\u003c/td\u003e\n\u003ctd\u003eST7789V_CMD_VCOMS\u003c/td\u003e\n\u003ctd\u003e0xbb\u003c/td\u003e\n\u003ctd\u003e0x20\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003egctrl\u003c/td\u003e\n\u003ctd\u003e.gctrl\u003c/td\u003e\n\u003ctd\u003eST7789V_CMD_GCTRL\u003c/td\u003e\n\u003ctd\u003e0xb7\u003c/td\u003e\n\u003ctd\u003e0x35\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003emdac\u003c/td\u003e\n\u003ctd\u003e.mdac\u003c/td\u003e\n\u003ctd\u003eST7789V_CMD_MADCTL\u003c/td\u003e\n\u003ctd\u003e0x36\u003c/td\u003e\n\u003ctd\u003euse CircuitPython 0x0C\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003egamma\u003c/td\u003e\n\u003ctd\u003e.gamma\u003c/td\u003e\n\u003ctd\u003eST7789V_CMD_GAMSET\u003c/td\u003e\n\u003ctd\u003e0x26\u003c/td\u003e\n\u003ctd\u003e0x01 (gamma 2.2)\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003ecolmod\u003c/td\u003e\n\u003ctd\u003e.colmod\u003c/td\u003e\n\u003ctd\u003eST7789V_CMD_COLMOD\u003c/td\u003e\n\u003ctd\u003e0x3a\u003c/td\u003e\n\u003ctd\u003euse CircuitPython 0x55\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003elcm\u003c/td\u003e\n\u003ctd\u003e.lcm\u003c/td\u003e\n\u003ctd\u003eST7789V_CMD_LCMCTRL\u003c/td\u003e\n\u003ctd\u003e0xc0\u003c/td\u003e\n\u003ctd\u003e0x2C\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eporch-param\u003c/td\u003e\n\u003ctd\u003e.porch_param\u003c/td\u003e\n\u003ctd\u003eST7789V_CMD_PORCTRL\u003c/td\u003e\n\u003ctd\u003e0xb2\u003c/td\u003e\n\u003ctd\u003e0C 0C 00 33 33\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003ecmd2en-param\u003c/td\u003e\n\u003ctd\u003e.cmd2en_param\u003c/td\u003e\n\u003ctd\u003eST7789V_CMD_CMD2EN\u003c/td\u003e\n\u003ctd\u003e0xdf\u003c/td\u003e\n\u003ctd\u003e5A 69 02 00\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003epwctrl1-param\u003c/td\u003e\n\u003ctd\u003e.pwctrl1_param\u003c/td\u003e\n\u003ctd\u003eST7789V_CMD_PWCTRL1\u003c/td\u003e\n\u003ctd\u003e0xd0\u003c/td\u003e\n\u003ctd\u003eA4 81\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003epvgam-param\u003c/td\u003e\n\u003ctd\u003e.pvgam_param\u003c/td\u003e\n\u003ctd\u003eST7789V_CMD_PVGAMCTRL\u003c/td\u003e\n\u003ctd\u003e0xe0\u003c/td\u003e\n\u003ctd\u003ed0 00 02 07 0b 1a 31 54 40 29 12 12 12 17\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003envgam-param\u003c/td\u003e\n\u003ctd\u003e.nvgam_param\u003c/td\u003e\n\u003ctd\u003eST7789V_CMD_NVGAMCTRL\u003c/td\u003e\n\u003ctd\u003e0xe1\u003c/td\u003e\n\u003ctd\u003ed0 00 02 07 05 25 2d 44 44 1c 18 16 1c 1d\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003eram-param\u003c/td\u003e\n\u003ctd\u003e.ram_param\u003c/td\u003e\n\u003ctd\u003eST7789V_CMD_RAMCTRL\u003c/td\u003e\n\u003ctd\u003e0xb0\u003c/td\u003e\n\u003ctd\u003e00 f0\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003ergb-param\u003c/td\u003e\n\u003ctd\u003e.rgb_param\u003c/td\u003e\n\u003ctd\u003eST7789V_CMD_RGBCTRL\u003c/td\u003e\n\u003ctd\u003e0xb1\u003c/td\u003e\n\u003ctd\u003e40 02 14\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\u003c/table\u003e\n","metadata":{"markdown":"| Devicetree    | Struct         | Define                | Hex  | Datasheet Default        |\n| ------------- | -------------- | --------------------- | ---- | ------------------------ |\n| vcom          | .vcom          | ST7789V\\_CMD\\_VCOMS     | 0xbb | 0x20                     |\n| gctrl         | .gctrl         | ST7789V\\_CMD\\_GCTRL     | 0xb7 | 0x35                     |\n| mdac          | .mdac          | ST7789V\\_CMD\\_MADCTL    | 0x36 | use CircuitPython 0x0C   |\n| gamma         | .gamma         | ST7789V\\_CMD\\_GAMSET    | 0x26 | 0x01 (gamma 2.2)         |\n| colmod        | .colmod        | ST7789V\\_CMD\\_COLMOD    | 0x3a | use CircuitPython 0x55   |\n| lcm           | .lcm           | ST7789V\\_CMD\\_LCMCTRL   | 0xc0 | 0x2C                     |\n| porch-param   | .porch\\_param   | ST7789V\\_CMD\\_PORCTRL   | 0xb2 | 0C 0C 00 33 33           |\n| cmd2en-param  | .cmd2en\\_param  | ST7789V\\_CMD\\_CMD2EN    | 0xdf | 5A 69 02 00              |\n| pwctrl1-param | .pwctrl1\\_param | ST7789V\\_CMD\\_PWCTRL1   | 0xd0 | A4 81                    |\n| pvgam-param   | .pvgam\\_param   | ST7789V\\_CMD\\_PVGAMCTRL | 0xe0 | d0 00 02 07 0b 1a 31 54 40 29 12 12 12 17 |\n| nvgam-param   | .nvgam\\_param   | ST7789V\\_CMD\\_NVGAMCTRL | 0xe1 | d0 00 02 07 05 25 2d 44 44 1c 18 16 1c 1d |\n| ram-param     | .ram\\_param     | ST7789V\\_CMD\\_RAMCTRL   | 0xb0 | 00 f0 |\n| rgb-param     | .rgb\\_param     | ST7789V\\_CMD\\_RGBCTRL   | 0xb1 | 40 02 14 |\n"}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eMaking the above table was mostly just a matter of copying default values from the datasheet. But, the gamma calibration array values were tricky. The required properties for positive (\u003ccode\u003epvgam-param\u003c/code\u003e) and negative (\u003ccode\u003envgam-param\u003c/code\u003e) gamma calibration correspond to the datasheet's\u0026nbsp;\u003ccode\u003ePVGAMCTRL\u003c/code\u003e and \u003ccode\u003eNVGAMCTRL\u003c/code\u003e MIPI commands. Each of those takes an array of 14 parameter data bytes.\u003c/p\u003e\n\u003cp\u003eUnfortunately, the datasheet doesn't list default values for the 14 parameter bytes. Instead, it gives a table of 18 gamma levels and a chart showing how the 18 values get packed as bitfields into 14 bytes. To calculate the array of bytes to use with the Devicetree properties, I wrote two short programs to pack the bitfields.\u003c/p\u003e\n\u003cp\u003eThis Python code calculates the parameter byte array for \u003ccode\u003ePVGAMCTRL\u003c/code\u003e:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\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":"vp0 = 0\nvp1 = 0\nvp2 = 0x2\nvp4 = 0x7\nvp6 = 0xb\nvp13 = 0xa\nvp20 = 0x31\nvp27 = 0x4\nvp36 = 0x5\nvp43 = 0x40\nvp50 = 0x9\nvp57 = 0x12\nvp59 = 0x12\nvp61 = 0x12\nvp62 = 0x17\nvp63 = 0xd\njp0 = 0x1\njp1 = 0x2\nparams = [\n    (vp63 \u003c\u003c 4) | vp0, vp1, vp2, vp4, vp6, (jp0 \u003c\u003c 4) | vp13, vp20,\n    (vp36 \u003c\u003c 4) | vp27, vp43, (jp1 \u003c\u003c 4) | vp50, vp57, vp59, vp61, vp62,\n]\nprint(\"PVGAMCTRL params = [\" + \" \".join(['%02x' % p for p in params]) + \"]\")\n#\n# PVGAMCTRL params = [d0 00 02 07 0b 1a 31 54 40 29 12 12 12 17]","metadata":{"language":"auto","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  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eThis Python code calculates the parameter byte array for \u003ccode\u003eNVGAMCTRL\u003c/code\u003e:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\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":"vn0 = 0x0\nvn1 = 0x0\nvn2 = 0x2\nvn4 = 0x7\nvn6 = 0x5\nvn13 = 0x5\nvn20 = 0x2d\nvn27 = 0x4\nvn36 = 0x4\nvn43 = 0x44\nvn50 = 0xc\nvn57 = 0x18\nvn59 = 0x16\nvn61 = 0x1c\nvn62 = 0x1d\nvn63 = 0xd\njn0 = 0x2\njn1 = 0x1\nparams = [\n    (vn63 \u003c\u003c 4) | vn0, vn1, vn2, vn4, vn6, (jn0 \u003c\u003c 4) | vn13, vn20,\n    (vn36 \u003c\u003c 4) | vn27, vn43, (jn1 \u003c\u003c 4) | vn50, vn57, vn59, vn61, vn62,\n]\nprint(\"NVGAMCTRL params = [\" + \" \".join(['%02x' % p for p in params]) + \"]\")\n#\n# NVGAMCTRL params = [d0 00 02 07 05 25 2d 44 44 1c 18 16 1c 1d]","metadata":{"language":"auto","linenums":false}},{"element_type":"text","content":"\n  \n  \n        \u003ch3\u003eST7789 MIPI Display Shield\u003c/h3\u003e\n      \n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eAssembling all the previously described devicetree stuff into an \u003ccode\u003eadafruit_2in_tft_ips_display\u003c/code\u003e\u0026nbsp;shield definition, we end up with these two files:\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eboards/shields/adafruit_2in_tft_ips_display/Kconfig.shield\u003c/strong\u003e:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"embed","content":"https://github.com/samblenny/zphqst-02/blob/v0.2.1/boards/shields/adafruit_2in_tft_ips_display/Kconfig.shield"},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003e\u003cstrong\u003eboards/shields/adafruit_2in_tft_ips_display/adafruit_2in_tft_ips_display.overlay\u003c/strong\u003e:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"embed","content":"https://github.com/samblenny/zphqst-02/blob/v0.2.1/boards/shields/adafruit_2in_tft_ips_display/adafruit_2in_tft_ips_display.overlay"},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eFixing Data/Command Polarity\u003c/h3\u003e\n\u003cp\u003eIt wasn't easy getting the Devicetree configuration for the \u003ccode\u003esitronix,st7789v\u003c/code\u003e driver to work. In particular, I spent a long time failing to realize that I had specified the data/command (DC) pin as \u003ccode\u003e\u0026lt;\u0026amp;eyespi_mipi 6 GPIO_ACTIVE_LOW\u0026gt;\u003c/code\u003e when it was supposed to be \u003ccode\u003e\u0026lt;\u0026amp;eyespi_mipi 6 GPIO_ACTIVE_HIGH\u0026gt;\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eAfter a long time reading the datasheet and eliminating other possibilities, I finally sat down with the logic analyzer to carefully look at signal timing and polarity. That's when I found my mistake.\u003c/p\u003e\n\u003cp\u003eThis is a screenshot showing the DC signal before I fixed the polarity (high for the command byte on the left, low for the parameter data bytes on the right):\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/660/original/display_init_1MHz_bad_DC.png?1740874365","metadata":{"caption":""}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eAnd this is how the DC signal looked once I fixed my mistake by specifying \u003ccode\u003eGPIO_ACTIVE_HIGH\u003c/code\u003e:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/661/original/display_init_1MHz_correct_DC.png?1740874525","metadata":{"caption":""}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003ch3\u003eBuild \u0026amp; Run Display Demo\u003c/h3\u003e\n      \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eOnce all the Devicetree configuration stuff in the EYESPI and TFT display shields is in good order, building and running Zephyr's \u003ccode\u003esamples/drivers/display\u003c/code\u003e sample application is straightforward.\u003c/p\u003e\n\u003cp\u003eThis is how I build and flash the sample app in a terminal with the bash shell on Debian 12:\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"code","content":"$ cd ~/code/zephyr-workspace\n$ source .venv/bin/activate\n(.venv) $ cd zphqst-02\n(.venv) $ rm -r build\n(.venv) $ west build -b feather_rp2350/rp2350a/m33  \\\n    --shield eyespi_mipi                            \\\n    --shield adafruit_2in_tft_ips_display           \\\n    ../zephyr/samples/drivers/display               \\\n    -- -DBOARD_ROOT=$(pwd) -DOPENOCD=../openocd/build/bin/openocd\n(.venv) $ west flash","metadata":{"language":"terminal","linenums":false}},{"element_type":"text","content":"\n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n  \n        \u003cp\u003eThis is what the code looks like when it runs (display shows white background with red, green, blue, and gray squares in the corners, the tone of the gray square fades from black to white):\u003c/p\u003e\n      \n\n\n\n\n\n\n\n\n\n\n","metadata":{}},{"element_type":"user_image","content":"https://cdn-learn.adafruit.com/user_assets/assets/000/001/659/original/zephyr-display-sample-photo.jpeg?1740873017","metadata":{"caption":""}}]