Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

640x480 8bppx and DVI_SYMBOLS_PER_WORD=1 half right #38

Open
mlorenzati opened this issue Aug 2, 2022 · 6 comments
Open

640x480 8bppx and DVI_SYMBOLS_PER_WORD=1 half right #38

mlorenzati opened this issue Aug 2, 2022 · 6 comments

Comments

@mlorenzati
Copy link

mlorenzati commented Aug 2, 2022

I'm testing 8bits per pixel (RGB332) in a 640x240 buffer mode using DVI_SYMBOLS_PER_WORD=1

uint8_t framebuf[FRAME_HEIGHT][FRAME_WIDTH];

in core 1 main I'm running the dvi
void __not_in_flash_func(core1_main)() {
	dvi_register_irqs_this_core(&dvi0, DMA_IRQ_0);
	dvi_start(&dvi0);
        dvi_scanbuf_main_8bpp(&dvi0);
	__builtin_unreachable();
}

video gfx buffer is properly set, but encoding appears to be doing half the screen, what could be wrong?

@mlorenzati
Copy link
Author

mlorenzati commented Aug 2, 2022

Code for reference
CMakeList, enabling 1 symbol per word
target_compile_definitions(graphicsTest PRIVATE DVI_VERTICAL_REPEAT=2 DVI_SYMBOLS_PER_WORD=1 )

#define FRAME_WIDTH 640
uint8_t framebuf[FRAME_HEIGHT][FRAME_WIDTH];
#endif

#define REFRESH_RATE 50
#define VREG_VSEL VREG_VOLTAGE_1_20
#define DVI_TIMING dvi_timing_640x480p_60hz

struct dvi_inst dvi0;

static uint hdmi_scanline = 2;

void __not_in_flash_func(core1_main)() {
	dvi_register_irqs_this_core(&dvi0, DMA_IRQ_0);
	dvi_start(&dvi0);
	dvi_scanbuf_main_8bpp(&dvi0);
	__builtin_unreachable();
}

static inline void core1_scanline_callback() {
	uint8_t *bufptr;
	while (queue_try_remove_u32(&dvi0.q_colour_free, &bufptr));
	bufptr = &framebuf[hdmi_scanline][0];
	queue_add_blocking_u32(&dvi0.q_colour_valid, &bufptr);
	if (++hdmi_scanline >= FRAME_HEIGHT) {
    	hdmi_scanline = 0;
	}
}

int main() {
	vreg_set_voltage(VREG_VSEL);
	sleep_ms(10);

	// Run system at TMDS bit clock
	set_sys_clock_khz(DVI_TIMING.bit_clk_khz, true);
	
	dvi0.timing = &DVI_TIMING;
	dvi0.ser_cfg = DVI_DEFAULT_SERIAL_CONFIG;
	dvi0.scanline_callback = core1_scanline_callback;
	dvi_init(&dvi0, next_striped_spin_lock_num(), next_striped_spin_lock_num());
	uint8_t *bufptr;
	
	queue_add_blocking_u32(&dvi0.q_colour_valid, &bufptr);
	bufptr += FRAME_WIDTH;
	queue_add_blocking_u32(&dvi0.q_colour_valid, &bufptr);

	printf("Core 1 start\n");
	multicore_launch_core1(core1_main);
	
	//Here I prepare a graphic on the buffer
	while (1)
	{
		sleep_ms(1000);
	}
	__builtin_unreachable();
}

@mlorenzati
Copy link
Author

Half screen shows the image properly, the other half has some data right but scrambled

@mlorenzati
Copy link
Author

Whats confusing for me is that RGB16 version, if I play around with DVI_SYMBOLS_PER_WORD I can go full or half resolution, on RGB8 it fails

@mlorenzati
Copy link
Author

Could you add @Wren6991 an example of dvi_scanbuf_main_8bpp with DVI_SYMBOLS_PER_WORD=1?

@mlorenzati
Copy link
Author

From what I could test, the only color that it's not properly coded is red, in the second half

@mlorenzati
Copy link
Author

I think I fixed it: I just added a DVI_SYMBOLS_PER_WORD==1 comparisson to leftshift encode.
I don't have the full understanding of the issue to ensure this is a proper fix, but it resolves my problem

void __not_in_flash_func(tmds_encode_data_channel_8bpp)(const uint32_t *pixbuf, uint32_t *symbuf, size_t n_pix, uint channel_msb, uint channel_lsb) {
 //...
	if (require_lshift || DVI_SYMBOLS_PER_WORD==1)	
		tmds_encode_loop_8bpp_leftshift(pixbuf, symbuf, n_pix, require_lshift);
	else
		tmds_encode_loop_8bpp(pixbuf, symbuf, n_pix);
//...
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant