@typecad/framework-zephyr 1.0.0-alpha.16 → 1.0.0-alpha.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -21
- package/README.md +49 -87
- package/dist/as-built.d.ts +2 -2
- package/dist/as-built.js +2 -2
- package/dist/audit.d.ts +111 -0
- package/dist/audit.js +416 -0
- package/dist/boardgen.d.ts +1 -9
- package/dist/boardgen.js +288 -47
- package/dist/chips/resolve.js +20 -0
- package/dist/chips/types.d.ts +22 -1
- package/dist/debug-codegen.js +1 -1
- package/dist/display/bindings.d.ts +55 -0
- package/dist/display/bindings.js +316 -0
- package/dist/display/gfx.d.ts +2 -3
- package/dist/display/gfx.js +166 -154
- package/dist/display/index.js +20 -1
- package/dist/display/mipi-dbi-host.d.ts +9 -0
- package/dist/display/mipi-dbi-host.js +174 -0
- package/dist/display/profiles.d.ts +109 -4
- package/dist/display/profiles.js +270 -7
- package/dist/display/touch-adapter.js +119 -49
- package/dist/display/ui-adapter-eink.d.ts +2 -0
- package/dist/display/ui-adapter-eink.js +4 -0
- package/dist/display/ui-adapter-gray.d.ts +8 -0
- package/dist/display/ui-adapter-gray.js +170 -0
- package/dist/display/ui-adapter-mono.d.ts +13 -0
- package/dist/display/ui-adapter-mono.js +230 -0
- package/dist/display/ui-adapter-native.d.ts +10 -0
- package/dist/display/ui-adapter-native.js +295 -0
- package/dist/display/ui-adapter-shared.d.ts +11 -0
- package/dist/display/ui-adapter-shared.js +122 -0
- package/dist/display/ui-adapter.js +510 -558
- package/dist/doctor.js +4 -4
- package/dist/dt-config/custom-board.js +2 -2
- package/dist/dt-config/kconfig.d.ts +62 -1
- package/dist/dt-config/kconfig.js +141 -38
- package/dist/dt-config/overlay.d.ts +15 -2
- package/dist/dt-config/overlay.js +433 -18
- package/dist/framework.manifest.d.ts +10 -4
- package/dist/framework.manifest.js +133 -17
- package/dist/index.d.ts +2 -0
- package/dist/index.js +14 -6
- package/dist/licenses.d.ts +2 -2
- package/dist/licenses.js +13 -92
- package/dist/lowering/can.d.ts +25 -0
- package/dist/lowering/can.js +97 -0
- package/dist/lowering/clock.d.ts +17 -0
- package/dist/lowering/clock.js +58 -0
- package/dist/lowering/fs.js +1 -1
- package/dist/lowering/gpio.js +0 -32
- package/dist/lowering/hid.d.ts +27 -0
- package/dist/lowering/hid.js +244 -0
- package/dist/lowering/http.js +264 -32
- package/dist/lowering/i2c.d.ts +8 -0
- package/dist/lowering/i2c.js +137 -5
- package/dist/lowering/i2s.d.ts +27 -0
- package/dist/lowering/i2s.js +98 -0
- package/dist/lowering/index.d.ts +9 -1
- package/dist/lowering/index.js +25 -1
- package/dist/lowering/interrupts.js +6 -0
- package/dist/lowering/matrix.d.ts +15 -0
- package/dist/lowering/matrix.js +63 -0
- package/dist/lowering/mqtt.js +110 -8
- package/dist/lowering/power.d.ts +3 -2
- package/dist/lowering/power.js +20 -45
- package/dist/lowering/pwm.js +25 -0
- package/dist/lowering/sensor.d.ts +2 -2
- package/dist/lowering/sensor.js +8 -4
- package/dist/lowering/strip.d.ts +16 -0
- package/dist/lowering/strip.js +70 -0
- package/dist/lowering/thread.js +5 -1
- package/dist/lowering/trace.d.ts +44 -0
- package/dist/lowering/trace.js +239 -0
- package/dist/lowering/uart.js +6 -1
- package/dist/lowering/usb.d.ts +3 -1
- package/dist/lowering/usb.js +16 -13
- package/dist/lowering/wdt.js +2 -29
- package/dist/sbom.d.ts +181 -0
- package/dist/sbom.js +901 -0
- package/dist/sdk/board-catalog-sync.d.ts +1 -3
- package/dist/sdk/board-catalog-sync.js +4 -10
- package/dist/strategy.d.ts +82 -46
- package/dist/strategy.js +639 -182
- package/dist/tmp-probe.d.ts +2 -0
- package/dist/tmp-probe.js +9 -0
- package/dist/toolchain/debug-config.d.ts +50 -90
- package/dist/toolchain/debug-config.js +239 -510
- package/dist/toolchain/env-check.d.ts +1 -3
- package/dist/toolchain/env-check.js +2 -7
- package/dist/toolchain/index.d.ts +28 -3
- package/dist/toolchain/index.js +498 -62
- package/dist/toolchain/runners.d.ts +16 -0
- package/dist/toolchain/runners.js +75 -0
- package/dist/toolchain/scaffold.d.ts +5 -2
- package/dist/toolchain/scaffold.js +79 -15
- package/dist/toolchain/west-discover.d.ts +6 -0
- package/dist/toolchain/west-discover.js +36 -13
- package/dist/toolchain/west-spawn.js +8 -2
- package/dist/west-inventory.d.ts +25 -0
- package/dist/west-inventory.js +97 -0
- package/installer/README.md +328 -328
- package/installer/install.sh +2 -2
- package/installer/templates/project/.typecad/activate-zephyr.ps1 +1 -1
- package/installer/templates/project/.typecad/activate-zephyr.sh +1 -1
- package/installer/templates/project/.vscode/settings.json +1 -1
- package/installer/templates/project/README.md +2 -2
- package/package.json +5 -5
- package/src/as-built.ts +206 -206
- package/src/audit.ts +529 -0
- package/src/boardgen.ts +265 -50
- package/src/chips/resolve.ts +21 -0
- package/src/chips/types.ts +10 -1
- package/src/display/bindings.ts +347 -0
- package/src/display/gfx.ts +318 -306
- package/src/display/index.ts +87 -70
- package/src/display/mipi-dbi-host.ts +183 -0
- package/src/display/profiles.ts +458 -139
- package/src/display/touch-adapter.ts +119 -49
- package/src/display/ui-adapter-eink.ts +13 -0
- package/src/display/ui-adapter-gray.ts +178 -0
- package/src/display/ui-adapter-mono.ts +238 -0
- package/src/display/ui-adapter-native.ts +304 -0
- package/src/display/ui-adapter-shared.ts +125 -0
- package/src/display/ui-adapter.ts +732 -781
- package/src/doctor.ts +4 -4
- package/src/dt-config/custom-board.ts +2 -2
- package/src/dt-config/kconfig.ts +647 -505
- package/src/dt-config/overlay.ts +1475 -1058
- package/src/framework.manifest.ts +659 -535
- package/src/index.ts +16 -6
- package/src/licenses.ts +346 -425
- package/src/lowering/can.ts +140 -0
- package/src/lowering/clock.ts +91 -0
- package/src/lowering/fs.ts +135 -135
- package/src/lowering/gpio.ts +0 -33
- package/src/lowering/hid.ts +261 -0
- package/src/lowering/http.ts +264 -32
- package/src/lowering/i2c.ts +142 -5
- package/src/lowering/i2s.ts +143 -0
- package/src/lowering/index.ts +18 -1
- package/src/lowering/interrupts.ts +6 -0
- package/src/lowering/matrix.ts +70 -0
- package/src/lowering/mqtt.ts +109 -8
- package/src/lowering/power.ts +41 -0
- package/src/lowering/pwm.ts +192 -167
- package/src/lowering/sensor.ts +159 -155
- package/src/lowering/strip.ts +81 -0
- package/src/lowering/thread.ts +5 -1
- package/src/lowering/trace.ts +270 -0
- package/src/lowering/uart.ts +6 -1
- package/src/lowering/usb.ts +16 -13
- package/src/lowering/wdt.ts +2 -25
- package/src/sbom.ts +1117 -0
- package/src/sdk/board-catalog-sync.ts +4 -25
- package/src/strategy.ts +2680 -2309
- package/src/toolchain/debug-config.ts +262 -522
- package/src/toolchain/env-check.ts +279 -285
- package/src/toolchain/index.ts +1792 -1359
- package/src/toolchain/runners.ts +80 -0
- package/src/toolchain/scaffold.ts +355 -296
- package/src/toolchain/west-discover.ts +35 -13
- package/src/toolchain/west-spawn.ts +174 -168
- package/src/west-inventory.ts +102 -0
- package/dist/async/timer-polyfill.d.ts +0 -10
- package/dist/async/timer-polyfill.js +0 -95
- package/dist/chips/board-overrides.d.ts +0 -7
- package/dist/chips/board-overrides.js +0 -11
- package/dist/chips/esp32.d.ts +0 -2
- package/dist/chips/esp32.js +0 -71
- package/dist/chips/esp32s3.d.ts +0 -2
- package/dist/chips/esp32s3.js +0 -103
- package/dist/chips/soc/.d.ts +0 -2
- package/dist/chips/soc/.js +0 -129
- package/dist/chips/soc/esp32.d.ts +0 -2
- package/dist/chips/soc/esp32.js +0 -120
- package/dist/chips/soc/esp32c3.d.ts +0 -2
- package/dist/chips/soc/esp32c3.js +0 -90
- package/dist/chips/soc/esp32c6.d.ts +0 -2
- package/dist/chips/soc/esp32c6.js +0 -109
- package/dist/chips/soc/esp32s3.d.ts +0 -2
- package/dist/chips/soc/esp32s3.js +0 -189
- package/dist/chips/soc/index.d.ts +0 -2
- package/dist/chips/soc/index.js +0 -23
- package/dist/chips/soc/nrf52840.d.ts +0 -2
- package/dist/chips/soc/nrf52840.js +0 -130
- package/dist/chips/soc/rp2040.d.ts +0 -2
- package/dist/chips/soc/rp2040.js +0 -141
- package/dist/chips/soc/rp2350a.d.ts +0 -2
- package/dist/chips/soc/rp2350a.js +0 -145
- package/dist/chips/soc/samd21g18a.d.ts +0 -2
- package/dist/chips/soc/samd21g18a.js +0 -143
- package/dist/chips/soc/stm32f411xe.d.ts +0 -2
- package/dist/chips/soc/stm32f411xe.js +0 -251
- package/dist/chips/xiao-ble.d.ts +0 -2
- package/dist/chips/xiao-ble.js +0 -100
- package/dist/lowering/pulse.d.ts +0 -7
- package/dist/lowering/pulse.js +0 -51
- package/dist/lowering/tone.d.ts +0 -10
- package/dist/lowering/tone.js +0 -63
- package/dist/lowering/worker-backing.d.ts +0 -14
- package/dist/lowering/worker-backing.js +0 -79
- package/dist/lowering/worker.d.ts +0 -6
- package/dist/lowering/worker.js +0 -14
- package/dist/sdk/board-data.generated.d.ts +0 -2
- package/dist/sdk/board-data.generated.js +0 -4
- package/dist/sdk/catalog-walker.d.ts +0 -90
- package/dist/sdk/catalog-walker.js +0 -682
- package/dist/sdk/dts-reader.d.ts +0 -83
- package/dist/sdk/dts-reader.js +0 -596
- package/src/debug-codegen.ts +0 -207
package/dist/display/gfx.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
// EMIT BOUNDARY: emitted bytes land in user firmware. Covered by the TypeCAD
|
|
11
11
|
// Runtime Exception (RUNTIME_EXCEPTION.md at the repo root).
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
13
|
+
import { displayFactsLine } from './profiles.js';
|
|
13
14
|
// 5x7 bitmap glyphs for 0-9 and A-Z. Each glyph is 5 bytes (columns), MSB=top.
|
|
14
15
|
// Unknown characters fall back to the space (all-zero columns).
|
|
15
16
|
// (Compact hand-authored bitmaps; the test asserts presence of '0'..'9','A'..'Z'.)
|
|
@@ -80,9 +81,8 @@ function fontTableCpp() {
|
|
|
80
81
|
* - `'mono'` (OLED, e.g. SSD1306): a full framebuffer — the standard model
|
|
81
82
|
* for page-buffered monochrome panels (the AGENTS.md "no full framebuffer"
|
|
82
83
|
* guardrail targets RGB SPI TFTs, not mono OLEDs). draw ops set bits;
|
|
83
|
-
* display_flush pushes the whole framebuffer
|
|
84
|
-
*
|
|
85
|
-
* bit = 0x80>>(x&7).
|
|
84
|
+
* display_flush pushes the whole framebuffer as VTILED MONO01 (the layout
|
|
85
|
+
* the driver consumes; see monoHelpers).
|
|
86
86
|
*/
|
|
87
87
|
export function buildDisplayRuntime(profile) {
|
|
88
88
|
const w = profile.width;
|
|
@@ -99,8 +99,12 @@ export function buildDisplayRuntime(profile) {
|
|
|
99
99
|
? [
|
|
100
100
|
'// CUTTLEFISH_DISPLAY_BEGIN',
|
|
101
101
|
`static const struct device* __tc_display = DEVICE_DT_GET(DT_NODELABEL(${profile.dtLabel}));`,
|
|
102
|
-
`// Mono framebuffer
|
|
103
|
-
|
|
102
|
+
`// Mono framebuffer, vtiled MONO01 — the layout Zephyr's ssd1306-class`,
|
|
103
|
+
`// drivers expect from display_write (SCREEN_INFO_MONO_VTILED, matching`,
|
|
104
|
+
`// cfb's draw_point): byte = fb[(y>>3)*${w} + x], bit = 1<<(y&7).`,
|
|
105
|
+
`// pitch must equal width and (y, height) must be multiples of 8 — the`,
|
|
106
|
+
`// full-frame flush satisfies both by construction.`,
|
|
107
|
+
`static uint8_t __tc_display_fb[(${w} * ${h} + 7) / 8];`,
|
|
104
108
|
'// CUTTLEFISH_DISPLAY_END',
|
|
105
109
|
]
|
|
106
110
|
: [
|
|
@@ -115,7 +119,10 @@ export function buildDisplayRuntime(profile) {
|
|
|
115
119
|
const fontTable = fontTableCpp();
|
|
116
120
|
return {
|
|
117
121
|
includes: ['<zephyr/drivers/display.h>'],
|
|
118
|
-
|
|
122
|
+
// Profile marker: lets the toolchain recover which profile emitted this
|
|
123
|
+
// runtime (profileFromEmittedSource in profiles.ts) instead of re-deriving
|
|
124
|
+
// geometry from the emitted C.
|
|
125
|
+
stateLines: [`// typecad-display-profile: ${profile.driver}`, displayFactsLine(profile), ...stateLines],
|
|
119
126
|
helpers,
|
|
120
127
|
fontTable,
|
|
121
128
|
};
|
|
@@ -123,86 +130,91 @@ export function buildDisplayRuntime(profile) {
|
|
|
123
130
|
/**
|
|
124
131
|
* Mono (OLED) helpers: a full framebuffer + bit-packing. SSD1306-class panels
|
|
125
132
|
* are page-buffered, so draw ops set bits in the framebuffer and display_flush
|
|
126
|
-
* pushes the whole buffer. color != 0 ⇒ lit.
|
|
133
|
+
* pushes the whole buffer. color != 0 ⇒ lit. The packing is VTILED MONO01
|
|
134
|
+
* (byte = 8 vertical pixels, fb[(y>>3)*W + x], bit = 1<<(y&7)) because that
|
|
135
|
+
* is what the driver's display_write consumes — a horizontal-packed buffer
|
|
136
|
+
* with pitch = rowBytes fails the driver's pitch==width check (-EINVAL) and
|
|
137
|
+
* nothing reaches the panel.
|
|
127
138
|
*/
|
|
128
139
|
function monoHelpers(w, h, blInit) {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
__tc_set_pixel(static_cast<uint16_t>(x + i), y, on);
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
__tc_set_pixel(x, static_cast<uint16_t>(y + row), on);
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
||
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
__desc.
|
|
201
|
-
__desc.
|
|
202
|
-
__desc.
|
|
203
|
-
__desc.
|
|
204
|
-
|
|
205
|
-
|
|
140
|
+
return `
|
|
141
|
+
// VTILED MONO01 pixel packing: byte = fb[(y>>3)*${w}] + x, bit = 1<<(y&7).
|
|
142
|
+
static inline void __tc_set_pixel(uint16_t x, uint16_t y, uint8_t on) {
|
|
143
|
+
if ((x >= ${w}U) || (y >= ${h}U)) { return; }
|
|
144
|
+
uint16_t idx = static_cast<uint16_t>((static_cast<uint32_t>(y) >> 3) * ${w}U + x);
|
|
145
|
+
uint8_t mask = static_cast<uint8_t>(1U << (y & 7U));
|
|
146
|
+
if (on != 0U) {
|
|
147
|
+
__tc_display_fb[idx] = static_cast<uint8_t>(__tc_display_fb[idx] | mask);
|
|
148
|
+
} else {
|
|
149
|
+
__tc_display_fb[idx] = static_cast<uint8_t>(__tc_display_fb[idx] & static_cast<uint8_t>(~mask));
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
static inline void display_init(void) {
|
|
154
|
+
if (!device_is_ready(__tc_display)) { for (;;) { k_msleep(1000); } }
|
|
155
|
+
${blInit}
|
|
156
|
+
for (uint16_t i = 0; i < static_cast<uint16_t>(sizeof(__tc_display_fb)); i++) { __tc_display_fb[i] = 0U; }
|
|
157
|
+
display_blanking_off(__tc_display);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
static inline void display_fill_rect(uint16_t x, uint16_t y, uint16_t rw, uint16_t rh, uint16_t color) {
|
|
161
|
+
uint8_t on = (color != 0U) ? 1U : 0U;
|
|
162
|
+
for (uint16_t row = 0; row < rh; row++) {
|
|
163
|
+
for (uint16_t i = 0; i < rw; i++) {
|
|
164
|
+
__tc_set_pixel(static_cast<uint16_t>(x + i), static_cast<uint16_t>(y + row), on);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
static inline void display_draw_rect(uint16_t x, uint16_t y, uint16_t rw, uint16_t rh, uint16_t color) {
|
|
170
|
+
uint8_t on = (color != 0U) ? 1U : 0U;
|
|
171
|
+
for (uint16_t i = 0; i < rw; i++) {
|
|
172
|
+
__tc_set_pixel(static_cast<uint16_t>(x + i), y, on);
|
|
173
|
+
__tc_set_pixel(static_cast<uint16_t>(x + i), static_cast<uint16_t>(y + rh - 1U), on);
|
|
174
|
+
}
|
|
175
|
+
for (uint16_t row = 1U; row < rh - 1U; row++) {
|
|
176
|
+
__tc_set_pixel(x, static_cast<uint16_t>(y + row), on);
|
|
177
|
+
__tc_set_pixel(static_cast<uint16_t>(x + rw - 1U), static_cast<uint16_t>(y + row), on);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
static inline void display_draw_text(uint16_t x, uint16_t y, const char* text, uint16_t color) {
|
|
182
|
+
uint8_t on = (color != 0U) ? 1U : 0U;
|
|
183
|
+
uint16_t cx = x;
|
|
184
|
+
for (const char* p = text; *p != 0; p++) {
|
|
185
|
+
uint8_t uc = static_cast<uint8_t>(*p);
|
|
186
|
+
if (uc >= 128U) { uc = static_cast<uint8_t>(' '); }
|
|
187
|
+
const uint8_t* glyph = &__tc_font5x7[uc][0];
|
|
188
|
+
if (uc >= static_cast<uint8_t>('a') && uc <= static_cast<uint8_t>('z')) {
|
|
189
|
+
glyph = &__tc_font5x7[uc - 32U][0];
|
|
190
|
+
} else if (uc < static_cast<uint8_t>('0')
|
|
191
|
+
|| (uc > static_cast<uint8_t>('9') && uc < static_cast<uint8_t>('A'))
|
|
192
|
+
|| uc > static_cast<uint8_t>('Z')) {
|
|
193
|
+
glyph = &__tc_font5x7[static_cast<uint8_t>(' ')][0];
|
|
194
|
+
}
|
|
195
|
+
for (uint16_t col = 0; col < 5U; col++) {
|
|
196
|
+
uint8_t bits = glyph[col];
|
|
197
|
+
for (uint16_t row = 0; row < 7U; row++) {
|
|
198
|
+
if ((bits & static_cast<uint8_t>(1U << row)) != 0U) {
|
|
199
|
+
__tc_set_pixel(static_cast<uint16_t>(cx + col), static_cast<uint16_t>(y + row), on);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
cx = static_cast<uint16_t>(cx + 6U);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
static inline void display_flush(void) {
|
|
208
|
+
// Full-frame push. pitch = width and height a multiple of 8 are the
|
|
209
|
+
// ssd1306 driver's hard requirements — the full frame satisfies both.
|
|
210
|
+
struct display_buffer_descriptor __desc;
|
|
211
|
+
__desc.buf_size = sizeof(__tc_display_fb); // ${w} * ${h} / 8 bytes
|
|
212
|
+
__desc.width = ${w}U;
|
|
213
|
+
__desc.height = ${h}U;
|
|
214
|
+
__desc.pitch = ${w}U; // vtiled: bytes per 8-pixel page row == width
|
|
215
|
+
__desc.frame_incomplete = false;
|
|
216
|
+
(void)display_write(__tc_display, 0, 0, &__desc, __tc_display_fb);
|
|
217
|
+
}
|
|
206
218
|
`;
|
|
207
219
|
}
|
|
208
220
|
/**
|
|
@@ -210,75 +222,75 @@ static inline void display_flush(void) {
|
|
|
210
222
|
* display_write. No full framebuffer (AGENTS.md rendering guardrails).
|
|
211
223
|
*/
|
|
212
224
|
function rgb565Helpers(w, blInit) {
|
|
213
|
-
return `
|
|
214
|
-
// Write a single row of \`rw\` rgb565 pixels at (x,y). Builds the
|
|
215
|
-
// display_buffer_descriptor the Zephyr display_write API requires (rgb565 =
|
|
216
|
-
// 2 bytes/pixel) and pushes the one-row line buffer.
|
|
217
|
-
static inline void __tc_display_write_row(uint16_t x, uint16_t y, uint16_t rw) {
|
|
218
|
-
struct display_buffer_descriptor __desc;
|
|
219
|
-
__desc.buf_size = static_cast<uint32_t>(rw) * 2U; // 2 bytes per rgb565 pixel
|
|
220
|
-
__desc.width = rw;
|
|
221
|
-
__desc.height = 1U;
|
|
222
|
-
__desc.pitch = rw;
|
|
223
|
-
__desc.frame_incomplete = false;
|
|
224
|
-
(void)display_write(__tc_display, x, y, &__desc, __tc_display_line);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
static inline void display_init(void) {
|
|
228
|
-
if (!device_is_ready(__tc_display)) { for (;;) { k_msleep(1000); } }
|
|
229
|
-
${blInit}
|
|
230
|
-
display_blanking_off(__tc_display);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
static inline void display_fill_rect(uint16_t x, uint16_t y, uint16_t rw, uint16_t h, uint16_t color) {
|
|
234
|
-
for (uint16_t row = 0; row < h; row++) {
|
|
235
|
-
for (uint16_t i = 0; i < rw; i++) { __tc_display_line[i] = color; }
|
|
236
|
-
__tc_display_write_row(x, static_cast<uint16_t>(y + row), rw);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
static inline void display_draw_rect(uint16_t x, uint16_t y, uint16_t rw, uint16_t h, uint16_t color) {
|
|
241
|
-
// Top + bottom edges.
|
|
242
|
-
for (uint16_t i = 0; i < rw; i++) { __tc_display_line[i] = color; }
|
|
243
|
-
__tc_display_write_row(x, y, rw);
|
|
244
|
-
__tc_display_write_row(x, static_cast<uint16_t>(y + h - 1U), rw);
|
|
245
|
-
// Left + right edges.
|
|
246
|
-
for (uint16_t row = 1U; row < h - 1U; row++) {
|
|
247
|
-
__tc_display_line[0] = color;
|
|
248
|
-
if (rw > 1U) { __tc_display_line[rw - 1U] = color; }
|
|
249
|
-
__tc_display_write_row(x, static_cast<uint16_t>(y + row), rw);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
static inline void display_draw_text(uint16_t x, uint16_t y, const char* text, uint16_t color) {
|
|
254
|
-
uint16_t cx = x;
|
|
255
|
-
for (const char* p = text; *p != 0; p++) {
|
|
256
|
-
// Read the byte UNSIGNED so bytes >= 0x80 don't index the 128-entry
|
|
257
|
-
// font table negatively (signed char would make 0x80 == -128).
|
|
258
|
-
uint8_t uc = static_cast<uint8_t>(*p);
|
|
259
|
-
if (uc >= 128U) { uc = static_cast<uint8_t>(' '); } // unknown → space
|
|
260
|
-
const uint8_t* glyph = &__tc_font5x7[uc][0];
|
|
261
|
-
// Lowercase → uppercase; anything outside 0-9/A-Z → space glyph.
|
|
262
|
-
if (uc >= static_cast<uint8_t>('a') && uc <= static_cast<uint8_t>('z')) {
|
|
263
|
-
glyph = &__tc_font5x7[uc - 32U][0];
|
|
264
|
-
} else if (uc < static_cast<uint8_t>('0')
|
|
265
|
-
|| (uc > static_cast<uint8_t>('9') && uc < static_cast<uint8_t>('A'))
|
|
266
|
-
|| uc > static_cast<uint8_t>('Z')) {
|
|
267
|
-
glyph = &__tc_font5x7[static_cast<uint8_t>(' ')][0];
|
|
268
|
-
}
|
|
269
|
-
for (uint16_t col = 0; col < 5U; col++) {
|
|
270
|
-
uint8_t bits = glyph[col];
|
|
271
|
-
for (uint16_t row = 0; row < 7U; row++) {
|
|
272
|
-
__tc_display_line[0] = ((bits & static_cast<uint8_t>(1U << row)) != 0U) ? color : 0U;
|
|
273
|
-
__tc_display_write_row(static_cast<uint16_t>(cx + col), static_cast<uint16_t>(y + row), 1U);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
cx = static_cast<uint16_t>(cx + 6U); // 5 cols + 1 space
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
static inline void display_flush(void) {
|
|
281
|
-
// No-op: writes are immediate via display_write; there is no framebuffer to push.
|
|
282
|
-
}
|
|
225
|
+
return `
|
|
226
|
+
// Write a single row of \`rw\` rgb565 pixels at (x,y). Builds the
|
|
227
|
+
// display_buffer_descriptor the Zephyr display_write API requires (rgb565 =
|
|
228
|
+
// 2 bytes/pixel) and pushes the one-row line buffer.
|
|
229
|
+
static inline void __tc_display_write_row(uint16_t x, uint16_t y, uint16_t rw) {
|
|
230
|
+
struct display_buffer_descriptor __desc;
|
|
231
|
+
__desc.buf_size = static_cast<uint32_t>(rw) * 2U; // 2 bytes per rgb565 pixel
|
|
232
|
+
__desc.width = rw;
|
|
233
|
+
__desc.height = 1U;
|
|
234
|
+
__desc.pitch = rw;
|
|
235
|
+
__desc.frame_incomplete = false;
|
|
236
|
+
(void)display_write(__tc_display, x, y, &__desc, __tc_display_line);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
static inline void display_init(void) {
|
|
240
|
+
if (!device_is_ready(__tc_display)) { for (;;) { k_msleep(1000); } }
|
|
241
|
+
${blInit}
|
|
242
|
+
display_blanking_off(__tc_display);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
static inline void display_fill_rect(uint16_t x, uint16_t y, uint16_t rw, uint16_t h, uint16_t color) {
|
|
246
|
+
for (uint16_t row = 0; row < h; row++) {
|
|
247
|
+
for (uint16_t i = 0; i < rw; i++) { __tc_display_line[i] = color; }
|
|
248
|
+
__tc_display_write_row(x, static_cast<uint16_t>(y + row), rw);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
static inline void display_draw_rect(uint16_t x, uint16_t y, uint16_t rw, uint16_t h, uint16_t color) {
|
|
253
|
+
// Top + bottom edges.
|
|
254
|
+
for (uint16_t i = 0; i < rw; i++) { __tc_display_line[i] = color; }
|
|
255
|
+
__tc_display_write_row(x, y, rw);
|
|
256
|
+
__tc_display_write_row(x, static_cast<uint16_t>(y + h - 1U), rw);
|
|
257
|
+
// Left + right edges.
|
|
258
|
+
for (uint16_t row = 1U; row < h - 1U; row++) {
|
|
259
|
+
__tc_display_line[0] = color;
|
|
260
|
+
if (rw > 1U) { __tc_display_line[rw - 1U] = color; }
|
|
261
|
+
__tc_display_write_row(x, static_cast<uint16_t>(y + row), rw);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
static inline void display_draw_text(uint16_t x, uint16_t y, const char* text, uint16_t color) {
|
|
266
|
+
uint16_t cx = x;
|
|
267
|
+
for (const char* p = text; *p != 0; p++) {
|
|
268
|
+
// Read the byte UNSIGNED so bytes >= 0x80 don't index the 128-entry
|
|
269
|
+
// font table negatively (signed char would make 0x80 == -128).
|
|
270
|
+
uint8_t uc = static_cast<uint8_t>(*p);
|
|
271
|
+
if (uc >= 128U) { uc = static_cast<uint8_t>(' '); } // unknown → space
|
|
272
|
+
const uint8_t* glyph = &__tc_font5x7[uc][0];
|
|
273
|
+
// Lowercase → uppercase; anything outside 0-9/A-Z → space glyph.
|
|
274
|
+
if (uc >= static_cast<uint8_t>('a') && uc <= static_cast<uint8_t>('z')) {
|
|
275
|
+
glyph = &__tc_font5x7[uc - 32U][0];
|
|
276
|
+
} else if (uc < static_cast<uint8_t>('0')
|
|
277
|
+
|| (uc > static_cast<uint8_t>('9') && uc < static_cast<uint8_t>('A'))
|
|
278
|
+
|| uc > static_cast<uint8_t>('Z')) {
|
|
279
|
+
glyph = &__tc_font5x7[static_cast<uint8_t>(' ')][0];
|
|
280
|
+
}
|
|
281
|
+
for (uint16_t col = 0; col < 5U; col++) {
|
|
282
|
+
uint8_t bits = glyph[col];
|
|
283
|
+
for (uint16_t row = 0; row < 7U; row++) {
|
|
284
|
+
__tc_display_line[0] = ((bits & static_cast<uint8_t>(1U << row)) != 0U) ? color : 0U;
|
|
285
|
+
__tc_display_write_row(static_cast<uint16_t>(cx + col), static_cast<uint16_t>(y + row), 1U);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
cx = static_cast<uint16_t>(cx + 6U); // 5 cols + 1 space
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
static inline void display_flush(void) {
|
|
293
|
+
// No-op: writes are immediate via display_write; there is no framebuffer to push.
|
|
294
|
+
}
|
|
283
295
|
`;
|
|
284
296
|
}
|
package/dist/display/index.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// init, so when state is uninitialized we seed the DEFAULT profile and lower
|
|
11
11
|
// anyway (the probe only checks code/expression is non-undefined).
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
13
|
-
import { DEFAULT_ZEPHYR_DISPLAY_PROFILE } from './profiles.js';
|
|
13
|
+
import { DEFAULT_ZEPHYR_DISPLAY_PROFILE, ZEPHYR_DISPLAY_PROFILES, synthesizeZephyrProfile } from './profiles.js';
|
|
14
14
|
// Re-export the UI display/touch adapters + profile registry so the strategy
|
|
15
15
|
// and consumers can reach them from the package barrel.
|
|
16
16
|
export { zephyrUiDisplayAdapter, zephyrDisplayAdapterGenerator } from './ui-adapter.js';
|
|
@@ -30,6 +30,25 @@ export function resolveZephyrDisplayOp(op, state) {
|
|
|
30
30
|
// fields, so use the default profile.
|
|
31
31
|
if (op.operation === 'display.init') {
|
|
32
32
|
state.initialized = true;
|
|
33
|
+
// Drop-in panels (driver = DT compatible): seed the synthesized profile
|
|
34
|
+
// so the direct-op GFX runtime sizes itself for THIS panel (the mono
|
|
35
|
+
// framebuffer branch keys off the profile's colorFormat/geometry). The
|
|
36
|
+
// op carries the resolved profile's colorFormat — explicit mono wins;
|
|
37
|
+
// otherwise the compatible table decides (ssd1306-class → mono).
|
|
38
|
+
const registered = ZEPHYR_DISPLAY_PROFILES[o.driver];
|
|
39
|
+
if (registered) {
|
|
40
|
+
state.profile = registered;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
const synth = synthesizeZephyrProfile({
|
|
44
|
+
driver: o.driver,
|
|
45
|
+
width: o.width,
|
|
46
|
+
height: o.height,
|
|
47
|
+
colorFormat: o.colorFormat,
|
|
48
|
+
});
|
|
49
|
+
if (synth)
|
|
50
|
+
state.profile = synth;
|
|
51
|
+
}
|
|
33
52
|
return { code: 'display_init();' };
|
|
34
53
|
}
|
|
35
54
|
// For non-init ops: if not initialized (validator probe path), seed the
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ZephyrDisplayProfile } from "./profiles.js";
|
|
2
|
+
/** Build the local CS-holding mipi-dbi host for a profile. Emits a device at
|
|
3
|
+
* the overlay's bridge node (bridgeLabel) implementing
|
|
4
|
+
* struct mipi_dbi_driver_api, plus the includes it needs. The panel driver
|
|
5
|
+
* reaches it via DEVICE_DT_GET(DT_INST_PARENT(display0)). */
|
|
6
|
+
export declare function localHoldCsDbiHost(profile: ZephyrDisplayProfile): {
|
|
7
|
+
includes: string[];
|
|
8
|
+
functions: string;
|
|
9
|
+
};
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// App-local CS-holding MIPI DBI host — the 'local-hold-cs' dbiHost.
|
|
3
|
+
//
|
|
4
|
+
// Implements the mipi-dbi host API for the overlay's zephyr,mipi-dbi-spi node
|
|
5
|
+
// with CS held across each command+data burst (GPIO-managed, DC toggled
|
|
6
|
+
// mid-burst — the Adafruit ST77xx protocol the direct transport verified on
|
|
7
|
+
// the clone-ST7796S rig). The stock mipi-dbi-spi driver issues the command
|
|
8
|
+
// byte and its parameters as two CS-deasserted SPI transactions, which
|
|
9
|
+
// scrambles clone ST77xx panels; the mipi-hold-cs DT knob that would fix it
|
|
10
|
+
// is documented by the binding but unimplemented in Zephyr 4.4.2. This host
|
|
11
|
+
// is that behavior, emitted app-locally — the stock bridge stays compiled
|
|
12
|
+
// out (CONFIG_MIPI_DBI_SPI=n) and the in-tree panel driver (e.g.
|
|
13
|
+
// sitronix,st7796s, CONFIG_ST7796S=y) binds on top unchanged.
|
|
14
|
+
//
|
|
15
|
+
// A bus host is a normal Zephyr extension point (11 ship in-tree); once
|
|
16
|
+
// upstream implements mipi-hold-cs, this section retires and the profile's
|
|
17
|
+
// dbiHost flips back to 'spi-bridge'.
|
|
18
|
+
//
|
|
19
|
+
// EMIT BOUNDARY: emitted bytes land in user firmware. Covered by the TypeCAD
|
|
20
|
+
// Runtime Exception (RUNTIME_EXCEPTION.md at the repo root).
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
/** Build the local CS-holding mipi-dbi host for a profile. Emits a device at
|
|
23
|
+
* the overlay's bridge node (bridgeLabel) implementing
|
|
24
|
+
* struct mipi_dbi_driver_api, plus the includes it needs. The panel driver
|
|
25
|
+
* reaches it via DEVICE_DT_GET(DT_INST_PARENT(display0)). */
|
|
26
|
+
export function localHoldCsDbiHost(profile) {
|
|
27
|
+
const bus = profile.busLabel ?? 'spi2';
|
|
28
|
+
const bridge = profile.bridgeLabel ?? 'mipi_dbi';
|
|
29
|
+
const includes = [
|
|
30
|
+
`#include <zephyr/drivers/mipi_dbi.h>`,
|
|
31
|
+
`#include <zephyr/drivers/spi.h>`,
|
|
32
|
+
];
|
|
33
|
+
const functions = `
|
|
34
|
+
// ── App-local MIPI DBI host (CS held across command+data) ───────────────
|
|
35
|
+
// The mipi-hold-cs behavior the zephyr,mipi-dbi-spi child binding documents:
|
|
36
|
+
// CS asserted by GPIO around each complete command+data burst (or whole
|
|
37
|
+
// display write), DC toggled mid-burst. The spi_config carried in the
|
|
38
|
+
// panel's mipi_dbi_config is used verbatim EXCEPT .cs, which this host
|
|
39
|
+
// nulls so the SPI driver never touches the CS line mid-burst.
|
|
40
|
+
static const struct gpio_dt_spec __tc_dbi_dc = GPIO_DT_SPEC_GET(DT_NODELABEL(${bridge}), dc_gpios);
|
|
41
|
+
static const struct gpio_dt_spec __tc_dbi_rst = GPIO_DT_SPEC_GET(DT_NODELABEL(${bridge}), reset_gpios);
|
|
42
|
+
// CS comes from the SPI bus node's cs-gpios, selected by the panel's
|
|
43
|
+
// dbi config .slave (= reg). The overlay puts the panel at index 0 and an
|
|
44
|
+
// SPI touch controller, if any, at index 1 — each owner drives its own CS.
|
|
45
|
+
static const struct gpio_dt_spec __tc_dbi_cs[] = {
|
|
46
|
+
#if DT_PROP_LEN(DT_NODELABEL(${bus}), cs_gpios) > 0
|
|
47
|
+
GPIO_DT_SPEC_GET_BY_IDX(DT_NODELABEL(${bus}), cs_gpios, 0),
|
|
48
|
+
#endif
|
|
49
|
+
#if DT_PROP_LEN(DT_NODELABEL(${bus}), cs_gpios) > 1
|
|
50
|
+
GPIO_DT_SPEC_GET_BY_IDX(DT_NODELABEL(${bus}), cs_gpios, 1),
|
|
51
|
+
#endif
|
|
52
|
+
};
|
|
53
|
+
#define __TC_DBI_CS_COUNT (sizeof(__tc_dbi_cs) / sizeof(__tc_dbi_cs[0]))
|
|
54
|
+
// Staging buffer for display writes: display_write buffers may live in PSRAM
|
|
55
|
+
// (not DMA-capable on ESP32); chunked SRAM staging is the pattern the direct
|
|
56
|
+
// transport proved on this rig. Reused, never per-frame (AGENTS.md).
|
|
57
|
+
static uint8_t __tc_dbi_bounce[4096];
|
|
58
|
+
|
|
59
|
+
static const struct gpio_dt_spec* __tc_dbi_cs_for(const struct mipi_dbi_config* cfg) {
|
|
60
|
+
if (cfg->config.slave >= __TC_DBI_CS_COUNT) return nullptr;
|
|
61
|
+
return &__tc_dbi_cs[cfg->config.slave];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// One command byte (DC low) + its parameters (DC high) under one CS burst.
|
|
65
|
+
static int __tc_dbi_command_write(const struct device* /*dev*/,
|
|
66
|
+
const struct mipi_dbi_config* cfg,
|
|
67
|
+
uint8_t cmd, const uint8_t* data, size_t len) {
|
|
68
|
+
const struct gpio_dt_spec* cs = __tc_dbi_cs_for(cfg);
|
|
69
|
+
if (cs == nullptr) return -EIO;
|
|
70
|
+
struct spi_config sc = cfg->config;
|
|
71
|
+
// This host owns CS — keep the SPI core off it. Both fields matter in
|
|
72
|
+
// Zephyr 4.4: the core gates on cs.cs_is_gpio (NOT the port pointer), and
|
|
73
|
+
// leaving it set makes spi_context_cs_control deref the port-less spec
|
|
74
|
+
// (EXCCAUSE 28 on the first panel init command — verified on hardware).
|
|
75
|
+
sc.cs.cs_is_gpio = false;
|
|
76
|
+
sc.cs.gpio.port = nullptr;
|
|
77
|
+
struct spi_buf __cb = { &cmd, 1 };
|
|
78
|
+
struct spi_buf_set __csb = { &__cb, 1 };
|
|
79
|
+
gpio_pin_set_dt(cs, 1);
|
|
80
|
+
gpio_pin_set_dt(&__tc_dbi_dc, 0);
|
|
81
|
+
int ret = spi_write(DEVICE_DT_GET(DT_NODELABEL(${bus})), &sc, &__csb);
|
|
82
|
+
if ((ret == 0) && (len > 0)) {
|
|
83
|
+
struct spi_buf __db = { const_cast<uint8_t*>(data), len };
|
|
84
|
+
struct spi_buf_set __dsb = { &__db, 1 };
|
|
85
|
+
gpio_pin_set_dt(&__tc_dbi_dc, 1);
|
|
86
|
+
ret = spi_write(DEVICE_DT_GET(DT_NODELABEL(${bus})), &sc, &__dsb);
|
|
87
|
+
}
|
|
88
|
+
gpio_pin_set_dt(cs, 0);
|
|
89
|
+
return ret;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Write-only host: the bridge node carries 'write-only' (no MISO readback
|
|
93
|
+
// path is wired for these panels).
|
|
94
|
+
static int __tc_dbi_command_read(const struct device* /*dev*/,
|
|
95
|
+
const struct mipi_dbi_config* /*cfg*/,
|
|
96
|
+
uint8_t* /*cmds*/, size_t /*num_cmds*/,
|
|
97
|
+
uint8_t* /*response*/, size_t /*len*/) {
|
|
98
|
+
return -ENOTSUP;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Stream desc->buf_size bytes to the panel (DC high) under one CS assertion,
|
|
102
|
+
// chunked through the SRAM bounce buffer.
|
|
103
|
+
static int __tc_dbi_write_display(const struct device* /*dev*/,
|
|
104
|
+
const struct mipi_dbi_config* cfg,
|
|
105
|
+
const uint8_t* framebuf,
|
|
106
|
+
struct display_buffer_descriptor* desc,
|
|
107
|
+
enum display_pixel_format /*pixfmt*/) {
|
|
108
|
+
const struct gpio_dt_spec* cs = __tc_dbi_cs_for(cfg);
|
|
109
|
+
if (cs == nullptr) return -EIO;
|
|
110
|
+
struct spi_config sc = cfg->config;
|
|
111
|
+
sc.cs.cs_is_gpio = false;
|
|
112
|
+
sc.cs.gpio.port = nullptr;
|
|
113
|
+
gpio_pin_set_dt(cs, 1);
|
|
114
|
+
gpio_pin_set_dt(&__tc_dbi_dc, 1);
|
|
115
|
+
const uint8_t* p = framebuf;
|
|
116
|
+
size_t remaining = desc->buf_size;
|
|
117
|
+
int ret = 0;
|
|
118
|
+
while ((remaining > 0) && (ret == 0)) {
|
|
119
|
+
size_t chunk = (remaining > sizeof(__tc_dbi_bounce)) ? sizeof(__tc_dbi_bounce) : remaining;
|
|
120
|
+
memcpy(__tc_dbi_bounce, p, chunk);
|
|
121
|
+
struct spi_buf __b = { __tc_dbi_bounce, chunk };
|
|
122
|
+
struct spi_buf_set __s = { &__b, 1 };
|
|
123
|
+
ret = spi_write(DEVICE_DT_GET(DT_NODELABEL(${bus})), &sc, &__s);
|
|
124
|
+
p += chunk;
|
|
125
|
+
remaining -= chunk;
|
|
126
|
+
}
|
|
127
|
+
gpio_pin_set_dt(cs, 0);
|
|
128
|
+
return ret;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Assert reset for the requested delay, then release (the stock host's
|
|
132
|
+
// semantics — st7796s calls mipi_dbi_reset(host, 100) at init).
|
|
133
|
+
static int __tc_dbi_reset(const struct device* /*dev*/, k_timeout_t delay) {
|
|
134
|
+
gpio_pin_set_dt(&__tc_dbi_rst, 1);
|
|
135
|
+
k_sleep(delay);
|
|
136
|
+
return gpio_pin_set_dt(&__tc_dbi_rst, 0);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Nothing is locked between calls (no per-panel spi reconfig here).
|
|
140
|
+
static int __tc_dbi_release(const struct device* /*dev*/,
|
|
141
|
+
const struct mipi_dbi_config* /*cfg*/) {
|
|
142
|
+
return 0;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
static DEVICE_API(mipi_dbi, __tc_dbi_api) = {
|
|
146
|
+
__tc_dbi_command_write,
|
|
147
|
+
__tc_dbi_command_read,
|
|
148
|
+
__tc_dbi_write_display,
|
|
149
|
+
__tc_dbi_reset,
|
|
150
|
+
__tc_dbi_release,
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
static int __tc_dbi_host_init(const struct device* /*dev*/) {
|
|
154
|
+
if (!device_is_ready(__tc_dbi_dc.port)) return -ENODEV;
|
|
155
|
+
gpio_pin_configure_dt(&__tc_dbi_dc, GPIO_OUTPUT);
|
|
156
|
+
if (device_is_ready(__tc_dbi_rst.port)) {
|
|
157
|
+
gpio_pin_configure_dt(&__tc_dbi_rst, GPIO_OUTPUT_INACTIVE);
|
|
158
|
+
}
|
|
159
|
+
for (size_t i = 0; i < __TC_DBI_CS_COUNT; i++) {
|
|
160
|
+
if (device_is_ready(__tc_dbi_cs[i].port)) {
|
|
161
|
+
gpio_pin_configure_dt(&__tc_dbi_cs[i], GPIO_OUTPUT_INACTIVE);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return 0;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Same init level/priority slot the stock bridge uses — panel drivers init
|
|
168
|
+
// later (CONFIG_DISPLAY_INIT_PRIORITY=85 > MIPI_DBI_INIT_PRIORITY=80), so
|
|
169
|
+
// the host's GPIOs are live before the panel's init commands run.
|
|
170
|
+
DEVICE_DT_DEFINE(DT_NODELABEL(${bridge}), __tc_dbi_host_init, NULL, NULL, NULL,
|
|
171
|
+
POST_KERNEL, CONFIG_MIPI_DBI_INIT_PRIORITY, &__tc_dbi_api);
|
|
172
|
+
`;
|
|
173
|
+
return { includes, functions };
|
|
174
|
+
}
|