# HG changeset patch # User Paul Boddie # Date 1541884292 -3600 # Node ID f1ce70172578685b93718dc1d3c5c4584fd369a8 # Parent 04b9cb49f0ac15320133e01b59c29d59af2a82b5 Moved VGA timing and transfer details to the VGA display abstraction, introducing an initialisation macro and simplifying the general display abstraction. diff -r 04b9cb49f0ac -r f1ce70172578 examples/vga/main.c --- a/examples/vga/main.c Sat Nov 10 21:39:51 2018 +0100 +++ b/examples/vga/main.c Sat Nov 10 22:11:32 2018 +0100 @@ -25,26 +25,21 @@ #include "init.h" #include "pic32_c.h" #include "utils.h" -#include "vga_display.h" #include "viewport.h" /* Specific functionality. */ #include "devconfig.h" #include "main.h" -#include "vga.h" +#include "vga_display.h" -/* Define DMA channels if not indicated in the build configuration. */ - -/* CPU-based transfers: no channels. */ +/* Define the scroll increment depending on how many DMA channels are used. + CPU-driven transfers permit an increment of 1. */ #ifdef TRANSFER_CPU #define SCROLL_XSTEP 1 - -/* DMA-based transfers: single channel by default. */ - #else #define SCROLL_XSTEP LINE_CHANNELS #endif diff -r 04b9cb49f0ac -r f1ce70172578 include/display.h --- a/include/display.h Sat Nov 10 21:39:51 2018 +0100 +++ b/include/display.h Sat Nov 10 22:11:32 2018 +0100 @@ -21,6 +21,7 @@ #define __DISPLAY_H__ #include +#include "vga.h" @@ -78,27 +79,20 @@ uint32_t cell_size; - /* DMA transfer sizes. */ - - uint32_t transfer_cell_size; - - /* Display line positions. */ - - uint32_t hfreq_limit, hsync_start, hsync_end; - - /* Display region scanline positions. */ - - uint32_t visible_start, vfp_start, vsync_start, vsync_end; - } display_config_t; -/* Initialise a display. */ +/* Initialise a display. This macro depends on certain VGA constants being + defined, and they are included above. + + Display(, int width, int height, int frames) +*/ #define Display(NAME, WIDTH, HEIGHT, FRAMES) \ uint8_t __##NAME##_framebuffer[(WIDTH) * (HEIGHT + 1) * (FRAMES)]; \ uint8_t *__##NAME##_screen_starts[FRAMES]; \ + \ display_config_t NAME = { \ .framebuffer=__##NAME##_framebuffer, \ .screen_starts=__##NAME##_screen_starts, \ @@ -113,16 +107,7 @@ \ .scanlines = SCANLINES, \ .line_channels = LINE_CHANNELS, \ - .cell_size = CELL_SIZE, \ - .transfer_cell_size = TRANSFER_CELL_SIZE, \ - \ - .hfreq_limit = HFREQ_LIMIT, \ - .hsync_start = HSYNC_START, \ - .hsync_end = HSYNC_END, \ - .visible_start = VISIBLE_START, \ - .vfp_start = VFP_START, \ - .vsync_start = VSYNC_START, \ - .vsync_end = VSYNC_END}; + .cell_size = CELL_SIZE}; /* Configuration functions. */ diff -r 04b9cb49f0ac -r f1ce70172578 include/vga_display.h --- a/include/vga_display.h Sat Nov 10 21:39:51 2018 +0100 +++ b/include/vga_display.h Sat Nov 10 22:11:32 2018 +0100 @@ -20,8 +20,9 @@ #ifndef __VGA_DISPLAY_H__ #define __VGA_DISPLAY_H__ +#include "display.h" #include "pic32_c.h" -#include "display.h" +#include "vga.h" @@ -41,6 +42,7 @@ /* DMA transfer properties. */ int line_channels, transfer_int_num; + uint32_t transfer_cell_size; /* Horizontal and vertical sync peripherals. */ @@ -62,11 +64,37 @@ display_config_t *display_config; + /* Display line positions. */ + + uint32_t hfreq_limit, hsync_start, hsync_end; + + /* Display region scanline positions. */ + + uint32_t visible_start, vfp_start, vsync_start, vsync_end; + } vga_display_t; -/* Initialisation. */ +/* Initialise a VGA display object with timing and pixel transfer details. + This macro depends on the VGA timing constants being defined, and they are + included above. + + VGA_Display() +*/ + +#define VGA_Display(NAME) \ + vga_display_t NAME = { \ + .transfer_cell_size = TRANSFER_CELL_SIZE, \ + .hfreq_limit = HFREQ_LIMIT, \ + .hsync_start = HSYNC_START, \ + .hsync_end = HSYNC_END, \ + .visible_start = VISIBLE_START, \ + .vfp_start = VFP_START, \ + .vsync_start = VSYNC_START, \ + .vsync_end = VSYNC_END}; + +/* Initialisation functions. */ void init_vga(display_config_t *display_config, int line_channels, int line_timer, int transfer_int_num); diff -r 04b9cb49f0ac -r f1ce70172578 lib/vga_display.c --- a/lib/vga_display.c Sat Nov 10 21:39:51 2018 +0100 +++ b/lib/vga_display.c Sat Nov 10 22:11:32 2018 +0100 @@ -17,7 +17,6 @@ * along with this program. If not, see . */ -#include "pic32_c.h" #include "init.h" #include "vga_display.h" @@ -25,7 +24,7 @@ /* Display state. */ -vga_display_t vga_display; +VGA_Display(vga_display); /* Pixel data. */ @@ -79,7 +78,7 @@ /* The timers have no prescaling (0). */ - timer_init(line_timer, 0, display_config->hfreq_limit); + timer_init(line_timer, 0, vga_display.hfreq_limit); /* Enable interrupt requests when the CPU needs to perform the transfer, as opposed to the DMA channels doing so. */ @@ -183,7 +182,7 @@ dma_set_interrupt(channel, int_num, 1); dma_set_destination(channel, HW_PHYSICAL(output), 1); - dma_set_cell(channel, vga_display.display_config->transfer_cell_size); + dma_set_cell(channel, vga_display.transfer_cell_size); } void vga_configure_zero_channel(int channel, int int_num, int initiating, @@ -230,8 +229,8 @@ channel and is handled to drive the display state machine. */ oc_init(hsync_unit, 0b101, vga_display.line_timer); - oc_set_pulse(hsync_unit, vga_display.display_config->hsync_end); - oc_set_pulse_end(hsync_unit, vga_display.display_config->hsync_start); + oc_set_pulse(hsync_unit, vga_display.hsync_end); + oc_set_pulse_end(hsync_unit, vga_display.hsync_start); oc_init_interrupt(hsync_unit, 7, 3); oc_on(hsync_unit); @@ -341,7 +340,7 @@ void vbp_active(void) { - if (vga_display.line < vga_display.display_config->visible_start) + if (vga_display.line < vga_display.visible_start) return; /* Enter the visible region. */ @@ -362,7 +361,7 @@ { display_config_t *cfg = vga_display.display_config; - if (vga_display.line < cfg->vfp_start) + if (vga_display.line < vga_display.vfp_start) { /* Update the line address and handle wraparound. */ @@ -393,7 +392,7 @@ void vfp_active(void) { - if (vga_display.line < vga_display.display_config->vsync_start) + if (vga_display.line < vga_display.vsync_start) return; /* Enter the vertical sync region. */ @@ -409,7 +408,7 @@ void vsync_active(void) { - if (vga_display.line < vga_display.display_config->vsync_end) + if (vga_display.line < vga_display.vsync_end) return; /* Start again at the top of the display. */