|
| 1 | +/* |
| 2 | + * Copyright (c) 2026 Richard Osterloh |
| 3 | + * |
| 4 | + * SPDX-License-Identifier: Apache-2.0 |
| 5 | + */ |
| 6 | + |
| 7 | +#include <zephyr/dt-bindings/adc/adc.h> |
| 8 | +#include <zephyr/dt-bindings/input/input-event-codes.h> |
| 9 | + |
| 10 | +&i2c0 { |
| 11 | + status = "okay"; |
| 12 | + |
| 13 | + ina3221: ina3221@40 { |
| 14 | + compatible = "ti,ina3221"; |
| 15 | + reg = <0x40>; |
| 16 | + /* PowerBread schematic: 50 mOhm shunts on channels 1+2 */ |
| 17 | + shunt-resistors = <50 50 50>; |
| 18 | + enable-channel = <1 1 0>; |
| 19 | + /* 140 us conversions, x4 averaging: full 2-ch cycle ~2.24 ms */ |
| 20 | + conv-time-shunt = <0>; |
| 21 | + conv-time-bus = <0>; |
| 22 | + avg-mode = <1>; |
| 23 | + }; |
| 24 | +}; |
| 25 | + |
| 26 | +/* |
| 27 | + * ST7735 0.96" 80x160 LCD, wired per the XIAO PowerBread schematic: |
| 28 | + * DIN=GPIO7 (SPI2 MOSI), CLK=GPIO10 (SPI2 SCLK), DC=GPIO8, RST=GPIO0, |
| 29 | + * CS tied low on the module (no CS GPIO), backlight hardwired on. |
| 30 | + * GPIO8 is SPIM2_MISO on the base board; re-pinmux SPI2 without MISO so |
| 31 | + * GPIO8 is free to drive the DC line (display is write-only). |
| 32 | + */ |
| 33 | + |
| 34 | +&pinctrl { |
| 35 | + spim2_lcd: spim2_lcd { |
| 36 | + group1 { |
| 37 | + pinmux = <SPIM2_SCLK_GPIO10>; |
| 38 | + }; |
| 39 | + group2 { |
| 40 | + pinmux = <SPIM2_MOSI_GPIO7>; |
| 41 | + output-low; |
| 42 | + }; |
| 43 | + }; |
| 44 | +}; |
| 45 | + |
| 46 | +&spi2 { |
| 47 | + pinctrl-0 = <&spim2_lcd>; |
| 48 | + pinctrl-names = "default"; |
| 49 | +}; |
| 50 | + |
| 51 | +/ { |
| 52 | + chosen { |
| 53 | + zephyr,display = &st7735r; |
| 54 | + }; |
| 55 | + |
| 56 | + mipi_dbi { |
| 57 | + compatible = "zephyr,mipi-dbi-spi"; |
| 58 | + spi-dev = <&spi2>; |
| 59 | + dc-gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>; |
| 60 | + reset-gpios = <&gpio0 0 GPIO_ACTIVE_LOW>; |
| 61 | + write-only; |
| 62 | + #address-cells = <1>; |
| 63 | + #size-cells = <0>; |
| 64 | + |
| 65 | + /* Panel init values from the in-tree heltec_wireless_tracker |
| 66 | + * (same 0.96" 160x80 ST7735 panel), rotated to portrait. |
| 67 | + */ |
| 68 | + st7735r: st7735r@0 { |
| 69 | + compatible = "sitronix,st7735r"; |
| 70 | + reg = <0>; |
| 71 | + mipi-max-frequency = <20000000>; |
| 72 | + mipi-mode = "MIPI_DBI_MODE_SPI_4WIRE"; |
| 73 | + width = <80>; |
| 74 | + height = <160>; |
| 75 | + /* Match upstream LGFX_096_XPB: invert=false, offset 24/0, |
| 76 | + * rotation 0 (no MX/MY), BGR color order. |
| 77 | + */ |
| 78 | + x-offset = <24>; |
| 79 | + y-offset = <0>; |
| 80 | + madctl = <0x00>; |
| 81 | + colmod = <0x05>; |
| 82 | + invctr = <7>; |
| 83 | + vmctr1 = <0x0e>; |
| 84 | + pwctr1 = [a2 02 84]; |
| 85 | + pwctr2 = [c1]; |
| 86 | + pwctr3 = [0a 00]; |
| 87 | + pwctr4 = [8a 2a]; |
| 88 | + pwctr5 = [8a ee]; |
| 89 | + frmctr1 = [01 26 2e]; |
| 90 | + frmctr2 = [01 26 2e]; |
| 91 | + frmctr3 = [01 26 2e 01 26 2e]; |
| 92 | + gamctrp1 = [0f 1a 0f 18 2f 28 20 22 1f 1b 23 37 00 07 02 10]; |
| 93 | + gamctrn1 = [0f 1b 0f 17 33 2c 29 2e 30 2e 30 3b 00 07 03 10]; |
| 94 | + }; |
| 95 | + }; |
| 96 | +}; |
| 97 | + |
| 98 | +/* |
| 99 | + * PowerBread dial wheel: resistor ladder on D2/A2 = GPIO1 = ADC1 channel 1. |
| 100 | + * Idle sits near 0 V; press/down/up produce distinct levels. Thresholds |
| 101 | + * derived from upstream's 10-bit values (XIAO ESP32-C3 build); calibrate |
| 102 | + * with `powerbread dial` and adjust here if the module differs. |
| 103 | + */ |
| 104 | + |
| 105 | +&adc0 { |
| 106 | + status = "okay"; |
| 107 | + #address-cells = <1>; |
| 108 | + #size-cells = <0>; |
| 109 | + |
| 110 | + channel@1 { |
| 111 | + reg = <1>; |
| 112 | + zephyr,gain = "ADC_GAIN_1_4"; |
| 113 | + zephyr,reference = "ADC_REF_INTERNAL"; |
| 114 | + zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>; |
| 115 | + zephyr,resolution = <12>; |
| 116 | + }; |
| 117 | +}; |
| 118 | + |
| 119 | +/ { |
| 120 | + dial: dial { |
| 121 | + compatible = "adc-keys"; |
| 122 | + io-channels = <&adc0 1>; |
| 123 | + keyup-threshold-mv = <0>; |
| 124 | + sample-period-ms = <20>; |
| 125 | + |
| 126 | + dial_press { |
| 127 | + press-thresholds-mv = <510>; |
| 128 | + zephyr,code = <INPUT_KEY_ENTER>; |
| 129 | + }; |
| 130 | + dial_down { |
| 131 | + press-thresholds-mv = <910>; |
| 132 | + zephyr,code = <INPUT_KEY_DOWN>; |
| 133 | + }; |
| 134 | + dial_up { |
| 135 | + press-thresholds-mv = <1580>; |
| 136 | + zephyr,code = <INPUT_KEY_UP>; |
| 137 | + }; |
| 138 | + }; |
| 139 | + |
| 140 | + longpress { |
| 141 | + compatible = "zephyr,input-longpress"; |
| 142 | + input = <&dial>; |
| 143 | + input-codes = <INPUT_KEY_ENTER>; |
| 144 | + short-codes = <INPUT_KEY_A>; |
| 145 | + long-codes = <INPUT_KEY_B>; |
| 146 | + long-delay-ms = <1000>; |
| 147 | + }; |
| 148 | +}; |
0 commit comments