1.1 --- a/init.c Thu Oct 18 11:13:02 2018 +0200
1.2 +++ b/init.c Thu Oct 18 13:36:42 2018 +0200
1.3 @@ -127,7 +127,7 @@
1.4
1.5 void dma_init(int channel, int auto_enable, uint8_t pri)
1.6 {
1.7 - if (channel > DCHMAX)
1.8 + if ((channel < DCHMIN) || (channel > DCHMAX))
1.9 return;
1.10
1.11 /* Initialise a channel. */
1.12 @@ -141,7 +141,7 @@
1.13
1.14 void dma_set_interrupt(int channel, uint8_t int_num, int enable)
1.15 {
1.16 - if (channel > DCHMAX)
1.17 + if ((channel < DCHMIN) || (channel > DCHMAX))
1.18 return;
1.19
1.20 /* Allow an interrupt to trigger the transfer. */
1.21 @@ -157,7 +157,7 @@
1.22 uint32_t destination_start_address, uint16_t destination_size,
1.23 uint16_t cell_size)
1.24 {
1.25 - if (channel > DCHMAX)
1.26 + if ((channel < DCHMIN) || (channel > DCHMAX))
1.27 return;
1.28
1.29 REG(DMA_REG(channel, DCHxSSIZ)) = source_size;
1.30 @@ -170,9 +170,9 @@
1.31 /* Configure interrupts caused by the channel. */
1.32
1.33 void dma_init_interrupt(int channel, uint8_t conditions,
1.34 - uint8_t int_pri, uint8_t int_sub)
1.35 + uint8_t pri, uint8_t sub)
1.36 {
1.37 - if (channel > DCHMAX)
1.38 + if ((channel < DCHMIN) || (channel > DCHMAX))
1.39 return;
1.40
1.41 /* Produce an interrupt for the provided conditions. */
1.42 @@ -182,7 +182,7 @@
1.43 /* Set interrupt priorities. */
1.44
1.45 REG(DMAIPC) = (REG(DMAIPC) & ~(DMA_IPC_PRI(channel, 7, 3))) |
1.46 - DMA_IPC_PRI(channel, int_pri, int_sub);
1.47 + DMA_IPC_PRI(channel, pri, sub);
1.48
1.49 /* Enable interrupt. */
1.50
1.51 @@ -193,7 +193,7 @@
1.52
1.53 void dma_on(int channel)
1.54 {
1.55 - if (channel > DCHMAX)
1.56 + if ((channel < DCHMIN) || (channel > DCHMAX))
1.57 return;
1.58
1.59 /* Enable channel. */
1.60 @@ -201,20 +201,63 @@
1.61 SET_REG(DMA_REG(channel, DCHxCON), 1 << 7);
1.62 }
1.63
1.64 +
1.65 +
1.66 +/* Timer configuration. */
1.67 +
1.68 +void timer_init(int timer, uint8_t prescale, uint16_t limit)
1.69 +{
1.70 + /* NOTE: Should convert from the real prescale value. */
1.71 +
1.72 + REG(TIMER_REG(timer, TxCON)) = (prescale & 0b111) << 4;
1.73 + REG(TIMER_REG(timer, TMRx)) = 0;
1.74 + REG(TIMER_REG(timer, PRx)) = limit;
1.75 +}
1.76 +
1.77 +/* Configure interrupts caused by the timer. */
1.78 +
1.79 +void timer_init_interrupt(int timer, uint8_t pri, uint8_t sub)
1.80 +{
1.81 + if ((timer < TIMERMIN) || (timer > TIMERMAX))
1.82 + return;
1.83 +
1.84 + /* Set interrupt priorities. */
1.85 +
1.86 + REG(TIMER_IPC_REG(timer)) = (REG(TIMER_IPC_REG(timer)) &
1.87 + ~(TIMER_IPC_PRI(timer, 7, 3))) |
1.88 + TIMER_IPC_PRI(timer, pri, sub);
1.89 +
1.90 + /* Enable interrupt. */
1.91 +
1.92 + SET_REG(TIMERIEC, TIMER_INT_FLAGS(timer, TxIE));
1.93 +}
1.94 +
1.95 +/* Enable a timer. */
1.96 +
1.97 +void timer_on(int timer)
1.98 +{
1.99 + if ((timer < TIMERMIN) || (timer > TIMERMAX))
1.100 + return;
1.101 +
1.102 + SET_REG(TIMER_REG(timer, TxCON), 1 << 15);
1.103 +}
1.104 +
1.105 +
1.106 +
1.107 /* UART configuration. */
1.108
1.109 -void uart_init(int channel, uint32_t baudrate)
1.110 +void uart_init(int uart, uint32_t baudrate)
1.111 {
1.112 /* NOTE: Configured in the initial payload. */
1.113
1.114 uint32_t FPB = 24000000;
1.115
1.116 - if ((channel < UARTMIN) || (channel > UARTMAX))
1.117 + if ((uart < UARTMIN) || (uart > UARTMAX))
1.118 return;
1.119
1.120 /* Disable the UART (ON). */
1.121
1.122 - CLR_REG(UART_REG(channel, UxMODE), 1 << 15);
1.123 + CLR_REG(UART_REG(uart, UxMODE), 1 << 15);
1.124
1.125 /* Set the baud rate. For example:
1.126
1.127 @@ -224,45 +267,46 @@
1.128 = 12
1.129 */
1.130
1.131 - REG(UART_REG(channel, UxBRG)) = (FPB / (16 * baudrate)) - 1;
1.132 + REG(UART_REG(uart, UxBRG)) = (FPB / (16 * baudrate)) - 1;
1.133
1.134 /* Disable interrupt (UxRIE) and clear flag (UxRIF). */
1.135
1.136 - CLR_REG(UARTIEC, UART_INT_FLAGS(channel, UxRIE));
1.137 - CLR_REG(UARTIFS, UART_INT_FLAGS(channel, UxRIF));
1.138 + CLR_REG(UARTIEC, UART_INT_FLAGS(uart, UxRIE));
1.139 + CLR_REG(UARTIFS, UART_INT_FLAGS(uart, UxRIF));
1.140 }
1.141
1.142 /* Configure interrupts caused by the UART. */
1.143
1.144 -void uart_init_interrupt(int channel, uint8_t pri, uint8_t sub)
1.145 +void uart_init_interrupt(int uart, uint8_t conditions,
1.146 + uint8_t pri, uint8_t sub)
1.147 {
1.148 - if ((channel < UARTMIN) || (channel > UARTMAX))
1.149 + if ((uart < UARTMIN) || (uart > UARTMAX))
1.150 return;
1.151
1.152 /* Set priorities: UxIP = pri; UxIS = sub */
1.153
1.154 - REG(UART_IPC_REG(channel)) = (REG(UART_IPC_REG(channel)) & ~UART_IPC_PRI(channel, 7, 3)) |
1.155 - UART_IPC_PRI(channel, pri, sub);
1.156 + REG(UART_IPC_REG(uart)) = (REG(UART_IPC_REG(uart)) & ~UART_IPC_PRI(uart, 7, 3)) |
1.157 + UART_IPC_PRI(uart, pri, sub);
1.158
1.159 - /* Enable interrupt (UxRIE). */
1.160 + /* Enable interrupts. */
1.161
1.162 - SET_REG(UARTIEC, UART_INT_FLAGS(channel, UxRIE));
1.163 + SET_REG(UARTIEC, UART_INT_FLAGS(uart, conditions));
1.164 }
1.165
1.166 /* Enable a UART. */
1.167
1.168 -void uart_on(int channel)
1.169 +void uart_on(int uart)
1.170 {
1.171 - if ((channel < UARTMIN) || (channel > UARTMAX))
1.172 + if ((uart < UARTMIN) || (uart > UARTMAX))
1.173 return;
1.174
1.175 /* Enable receive (URXEN) and transmit (UTXEN). */
1.176
1.177 - SET_REG(UART_REG(channel, UxSTA), (1 << 12) | (1 << 10));
1.178 + SET_REG(UART_REG(uart, UxSTA), (1 << 12) | (1 << 10));
1.179
1.180 /* Start UART. */
1.181
1.182 - SET_REG(UART_REG(channel, UxMODE), 1 << 15);
1.183 + SET_REG(UART_REG(uart, UxMODE), 1 << 15);
1.184 }
1.185
1.186
1.187 @@ -283,23 +327,53 @@
1.188 return PRI(pri, sub) << (DCHIPCBASE + (channel - DCHMIN) * DCHIPCSTEP);
1.189 }
1.190
1.191 +/* Return encoded timer interrupt priorities for combining with a register. */
1.192 +
1.193 +uint32_t TIMER_IPC_PRI(int timer, uint8_t pri, uint8_t sub)
1.194 +{
1.195 + (void) timer;
1.196 + return PRI(pri, sub) << TIMERIPCBASE;
1.197 +}
1.198 +
1.199 +/* Return the timer interrupt priorities register. */
1.200 +
1.201 +uint32_t TIMER_IPC_REG(int timer)
1.202 +{
1.203 + switch (timer)
1.204 + {
1.205 + case 1: return TIMER1IPC;
1.206 + case 2: return TIMER2IPC;
1.207 + case 3: return TIMER3IPC;
1.208 + case 4: return TIMER4IPC;
1.209 + case 5: return TIMER5IPC;
1.210 + default: return 0; /* should not occur */
1.211 + }
1.212 +}
1.213 +
1.214 +/* Return the timer interrupt flags for combining with a register. */
1.215 +
1.216 +int TIMER_INT_FLAGS(int timer, uint8_t flags)
1.217 +{
1.218 + return (flags & 0b1) << (TIMERINTBASE + (timer - TIMERMIN) * TIMERINTSTEP);
1.219 +}
1.220 +
1.221 /* Return encoded UART interrupt priorities for combining with a register. */
1.222
1.223 -uint32_t UART_IPC_PRI(int channel, uint8_t pri, uint8_t sub)
1.224 +uint32_t UART_IPC_PRI(int uart, uint8_t pri, uint8_t sub)
1.225 {
1.226 - return PRI(pri, sub) << (channel == 1 ? UART1IPCBASE : UART2IPCBASE);
1.227 + return PRI(pri, sub) << (uart == 1 ? UART1IPCBASE : UART2IPCBASE);
1.228 }
1.229
1.230 /* Return the UART interrupt priorities register. */
1.231
1.232 -uint32_t UART_IPC_REG(int channel)
1.233 +uint32_t UART_IPC_REG(int uart)
1.234 {
1.235 - return channel == 1 ? UART1IPC : UART2IPC;
1.236 + return uart == 1 ? UART1IPC : UART2IPC;
1.237 }
1.238
1.239 -/* Return the UART interrupt flags shift offset. */
1.240 +/* Return the UART interrupt flags for combining with a register. */
1.241
1.242 -int UART_INT_FLAGS(int channel, uint8_t flags)
1.243 +int UART_INT_FLAGS(int uart, uint8_t flags)
1.244 {
1.245 - return (flags & 0b111) << (UARTINTBASE + (channel - UARTMIN) * UARTINTSTEP);
1.246 + return (flags & 0b111) << (UARTINTBASE + (uart - UARTMIN) * UARTINTSTEP);
1.247 }
2.1 --- a/init.h Thu Oct 18 11:13:02 2018 +0200
2.2 +++ b/init.h Thu Oct 18 13:36:42 2018 +0200
2.3 @@ -24,7 +24,7 @@
2.4 void dma_init(int channel, int auto_enable, uint8_t pri);
2.5
2.6 void dma_init_interrupt(int channel, uint8_t conditions,
2.7 - uint8_t int_pri, uint8_t int_sub);
2.8 + uint8_t pri, uint8_t sub);
2.9
2.10 void dma_on(int channel);
2.11
2.12 @@ -35,21 +35,33 @@
2.13 uint32_t destination_start_address, uint16_t destination_size,
2.14 uint16_t cell_size);
2.15
2.16 +uint32_t DMA_IPC_PRI(int channel, uint8_t pri, uint8_t sub);
2.17 +
2.18 +/* Timer configuration. */
2.19 +
2.20 +void timer_init(int timer, uint8_t prescale, uint16_t limit);
2.21 +
2.22 +void timer_init_interrupt(int timer, uint8_t pri, uint8_t sub);
2.23 +
2.24 +void timer_on(int timer);
2.25 +
2.26 +uint32_t TIMER_IPC_PRI(int timer, uint8_t pri, uint8_t sub);
2.27 +uint32_t TIMER_IPC_REG(int timer);
2.28 +
2.29 +int TIMER_INT_FLAGS(int timer, uint8_t flags);
2.30 +
2.31 /* UART configuration. */
2.32
2.33 -void uart_init(int channel, uint32_t baudrate);
2.34 +void uart_init(int uart, uint32_t baudrate);
2.35
2.36 -void uart_init_interrupt(int channel, uint8_t pri, uint8_t sub);
2.37 -
2.38 -void uart_on(int channel);
2.39 +void uart_init_interrupt(int uart, uint8_t conditions,
2.40 + uint8_t pri, uint8_t sub);
2.41
2.42 -/* Utility functions. */
2.43 -
2.44 -uint32_t DMA_IPC_PRI(int channel, uint8_t pri, uint8_t sub);
2.45 +void uart_on(int uart);
2.46
2.47 -uint32_t UART_IPC_PRI(int channel, uint8_t pri, uint8_t sub);
2.48 -uint32_t UART_IPC_REG(int channel);
2.49 +uint32_t UART_IPC_PRI(int uart, uint8_t pri, uint8_t sub);
2.50 +uint32_t UART_IPC_REG(int uart);
2.51
2.52 -int UART_INT_FLAGS(int channel, uint8_t flags);
2.53 +int UART_INT_FLAGS(int uart, uint8_t flags);
2.54
2.55 #endif /* __INIT_H__ */
3.1 --- a/main.c Thu Oct 18 11:13:02 2018 +0200
3.2 +++ b/main.c Thu Oct 18 13:36:42 2018 +0200
3.3 @@ -41,6 +41,7 @@
3.4 /* Invert outputs (LED). */
3.5
3.6 INV_REG(port, pins);
3.7 +
3.8 bits(DMA_REG(0, DCHxCON));
3.9 bits(DMA_REG(0, DCHxECON));
3.10 bits(DMA_REG(0, DCHxINT));
3.11 @@ -72,7 +73,7 @@
3.12 /* Set UART interrupt priority below CPU priority. */
3.13
3.14 uart_init(1, 115200);
3.15 - uart_init_interrupt(1, 1, 3);
3.16 + uart_init_interrupt(1, UxRIF, 1, 3);
3.17 uart_on(1);
3.18
3.19 interrupts_on();