1.1 --- a/examples/vga-dual/Makefile Thu Oct 25 21:11:22 2018 +0200
1.2 +++ b/examples/vga-dual/Makefile Thu Oct 25 21:19:01 2018 +0200
1.3 @@ -30,4 +30,9 @@
1.4 SRC = $(START_SRC) main.c $(COMMON_SRC) $(DISPLAY_SRC)
1.5 OBJ = $(START_OBJ) main.o $(COMMON_OBJ) $(DISPLAY_OBJ)
1.6
1.7 +# Application-specific adjustments.
1.8 +# See: examples/vga/Makefile
1.9 +
1.10 +CFLAGS += -DLINE_CHANNELS=2 -I../vga
1.11 +
1.12 include ../../mk/rules.mk
2.1 --- a/examples/vga-dual/devconfig.h Thu Oct 25 21:11:22 2018 +0200
2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2.3 @@ -1,63 +0,0 @@
2.4 -/*
2.5 - * Device configuration.
2.6 - *
2.7 - * Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk>
2.8 - *
2.9 - * This program is free software: you can redistribute it and/or modify
2.10 - * it under the terms of the GNU General Public License as published by
2.11 - * the Free Software Foundation, either version 3 of the License, or
2.12 - * (at your option) any later version.
2.13 - *
2.14 - * This program is distributed in the hope that it will be useful,
2.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
2.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.17 - * GNU General Public License for more details.
2.18 - *
2.19 - * You should have received a copy of the GNU General Public License
2.20 - * along with this program. If not, see <http://www.gnu.org/licenses/>.
2.21 - */
2.22 -
2.23 -#ifndef __CONFIG_H__
2.24 -#define __CONFIG_H__
2.25 -
2.26 -#include "pic32.h"
2.27 -
2.28 -/*
2.29 -Set the oscillator to be the FRC oscillator with PLL, with peripheral clock
2.30 -divided by 2 (FPBDIV), and FRCDIV+PLL selected (FNOSC).
2.31 -
2.32 -The watchdog timer (FWDTEN) is also disabled.
2.33 -
2.34 -The secondary oscillator pin (FSOSCEN) is disabled to avoid pin conflicts with
2.35 -RPB4.
2.36 -*/
2.37 -
2.38 -#define DEVCFG1_CONFIG (DEVCFG1_FWDTEN_OFF | DEVCFG1_FPBDIV_2 | \
2.39 - DEVCFG1_OSCIOFNC_OFF | DEVCFG1_FSOSCEN_OFF | \
2.40 - DEVCFG1_FNOSC_FRCDIV_PLL)
2.41 -
2.42 -/*
2.43 -Set the FRC oscillator PLL function with an input division of 2, an output
2.44 -division of 2, a multiplication of 24, yielding a multiplication of 6.
2.45 -
2.46 -The FRC is apparently at 8MHz but enforces input division of 2 to produce a
2.47 -frequency in the acceptable range from 4MHz to 5MHz for the PLL:
2.48 -
2.49 -8MHz / 2 = 4MHz
2.50 -
2.51 -Multiplication and output division should produce a system clock of 48MHz:
2.52 -
2.53 -4MHz * 24 / 2 = 48MHz
2.54 -*/
2.55 -
2.56 -#define DEVCFG2_CONFIG (DEVCFG2_FPLLODIV_2 | DEVCFG2_FPLLMUL_24 | \
2.57 - DEVCFG2_FPLLIDIV_2)
2.58 -
2.59 -/*
2.60 -The peripheral clock frequency (FPB) will be 24MHz given the above DEVCFG1 and
2.61 -DEVCFG2 settings.
2.62 -*/
2.63 -
2.64 -#define FPB 24000000
2.65 -
2.66 -#endif /* __CONFIG_H__ */
3.1 --- a/examples/vga-dual/main.c Thu Oct 25 21:11:22 2018 +0200
3.2 +++ b/examples/vga-dual/main.c Thu Oct 25 21:19:01 2018 +0200
3.3 @@ -1,148 +1,1 @@
3.4 -/*
3.5 - * Generate a VGA signal using a PIC32 microcontroller.
3.6 - *
3.7 - * Copyright (C) 2017, 2018 Paul Boddie <paul@boddie.org.uk>
3.8 - *
3.9 - * This program is free software: you can redistribute it and/or modify
3.10 - * it under the terms of the GNU General Public License as published by
3.11 - * the Free Software Foundation, either version 3 of the License, or
3.12 - * (at your option) any later version.
3.13 - *
3.14 - * This program is distributed in the hope that it will be useful,
3.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
3.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3.17 - * GNU General Public License for more details.
3.18 - *
3.19 - * You should have received a copy of the GNU General Public License
3.20 - * along with this program. If not, see <http://www.gnu.org/licenses/>.
3.21 - */
3.22 -
3.23 -
3.24 -#include "pic32_c.h"
3.25 -#include "init.h"
3.26 -#include "debug.h"
3.27 -
3.28 -/* Specific functionality. */
3.29 -
3.30 -#include "main.h"
3.31 -#include "devconfig.h"
3.32 -#include "vga.h"
3.33 -#include "display.h"
3.34 -#include "display_config.h"
3.35 -#include "vga_display.h"
3.36 -
3.37 -
3.38 -
3.39 -/* Blink an attached LED with delays implemented using a loop. */
3.40 -
3.41 -static void blink(uint32_t delay, uint32_t port, uint32_t pins)
3.42 -{
3.43 - uint32_t counter;
3.44 -
3.45 - /* Clear outputs (LED). */
3.46 -
3.47 - CLR_REG(port, pins);
3.48 -
3.49 - while (1)
3.50 - {
3.51 - counter = delay;
3.52 -
3.53 - while (counter--) __asm__(""); /* retain loop */
3.54 -
3.55 - /* Invert outputs (LED). */
3.56 -
3.57 - INV_REG(port, pins);
3.58 - }
3.59 -}
3.60 -
3.61 -
3.62 -
3.63 -/* Main program. */
3.64 -
3.65 -void main(void)
3.66 -{
3.67 - init_memory();
3.68 - init_pins();
3.69 - init_outputs();
3.70 -
3.71 - unlock_config();
3.72 - config_oc();
3.73 - config_uart();
3.74 - lock_config();
3.75 -
3.76 - init_dma();
3.77 -
3.78 - /* Initialise VGA output structures with two line channels and no initiating
3.79 - channel. */
3.80 -
3.81 - init_vga(&display_config, 2, -1);
3.82 -
3.83 - /* Configure VGA output transfer details along with a timer and output
3.84 - compare units for horizontal and vertical sync. */
3.85 -
3.86 - vga_configure_transfer(T2, PORTB);
3.87 - vga_configure_sync(1, 2, 2);
3.88 -
3.89 - uart_init(1, FPB, 115200);
3.90 - uart_on(1);
3.91 -
3.92 - test_linedata(&display_config);
3.93 -
3.94 - interrupts_on();
3.95 -
3.96 - blink(3 << 24, PORTA, 1 << 3);
3.97 -}
3.98 -
3.99 -
3.100 -
3.101 -/* Exception and interrupt handlers. */
3.102 -
3.103 -void exception_handler(void)
3.104 -{
3.105 - blink(3 << 12, PORTA, 1 << 3);
3.106 -}
3.107 -
3.108 -void interrupt_handler(void)
3.109 -{
3.110 - uint32_t ifs;
3.111 -
3.112 - /* Check for a OC1 interrupt condition. */
3.113 -
3.114 - ifs = REG(OCIFS) & OC_INT_FLAGS(1, OCxIF);
3.115 -
3.116 - if (ifs)
3.117 - {
3.118 - vga_interrupt_handler();
3.119 - CLR_REG(OCIFS, ifs);
3.120 - }
3.121 -}
3.122 -
3.123 -
3.124 -
3.125 -/* Peripheral pin configuration. */
3.126 -
3.127 -void config_oc(void)
3.128 -{
3.129 - /* Map OC1 to RPA0. */
3.130 -
3.131 - REG(RPA0R) = 0b0101; /* RPA0R<3:0> = 0101 (OC1) */
3.132 -
3.133 - /* Map OC2 to RPA1. */
3.134 -
3.135 - REG(RPA1R) = 0b0101; /* RPA1R<3:0> = 0101 (OC2) */
3.136 -}
3.137 -
3.138 -void config_uart(void)
3.139 -{
3.140 - /* Map U1RX to RPB13. */
3.141 -
3.142 - REG(U1RXR) = 0b0011; /* U1RXR<3:0> = 0011 (RPB13) */
3.143 -
3.144 - /* Map U1TX to RPB15. */
3.145 -
3.146 - REG(RPB15R) = 0b0001; /* RPB15R<3:0> = 0001 (U1TX) */
3.147 -
3.148 - /* Set RPB13 to input. */
3.149 -
3.150 - SET_REG(TRISB, 1 << 13);
3.151 -}
3.152 +../vga/main.c
3.153 \ No newline at end of file
4.1 --- a/examples/vga-dual/main.h Thu Oct 25 21:11:22 2018 +0200
4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
4.3 @@ -1,30 +0,0 @@
4.4 -/*
4.5 - * Generate a VGA signal using a PIC32 microcontroller.
4.6 - *
4.7 - * Copyright (C) 2017, 2018 Paul Boddie <paul@boddie.org.uk>
4.8 - *
4.9 - * This program is free software: you can redistribute it and/or modify
4.10 - * it under the terms of the GNU General Public License as published by
4.11 - * the Free Software Foundation, either version 3 of the License, or
4.12 - * (at your option) any later version.
4.13 - *
4.14 - * This program is distributed in the hope that it will be useful,
4.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
4.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4.17 - * GNU General Public License for more details.
4.18 - *
4.19 - * You should have received a copy of the GNU General Public License
4.20 - * along with this program. If not, see <http://www.gnu.org/licenses/>.
4.21 - */
4.22 -
4.23 -#ifndef __MAIN_H__
4.24 -#define __MAIN_H__
4.25 -
4.26 -#include "vga_display.h"
4.27 -
4.28 -/* Peripheral pin configuration. */
4.29 -
4.30 -void config_oc(void);
4.31 -void config_uart(void);
4.32 -
4.33 -#endif /* __MAIN_H__ */
5.1 --- a/examples/vga-pmp/Makefile Thu Oct 25 21:11:22 2018 +0200
5.2 +++ b/examples/vga-pmp/Makefile Thu Oct 25 21:19:01 2018 +0200
5.3 @@ -30,4 +30,8 @@
5.4 SRC = $(START_SRC) main.c $(COMMON_SRC) $(DISPLAY_SRC)
5.5 OBJ = $(START_OBJ) main.o $(COMMON_OBJ) $(DISPLAY_OBJ)
5.6
5.7 +# Application-specific adjustments.
5.8 +
5.9 +CFLAGS += -I../vga
5.10 +
5.11 include ../../mk/rules.mk
6.1 --- a/examples/vga-pmp/main.c Thu Oct 25 21:11:22 2018 +0200
6.2 +++ b/examples/vga-pmp/main.c Thu Oct 25 21:19:01 2018 +0200
6.3 @@ -79,16 +79,16 @@
6.4 pm_set_output(0, 1, 0);
6.5 pm_on(0);
6.6
6.7 - /* Initialise VGA output structures with a single line channel and no
6.8 - initiating channel. */
6.9 + /* Initialise VGA output with a single line channel, configuring Timer2,
6.10 + with no transfer timer and thus no initiating channel. */
6.11
6.12 - init_vga(&display_config, 1, -1);
6.13 + init_vga_with_timers(&display_config, 1, 2, 0);
6.14
6.15 - /* Configure VGA output transfer details along with a timer and output
6.16 - compare units for horizontal and vertical sync. */
6.17 + /* Configure VGA output transfer to the parallel mode output register, also
6.18 + configuring output compare units for horizontal and vertical sync. */
6.19
6.20 - vga_configure_transfer(T2, PM_REG(0, PMxDIN));
6.21 - vga_configure_sync(1, 2, 2);
6.22 + vga_configure_transfer(PM_REG(0, PMxDIN));
6.23 + vga_configure_sync(1, 2);
6.24
6.25 uart_init(1, FPB, 115200);
6.26 uart_on(1);
7.1 --- a/examples/vga-pmp/main.h Thu Oct 25 21:11:22 2018 +0200
7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
7.3 @@ -1,30 +0,0 @@
7.4 -/*
7.5 - * Generate a VGA signal using a PIC32 microcontroller.
7.6 - *
7.7 - * Copyright (C) 2017, 2018 Paul Boddie <paul@boddie.org.uk>
7.8 - *
7.9 - * This program is free software: you can redistribute it and/or modify
7.10 - * it under the terms of the GNU General Public License as published by
7.11 - * the Free Software Foundation, either version 3 of the License, or
7.12 - * (at your option) any later version.
7.13 - *
7.14 - * This program is distributed in the hope that it will be useful,
7.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
7.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7.17 - * GNU General Public License for more details.
7.18 - *
7.19 - * You should have received a copy of the GNU General Public License
7.20 - * along with this program. If not, see <http://www.gnu.org/licenses/>.
7.21 - */
7.22 -
7.23 -#ifndef __MAIN_H__
7.24 -#define __MAIN_H__
7.25 -
7.26 -#include "vga_display.h"
7.27 -
7.28 -/* Peripheral pin configuration. */
7.29 -
7.30 -void config_oc(void);
7.31 -void config_uart(void);
7.32 -
7.33 -#endif /* __MAIN_H__ */
8.1 --- a/examples/vga-timer/Makefile Thu Oct 25 21:11:22 2018 +0200
8.2 +++ b/examples/vga-timer/Makefile Thu Oct 25 21:19:01 2018 +0200
8.3 @@ -30,4 +30,9 @@
8.4 SRC = $(START_SRC) main.c $(COMMON_SRC) $(DISPLAY_SRC)
8.5 OBJ = $(START_OBJ) main.o $(COMMON_OBJ) $(DISPLAY_OBJ)
8.6
8.7 +# Application-specific adjustments.
8.8 +# See: examples/vga/Makefile
8.9 +
8.10 +CFLAGS += -DLINE_CHANNELS=2 -DTRANSFER_TIMER=3 -I../vga
8.11 +
8.12 include ../../mk/rules.mk
9.1 --- a/examples/vga-timer/devconfig.h Thu Oct 25 21:11:22 2018 +0200
9.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
9.3 @@ -1,63 +0,0 @@
9.4 -/*
9.5 - * Device configuration.
9.6 - *
9.7 - * Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk>
9.8 - *
9.9 - * This program is free software: you can redistribute it and/or modify
9.10 - * it under the terms of the GNU General Public License as published by
9.11 - * the Free Software Foundation, either version 3 of the License, or
9.12 - * (at your option) any later version.
9.13 - *
9.14 - * This program is distributed in the hope that it will be useful,
9.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
9.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9.17 - * GNU General Public License for more details.
9.18 - *
9.19 - * You should have received a copy of the GNU General Public License
9.20 - * along with this program. If not, see <http://www.gnu.org/licenses/>.
9.21 - */
9.22 -
9.23 -#ifndef __CONFIG_H__
9.24 -#define __CONFIG_H__
9.25 -
9.26 -#include "pic32.h"
9.27 -
9.28 -/*
9.29 -Set the oscillator to be the FRC oscillator with PLL, with peripheral clock
9.30 -divided by 2 (FPBDIV), and FRCDIV+PLL selected (FNOSC).
9.31 -
9.32 -The watchdog timer (FWDTEN) is also disabled.
9.33 -
9.34 -The secondary oscillator pin (FSOSCEN) is disabled to avoid pin conflicts with
9.35 -RPB4.
9.36 -*/
9.37 -
9.38 -#define DEVCFG1_CONFIG (DEVCFG1_FWDTEN_OFF | DEVCFG1_FPBDIV_2 | \
9.39 - DEVCFG1_OSCIOFNC_OFF | DEVCFG1_FSOSCEN_OFF | \
9.40 - DEVCFG1_FNOSC_FRCDIV_PLL)
9.41 -
9.42 -/*
9.43 -Set the FRC oscillator PLL function with an input division of 2, an output
9.44 -division of 2, a multiplication of 24, yielding a multiplication of 6.
9.45 -
9.46 -The FRC is apparently at 8MHz but enforces input division of 2 to produce a
9.47 -frequency in the acceptable range from 4MHz to 5MHz for the PLL:
9.48 -
9.49 -8MHz / 2 = 4MHz
9.50 -
9.51 -Multiplication and output division should produce a system clock of 48MHz:
9.52 -
9.53 -4MHz * 24 / 2 = 48MHz
9.54 -*/
9.55 -
9.56 -#define DEVCFG2_CONFIG (DEVCFG2_FPLLODIV_2 | DEVCFG2_FPLLMUL_24 | \
9.57 - DEVCFG2_FPLLIDIV_2)
9.58 -
9.59 -/*
9.60 -The peripheral clock frequency (FPB) will be 24MHz given the above DEVCFG1 and
9.61 -DEVCFG2 settings.
9.62 -*/
9.63 -
9.64 -#define FPB 24000000
9.65 -
9.66 -#endif /* __CONFIG_H__ */
10.1 --- a/examples/vga-timer/main.c Thu Oct 25 21:11:22 2018 +0200
10.2 +++ b/examples/vga-timer/main.c Thu Oct 25 21:19:01 2018 +0200
10.3 @@ -1,165 +1,1 @@
10.4 -/*
10.5 - * Generate a VGA signal using a PIC32 microcontroller.
10.6 - *
10.7 - * Copyright (C) 2017, 2018 Paul Boddie <paul@boddie.org.uk>
10.8 - *
10.9 - * This program is free software: you can redistribute it and/or modify
10.10 - * it under the terms of the GNU General Public License as published by
10.11 - * the Free Software Foundation, either version 3 of the License, or
10.12 - * (at your option) any later version.
10.13 - *
10.14 - * This program is distributed in the hope that it will be useful,
10.15 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
10.16 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10.17 - * GNU General Public License for more details.
10.18 - *
10.19 - * You should have received a copy of the GNU General Public License
10.20 - * along with this program. If not, see <http://www.gnu.org/licenses/>.
10.21 - */
10.22 -
10.23 -
10.24 -#include "pic32_c.h"
10.25 -#include "init.h"
10.26 -#include "debug.h"
10.27 -
10.28 -/* Specific functionality. */
10.29 -
10.30 -#include "main.h"
10.31 -#include "devconfig.h"
10.32 -#include "vga.h"
10.33 -#include "display.h"
10.34 -#include "display_config.h"
10.35 -#include "vga_display.h"
10.36 -
10.37 -
10.38 -
10.39 -/* Blink an attached LED with delays implemented using a loop. */
10.40 -
10.41 -static void blink(uint32_t delay, uint32_t port, uint32_t pins)
10.42 -{
10.43 - uint32_t counter;
10.44 -
10.45 - /* Clear outputs (LED). */
10.46 -
10.47 - CLR_REG(port, pins);
10.48 -
10.49 - while (1)
10.50 - {
10.51 - counter = delay;
10.52 -
10.53 - while (counter--) __asm__(""); /* retain loop */
10.54 -
10.55 - /* Invert outputs (LED). */
10.56 -
10.57 - INV_REG(port, pins);
10.58 - }
10.59 -}
10.60 -
10.61 -
10.62 -
10.63 -/* Main program. */
10.64 -
10.65 -void main(void)
10.66 -{
10.67 - init_memory();
10.68 - init_pins();
10.69 - init_outputs();
10.70 -
10.71 - unlock_config();
10.72 - config_oc();
10.73 - config_uart();
10.74 - lock_config();
10.75 -
10.76 - init_dma();
10.77 -
10.78 - /* Initialise VGA output structures with two line channels and an initiating
10.79 - channel. */
10.80 -
10.81 - init_vga(&display_config, 2, T2);
10.82 -
10.83 - /* Peripheral relationships:
10.84 -
10.85 - Timer2 -> OC1
10.86 - -> OC2 (vertical sync region)
10.87 - -> DMA1: zerodata -> PORTB (visible region)
10.88 - |
10.89 - Timer3 -> DMA0: linedata -> PORTB
10.90 - Timer3 -> DMA2: linedata -> PORTB
10.91 - |
10.92 - Timer3 -> DMA3: zerodata -> PORTB
10.93 - */
10.94 -
10.95 - /* Configure VGA output transfer details along with a timer and output
10.96 - compare units for horizontal and vertical sync. */
10.97 -
10.98 - vga_configure_transfer(T3, PORTB);
10.99 - vga_configure_sync(1, 2, 2);
10.100 -
10.101 - /* Configure a timer for line data transfers. */
10.102 -
10.103 - timer_init(3, 0, 1);
10.104 - timer_on(3);
10.105 -
10.106 - uart_init(1, FPB, 115200);
10.107 - uart_on(1);
10.108 -
10.109 - test_linedata(&display_config);
10.110 -
10.111 - interrupts_on();
10.112 -
10.113 - blink(3 << 24, PORTA, 1 << 3);
10.114 -}
10.115 -
10.116 -
10.117 -
10.118 -/* Exception and interrupt handlers. */
10.119 -
10.120 -void exception_handler(void)
10.121 -{
10.122 - blink(3 << 12, PORTA, 1 << 3);
10.123 -}
10.124 -
10.125 -void interrupt_handler(void)
10.126 -{
10.127 - uint32_t ifs;
10.128 -
10.129 - /* Check for a OC1 interrupt condition. */
10.130 -
10.131 - ifs = REG(OCIFS) & OC_INT_FLAGS(1, OCxIF);
10.132 -
10.133 - if (ifs)
10.134 - {
10.135 - vga_interrupt_handler();
10.136 - CLR_REG(OCIFS, ifs);
10.137 - }
10.138 -}
10.139 -
10.140 -
10.141 -
10.142 -/* Peripheral pin configuration. */
10.143 -
10.144 -void config_oc(void)
10.145 -{
10.146 - /* Map OC1 to RPA0. */
10.147 -
10.148 - REG(RPA0R) = 0b0101; /* RPA0R<3:0> = 0101 (OC1) */
10.149 -
10.150 - /* Map OC2 to RPA1. */
10.151 -
10.152 - REG(RPA1R) = 0b0101; /* RPA1R<3:0> = 0101 (OC2) */
10.153 -}
10.154 -
10.155 -void config_uart(void)
10.156 -{
10.157 - /* Map U1RX to RPB13. */
10.158 -
10.159 - REG(U1RXR) = 0b0011; /* U1RXR<3:0> = 0011 (RPB13) */
10.160 -
10.161 - /* Map U1TX to RPB15. */
10.162 -
10.163 - REG(RPB15R) = 0b0001; /* RPB15R<3:0> = 0001 (U1TX) */
10.164 -
10.165 - /* Set RPB13 to input. */
10.166 -
10.167 - SET_REG(TRISB, 1 << 13);
10.168 -}
10.169 +../vga/main.c
10.170 \ No newline at end of file
11.1 --- a/examples/vga-timer/main.h Thu Oct 25 21:11:22 2018 +0200
11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
11.3 @@ -1,30 +0,0 @@
11.4 -/*
11.5 - * Generate a VGA signal using a PIC32 microcontroller.
11.6 - *
11.7 - * Copyright (C) 2017, 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 __MAIN_H__
11.24 -#define __MAIN_H__
11.25 -
11.26 -#include "vga_display.h"
11.27 -
11.28 -/* Peripheral pin configuration. */
11.29 -
11.30 -void config_oc(void);
11.31 -void config_uart(void);
11.32 -
11.33 -#endif /* __MAIN_H__ */
12.1 --- a/examples/vga/Makefile Thu Oct 25 21:11:22 2018 +0200
12.2 +++ b/examples/vga/Makefile Thu Oct 25 21:19:01 2018 +0200
12.3 @@ -30,4 +30,13 @@
12.4 SRC = $(START_SRC) main.c $(COMMON_SRC) $(DISPLAY_SRC)
12.5 OBJ = $(START_OBJ) main.o $(COMMON_OBJ) $(DISPLAY_OBJ)
12.6
12.7 +# Application-specific adjustments.
12.8 +
12.9 +# Setting: Default: Alternatives:
12.10 +# LINE_CHANNELS 1 2
12.11 +# LINE_TIMER 2 3, 4, 5
12.12 +# TRANSFER_TIMER 0 2, 3, 4, 5
12.13 +
12.14 +CFLAGS += -DLINE_CHANNELS=1
12.15 +
12.16 include ../../mk/rules.mk
13.1 --- a/examples/vga/main.c Thu Oct 25 21:11:22 2018 +0200
13.2 +++ b/examples/vga/main.c Thu Oct 25 21:19:01 2018 +0200
13.3 @@ -33,6 +33,22 @@
13.4
13.5
13.6
13.7 +/* Define timers if not indicated in the build configuration. */
13.8 +
13.9 +#ifndef LINE_CHANNELS
13.10 +#define LINE_CHANNELS 1
13.11 +#endif
13.12 +
13.13 +#ifndef LINE_TIMER
13.14 +#define LINE_TIMER 2
13.15 +#endif
13.16 +
13.17 +#ifndef TRANSFER_TIMER
13.18 +#define TRANSFER_TIMER 0
13.19 +#endif
13.20 +
13.21 +
13.22 +
13.23 /* Blink an attached LED with delays implemented using a loop. */
13.24
13.25 static void blink(uint32_t delay, uint32_t port, uint32_t pins)
13.26 @@ -72,16 +88,17 @@
13.27
13.28 init_dma();
13.29
13.30 - /* Initialise VGA output structures with a single line channel and no
13.31 - initiating channel. */
13.32 + /* Initialise VGA output with one or two line channels, configuring a line
13.33 + timer and any transfer timer, with an initiating channel being introduced
13.34 + if a transfer timer is specified. */
13.35
13.36 - init_vga(&display_config, 1, -1);
13.37 + init_vga_with_timers(&display_config, LINE_CHANNELS, LINE_TIMER, TRANSFER_TIMER);
13.38
13.39 - /* Configure VGA output transfer details along with a timer and output
13.40 - compare units for horizontal and vertical sync. */
13.41 + /* Configure VGA output transfer to the output register, also configuring
13.42 + output compare units for horizontal and vertical sync. */
13.43
13.44 - vga_configure_transfer(T2, PORTB);
13.45 - vga_configure_sync(1, 2, 2);
13.46 + vga_configure_transfer(PORTB);
13.47 + vga_configure_sync(1, 2);
13.48
13.49 uart_init(1, FPB, 115200);
13.50 uart_on(1);
14.1 --- a/include/vga_display.h Thu Oct 25 21:11:22 2018 +0200
14.2 +++ b/include/vga_display.h Thu Oct 25 21:19:01 2018 +0200
14.3 @@ -35,11 +35,11 @@
14.4
14.5 /* DMA transfer properties. */
14.6
14.7 - int line_channels, initiating_int_num;
14.8 + int line_timer, line_channels, transfer_int_num;
14.9
14.10 /* Horizontal and vertical sync peripherals. */
14.11
14.12 - int timer, hsync_unit, vsync_unit;
14.13 + int hsync_unit, vsync_unit;
14.14
14.15 /* Current scanline. */
14.16
14.17 @@ -60,11 +60,16 @@
14.18 /* Initialisation. */
14.19
14.20 void init_vga(display_config_t *display_config, int line_channels,
14.21 - int initiating_int_num);
14.22 + int line_timer, int initiating_int_num);
14.23 +
14.24 +void init_vga_with_timers(display_config_t *display_config, int line_channels,
14.25 + int line_timer, int transfer_timer);
14.26
14.27 -void vga_configure_sync(int hsync_unit, int vsync_unit, int timer);
14.28 +void vga_configure_sync(int hsync_unit, int vsync_unit);
14.29
14.30 -void vga_configure_transfer(int transfer_int_num, uint32_t output);
14.31 +void vga_configure_transfer(uint32_t output);
14.32 +
14.33 +/* Initialisation helpers. */
14.34
14.35 void vga_configure_line_channel(int channel, int int_num, enum dma_chain chain,
14.36 uint32_t output);
15.1 --- a/lib/vga_display.c Thu Oct 25 21:11:22 2018 +0200
15.2 +++ b/lib/vga_display.c Thu Oct 25 21:19:01 2018 +0200
15.3 @@ -37,30 +37,78 @@
15.4 /* Initialise the state machine. */
15.5
15.6 void init_vga(display_config_t *display_config, int line_channels,
15.7 - int initiating_int_num)
15.8 + int line_timer, int transfer_int_num)
15.9 {
15.10 /* Display parameters. */
15.11
15.12 vga_display.display_config = display_config;
15.13 vga_display.line_channels = line_channels;
15.14 - vga_display.initiating_int_num = initiating_int_num;
15.15
15.16 /* Initial state. */
15.17
15.18 vga_display.state_handler = vbp_active;
15.19 vga_display.line = 0;
15.20 +
15.21 + /* Configure a general display timer to start line data transfer and for the
15.22 + horizontal sync. */
15.23 +
15.24 + vga_display.line_timer = line_timer;
15.25 +
15.26 + /* Configure a separate transfer interrupt condition, if indicated.
15.27 + Otherwise, transfers are initiated by the line timer. */
15.28 +
15.29 + vga_display.transfer_int_num = transfer_int_num;
15.30 +}
15.31 +
15.32 +/* Initialise a separate transfer timer if different from the general display
15.33 + timer. */
15.34 +
15.35 +void init_vga_with_timers(display_config_t *display_config, int line_channels,
15.36 + int line_timer, int transfer_timer)
15.37 +{
15.38 + /* Initialise the basic properties of the display. */
15.39 +
15.40 + init_vga(display_config, line_channels, line_timer,
15.41 + transfer_timer ? timer_interrupt_number(transfer_timer) : -1);
15.42 +
15.43 + /* Configure a line timer for horizontal sync and line data transfers. */
15.44 +
15.45 + /* The timers have no prescaling (0). */
15.46 +
15.47 + timer_init(line_timer, 0, display_config->hfreq_limit);
15.48 + timer_on(line_timer);
15.49 +
15.50 + /* Configure a separate transfer timer, if indicated. */
15.51 +
15.52 + if (!transfer_timer || (transfer_timer == line_timer))
15.53 + return;
15.54 +
15.55 + /* The timer wraps around immediately. */
15.56 +
15.57 + timer_init(transfer_timer, 0, 1);
15.58 + timer_on(transfer_timer);
15.59 }
15.60
15.61
15.62
15.63 /* Configure DMA channels for the transfer of pixel data. */
15.64
15.65 -void vga_configure_transfer(int transfer_int_num, uint32_t output)
15.66 +void vga_configure_transfer(uint32_t output)
15.67 {
15.68 - int initiating_channel = vga_display.initiating_int_num >= 0;
15.69 int dual_channel = vga_display.line_channels == 2;
15.70 int channel = 0;
15.71
15.72 + /* Determine whether an initiating channel is used. */
15.73 +
15.74 + int initiating_channel = vga_display.transfer_int_num >= 0;
15.75 +
15.76 + /* Determine the different interrupt conditions, with pixel data employing
15.77 + any specified transfer condition or the line condition otherwise. */
15.78 +
15.79 + int line_int_num = timer_interrupt_number(vga_display.line_timer);
15.80 + int transfer_int_num = initiating_channel ?
15.81 + vga_display.transfer_int_num : line_int_num;
15.82 +
15.83 /* Where dual line channels are involved, put the first before any
15.84 initiating channel, chaining it to such a channel. */
15.85
15.86 @@ -71,13 +119,12 @@
15.87 output);
15.88 }
15.89
15.90 - /* Introduce a special initiating channel if an interrupt has been
15.91 - indicated. */
15.92 + /* Introduce a special initiating channel if a separate transfer interrupt
15.93 + has been indicated. */
15.94
15.95 if (initiating_channel)
15.96 {
15.97 - vga_configure_zero_channel(channel++, vga_display.initiating_int_num, 1,
15.98 - output);
15.99 + vga_configure_zero_channel(channel++, line_int_num, 1, output);
15.100 }
15.101
15.102 /* A line channel is always configured, chaining it to any initiating
15.103 @@ -146,30 +193,22 @@
15.104 ZERO_LENGTH);
15.105 }
15.106
15.107 -/* Configure a timer and output compare units for horizontal and vertical
15.108 - sync. */
15.109 +/* Configure output compare units for horizontal and vertical sync. */
15.110
15.111 -void vga_configure_sync(int hsync_unit, int vsync_unit, int timer)
15.112 +void vga_configure_sync(int hsync_unit, int vsync_unit)
15.113 {
15.114 /* Record the peripherals in use. */
15.115
15.116 vga_display.hsync_unit = hsync_unit;
15.117 vga_display.vsync_unit = vsync_unit;
15.118 - vga_display.timer = timer;
15.119
15.120 - /* Configure a timer for the horizontal sync. The timer has no prescaling
15.121 - (0). */
15.122 -
15.123 - timer_init(timer, 0, vga_display.display_config->hfreq_limit);
15.124 - timer_on(timer);
15.125 -
15.126 /* Horizontal sync. */
15.127
15.128 /* Configure output compare in dual compare (continuous output) mode using
15.129 the timer as time base. The interrupt condition drives the first DMA
15.130 channel and is handled to drive the display state machine. */
15.131
15.132 - oc_init(hsync_unit, 0b101, timer);
15.133 + oc_init(hsync_unit, 0b101, vga_display.line_timer);
15.134 oc_set_pulse(hsync_unit, vga_display.display_config->hsync_end);
15.135 oc_set_pulse_end(hsync_unit, vga_display.display_config->hsync_start);
15.136 oc_init_interrupt(hsync_unit, 7, 3);
15.137 @@ -181,7 +220,7 @@
15.138 the timer as time base. The unit is enabled later. It is only really used
15.139 to achieve precisely-timed level transitions in hardware. */
15.140
15.141 - oc_init(vsync_unit, 0b010, timer);
15.142 + oc_init(vsync_unit, 0b010, vga_display.line_timer);
15.143 oc_set_pulse(vsync_unit, 0);
15.144 }
15.145
15.146 @@ -296,7 +335,7 @@
15.147
15.148 /* Determine whether an initiating channel is used. */
15.149
15.150 - int initiating_channel = vga_display.initiating_int_num >= 0;
15.151 + int initiating_channel = vga_display.transfer_int_num >= 0;
15.152 int channel = 0;
15.153
15.154 /* Update the source of a secondary line channel. */
15.155 @@ -330,9 +369,12 @@
15.156
15.157 void update_transfers(int enable)
15.158 {
15.159 - int initiating_channel = vga_display.initiating_int_num >= 0;
15.160 + void (*fn)() = enable ? dma_on : dma_off;
15.161 +
15.162 + /* Determine whether an initiating channel is used. */
15.163 +
15.164 + int initiating_channel = vga_display.transfer_int_num >= 0;
15.165 int channel = 0;
15.166 - void (*fn)() = enable ? dma_on : dma_off;
15.167
15.168 /* Update line channels if no initiating channel is used. */
15.169
15.170 @@ -364,7 +406,7 @@
15.171
15.172 void vsync_low(void)
15.173 {
15.174 - oc_init(vga_display.vsync_unit, 0b010, vga_display.timer);
15.175 + oc_init(vga_display.vsync_unit, 0b010, vga_display.line_timer);
15.176 oc_on(vga_display.vsync_unit);
15.177 }
15.178
15.179 @@ -373,6 +415,6 @@
15.180
15.181 void vsync_high(void)
15.182 {
15.183 - oc_init(vga_display.vsync_unit, 0b001, vga_display.timer);
15.184 + oc_init(vga_display.vsync_unit, 0b001, vga_display.line_timer);
15.185 oc_on(vga_display.vsync_unit);
15.186 }