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

Help ? Is it a bug, is this not possible ? 640x480 colour mode doesn't seem to work ? #78

Open
paulscottrobson opened this issue Dec 20, 2024 · 2 comments

Comments

@paulscottrobson
Copy link

I'm trying to create a multi-mode display. I have a 640x480x8 3 bitplane mode, which is based on the "dht_logging" demo, which works very well, so there's no hardware problem.

I'm trying to introduce a second mode, which will be 320x240x256 colour mode, that can be switched between, hopefully (!), hence the switch{} in the main body. Initially I'm trying to make 640x480x256 colour work with one line fixed data (buffer) before halving the resolution (as 640x480x256 takes up too much RAM)

This is the bit that starts case DVI_MODE_320_240_256

I can't get it to work, it red screens which I think means it's just not working, and I can't see what the problem is. I've tried many variations of this, the best of which was using the 8 bit encoder to encode RGB 2 bit colour, that produced something which was clearly dependent on the buffer, but didn't behave in a way I could figure out from that colour. (the part working one is at the end). This was based on one of the demos too. It output alternating red lines with yellow scattered in it, and solid red lines.

	DVI_VERTICAL_REPEAT=1
	DVI_N_TMDS_BUFFERS=3
#include "common.h"

#include "dvi.h"
#include "dvi_serialiser.h"
#include "common_dvi_pin_configs.h"
#include "tmds_encode.h"

#include "hardware/dvi_common.h"

// ***************************************************************************************
//
//						Frame buffer, these are 3 planar bitmaps.
//
// ***************************************************************************************

#define FRAME_WIDTH 640  															// Not the *pixels*, it's the display setting.
#define FRAME_HEIGHT 480

#define PLANE_SIZE_BYTES (FRAME_WIDTH * FRAME_HEIGHT / 8)
static uint8_t framebuf[3 * PLANE_SIZE_BYTES];

struct dvi_inst dvi0;																// PicoDVI structure
struct DVIModeInformation dvi_modeInfo;  											// Mode information structure.
static int currentMode;

// ***************************************************************************************
//
//									The main line renderer
//
// ***************************************************************************************

void __not_in_flash("main") dvi_core1_main() {

	uint32_t *tmdsbuf;
	dvi_register_irqs_this_core(&dvi0, DMA_IRQ_0);
	dvi_start(&dvi0);
	uint y = -1;
	uint8_t buffer[640];

	while (true) {
			y = (y + 1) % FRAME_HEIGHT;
			switch(currentMode) {
				//
				//		Mode 0 is 640x480x8 colours as 3 bitplanes.
				//
				case DVI_MODE_640_480_8:
					queue_remove_blocking_u32(&dvi0.q_tmds_free, &tmdsbuf);
					for (uint component = 0; component < 3; ++component) {
						tmds_encode_1bpp(
							(const uint32_t*)&framebuf[y * FRAME_WIDTH / 8 + component * PLANE_SIZE_BYTES],
							tmdsbuf + (2-component) * FRAME_WIDTH / DVI_SYMBOLS_PER_WORD,  	// The (2-x) here makes it BGR Acordn standard
							FRAME_WIDTH
						);
					}
					queue_add_blocking_u32(&dvi0.q_tmds_valid, &tmdsbuf);
					break;
				//
				//		Mode 1 is 340x240x256 colours in byte format.
				//
				case DVI_MODE_320_240_256:					
					uint32_t *bufptr;
					while (queue_try_remove_u32(&dvi0.q_colour_free, &bufptr));
					for (int i = 0;i < 640;i++) buffer[i] = i;
					bufptr = (uint32_t *)buffer;
					queue_add_blocking_u32(&dvi0.q_colour_valid, &bufptr);					
					break;

				default:
					break;
			}
	}
}

// ***************************************************************************************
//
//									Start the DVI driver
//
// ***************************************************************************************

void DVIStart(void) {
	currentMode = DVI_MODE_640_480_8;
	currentMode = DVI_MODE_320_240_256;
	vreg_set_voltage(VREG_VSEL);  													// Set CPU voltage
	sleep_ms(10);  																	// Let it settle for 0.01s
	set_sys_clock_khz(DVI_TIMING.bit_clk_khz, true);  								// Set the DVI compatible clock speed
	setup_default_uart();  															// Initialise the UART

	dvi0.timing = &DVI_TIMING;  													// Select timing and pinout
	dvi0.ser_cfg = *DVIGetHDMIConfig();

	dvi_init(&dvi0, next_striped_spin_lock_num(), next_striped_spin_lock_num());	// Initialise DVI
	multicore_launch_core1(dvi_core1_main);  										// Run DVI driver on core #1
}

(This one works a bit but gives red lines with yellow scattered throughout ???)

					queue_remove_blocking_u32(&dvi0.q_tmds_free, &tmdsbuf);
					// NB the scanline buffers are half-resolution!
					for (int i = 0;i < 640;i++) buffer[i] = 0x1C;
					tmds_encode_data_channel_8bpp((const uint32_t *)buffer, tmdsbuf, pixwidth / 2, blue_msb, blue_lsb);
					tmds_encode_data_channel_8bpp((const uint32_t *)buffer, tmdsbuf + pixwidth, pixwidth / 2, green_msb, green_lsb);
					tmds_encode_data_channel_8bpp((const uint32_t *)buffer, tmdsbuf + 2 * pixwidth, pixwidth / 2, red_msb, red_lsb);
					queue_add_blocking_u32(&dvi0.q_tmds_valid, &tmdsbuf);
@paulscottrobson
Copy link
Author

paulscottrobson commented Dec 20, 2024

With the tdms version, if I set the buffer to all 0x03 it is blue (with cyan dots on alternate lines) which would make sense, as it is RGB 332. However 1C is Red, and E0 is green (again with the dots) , which suggest GRB ?

If I use buffer[i] = (i & 0x20) ? 0x03:0x1C l e.g. blocks of alternating colours, it red screens.

@paulscottrobson
Copy link
Author

The code is here https://github.com/paulscottrobson/arturo ; it is designed for an Olimex board (RP2040PC)

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