1.1 --- a/examples/vga-dual/main.c Tue Oct 23 23:25:47 2018 +0200
1.2 +++ b/examples/vga-dual/main.c Wed Oct 24 00:50:48 2018 +0200
1.3 @@ -29,17 +29,9 @@
1.4 #include "vga.h"
1.5 #include "display.h"
1.6 #include "display_config.h"
1.7 -
1.8 +#include "vga_display.h"
1.9
1.10
1.11 -/* Display state. */
1.12 -
1.13 -static void (*state_handler)(void);
1.14 -static uint32_t line;
1.15 -
1.16 -/* Pointers to pixel lines. */
1.17 -
1.18 -static uint8_t *linedata;
1.19
1.20 /* Pixel data. */
1.21
1.22 @@ -75,8 +67,9 @@
1.23
1.24 void main(void)
1.25 {
1.26 - line = 0;
1.27 - state_handler = vbp_active;
1.28 + init_vga(&display_config, start_visible, update_visible, stop_visible,
1.29 + vsync_high, vsync_low);
1.30 +
1.31 test_linedata(&display_config);
1.32
1.33 init_memory();
1.34 @@ -179,104 +172,59 @@
1.35
1.36 if (ifs)
1.37 {
1.38 - line += 1;
1.39 - state_handler();
1.40 + vga_interrupt_handler();
1.41 CLR_REG(OCIFS, ifs);
1.42 }
1.43 }
1.44
1.45
1.46
1.47 -/* Vertical back porch region. */
1.48 -
1.49 -void vbp_active(void)
1.50 -{
1.51 - if (line < VISIBLE_START)
1.52 - return;
1.53 -
1.54 - /* Enter the visible region. */
1.55 +/* Enable the channels for the next line. */
1.56
1.57 - state_handler = visible_active;
1.58 -
1.59 - /* Set the line address. */
1.60 -
1.61 - linedata = display_config.screen_start;
1.62 - dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length / 2);
1.63 - dma_set_source(1, PHYSICAL((uint32_t) linedata + display_config.line_length / 2),
1.64 +void start_visible(vga_display_t *vga_display)
1.65 +{
1.66 + dma_set_source(0, PHYSICAL((uint32_t) vga_display->linedata),
1.67 display_config.line_length / 2);
1.68 -
1.69 - /* Enable the channels for the next line. */
1.70 -
1.71 + dma_set_source(1, PHYSICAL((uint32_t) vga_display->linedata +
1.72 + display_config.line_length / 2),
1.73 + display_config.line_length / 2);
1.74 dma_on(0);
1.75 dma_on(1);
1.76 }
1.77
1.78 -/* Visible region. */
1.79 -
1.80 -void visible_active(void)
1.81 -{
1.82 - INV_REG(PORTA, 1 << 2);
1.83 -
1.84 - if (line < VFP_START)
1.85 - {
1.86 - /* Update the line address and handle wraparound. */
1.87 +/* Update the channels for the next line. */
1.88
1.89 - if (!(line % display_config.line_multiplier))
1.90 - {
1.91 - linedata += display_config.line_length;
1.92 - if (linedata >= display_config.screen_limit)
1.93 - linedata -= display_config.screen_size;
1.94 - }
1.95 +void update_visible(vga_display_t *vga_display)
1.96 +{
1.97 + dma_set_source(0, PHYSICAL((uint32_t) vga_display->linedata),
1.98 + display_config.line_length / 2);
1.99 + dma_set_source(1, PHYSICAL((uint32_t) vga_display->linedata +
1.100 + display_config.line_length / 2),
1.101 + display_config.line_length / 2);
1.102 +}
1.103
1.104 - dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length / 2);
1.105 - dma_set_source(1, PHYSICAL((uint32_t) linedata + display_config.line_length / 2),
1.106 - display_config.line_length / 2);
1.107 - return;
1.108 - }
1.109 +/* Disable the channels for the next line. */
1.110
1.111 - /* End the visible region. */
1.112 -
1.113 - state_handler = vfp_active;
1.114 -
1.115 - /* Disable the channels for the next line. */
1.116 -
1.117 +void stop_visible(vga_display_t *vga_display)
1.118 +{
1.119 dma_off(0);
1.120 dma_off(1);
1.121 }
1.122
1.123 -/* Vertical front porch region. */
1.124 -
1.125 -void vfp_active(void)
1.126 -{
1.127 - if (line < VSYNC_START)
1.128 - return;
1.129 +/* Bring vsync low (single compare, output driven low) when the next line
1.130 + starts. */
1.131
1.132 - /* Enter the vertical sync region. */
1.133 -
1.134 - state_handler = vsync_active;
1.135 -
1.136 - /* Bring vsync low (single compare, output driven low) when the next line
1.137 - starts. */
1.138 -
1.139 +void vsync_low(void)
1.140 +{
1.141 oc_init(2, 0b010, 2);
1.142 oc_on(2);
1.143 }
1.144
1.145 -/* Vertical sync region. */
1.146 -
1.147 -void vsync_active(void)
1.148 -{
1.149 - if (line < VSYNC_END)
1.150 - return;
1.151 +/* Bring vsync high (single compare, output driven high) when the next line
1.152 + starts. */
1.153
1.154 - /* Start again at the top of the display. */
1.155 -
1.156 - line = 0;
1.157 - state_handler = vbp_active;
1.158 -
1.159 - /* Bring vsync high (single compare, output driven high) when the next line
1.160 - starts. */
1.161 -
1.162 +void vsync_high(void)
1.163 +{
1.164 oc_init(2, 0b001, 2);
1.165 oc_on(2);
1.166 }
2.1 --- a/examples/vga-dual/main.h Tue Oct 23 23:25:47 2018 +0200
2.2 +++ b/examples/vga-dual/main.h Wed Oct 24 00:50:48 2018 +0200
2.3 @@ -20,16 +20,22 @@
2.4 #ifndef __MAIN_H__
2.5 #define __MAIN_H__
2.6
2.7 +#include "vga_display.h"
2.8 +
2.9 /* Peripheral pin configuration. */
2.10
2.11 void config_oc(void);
2.12 void config_uart(void);
2.13
2.14 -/* Display state handlers. */
2.15 +/* Display operations. */
2.16
2.17 -void vbp_active(void);
2.18 -void visible_active(void);
2.19 -void vfp_active(void);
2.20 -void vsync_active(void);
2.21 +void start_visible(vga_display_t *vga_display);
2.22 +void update_visible(vga_display_t *vga_display);
2.23 +void stop_visible(vga_display_t *vga_display);
2.24 +
2.25 +/* Vertical sync operations. */
2.26 +
2.27 +void vsync_high(void);
2.28 +void vsync_low(void);
2.29
2.30 #endif /* __MAIN_H__ */
3.1 --- a/examples/vga-pmp/main.c Tue Oct 23 23:25:47 2018 +0200
3.2 +++ b/examples/vga-pmp/main.c Wed Oct 24 00:50:48 2018 +0200
3.3 @@ -29,17 +29,9 @@
3.4 #include "vga.h"
3.5 #include "display.h"
3.6 #include "display_config.h"
3.7 -
3.8 +#include "vga_display.h"
3.9
3.10
3.11 -/* Display state. */
3.12 -
3.13 -static void (*state_handler)(void);
3.14 -static uint32_t line;
3.15 -
3.16 -/* Pointers to pixel lines. */
3.17 -
3.18 -static uint8_t *linedata;
3.19
3.20 /* Pixel data. */
3.21
3.22 @@ -75,8 +67,9 @@
3.23
3.24 void main(void)
3.25 {
3.26 - line = 0;
3.27 - state_handler = vbp_active;
3.28 + init_vga(&display_config, start_visible, update_visible, stop_visible,
3.29 + vsync_high, vsync_low);
3.30 +
3.31 test_linedata(&display_config);
3.32
3.33 init_memory();
3.34 @@ -104,7 +97,8 @@
3.35 dma_init(0, 3);
3.36 dma_set_auto_enable(0, 1);
3.37 dma_set_interrupt(0, T2, 1);
3.38 - dma_set_transfer(0, PHYSICAL((uint32_t) linedata), display_config.line_length,
3.39 + dma_set_transfer(0, PHYSICAL((uint32_t) display_config.screen_start),
3.40 + display_config.line_length,
3.41 HW_PHYSICAL(PM_REG(0, PMxDIN)), 1,
3.42 TRANSFER_CELL_SIZE);
3.43
3.44 @@ -175,96 +169,51 @@
3.45
3.46 if (ifs)
3.47 {
3.48 - line += 1;
3.49 - state_handler();
3.50 + vga_interrupt_handler();
3.51 CLR_REG(OCIFS, ifs);
3.52 }
3.53 }
3.54
3.55
3.56
3.57 -/* Vertical back porch region. */
3.58 -
3.59 -void vbp_active(void)
3.60 -{
3.61 - if (line < VISIBLE_START)
3.62 - return;
3.63 -
3.64 - /* Enter the visible region. */
3.65 +/* Enable the channel for the next line. */
3.66
3.67 - state_handler = visible_active;
3.68 -
3.69 - /* Set the line address. */
3.70 -
3.71 - linedata = display_config.screen_start;
3.72 - dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length);
3.73 -
3.74 - /* Enable the channel for the next line. */
3.75 -
3.76 +void start_visible(vga_display_t *vga_display)
3.77 +{
3.78 + dma_set_source(0, PHYSICAL((uint32_t) vga_display->linedata),
3.79 + display_config.line_length);
3.80 dma_on(0);
3.81 }
3.82
3.83 -/* Visible region. */
3.84 -
3.85 -void visible_active(void)
3.86 -{
3.87 - if (line < VFP_START)
3.88 - {
3.89 - /* Update the line address and handle wraparound. */
3.90 +/* Update the channel for the next line. */
3.91
3.92 - if (!(line % display_config.line_multiplier))
3.93 - {
3.94 - linedata += display_config.line_length;
3.95 - if (linedata >= display_config.screen_limit)
3.96 - linedata -= display_config.screen_size;
3.97 - }
3.98 +void update_visible(vga_display_t *vga_display)
3.99 +{
3.100 + dma_set_source(0, PHYSICAL((uint32_t) vga_display->linedata),
3.101 + display_config.line_length);
3.102 +}
3.103
3.104 - dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length);
3.105 - return;
3.106 - }
3.107 +/* Disable the channel for the next line. */
3.108
3.109 - /* End the visible region. */
3.110 -
3.111 - state_handler = vfp_active;
3.112 -
3.113 - /* Disable the channel for the next line. */
3.114 -
3.115 +void stop_visible(vga_display_t *vga_display)
3.116 +{
3.117 dma_off(0);
3.118 }
3.119
3.120 -/* Vertical front porch region. */
3.121 -
3.122 -void vfp_active(void)
3.123 -{
3.124 - if (line < VSYNC_START)
3.125 - return;
3.126 +/* Bring vsync low (single compare, output driven low) when the next line
3.127 + starts. */
3.128
3.129 - /* Enter the vertical sync region. */
3.130 -
3.131 - state_handler = vsync_active;
3.132 -
3.133 - /* Bring vsync low (single compare, output driven low) when the next line
3.134 - starts. */
3.135 -
3.136 +void vsync_low(void)
3.137 +{
3.138 oc_init(2, 0b010, 2);
3.139 oc_on(2);
3.140 }
3.141
3.142 -/* Vertical sync region. */
3.143 -
3.144 -void vsync_active(void)
3.145 -{
3.146 - if (line < VSYNC_END)
3.147 - return;
3.148 +/* Bring vsync high (single compare, output driven high) when the next line
3.149 + starts. */
3.150
3.151 - /* Start again at the top of the display. */
3.152 -
3.153 - line = 0;
3.154 - state_handler = vbp_active;
3.155 -
3.156 - /* Bring vsync high (single compare, output driven high) when the next line
3.157 - starts. */
3.158 -
3.159 +void vsync_high(void)
3.160 +{
3.161 oc_init(2, 0b001, 2);
3.162 oc_on(2);
3.163 }
4.1 --- a/examples/vga-pmp/main.h Tue Oct 23 23:25:47 2018 +0200
4.2 +++ b/examples/vga-pmp/main.h Wed Oct 24 00:50:48 2018 +0200
4.3 @@ -20,16 +20,22 @@
4.4 #ifndef __MAIN_H__
4.5 #define __MAIN_H__
4.6
4.7 +#include "vga_display.h"
4.8 +
4.9 /* Peripheral pin configuration. */
4.10
4.11 void config_oc(void);
4.12 void config_uart(void);
4.13
4.14 -/* Display state handlers. */
4.15 +/* Display operations. */
4.16
4.17 -void vbp_active(void);
4.18 -void visible_active(void);
4.19 -void vfp_active(void);
4.20 -void vsync_active(void);
4.21 +void start_visible(vga_display_t *vga_display);
4.22 +void update_visible(vga_display_t *vga_display);
4.23 +void stop_visible(vga_display_t *vga_display);
4.24 +
4.25 +/* Vertical sync operations. */
4.26 +
4.27 +void vsync_high(void);
4.28 +void vsync_low(void);
4.29
4.30 #endif /* __MAIN_H__ */
5.1 --- a/examples/vga-timer/main.c Tue Oct 23 23:25:47 2018 +0200
5.2 +++ b/examples/vga-timer/main.c Wed Oct 24 00:50:48 2018 +0200
5.3 @@ -29,17 +29,9 @@
5.4 #include "vga.h"
5.5 #include "display.h"
5.6 #include "display_config.h"
5.7 -
5.8 +#include "vga_display.h"
5.9
5.10
5.11 -/* Display state. */
5.12 -
5.13 -static void (*state_handler)(void);
5.14 -static uint32_t line;
5.15 -
5.16 -/* Pointers to pixel lines. */
5.17 -
5.18 -static uint8_t *linedata;
5.19
5.20 /* Pixel data. */
5.21
5.22 @@ -75,8 +67,9 @@
5.23
5.24 void main(void)
5.25 {
5.26 - line = 0;
5.27 - state_handler = vbp_active;
5.28 + init_vga(&display_config, start_visible, update_visible, stop_visible,
5.29 + vsync_high, vsync_low);
5.30 +
5.31 test_linedata(&display_config);
5.32
5.33 init_memory();
5.34 @@ -206,102 +199,57 @@
5.35
5.36 if (ifs)
5.37 {
5.38 - line += 1;
5.39 - state_handler();
5.40 + vga_interrupt_handler();
5.41 CLR_REG(OCIFS, ifs);
5.42 }
5.43 }
5.44
5.45
5.46
5.47 -/* Vertical back porch region. */
5.48 -
5.49 -void vbp_active(void)
5.50 -{
5.51 - if (line < VISIBLE_START)
5.52 - return;
5.53 -
5.54 - /* Enter the visible region. */
5.55 +/* Enable the channels for the next line. */
5.56
5.57 - state_handler = visible_active;
5.58 -
5.59 - /* Set the line address. */
5.60 -
5.61 - linedata = display_config.screen_start;
5.62 - dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length / 2);
5.63 - dma_set_source(2, PHYSICAL((uint32_t) linedata + display_config.line_length / 2),
5.64 +void start_visible(vga_display_t *vga_display)
5.65 +{
5.66 + dma_set_source(0, PHYSICAL((uint32_t) vga_display->linedata),
5.67 display_config.line_length / 2);
5.68 -
5.69 - /* Enable the channels for the next line. */
5.70 -
5.71 + dma_set_source(2, PHYSICAL((uint32_t) vga_display->linedata +
5.72 + display_config.line_length / 2),
5.73 + display_config.line_length / 2);
5.74 dma_on(1);
5.75 }
5.76
5.77 -/* Visible region. */
5.78 -
5.79 -void visible_active(void)
5.80 -{
5.81 - INV_REG(PORTA, 1 << 2);
5.82 -
5.83 - if (line < VFP_START)
5.84 - {
5.85 - /* Update the line address and handle wraparound. */
5.86 +/* Update the channels for the next line. */
5.87
5.88 - if (!(line % display_config.line_multiplier))
5.89 - {
5.90 - linedata += display_config.line_length;
5.91 - if (linedata >= display_config.screen_limit)
5.92 - linedata -= display_config.screen_size;
5.93 - }
5.94 +void update_visible(vga_display_t *vga_display)
5.95 +{
5.96 + dma_set_source(0, PHYSICAL((uint32_t) vga_display->linedata),
5.97 + display_config.line_length / 2);
5.98 + dma_set_source(2, PHYSICAL((uint32_t) vga_display->linedata +
5.99 + display_config.line_length / 2),
5.100 + display_config.line_length / 2);
5.101 +}
5.102
5.103 - dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length / 2);
5.104 - dma_set_source(2, PHYSICAL((uint32_t) linedata + display_config.line_length / 2),
5.105 - display_config.line_length / 2);
5.106 - return;
5.107 - }
5.108 +/* Disable the channels for the next line. */
5.109
5.110 - /* End the visible region. */
5.111 -
5.112 - state_handler = vfp_active;
5.113 -
5.114 - /* Disable the channels for the next line. */
5.115 -
5.116 +void stop_visible(vga_display_t *vga_display)
5.117 +{
5.118 dma_off(1);
5.119 }
5.120
5.121 -/* Vertical front porch region. */
5.122 -
5.123 -void vfp_active(void)
5.124 -{
5.125 - if (line < VSYNC_START)
5.126 - return;
5.127 +/* Bring vsync low (single compare, output driven low) when the next line
5.128 + starts. */
5.129
5.130 - /* Enter the vertical sync region. */
5.131 -
5.132 - state_handler = vsync_active;
5.133 -
5.134 - /* Bring vsync low (single compare, output driven low) when the next line
5.135 - starts. */
5.136 -
5.137 +void vsync_low(void)
5.138 +{
5.139 oc_init(2, 0b010, 2);
5.140 oc_on(2);
5.141 }
5.142
5.143 -/* Vertical sync region. */
5.144 -
5.145 -void vsync_active(void)
5.146 -{
5.147 - if (line < VSYNC_END)
5.148 - return;
5.149 +/* Bring vsync high (single compare, output driven high) when the next line
5.150 + starts. */
5.151
5.152 - /* Start again at the top of the display. */
5.153 -
5.154 - line = 0;
5.155 - state_handler = vbp_active;
5.156 -
5.157 - /* Bring vsync high (single compare, output driven high) when the next line
5.158 - starts. */
5.159 -
5.160 +void vsync_high(void)
5.161 +{
5.162 oc_init(2, 0b001, 2);
5.163 oc_on(2);
5.164 }
6.1 --- a/examples/vga-timer/main.h Tue Oct 23 23:25:47 2018 +0200
6.2 +++ b/examples/vga-timer/main.h Wed Oct 24 00:50:48 2018 +0200
6.3 @@ -20,16 +20,22 @@
6.4 #ifndef __MAIN_H__
6.5 #define __MAIN_H__
6.6
6.7 +#include "vga_display.h"
6.8 +
6.9 /* Peripheral pin configuration. */
6.10
6.11 void config_oc(void);
6.12 void config_uart(void);
6.13
6.14 -/* Display state handlers. */
6.15 +/* Display operations. */
6.16
6.17 -void vbp_active(void);
6.18 -void visible_active(void);
6.19 -void vfp_active(void);
6.20 -void vsync_active(void);
6.21 +void start_visible(vga_display_t *vga_display);
6.22 +void update_visible(vga_display_t *vga_display);
6.23 +void stop_visible(vga_display_t *vga_display);
6.24 +
6.25 +/* Vertical sync operations. */
6.26 +
6.27 +void vsync_high(void);
6.28 +void vsync_low(void);
6.29
6.30 #endif /* __MAIN_H__ */
7.1 --- a/examples/vga/main.c Tue Oct 23 23:25:47 2018 +0200
7.2 +++ b/examples/vga/main.c Wed Oct 24 00:50:48 2018 +0200
7.3 @@ -29,17 +29,9 @@
7.4 #include "vga.h"
7.5 #include "display.h"
7.6 #include "display_config.h"
7.7 -
7.8 +#include "vga_display.h"
7.9
7.10
7.11 -/* Display state. */
7.12 -
7.13 -static void (*state_handler)(void);
7.14 -static uint32_t line;
7.15 -
7.16 -/* Pointers to pixel lines. */
7.17 -
7.18 -static uint8_t *linedata;
7.19
7.20 /* Pixel data. */
7.21
7.22 @@ -75,8 +67,8 @@
7.23
7.24 void main(void)
7.25 {
7.26 - line = 0;
7.27 - state_handler = vbp_active;
7.28 + init_vga(&display_config, start_visible, update_visible, stop_visible,
7.29 + vsync_high, vsync_low);
7.30
7.31 test_linedata(&display_config);
7.32
7.33 @@ -168,98 +160,51 @@
7.34
7.35 if (ifs)
7.36 {
7.37 - line += 1;
7.38 - state_handler();
7.39 + vga_interrupt_handler();
7.40 CLR_REG(OCIFS, ifs);
7.41 }
7.42 }
7.43
7.44
7.45
7.46 -/* Vertical back porch region. */
7.47 -
7.48 -void vbp_active(void)
7.49 -{
7.50 - if (line < VISIBLE_START)
7.51 - return;
7.52 -
7.53 - /* Enter the visible region. */
7.54 +/* Enable the channel for the next line. */
7.55
7.56 - state_handler = visible_active;
7.57 -
7.58 - /* Set the line address. */
7.59 -
7.60 - linedata = display_config.screen_start;
7.61 - dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length);
7.62 -
7.63 - /* Enable the channel for the next line. */
7.64 -
7.65 +void start_visible(vga_display_t *vga_display)
7.66 +{
7.67 + dma_set_source(0, PHYSICAL((uint32_t) vga_display->linedata),
7.68 + display_config.line_length);
7.69 dma_on(0);
7.70 }
7.71
7.72 -/* Visible region. */
7.73 -
7.74 -void visible_active(void)
7.75 -{
7.76 - INV_REG(PORTA, 1 << 2);
7.77 -
7.78 - if (line < VFP_START)
7.79 - {
7.80 - /* Update the line address and handle wraparound. */
7.81 +/* Update the channel for the next line. */
7.82
7.83 - if (!(line % display_config.line_multiplier))
7.84 - {
7.85 - linedata += display_config.line_length;
7.86 - if (linedata >= display_config.screen_limit)
7.87 - linedata -= display_config.screen_size;
7.88 - }
7.89 +void update_visible(vga_display_t *vga_display)
7.90 +{
7.91 + dma_set_source(0, PHYSICAL((uint32_t) vga_display->linedata),
7.92 + display_config.line_length);
7.93 +}
7.94
7.95 - dma_set_source(0, PHYSICAL((uint32_t) linedata), display_config.line_length);
7.96 - return;
7.97 - }
7.98 +/* Disable the channel for the next line. */
7.99
7.100 - /* End the visible region. */
7.101 -
7.102 - state_handler = vfp_active;
7.103 -
7.104 - /* Disable the channel for the next line. */
7.105 -
7.106 +void stop_visible(vga_display_t *vga_display)
7.107 +{
7.108 dma_off(0);
7.109 }
7.110
7.111 -/* Vertical front porch region. */
7.112 -
7.113 -void vfp_active(void)
7.114 -{
7.115 - if (line < VSYNC_START)
7.116 - return;
7.117 +/* Bring vsync low (single compare, output driven low) when the next line
7.118 + starts. */
7.119
7.120 - /* Enter the vertical sync region. */
7.121 -
7.122 - state_handler = vsync_active;
7.123 -
7.124 - /* Bring vsync low (single compare, output driven low) when the next line
7.125 - starts. */
7.126 -
7.127 +void vsync_low(void)
7.128 +{
7.129 oc_init(2, 0b010, 2);
7.130 oc_on(2);
7.131 }
7.132
7.133 -/* Vertical sync region. */
7.134 -
7.135 -void vsync_active(void)
7.136 -{
7.137 - if (line < VSYNC_END)
7.138 - return;
7.139 +/* Bring vsync high (single compare, output driven high) when the next line
7.140 + starts. */
7.141
7.142 - /* Start again at the top of the display. */
7.143 -
7.144 - line = 0;
7.145 - state_handler = vbp_active;
7.146 -
7.147 - /* Bring vsync high (single compare, output driven high) when the next line
7.148 - starts. */
7.149 -
7.150 +void vsync_high(void)
7.151 +{
7.152 oc_init(2, 0b001, 2);
7.153 oc_on(2);
7.154 }
8.1 --- a/examples/vga/main.h Tue Oct 23 23:25:47 2018 +0200
8.2 +++ b/examples/vga/main.h Wed Oct 24 00:50:48 2018 +0200
8.3 @@ -20,16 +20,22 @@
8.4 #ifndef __MAIN_H__
8.5 #define __MAIN_H__
8.6
8.7 +#include "vga_display.h"
8.8 +
8.9 /* Peripheral pin configuration. */
8.10
8.11 void config_oc(void);
8.12 void config_uart(void);
8.13
8.14 -/* Display state handlers. */
8.15 +/* Display operations. */
8.16
8.17 -void vbp_active(void);
8.18 -void visible_active(void);
8.19 -void vfp_active(void);
8.20 -void vsync_active(void);
8.21 +void start_visible(vga_display_t *vga_display);
8.22 +void update_visible(vga_display_t *vga_display);
8.23 +void stop_visible(vga_display_t *vga_display);
8.24 +
8.25 +/* Vertical sync operations. */
8.26 +
8.27 +void vsync_high(void);
8.28 +void vsync_low(void);
8.29
8.30 #endif /* __MAIN_H__ */
9.1 --- a/include/display.h Tue Oct 23 23:25:47 2018 +0200
9.2 +++ b/include/display.h Wed Oct 24 00:50:48 2018 +0200
9.3 @@ -46,6 +46,10 @@
9.4
9.5 int cell_size;
9.6
9.7 + /* Display region scanline positions. */
9.8 +
9.9 + uint32_t visible_start, vfp_start, vsync_start, vsync_end;
9.10 +
9.11 } display_config_t;
9.12
9.13
10.1 --- a/include/display_config.h Tue Oct 23 23:25:47 2018 +0200
10.2 +++ b/include/display_config.h Wed Oct 24 00:50:48 2018 +0200
10.3 @@ -1,5 +1,5 @@
10.4 /*
10.5 - * VGA-specific display-related functions.
10.6 + * Initialisation of application-specific display configuration.
10.7 *
10.8 * Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk>
10.9 *
10.10 @@ -17,22 +17,36 @@
10.11 * along with this program. If not, see <http://www.gnu.org/licenses/>.
10.12 */
10.13
10.14 -#ifndef __DISPLAY_VGA_H__
10.15 -#define __DISPLAY_VGA_H__
10.16 +#ifndef __DISPLAY_CONFIG_H__
10.17 +#define __DISPLAY_CONFIG_H__
10.18
10.19 #include "display.h"
10.20
10.21 uint8_t framebuffer[SCREEN_SIZE];
10.22
10.23 display_config_t display_config = {
10.24 +
10.25 + /* Set the reserved memory as the framebuffer. */
10.26 +
10.27 .framebuffer = framebuffer,
10.28 + .screen_start = framebuffer,
10.29 + .screen_limit = framebuffer + SCREEN_SIZE,
10.30 +
10.31 + /* Define screen dimensions and properties. */
10.32 +
10.33 .screen_size = SCREEN_SIZE,
10.34 .line_length = LINE_LENGTH,
10.35 .line_count = LINE_COUNT,
10.36 .line_multiplier = LINE_MULTIPLIER,
10.37 .cell_size = CELL_SIZE,
10.38 - .screen_start = framebuffer,
10.39 - .screen_limit = framebuffer + SCREEN_SIZE,
10.40 +
10.41 + /* Define display region properties. */
10.42 +
10.43 + .visible_start = VISIBLE_START,
10.44 + .vfp_start = VFP_START,
10.45 + .vsync_start = VSYNC_START,
10.46 + .vsync_end = VSYNC_END,
10.47 +
10.48 };
10.49
10.50 -#endif /* __DISPLAY_VGA_H__ */
10.51 +#endif /* __DISPLAY_CONFIG_H__ */
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/include/vga_display.h Wed Oct 24 00:50:48 2018 +0200
11.3 @@ -0,0 +1,82 @@
11.4 +/*
11.5 + * VGA display-related functions.
11.6 + *
11.7 + * Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk>
11.8 + *
11.9 + * This program is free software: you can redistribute it and/or modify
11.10 + * it under the terms of the GNU General Public License as published by
11.11 + * the Free Software Foundation, either version 3 of the License, or
11.12 + * (at your option) any later version.
11.13 + *
11.14 + * This program is distributed in the hope that it will be useful,
11.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11.17 + * GNU General Public License for more details.
11.18 + *
11.19 + * You should have received a copy of the GNU General Public License
11.20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
11.21 + */
11.22 +
11.23 +#ifndef __VGA_DISPLAY_H__
11.24 +#define __VGA_DISPLAY_H__
11.25 +
11.26 +#include "display.h"
11.27 +
11.28 +
11.29 +
11.30 +/* Display configuration type. */
11.31 +
11.32 +typedef struct
11.33 +{
11.34 + /* Current display state handler. */
11.35 +
11.36 + void (*state_handler)();
11.37 +
11.38 + /* Display state handlers. */
11.39 +
11.40 + void (*start_visible)();
11.41 + void (*update_visible)();
11.42 + void (*stop_visible)();
11.43 +
11.44 + /* Vertical sync operations. */
11.45 +
11.46 + void (*vsync_high)();
11.47 + void (*vsync_low)();
11.48 +
11.49 + /* Current scanline. */
11.50 +
11.51 + uint32_t line;
11.52 +
11.53 + /* Pointers to pixel lines. */
11.54 +
11.55 + uint8_t *linedata;
11.56 +
11.57 + /* General display configuration. */
11.58 +
11.59 + display_config_t *display_config;
11.60 +
11.61 +} vga_display_t;
11.62 +
11.63 +
11.64 +
11.65 +/* Initialisation. */
11.66 +
11.67 +void init_vga(display_config_t *display_config,
11.68 + void (*start_visible)(),
11.69 + void (*update_visible)(),
11.70 + void (*stop_visible)(),
11.71 + void (*vsync_high)(),
11.72 + void (*vsync_low)());
11.73 +
11.74 +/* Interrupt handlers. */
11.75 +
11.76 +void vga_interrupt_handler(void);
11.77 +
11.78 +/* Display state handlers. */
11.79 +
11.80 +void vbp_active(void);
11.81 +void visible_active(void);
11.82 +void vfp_active(void);
11.83 +void vsync_active(void);
11.84 +
11.85 +#endif /* __VGA_DISPLAY_H__ */
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/lib/vga_display.c Wed Oct 24 00:50:48 2018 +0200
12.3 @@ -0,0 +1,150 @@
12.4 +/*
12.5 + * Generate a VGA signal using a PIC32 microcontroller.
12.6 + *
12.7 + * Copyright (C) 2017, 2018 Paul Boddie <paul@boddie.org.uk>
12.8 + *
12.9 + * This program is free software: you can redistribute it and/or modify
12.10 + * it under the terms of the GNU General Public License as published by
12.11 + * the Free Software Foundation, either version 3 of the License, or
12.12 + * (at your option) any later version.
12.13 + *
12.14 + * This program is distributed in the hope that it will be useful,
12.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
12.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12.17 + * GNU General Public License for more details.
12.18 + *
12.19 + * You should have received a copy of the GNU General Public License
12.20 + * along with this program. If not, see <http://www.gnu.org/licenses/>.
12.21 + */
12.22 +
12.23 +#include "pic32_c.h"
12.24 +#include "vga_display.h"
12.25 +
12.26 +
12.27 +
12.28 +/* Display state. */
12.29 +
12.30 +vga_display_t vga_display;
12.31 +
12.32 +
12.33 +
12.34 +/* Initialise the state machine. */
12.35 +
12.36 +void init_vga(display_config_t *display_config,
12.37 + void (*start_visible)(),
12.38 + void (*update_visible)(),
12.39 + void (*stop_visible)(),
12.40 + void (*vsync_high)(),
12.41 + void (*vsync_low)())
12.42 +{
12.43 + /* Display parameters. */
12.44 +
12.45 + vga_display.display_config = display_config;
12.46 +
12.47 + /* Display state handlers. */
12.48 +
12.49 + vga_display.start_visible = start_visible;
12.50 + vga_display.update_visible = update_visible;
12.51 + vga_display.stop_visible = stop_visible;
12.52 +
12.53 + /* Vertical sync operations. */
12.54 +
12.55 + vga_display.vsync_high = vsync_high;
12.56 + vga_display.vsync_low = vsync_low;
12.57 +
12.58 + /* Initial state. */
12.59 +
12.60 + vga_display.state_handler = vbp_active;
12.61 + vga_display.line = 0;
12.62 +}
12.63 +
12.64 +
12.65 +
12.66 +/* Interrupt handlers. */
12.67 +
12.68 +void vga_interrupt_handler(void)
12.69 +{
12.70 + vga_display.line += 1;
12.71 + vga_display.state_handler();
12.72 +}
12.73 +
12.74 +
12.75 +
12.76 +/* Vertical back porch region. */
12.77 +
12.78 +void vbp_active(void)
12.79 +{
12.80 + if (vga_display.line < vga_display.display_config->visible_start)
12.81 + return;
12.82 +
12.83 + /* Enter the visible region. */
12.84 +
12.85 + vga_display.state_handler = visible_active;
12.86 +
12.87 + /* Set the line address. */
12.88 +
12.89 + vga_display.linedata = vga_display.display_config->screen_start;
12.90 + vga_display.start_visible(&vga_display);
12.91 +}
12.92 +
12.93 +/* Visible region. */
12.94 +
12.95 +void visible_active(void)
12.96 +{
12.97 + if (vga_display.line < vga_display.display_config->vfp_start)
12.98 + {
12.99 + /* Update the line address and handle wraparound. */
12.100 +
12.101 + if (!(vga_display.line % vga_display.display_config->line_multiplier))
12.102 + {
12.103 + vga_display.linedata += vga_display.display_config->line_length;
12.104 +
12.105 + if (vga_display.linedata >= vga_display.display_config->screen_limit)
12.106 + vga_display.linedata -= vga_display.display_config->screen_size;
12.107 + }
12.108 +
12.109 + vga_display.update_visible(&vga_display);
12.110 + return;
12.111 + }
12.112 +
12.113 + /* End the visible region. */
12.114 +
12.115 + vga_display.state_handler = vfp_active;
12.116 +
12.117 + /* Disable the channel for the next line. */
12.118 +
12.119 + vga_display.stop_visible(&vga_display);
12.120 +}
12.121 +
12.122 +/* Vertical front porch region. */
12.123 +
12.124 +void vfp_active(void)
12.125 +{
12.126 + if (vga_display.line < vga_display.display_config->vsync_start)
12.127 + return;
12.128 +
12.129 + /* Enter the vertical sync region. */
12.130 +
12.131 + vga_display.state_handler = vsync_active;
12.132 +
12.133 + /* Bring vsync low when the next line starts. */
12.134 +
12.135 + vga_display.vsync_low();
12.136 +}
12.137 +
12.138 +/* Vertical sync region. */
12.139 +
12.140 +void vsync_active(void)
12.141 +{
12.142 + if (vga_display.line < vga_display.display_config->vsync_end)
12.143 + return;
12.144 +
12.145 + /* Start again at the top of the display. */
12.146 +
12.147 + vga_display.line = 0;
12.148 + vga_display.state_handler = vbp_active;
12.149 +
12.150 + /* Bring vsync high when the next line starts. */
12.151 +
12.152 + vga_display.vsync_high();
12.153 +}
13.1 --- a/mk/common.mk Tue Oct 23 23:25:47 2018 +0200
13.2 +++ b/mk/common.mk Wed Oct 24 00:50:48 2018 +0200
13.3 @@ -51,8 +51,8 @@
13.4 COMMON_SRC = $(LIBDIR)/init.c $(LIBDIR)/debug.c $(LIBDIR)/cpu.S
13.5 COMMON_OBJ = $(LIBDIR)/init.o $(LIBDIR)/debug.o $(LIBDIR)/cpu.o
13.6
13.7 -DISPLAY_SRC = $(LIBDIR)/display.c
13.8 -DISPLAY_OBJ = $(LIBDIR)/display.o
13.9 +DISPLAY_SRC = $(LIBDIR)/display.c $(LIBDIR)/vga_display.c
13.10 +DISPLAY_OBJ = $(LIBDIR)/display.o $(LIBDIR)/vga_display.o
13.11
13.12 # Common linker script.
13.13