1.1 --- a/examples/vga/main.c Sat Nov 10 21:39:51 2018 +0100
1.2 +++ b/examples/vga/main.c Sat Nov 10 22:11:32 2018 +0100
1.3 @@ -25,26 +25,21 @@
1.4 #include "init.h"
1.5 #include "pic32_c.h"
1.6 #include "utils.h"
1.7 -#include "vga_display.h"
1.8 #include "viewport.h"
1.9
1.10 /* Specific functionality. */
1.11
1.12 #include "devconfig.h"
1.13 #include "main.h"
1.14 -#include "vga.h"
1.15 +#include "vga_display.h"
1.16
1.17
1.18
1.19 -/* Define DMA channels if not indicated in the build configuration. */
1.20 -
1.21 -/* CPU-based transfers: no channels. */
1.22 +/* Define the scroll increment depending on how many DMA channels are used.
1.23 + CPU-driven transfers permit an increment of 1. */
1.24
1.25 #ifdef TRANSFER_CPU
1.26 #define SCROLL_XSTEP 1
1.27 -
1.28 -/* DMA-based transfers: single channel by default. */
1.29 -
1.30 #else
1.31 #define SCROLL_XSTEP LINE_CHANNELS
1.32 #endif
2.1 --- a/include/display.h Sat Nov 10 21:39:51 2018 +0100
2.2 +++ b/include/display.h Sat Nov 10 22:11:32 2018 +0100
2.3 @@ -21,6 +21,7 @@
2.4 #define __DISPLAY_H__
2.5
2.6 #include <stdint.h>
2.7 +#include "vga.h"
2.8
2.9
2.10
2.11 @@ -78,27 +79,20 @@
2.12
2.13 uint32_t cell_size;
2.14
2.15 - /* DMA transfer sizes. */
2.16 -
2.17 - uint32_t transfer_cell_size;
2.18 -
2.19 - /* Display line positions. */
2.20 -
2.21 - uint32_t hfreq_limit, hsync_start, hsync_end;
2.22 -
2.23 - /* Display region scanline positions. */
2.24 -
2.25 - uint32_t visible_start, vfp_start, vsync_start, vsync_end;
2.26 -
2.27 } display_config_t;
2.28
2.29
2.30
2.31 -/* Initialise a display. */
2.32 +/* Initialise a display. This macro depends on certain VGA constants being
2.33 + defined, and they are included above.
2.34 +
2.35 + Display(<name>, int width, int height, int frames)
2.36 +*/
2.37
2.38 #define Display(NAME, WIDTH, HEIGHT, FRAMES) \
2.39 uint8_t __##NAME##_framebuffer[(WIDTH) * (HEIGHT + 1) * (FRAMES)]; \
2.40 uint8_t *__##NAME##_screen_starts[FRAMES]; \
2.41 + \
2.42 display_config_t NAME = { \
2.43 .framebuffer=__##NAME##_framebuffer, \
2.44 .screen_starts=__##NAME##_screen_starts, \
2.45 @@ -113,16 +107,7 @@
2.46 \
2.47 .scanlines = SCANLINES, \
2.48 .line_channels = LINE_CHANNELS, \
2.49 - .cell_size = CELL_SIZE, \
2.50 - .transfer_cell_size = TRANSFER_CELL_SIZE, \
2.51 - \
2.52 - .hfreq_limit = HFREQ_LIMIT, \
2.53 - .hsync_start = HSYNC_START, \
2.54 - .hsync_end = HSYNC_END, \
2.55 - .visible_start = VISIBLE_START, \
2.56 - .vfp_start = VFP_START, \
2.57 - .vsync_start = VSYNC_START, \
2.58 - .vsync_end = VSYNC_END};
2.59 + .cell_size = CELL_SIZE};
2.60
2.61 /* Configuration functions. */
2.62
3.1 --- a/include/vga_display.h Sat Nov 10 21:39:51 2018 +0100
3.2 +++ b/include/vga_display.h Sat Nov 10 22:11:32 2018 +0100
3.3 @@ -20,8 +20,9 @@
3.4 #ifndef __VGA_DISPLAY_H__
3.5 #define __VGA_DISPLAY_H__
3.6
3.7 +#include "display.h"
3.8 #include "pic32_c.h"
3.9 -#include "display.h"
3.10 +#include "vga.h"
3.11
3.12
3.13
3.14 @@ -41,6 +42,7 @@
3.15 /* DMA transfer properties. */
3.16
3.17 int line_channels, transfer_int_num;
3.18 + uint32_t transfer_cell_size;
3.19
3.20 /* Horizontal and vertical sync peripherals. */
3.21
3.22 @@ -62,11 +64,37 @@
3.23
3.24 display_config_t *display_config;
3.25
3.26 + /* Display line positions. */
3.27 +
3.28 + uint32_t hfreq_limit, hsync_start, hsync_end;
3.29 +
3.30 + /* Display region scanline positions. */
3.31 +
3.32 + uint32_t visible_start, vfp_start, vsync_start, vsync_end;
3.33 +
3.34 } vga_display_t;
3.35
3.36
3.37
3.38 -/* Initialisation. */
3.39 +/* Initialise a VGA display object with timing and pixel transfer details.
3.40 + This macro depends on the VGA timing constants being defined, and they are
3.41 + included above.
3.42 +
3.43 + VGA_Display(<name>)
3.44 +*/
3.45 +
3.46 +#define VGA_Display(NAME) \
3.47 + vga_display_t NAME = { \
3.48 + .transfer_cell_size = TRANSFER_CELL_SIZE, \
3.49 + .hfreq_limit = HFREQ_LIMIT, \
3.50 + .hsync_start = HSYNC_START, \
3.51 + .hsync_end = HSYNC_END, \
3.52 + .visible_start = VISIBLE_START, \
3.53 + .vfp_start = VFP_START, \
3.54 + .vsync_start = VSYNC_START, \
3.55 + .vsync_end = VSYNC_END};
3.56 +
3.57 +/* Initialisation functions. */
3.58
3.59 void init_vga(display_config_t *display_config, int line_channels,
3.60 int line_timer, int transfer_int_num);
4.1 --- a/lib/vga_display.c Sat Nov 10 21:39:51 2018 +0100
4.2 +++ b/lib/vga_display.c Sat Nov 10 22:11:32 2018 +0100
4.3 @@ -17,7 +17,6 @@
4.4 * along with this program. If not, see <http://www.gnu.org/licenses/>.
4.5 */
4.6
4.7 -#include "pic32_c.h"
4.8 #include "init.h"
4.9 #include "vga_display.h"
4.10
4.11 @@ -25,7 +24,7 @@
4.12
4.13 /* Display state. */
4.14
4.15 -vga_display_t vga_display;
4.16 +VGA_Display(vga_display);
4.17
4.18 /* Pixel data. */
4.19
4.20 @@ -79,7 +78,7 @@
4.21
4.22 /* The timers have no prescaling (0). */
4.23
4.24 - timer_init(line_timer, 0, display_config->hfreq_limit);
4.25 + timer_init(line_timer, 0, vga_display.hfreq_limit);
4.26
4.27 /* Enable interrupt requests when the CPU needs to perform the transfer, as
4.28 opposed to the DMA channels doing so. */
4.29 @@ -183,7 +182,7 @@
4.30 dma_set_interrupt(channel, int_num, 1);
4.31
4.32 dma_set_destination(channel, HW_PHYSICAL(output), 1);
4.33 - dma_set_cell(channel, vga_display.display_config->transfer_cell_size);
4.34 + dma_set_cell(channel, vga_display.transfer_cell_size);
4.35 }
4.36
4.37 void vga_configure_zero_channel(int channel, int int_num, int initiating,
4.38 @@ -230,8 +229,8 @@
4.39 channel and is handled to drive the display state machine. */
4.40
4.41 oc_init(hsync_unit, 0b101, vga_display.line_timer);
4.42 - oc_set_pulse(hsync_unit, vga_display.display_config->hsync_end);
4.43 - oc_set_pulse_end(hsync_unit, vga_display.display_config->hsync_start);
4.44 + oc_set_pulse(hsync_unit, vga_display.hsync_end);
4.45 + oc_set_pulse_end(hsync_unit, vga_display.hsync_start);
4.46 oc_init_interrupt(hsync_unit, 7, 3);
4.47 oc_on(hsync_unit);
4.48
4.49 @@ -341,7 +340,7 @@
4.50
4.51 void vbp_active(void)
4.52 {
4.53 - if (vga_display.line < vga_display.display_config->visible_start)
4.54 + if (vga_display.line < vga_display.visible_start)
4.55 return;
4.56
4.57 /* Enter the visible region. */
4.58 @@ -362,7 +361,7 @@
4.59 {
4.60 display_config_t *cfg = vga_display.display_config;
4.61
4.62 - if (vga_display.line < cfg->vfp_start)
4.63 + if (vga_display.line < vga_display.vfp_start)
4.64 {
4.65 /* Update the line address and handle wraparound. */
4.66
4.67 @@ -393,7 +392,7 @@
4.68
4.69 void vfp_active(void)
4.70 {
4.71 - if (vga_display.line < vga_display.display_config->vsync_start)
4.72 + if (vga_display.line < vga_display.vsync_start)
4.73 return;
4.74
4.75 /* Enter the vertical sync region. */
4.76 @@ -409,7 +408,7 @@
4.77
4.78 void vsync_active(void)
4.79 {
4.80 - if (vga_display.line < vga_display.display_config->vsync_end)
4.81 + if (vga_display.line < vga_display.vsync_end)
4.82 return;
4.83
4.84 /* Start again at the top of the display. */