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_800_H_SYNC_POLARITY 0
57- #define MODE_800_H_FRONT_PORCH 24
58- #define MODE_800_H_SYNC_WIDTH 72
59- #define MODE_800_H_BACK_PORCH 96
60- #define MODE_800_H_ACTIVE_PIXELS 800
61-
62- #define MODE_800_V_SYNC_POLARITY 1
63- #define MODE_800_V_FRONT_PORCH 3
64- #define MODE_800_V_SYNC_WIDTH 10
65- #define MODE_800_V_BACK_PORCH 7
56+ #define MODE_720_H_SYNC_POLARITY 0
57+ #define MODE_720_H_FRONT_PORCH 24
58+ #define MODE_720_H_SYNC_WIDTH 64
59+ #define MODE_720_H_BACK_PORCH 88
60+ #define MODE_720_H_ACTIVE_PIXELS 720
61+
62+ #define MODE_720_V_SYNC_POLARITY 0
63+ #define MODE_720_V_FRONT_PORCH 3
64+ #define MODE_720_V_SYNC_WIDTH 4
65+ #define MODE_720_V_BACK_PORCH 13
66+ #define MODE_720_V_ACTIVE_LINES 400
6667
6768#define MODE_640_H_SYNC_POLARITY 0
6869#define MODE_640_H_FRONT_PORCH 16
7475#define MODE_640_V_FRONT_PORCH 10
7576#define MODE_640_V_SYNC_WIDTH 2
7677#define MODE_640_V_BACK_PORCH 33
77- #define MODE_V_ACTIVE_LINES 480
78+ #define MODE_640_V_ACTIVE_LINES 480
7879
79- #define MODE_800_V_TOTAL_LINES ( \
80- MODE_800_V_FRONT_PORCH + MODE_800_V_SYNC_WIDTH + \
81- MODE_800_V_BACK_PORCH + MODE_V_ACTIVE_LINES \
80+ #define MODE_720_V_TOTAL_LINES ( \
81+ MODE_720_V_FRONT_PORCH + MODE_720_V_SYNC_WIDTH + \
82+ MODE_720_V_BACK_PORCH + MODE_720_V_ACTIVE_LINES \
8283 )
8384#define MODE_640_V_TOTAL_LINES ( \
8485 MODE_640_V_FRONT_PORCH + MODE_640_V_SYNC_WIDTH + \
85- MODE_640_V_BACK_PORCH + MODE_V_ACTIVE_LINES \
86+ MODE_640_V_BACK_PORCH + MODE_640_V_ACTIVE_LINES \
8687 )
8788
8889#define HSTX_CMD_RAW (0x0u << 12)
@@ -124,34 +125,34 @@ static uint32_t vactive_line640[] = {
124125 HSTX_CMD_TMDS | MODE_640_H_ACTIVE_PIXELS
125126};
126127
127- static uint32_t vblank_line800_vsync_off [] = {
128- HSTX_CMD_RAW_REPEAT | MODE_800_H_FRONT_PORCH ,
129- SYNC_V0_H1 ,
130- HSTX_CMD_RAW_REPEAT | MODE_800_H_SYNC_WIDTH ,
131- SYNC_V0_H0 ,
132- HSTX_CMD_RAW_REPEAT | (MODE_800_H_BACK_PORCH + MODE_800_H_ACTIVE_PIXELS ),
133- SYNC_V0_H1
134- };
135-
136- static uint32_t vblank_line800_vsync_on [] = {
137- HSTX_CMD_RAW_REPEAT | MODE_800_H_FRONT_PORCH ,
128+ static uint32_t vblank_line720_vsync_off [] = {
129+ HSTX_CMD_RAW_REPEAT | MODE_720_H_FRONT_PORCH ,
138130 SYNC_V1_H1 ,
139- HSTX_CMD_RAW_REPEAT | MODE_800_H_SYNC_WIDTH ,
131+ HSTX_CMD_RAW_REPEAT | MODE_720_H_SYNC_WIDTH ,
140132 SYNC_V1_H0 ,
141- HSTX_CMD_RAW_REPEAT | (MODE_800_H_BACK_PORCH + MODE_800_H_ACTIVE_PIXELS ),
133+ HSTX_CMD_RAW_REPEAT | (MODE_720_H_BACK_PORCH + MODE_720_H_ACTIVE_PIXELS ),
142134 SYNC_V1_H1
143135};
144136
145- static uint32_t vactive_line800 [] = {
146- HSTX_CMD_RAW_REPEAT | MODE_800_H_FRONT_PORCH ,
137+ static uint32_t vblank_line720_vsync_on [] = {
138+ HSTX_CMD_RAW_REPEAT | MODE_720_H_FRONT_PORCH ,
139+ SYNC_V0_H1 ,
140+ HSTX_CMD_RAW_REPEAT | MODE_720_H_SYNC_WIDTH ,
141+ SYNC_V0_H0 ,
142+ HSTX_CMD_RAW_REPEAT | (MODE_720_H_BACK_PORCH + MODE_720_H_ACTIVE_PIXELS ),
143+ SYNC_V0_H1
144+ };
145+
146+ static uint32_t vactive_line720 [] = {
147+ HSTX_CMD_RAW_REPEAT | MODE_720_H_FRONT_PORCH ,
147148 SYNC_V1_H1 ,
148149 HSTX_CMD_NOP ,
149- HSTX_CMD_RAW_REPEAT | MODE_800_H_SYNC_WIDTH ,
150+ HSTX_CMD_RAW_REPEAT | MODE_720_H_SYNC_WIDTH ,
150151 SYNC_V1_H0 ,
151152 HSTX_CMD_NOP ,
152- HSTX_CMD_RAW_REPEAT | MODE_800_H_BACK_PORCH ,
153+ HSTX_CMD_RAW_REPEAT | MODE_720_H_BACK_PORCH ,
153154 SYNC_V1_H1 ,
154- HSTX_CMD_TMDS | MODE_800_H_ACTIVE_PIXELS
155+ HSTX_CMD_TMDS | MODE_720_H_ACTIVE_PIXELS
155156};
156157
157158picodvi_framebuffer_obj_t * active_picodvi = NULL ;
@@ -171,10 +172,16 @@ static void __not_in_flash_func(dma_irq_handler)(void) {
171172}
172173
173174static bool mode_ok (mp_uint_t width , mp_uint_t height , mp_uint_t color_depth ) {
174- if ((width == 640 || width == 800 ) && height == 480 && (color_depth < 8 )) {
175+ if (width == 640 && height == 480 && (color_depth < 8 )) {
176+ return true;
177+ }
178+ if (width == 320 && height == 240 ) {
179+ return true;
180+ }
181+ if (width == 720 && height == 400 ) {
175182 return true;
176183 }
177- if (( width == 320 || width == 400 ) && height == 240 ) {
184+ if (width == 360 && height == 200 ) {
178185 return true;
179186 }
180187 return false;
@@ -195,7 +202,7 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self,
195202 mp_raise_ValueError_varg (MP_ERROR_TEXT ("Invalid %q and %q for color depth %d" ), MP_QSTR_width , MP_QSTR_height , color_depth );
196203 }
197204
198- bool pixel_doubled = height = = 240 ;
205+ bool pixel_doubled = height < = 240 ;
199206
200207 size_t all_allocated = 0 ;
201208 int8_t pins [8 ] = {
@@ -251,10 +258,9 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self,
251258 }
252259
253260 if (width % 320 == 0 ) {
254- self -> dma_commands_len = (MODE_640_V_FRONT_PORCH + MODE_640_V_SYNC_WIDTH + MODE_640_V_BACK_PORCH + 2 * MODE_V_ACTIVE_LINES + 1 ) * dma_command_size ;
261+ self -> dma_commands_len = (MODE_640_V_FRONT_PORCH + MODE_640_V_SYNC_WIDTH + MODE_640_V_BACK_PORCH + 2 * MODE_640_V_ACTIVE_LINES + 1 ) * dma_command_size ;
255262 } else {
256-
257- self -> dma_commands_len = (MODE_800_V_FRONT_PORCH + MODE_800_V_SYNC_WIDTH + MODE_800_V_BACK_PORCH + 2 * MODE_V_ACTIVE_LINES + 1 ) * dma_command_size ;
263+ self -> dma_commands_len = (MODE_720_V_FRONT_PORCH + MODE_720_V_SYNC_WIDTH + MODE_720_V_BACK_PORCH + 2 * MODE_720_V_ACTIVE_LINES + 1 ) * dma_command_size ;
258264 }
259265 self -> dma_commands = (uint32_t * )port_malloc (self -> dma_commands_len * sizeof (uint32_t ), true);
260266 if (self -> dma_commands == NULL || ((size_t )self -> framebuffer & 0xf0000000 ) == 0x10000000 ) {
@@ -290,27 +296,27 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self,
290296 if (self -> width % 320 == 0 ) {
291297 frontporch_start = MODE_640_V_TOTAL_LINES - MODE_640_V_FRONT_PORCH ;
292298 } else {
293- frontporch_start = MODE_800_V_TOTAL_LINES - MODE_800_V_FRONT_PORCH ;
299+ frontporch_start = MODE_720_V_TOTAL_LINES - MODE_720_V_FRONT_PORCH ;
294300 }
295301 size_t frontporch_end = frontporch_start ;
296302 if (self -> width % 320 == 0 ) {
297303 frontporch_end += MODE_640_V_FRONT_PORCH ;
298304 } else {
299- frontporch_end += MODE_800_V_FRONT_PORCH ;
305+ frontporch_end += MODE_720_V_FRONT_PORCH ;
300306 }
301307 size_t vsync_start = 0 ;
302308 size_t vsync_end = vsync_start ;
303309 if (self -> width % 320 == 0 ) {
304310 vsync_end += MODE_640_V_SYNC_WIDTH ;
305311 } else {
306- vsync_end += MODE_800_V_SYNC_WIDTH ;
312+ vsync_end += MODE_720_V_SYNC_WIDTH ;
307313 }
308314 size_t backporch_start = vsync_end ;
309315 size_t backporch_end = backporch_start ;
310316 if (self -> width % 320 == 0 ) {
311317 backporch_end += MODE_640_V_BACK_PORCH ;
312318 } else {
313- backporch_end += MODE_800_V_BACK_PORCH ;
319+ backporch_end += MODE_720_V_BACK_PORCH ;
314320 }
315321 size_t active_start = backporch_end ;
316322
@@ -345,15 +351,15 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self,
345351 dma_channel_hw_addr (self -> dma_pixel_channel )-> al1_write_addr = dma_write_addr ;
346352 }
347353 bool is_640_based = (width == 320 || width == 640 );
348- uint32_t * vblank_line_vsync_on = is_640_based ? vblank_line640_vsync_on : vblank_line800_vsync_on ;
349- uint32_t * vblank_line_vsync_off = is_640_based ? vblank_line640_vsync_off : vblank_line800_vsync_off ;
350- uint32_t * vactive_line = is_640_based ? vactive_line640 : vactive_line800 ;
354+ uint32_t * vblank_line_vsync_on = is_640_based ? vblank_line640_vsync_on : vblank_line720_vsync_on ;
355+ uint32_t * vblank_line_vsync_off = is_640_based ? vblank_line640_vsync_off : vblank_line720_vsync_off ;
356+ uint32_t * vactive_line = is_640_based ? vactive_line640 : vactive_line720 ;
351357
352358 size_t mode_v_total_lines ;
353359 if (is_640_based ) {
354360 mode_v_total_lines = MODE_640_V_TOTAL_LINES ;
355361 } else {
356- mode_v_total_lines = MODE_800_V_TOTAL_LINES ;
362+ mode_v_total_lines = MODE_720_V_TOTAL_LINES ;
357363 }
358364
359365 for (size_t v_scanline = 0 ; v_scanline < mode_v_total_lines ; v_scanline ++ ) {
@@ -450,7 +456,7 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self,
450456 1 << HSTX_CTRL_EXPAND_SHIFT_RAW_N_SHIFTS_LSB |
451457 0 << HSTX_CTRL_EXPAND_SHIFT_RAW_SHIFT_LSB ;
452458
453- uint32_t clk_factor = is_640_based ? 5u : 4u ;
459+ uint32_t clk_factor = is_640_based ? 5u : 5u ;
454460
455461 // Serial output config: clock period of 4 or 5 cycles, pop from command
456462 // expander every 4 or 5 cycles, shift the output shiftreg by 2 every cycle.
0 commit comments