Skip to content

Commit bdedbe0

Browse files
committed
Merge remote-tracking branch 'jepler/rp2350-800' into fruit_jam
2 parents 94bc51a + 3a7135f commit bdedbe0

File tree

2 files changed

+89
-30
lines changed

2 files changed

+89
-30
lines changed

locale/circuitpython.pot

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1248,11 +1248,14 @@ msgstr ""
12481248
msgid "Invalid %q"
12491249
msgstr ""
12501250

1251-
#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c
12521251
#: shared-module/aurora_epaper/aurora_framebuffer.c
12531252
msgid "Invalid %q and %q"
12541253
msgstr ""
12551254

1255+
#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c
1256+
msgid "Invalid %q and %q for color depth %d"
1257+
msgstr ""
1258+
12561259
#: ports/atmel-samd/common-hal/microcontroller/Pin.c
12571260
#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c
12581261
#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c

ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c

Lines changed: 85 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,17 @@
5353
#define SYNC_V1_H0 (TMDS_CTRL_10 | (TMDS_CTRL_00 << 10) | (TMDS_CTRL_00 << 20))
5454
#define SYNC_V1_H1 (TMDS_CTRL_11 | (TMDS_CTRL_00 << 10) | (TMDS_CTRL_00 << 20))
5555

56-
#define MODE_H_SYNC_POLARITY 0
57-
#define MODE_H_FRONT_PORCH 16
58-
#define MODE_H_SYNC_WIDTH 96
59-
#define MODE_H_BACK_PORCH 48
60-
#define MODE_H_ACTIVE_PIXELS 640
56+
#define MODE_800_H_SYNC_POLARITY 0
57+
#define MODE_800_H_FRONT_PORCH 16
58+
#define MODE_800_H_SYNC_WIDTH 96
59+
#define MODE_800_H_BACK_PORCH 48
60+
#define MODE_800_H_ACTIVE_PIXELS 800
61+
62+
#define MODE_640_H_SYNC_POLARITY 0
63+
#define MODE_640_H_FRONT_PORCH 16
64+
#define MODE_640_H_SYNC_WIDTH 96
65+
#define MODE_640_H_BACK_PORCH 48
66+
#define MODE_640_H_ACTIVE_PIXELS 640
6167

6268
#define MODE_V_SYNC_POLARITY 0
6369
#define MODE_V_FRONT_PORCH 10
@@ -83,34 +89,64 @@
8389
// ----------------------------------------------------------------------------
8490
// HSTX command lists
8591

