@@ -140,7 +140,7 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self,
140140 mp_raise_msg_varg (& mp_type_RuntimeError , MP_ERROR_TEXT ("%q in use" ), MP_QSTR_picodvi );
141141 }
142142
143- if (!(width == 640 && height == 480 ) && !(width == 320 && height == 240 && color_depth == 16 )) {
143+ if (!(width == 640 && height == 480 ) && !(width == 320 && height == 240 && ( color_depth == 16 || color_depth == 8 ) )) {
144144 mp_raise_ValueError_varg (MP_ERROR_TEXT ("Invalid %q and %q" ), MP_QSTR_width , MP_QSTR_height );
145145 }
146146
@@ -243,11 +243,14 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self,
243243 DMA_CH0_CTRL_TRIG_INCR_READ_BITS |
244244 DMA_CH0_CTRL_TRIG_EN_BITS ;
245245 uint32_t dma_pixel_ctrl ;
246- // We do 16 bit transfers when pixel doubling and the memory bus will
247- // duplicate the 16 bits to produce 32 bits for the HSTX. HSTX config is the
248- // same.
249246 if (pixel_doubled ) {
250- dma_pixel_ctrl = dma_ctrl | DMA_SIZE_16 << DMA_CH0_CTRL_TRIG_DATA_SIZE_LSB ;
247+ // We do color_depth size transfers when pixel doubling. The memory bus will
248+ // duplicate the 16 bits to produce 32 bits for the HSTX.
249+ if (color_depth == 16 ) {
250+ dma_pixel_ctrl = dma_ctrl | DMA_SIZE_16 << DMA_CH0_CTRL_TRIG_DATA_SIZE_LSB ;
251+ } else {
252+ dma_pixel_ctrl = dma_ctrl | DMA_SIZE_8 << DMA_CH0_CTRL_TRIG_DATA_SIZE_LSB ;
253+ }
251254 } else {
252255 dma_pixel_ctrl = dma_ctrl | DMA_SIZE_32 << DMA_CH0_CTRL_TRIG_DATA_SIZE_LSB ;
253256 }
@@ -287,7 +290,9 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self,
287290 self -> dma_commands [command_word ++ ] = dma_pixel_ctrl ;
288291 self -> dma_commands [command_word ++ ] = dma_write_addr ;
289292 row /= 2 ;
290- transfer_count *= 2 ;
293+ // When pixel doubling, we do one transfer per pixel and it gets
294+ // mirrored into the rest of the word.
295+ transfer_count = self -> width ;
291296 }
292297 self -> dma_commands [command_word ++ ] = transfer_count ;
293298 uint32_t * row_start = & self -> framebuffer [row * self -> pitch ];
@@ -341,10 +346,17 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self,
341346 (color_depth - 1 ) << HSTX_CTRL_EXPAND_TMDS_L0_NBITS_LSB |
342347 rot << HSTX_CTRL_EXPAND_TMDS_L0_ROT_LSB ;
343348 }
349+ size_t shifts_before_empty = ((32 / color_depth ) % 32 );
350+ if (pixel_doubled && color_depth == 8 ) {
351+ // All but 320x240 at 8bits will shift through all 32 bits. We are only
352+ // doubling so we only need 16 bits (2 x 8) to get our doubled pixel.
353+ shifts_before_empty = 2 ;
354+ }
355+
344356 // Pixels come in 32 bits at a time. color_depth dictates the number
345357 // of pixels per word. Control symbols (RAW) are an entire 32-bit word.
346358 hstx_ctrl_hw -> expand_shift =
347- (( 32 / color_depth ) % 32 ) << HSTX_CTRL_EXPAND_SHIFT_ENC_N_SHIFTS_LSB |
359+ shifts_before_empty << HSTX_CTRL_EXPAND_SHIFT_ENC_N_SHIFTS_LSB |
348360 color_depth << HSTX_CTRL_EXPAND_SHIFT_ENC_SHIFT_LSB |
349361 1 << HSTX_CTRL_EXPAND_SHIFT_RAW_N_SHIFTS_LSB |
350362 0 << HSTX_CTRL_EXPAND_SHIFT_RAW_SHIFT_LSB ;
0 commit comments