dvi.h
1 #ifndef _DVI_H 2 #define _DVI_H 3 4 #define N_TMDS_LANES 3 5 #define TMDS_SYNC_LANE 0 // blue! 6 7 #include "pico/util/queue.h" 8 9 #include "dvi_config_defs.h" 10 #include "dvi_timing.h" 11 #include "dvi_serialiser.h" 12 #include "util_queue_u32_inline.h" 13 14 typedef void (*dvi_callback_t)(void); 15 16 struct dvi_inst { 17 // Config --- 18 const struct dvi_timing *timing; 19 struct dvi_lane_dma_cfg dma_cfg[N_TMDS_LANES]; 20 struct dvi_timing_state timing_state; 21 struct dvi_serialiser_cfg ser_cfg; 22 // Called in the DMA IRQ once per scanline -- careful with the run time! 23 dvi_callback_t scanline_callback; 24 25 // State --- 26 struct dvi_scanline_dma_list dma_list_vblank_sync; 27 struct dvi_scanline_dma_list dma_list_vblank_nosync; 28 struct dvi_scanline_dma_list dma_list_active; 29 struct dvi_scanline_dma_list dma_list_error; 30 31 // After a TMDS buffer has been enqueue via a control block for the last 32 // time, two IRQs must go by before freeing. The first indicates the control 33 // block for this buf has been loaded, and the second occurs some time after 34 // the actual data DMA transfer has completed. 35 uint32_t *tmds_buf_release_next; 36 uint32_t *tmds_buf_release; 37 // Remember how far behind the source is on TMDS scanlines, so we can output 38 // solid colour until they catch up (rather than dying spectacularly) 39 uint late_scanline_ctr; 40 41 // Encoded scanlines: 42 queue_t q_tmds_valid; 43 queue_t q_tmds_free; 44 45 // Either scanline buffers or frame buffers: 46 queue_t q_colour_valid; 47 queue_t q_colour_free; 48 49 }; 50 51 // Set up data structures and hardware for DVI. 52 void dvi_init(struct dvi_inst *inst, uint spinlock_tmds_queue, uint spinlock_colour_queue); 53 54 // Call this after calling dvi_init(). DVI DMA interrupts will be routed to 55 // whichever core called this function. Registers an exclusive IRQ handler. 56 void dvi_register_irqs_this_core(struct dvi_inst *inst, uint irq_num); 57 58 // Start actually wiggling TMDS pairs. Call this once you have initialised the 59 // DVI, have registered the IRQs, and are producing rendered scanlines. 60 void dvi_start(struct dvi_inst *inst); 61 62 // TMDS encode worker function: core enters and doesn't leave, but still 63 // responds to IRQs. Repeatedly pop a scanline buffer from q_colour_valid, 64 // TMDS encode it, and pass it to the tmds valid queue. 65 void dvi_scanbuf_main_8bpp(struct dvi_inst *inst); 66 void dvi_scanbuf_main_16bpp(struct dvi_inst *inst); 67 68 // Same as above, but each q_colour_valid entry is a framebuffer 69 void dvi_framebuf_main_8bpp(struct dvi_inst *inst); 70 void dvi_framebuf_main_16bpp(struct dvi_inst *inst); 71 72 #endif