86-
static uint32_t vblank_line_vsync_off[] = {
87-
HSTX_CMD_RAW_REPEAT | MODE_H_FRONT_PORCH,
92+
static uint32_t vblank_line640_vsync_off[] = {
93+
HSTX_CMD_RAW_REPEAT | MODE_640_H_FRONT_PORCH,
8894
SYNC_V1_H1,
89-
HSTX_CMD_RAW_REPEAT | MODE_H_SYNC_WIDTH,
95+
HSTX_CMD_RAW_REPEAT | MODE_640_H_SYNC_WIDTH,
9096
SYNC_V1_H0,
91-
HSTX_CMD_RAW_REPEAT | (MODE_H_BACK_PORCH + MODE_H_ACTIVE_PIXELS),
97+
HSTX_CMD_RAW_REPEAT | (MODE_640_H_BACK_PORCH + MODE_640_H_ACTIVE_PIXELS),
9298
SYNC_V1_H1
9399
};
94100

95-
static uint32_t vblank_line_vsync_on[] = {
96-
HSTX_CMD_RAW_REPEAT | MODE_H_FRONT_PORCH,
101+
static uint32_t vblank_line640_vsync_on[] = {
102+
HSTX_CMD_RAW_REPEAT | MODE_640_H_FRONT_PORCH,
97103
SYNC_V0_H1,
98-
HSTX_CMD_RAW_REPEAT | MODE_H_SYNC_WIDTH,
104+
HSTX_CMD_RAW_REPEAT | MODE_640_H_SYNC_WIDTH,
99105
SYNC_V0_H0,
100-
HSTX_CMD_RAW_REPEAT | (MODE_H_BACK_PORCH + MODE_H_ACTIVE_PIXELS),
106+
HSTX_CMD_RAW_REPEAT | (MODE_640_H_BACK_PORCH + MODE_640_H_ACTIVE_PIXELS),
101107
SYNC_V0_H1
102108
};
103109

104-
static uint32_t vactive_line[] = {
105-
HSTX_CMD_RAW_REPEAT | MODE_H_FRONT_PORCH,
110+
static uint32_t vactive_line640[] = {
111+
HSTX_CMD_RAW_REPEAT | MODE_640_H_FRONT_PORCH,
106112
SYNC_V1_H1,
107113
HSTX_CMD_NOP,
108-
HSTX_CMD_RAW_REPEAT | MODE_H_SYNC_WIDTH,
114+
HSTX_CMD_RAW_REPEAT | MODE_640_H_SYNC_WIDTH,
109115
SYNC_V1_H0,
110116
HSTX_CMD_NOP,
111-
HSTX_CMD_RAW_REPEAT | MODE_H_BACK_PORCH,
117+
HSTX_CMD_RAW_REPEAT | MODE_640_H_BACK_PORCH,
112118
SYNC_V1_H1,
113-
HSTX_CMD_TMDS | MODE_H_ACTIVE_PIXELS
119+
HSTX_CMD_TMDS | MODE_640_H_ACTIVE_PIXELS
120+
};
121+
122+
static uint32_t vblank_line800_vsync_off[] = {
123+
HSTX_CMD_RAW_REPEAT | MODE_800_H_FRONT_PORCH,
124+
SYNC_V1_H1,
125+
HSTX_CMD_RAW_REPEAT | MODE_800_H_SYNC_WIDTH,
126+
SYNC_V1_H0,
127+
HSTX_CMD_RAW_REPEAT | (MODE_800_H_BACK_PORCH + MODE_800_H_ACTIVE_PIXELS),
128+
SYNC_V1_H1
129+
};
130+
131+
static uint32_t vblank_line800_vsync_on[] = {
132+
HSTX_CMD_RAW_REPEAT | MODE_800_H_FRONT_PORCH,
133+
SYNC_V0_H1,
134+
HSTX_CMD_RAW_REPEAT | MODE_800_H_SYNC_WIDTH,
135+
SYNC_V0_H0,
136+
HSTX_CMD_RAW_REPEAT | (MODE_800_H_BACK_PORCH + MODE_800_H_ACTIVE_PIXELS),
137+
SYNC_V0_H1
138+
};
139+
140+
static uint32_t vactive_line800[] = {
141+
HSTX_CMD_RAW_REPEAT | MODE_800_H_FRONT_PORCH,
142+
SYNC_V1_H1,
143+
HSTX_CMD_NOP,
144+
HSTX_CMD_RAW_REPEAT | MODE_800_H_SYNC_WIDTH,
145+
SYNC_V1_H0,
146+
HSTX_CMD_NOP,
147+
HSTX_CMD_RAW_REPEAT | MODE_800_H_BACK_PORCH,
148+
SYNC_V1_H1,
149+
HSTX_CMD_TMDS | MODE_800_H_ACTIVE_PIXELS
114150
};
115151

116152
picodvi_framebuffer_obj_t *active_picodvi = NULL;
@@ -129,6 +165,16 @@ static void __not_in_flash_func(dma_irq_handler)(void) {
129165
ch->al3_read_addr_trig = (uintptr_t)active_picodvi->dma_commands;
130166
}
131167

168+
static bool mode_ok(mp_uint_t width, mp_uint_t height, mp_uint_t color_depth) {
169+
if ((width == 640 || width == 800) && height == 480 && (color_depth < 8)) {
170+
return true;
171+
}
172+
if ((width == 320 || width == 400) && height == 240) {
173+
return true;
174+
}
175+
return false;
176+
}
177+
132178
void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self,
133179
mp_uint_t width, mp_uint_t height,
134180
const mcu_pin_obj_t *clk_dp, const mcu_pin_obj_t *clk_dn,
@@ -140,11 +186,11 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self,
140186
mp_raise_msg_varg(&mp_type_RuntimeError, MP_ERROR_TEXT("%q in use"), MP_QSTR_picodvi);
141187
}
142188

143-
if (!(width == 640 && height == 480) && !(width == 320 && height == 240 && (color_depth == 16 || color_depth == 8))) {
144-
mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q and %q"), MP_QSTR_width, MP_QSTR_height);
189+
if (!mode_ok(width, height, color_depth)) {
190+
mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q and %q for color depth %d"), MP_QSTR_width, MP_QSTR_height, color_depth);
145191
}
146192

147-
bool pixel_doubled = width == 320 && height == 240;
193+
bool pixel_doubled = height == 240;
148194

149195
size_t all_allocated = 0;
150196
int8_t pins[8] = {
@@ -267,22 +313,27 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self,
267313
dma_channel_hw_addr(self->dma_pixel_channel)->al1_ctrl = dma_ctrl;
268314
dma_channel_hw_addr(self->dma_pixel_channel)->al1_write_addr = dma_write_addr;
269315
}
316+
bool is_640_based = (width == 320 || width == 640);
317+
uint32_t *vblank_line_vsync_on = is_640_based ? vblank_line640_vsync_on : vblank_line800_vsync_on;
318+
uint32_t *vblank_line_vsync_off = is_640_based ? vblank_line640_vsync_off : vblank_line800_vsync_off;
319+
uint32_t *vactive_line = is_640_based ? vactive_line640 : vactive_line800;
320+
270321
for (size_t v_scanline = 0; v_scanline < MODE_V_TOTAL_LINES; v_scanline++) {
271322
if (pixel_doubled) {
272323
self->dma_commands[command_word++] = dma_ctrl;
273324
self->dma_commands[command_word++] = dma_write_addr;
274325
}
275326
if (vsync_start <= v_scanline && v_scanline < vsync_end) {
276-
self->dma_commands[command_word++] = count_of(vblank_line_vsync_on);
327+
self->dma_commands[command_word++] = count_of(vblank_line640_vsync_on);
277328
self->dma_commands[command_word++] = (uintptr_t)vblank_line_vsync_on;
278329
} else if (backporch_start <= v_scanline && v_scanline < backporch_end) {
279-
self->dma_commands[command_word++] = count_of(vblank_line_vsync_off);
330+
self->dma_commands[command_word++] = count_of(vblank_line640_vsync_off);
280331
self->dma_commands[command_word++] = (uintptr_t)vblank_line_vsync_off;
281332
} else if (frontporch_start <= v_scanline && v_scanline < frontporch_end) {
282-
self->dma_commands[command_word++] = count_of(vblank_line_vsync_off);
333+
self->dma_commands[command_word++] = count_of(vblank_line640_vsync_off);
283334
self->dma_commands[command_word++] = (uintptr_t)vblank_line_vsync_off;
284335
} else {
285-
self->dma_commands[command_word++] = count_of(vactive_line);
336+
self->dma_commands[command_word++] = count_of(vactive_line640);
286337
self->dma_commands[command_word++] = (uintptr_t)vactive_line;
287338
size_t row = v_scanline - active_start;
288339
size_t transfer_count = words_per_line;
@@ -361,13 +412,15 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self,
361412
1 << HSTX_CTRL_EXPAND_SHIFT_RAW_N_SHIFTS_LSB |
362413
0 << HSTX_CTRL_EXPAND_SHIFT_RAW_SHIFT_LSB;
363414

364-
// Serial output config: clock period of 5 cycles, pop from command
365-
// expander every 5 cycles, shift the output shiftreg by 2 every cycle.
415+
uint32_t clk_factor = is_640_based ? 5u : 4u;
416+
417+
// Serial output config: clock period of 4 or 5 cycles, pop from command
418+
// expander every 4 or 5 cycles, shift the output shiftreg by 2 every cycle.
366419
hstx_ctrl_hw->csr = 0;
367420
hstx_ctrl_hw->csr =
368421
HSTX_CTRL_CSR_EXPAND_EN_BITS |
369-
5u << HSTX_CTRL_CSR_CLKDIV_LSB |
370-
5u << HSTX_CTRL_CSR_N_SHIFTS_LSB |
422+
clk_factor << HSTX_CTRL_CSR_CLKDIV_LSB |
423+
clk_factor << HSTX_CTRL_CSR_N_SHIFTS_LSB |
371424
2u << HSTX_CTRL_CSR_SHIFT_LSB |
372425
HSTX_CTRL_CSR_EN_BITS;
373426

@@ -376,6 +429,9 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self,
376429
// 250 Mbps, which is very close to the bit clock for 480p 60Hz (252 MHz).
377430
// If we want the exact rate then we'll have to reconfigure PLLs.
378431

432+
// Similarly for 800 it's at least close to the nominal rate, we hope..
433+
// (since 800/640 is 5/4)
434+
379435
// Setup the data to pin mapping. `pins` is a pair of pins in a standard
380436
// order: clock, red, green and blue. We don't actually care they are next
381437
// to one another but they'll work better that way.

0 commit comments

Comments
 (0)