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 }