main.c
 1  #include <stdio.h>
 2  #include <stdlib.h>
 3  #include "pico/stdlib.h"
 4  #include "pico/multicore.h"
 5  #include "hardware/clocks.h"
 6  #include "hardware/irq.h"
 7  #include "hardware/sync.h"
 8  #include "hardware/gpio.h"
 9  #include "hardware/vreg.h"
10  
11  #include "dvi.h"
12  #include "dvi_serialiser.h"
13  #include "common_dvi_pin_configs.h"
14  #include "tmds_encode.h"
15  
16  #include "testcard_display1_rgb332.h"
17  #include "testcard_display2_rgb332.h"
18  
19  // DVDD 1.2V (1.1V seems ok too)
20  #define FRAME_WIDTH 320
21  #define FRAME_HEIGHT 240
22  #define VREG_VSEL VREG_VOLTAGE_1_20
23  #define DVI_TIMING dvi_timing_640x480p_60hz
24  
25  
26  void display_scrolling_testcard(struct dvi_inst *inst, const uint8_t *img) {
27  	const uint red_msb   = 7;
28  	const uint red_lsb   = 5;
29  	const uint green_msb = 4;
30  	const uint green_lsb = 2;
31  	const uint blue_msb  = 1;
32  	const uint blue_lsb  = 0;
33  	uint pixwidth = inst->timing->h_active_pixels;
34  	uint frame_ctr = 0;
35  	while (true) {
36  		for (uint y = 0; y < FRAME_HEIGHT; ++y) {
37  			uint y_scroll = (y + frame_ctr) % FRAME_HEIGHT;
38  			const uint8_t *colourbuf = &((const uint8_t*)img)[y_scroll * FRAME_WIDTH];
39  			uint32_t *tmdsbuf;
40  			queue_remove_blocking_u32(&inst->q_tmds_free, &tmdsbuf);
41  			// NB the scanline buffers are half-resolution!
42  			tmds_encode_data_channel_8bpp((const uint32_t*)colourbuf, tmdsbuf, pixwidth / 2, blue_msb, blue_lsb);
43  			tmds_encode_data_channel_8bpp((const uint32_t*)colourbuf, tmdsbuf + pixwidth, pixwidth / 2, green_msb, green_lsb);
44  			tmds_encode_data_channel_8bpp((const uint32_t*)colourbuf, tmdsbuf + 2 * pixwidth, pixwidth / 2, red_msb, red_lsb);
45  			queue_add_blocking_u32(&inst->q_tmds_valid, &tmdsbuf);
46  		}
47  		++frame_ctr;
48  	}
49  }
50  
51  struct dvi_inst dvi0;
52  struct dvi_inst dvi1;
53  
54  void core1_main() {
55  	dvi_register_irqs_this_core(&dvi1, DMA_IRQ_1);
56  	dvi_start(&dvi1);
57  	display_scrolling_testcard(&dvi1, (const uint8_t*)testcard_display2);
58  }
59  
60  int main() {
61  	vreg_set_voltage(VREG_VSEL);
62  	sleep_ms(10);
63  	// Run system at TMDS bit clock
64  	set_sys_clock_khz(DVI_TIMING.bit_clk_khz, true);
65  
66  	setup_default_uart();
67  
68  	dvi0.timing = &DVI_TIMING;
69  	dvi0.ser_cfg = picodvi_dvi_cfg;
70  	dvi_init(&dvi0, next_striped_spin_lock_num(), next_striped_spin_lock_num());
71  
72  	dvi1.timing = &DVI_TIMING;
73  	dvi1.ser_cfg = picodvi_pmod0_cfg;
74  	dvi1.ser_cfg.pio = pio1;
75  	dvi_init(&dvi1, next_striped_spin_lock_num(), next_striped_spin_lock_num());
76  
77  	multicore_launch_core1(core1_main);
78  	sleep_ms(10);
79  
80  	dvi_register_irqs_this_core(&dvi0, DMA_IRQ_0);
81  	dvi_start(&dvi0);
82  	display_scrolling_testcard(&dvi0, (const uint8_t*)testcard_display1);
83  }