/ software / libdvi / dvi.h
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