1.1 --- a/init.c Thu Oct 18 21:05:18 2018 +0200
1.2 +++ b/init.c Thu Oct 18 22:45:55 2018 +0200
1.3 @@ -204,7 +204,8 @@
1.4
1.5 /* Set interrupt priorities. */
1.6
1.7 - REG(DMAIPC) = (REG(DMAIPC) & ~(DMA_IPC_PRI(channel, 7, 3))) |
1.8 + REG(DMAIPC) = (REG(DMAIPC) &
1.9 + ~(DMA_IPC_PRI(channel, 7, 3))) |
1.10 DMA_IPC_PRI(channel, pri, sub);
1.11
1.12 /* Enable interrupt. */
1.13 @@ -226,6 +227,71 @@
1.14
1.15
1.16
1.17 +/* Output compare configuration. */
1.18 +
1.19 +void oc_init(int unit, uint8_t mode, int timer)
1.20 +{
1.21 + if ((unit < OCMIN) || (unit > OCMAX))
1.22 + return;
1.23 +
1.24 + REG(OC_REG(unit, OCxCON)) = (timer == 3 ? (1 << 3) : 0) | (mode & 0b111);
1.25 +}
1.26 +
1.27 +/* Set the start value for the pulse. */
1.28 +
1.29 +void oc_set_pulse(int unit, uint32_t start)
1.30 +{
1.31 + if ((unit < OCMIN) || (unit > OCMAX))
1.32 + return;
1.33 +
1.34 + REG(OC_REG(unit, OCxR)) = start;
1.35 +}
1.36 +
1.37 +/* Set the end value for the pulse. */
1.38 +
1.39 +void oc_set_pulse_end(int unit, uint32_t end)
1.40 +{
1.41 + if ((unit < OCMIN) || (unit > OCMAX))
1.42 + return;
1.43 +
1.44 + REG(OC_REG(unit, OCxRS)) = end;
1.45 +}
1.46 +
1.47 +/* Configure interrupts caused by the unit. */
1.48 +
1.49 +void oc_init_interrupt(int unit, uint8_t pri, uint8_t sub)
1.50 +{
1.51 + if ((unit < OCMIN) || (unit > OCMAX))
1.52 + return;
1.53 +
1.54 + /* Disable interrupt and clear interrupt flag. */
1.55 +
1.56 + CLR_REG(OCIEC, OC_INT_FLAGS(unit, OCxIE));
1.57 + CLR_REG(OCIFS, OC_INT_FLAGS(unit, OCxIF));
1.58 +
1.59 + /* Set interrupt priorities. */
1.60 +
1.61 + REG(OC_IPC_REG(unit)) = (REG(OC_IPC_REG(unit)) &
1.62 + ~(OC_IPC_PRI(unit, 7, 3))) |
1.63 + OC_IPC_PRI(unit, pri, sub);
1.64 +
1.65 + /* Enable interrupt. */
1.66 +
1.67 + SET_REG(OCIEC, OC_INT_FLAGS(unit, OCxIE));
1.68 +}
1.69 +
1.70 +/* Enable a unit. */
1.71 +
1.72 +void oc_on(int unit)
1.73 +{
1.74 + if ((unit < OCMIN) || (unit > OCMAX))
1.75 + return;
1.76 +
1.77 + SET_REG(OC_REG(unit, OCxCON), 1 << 15);
1.78 +}
1.79 +
1.80 +
1.81 +
1.82 /* Timer configuration. */
1.83
1.84 void timer_init(int timer, uint8_t prescale, uint16_t limit)
1.85 @@ -244,6 +310,11 @@
1.86 if ((timer < TIMERMIN) || (timer > TIMERMAX))
1.87 return;
1.88
1.89 + /* Disable interrupt and clear interrupt flag. */
1.90 +
1.91 + CLR_REG(TIMERIEC, TIMER_INT_FLAGS(timer, TxIE));
1.92 + CLR_REG(TIMERIFS, TIMER_INT_FLAGS(timer, TxIF));
1.93 +
1.94 /* Set interrupt priorities. */
1.95
1.96 REG(TIMER_IPC_REG(timer)) = (REG(TIMER_IPC_REG(timer)) &
1.97 @@ -291,11 +362,6 @@
1.98 */
1.99
1.100 REG(UART_REG(uart, UxBRG)) = (FPB / (16 * baudrate)) - 1;
1.101 -
1.102 - /* Disable interrupt (UxRIE) and clear flag (UxRIF). */
1.103 -
1.104 - CLR_REG(UARTIEC, UART_INT_FLAGS(uart, UxRIE));
1.105 - CLR_REG(UARTIFS, UART_INT_FLAGS(uart, UxRIF));
1.106 }
1.107
1.108 /* Configure interrupts caused by the UART. */
1.109 @@ -306,10 +372,16 @@
1.110 if ((uart < UARTMIN) || (uart > UARTMAX))
1.111 return;
1.112
1.113 + /* Disable interrupts and clear interrupt flags. */
1.114 +
1.115 + CLR_REG(UARTIEC, UART_INT_FLAGS(uart, UxTIE | UxRIE | UxEIE));
1.116 + CLR_REG(UARTIFS, UART_INT_FLAGS(uart, UxTIF | UxRIF | UxEIF));
1.117 +
1.118 /* Set priorities: UxIP = pri; UxIS = sub */
1.119
1.120 - REG(UART_IPC_REG(uart)) = (REG(UART_IPC_REG(uart)) & ~UART_IPC_PRI(uart, 7, 3)) |
1.121 - UART_IPC_PRI(uart, pri, sub);
1.122 + REG(UART_IPC_REG(uart)) = (REG(UART_IPC_REG(uart)) &
1.123 + ~UART_IPC_PRI(uart, 7, 3)) |
1.124 + UART_IPC_PRI(uart, pri, sub);
1.125
1.126 /* Enable interrupts. */
1.127
1.128 @@ -357,6 +429,36 @@
1.129 return PRI(pri, sub) << (DCHIPCBASE + (channel - DCHMIN) * DCHIPCSTEP);
1.130 }
1.131
1.132 +/* Return encoded output compare interrupt priorities for combining with a register. */
1.133 +
1.134 +uint32_t OC_IPC_PRI(int unit, uint8_t pri, uint8_t sub)
1.135 +{
1.136 + (void) unit;
1.137 + return PRI(pri, sub) << OCIPCBASE;
1.138 +}
1.139 +
1.140 +/* Return the output compare interrupt priorities register. */
1.141 +
1.142 +uint32_t OC_IPC_REG(int unit)
1.143 +{
1.144 + switch (unit)
1.145 + {
1.146 + case 1: return OC1IPC;
1.147 + case 2: return OC2IPC;
1.148 + case 3: return OC3IPC;
1.149 + case 4: return OC4IPC;
1.150 + case 5: return OC5IPC;
1.151 + default: return 0; /* should not occur */
1.152 + }
1.153 +}
1.154 +
1.155 +/* Return the output compare interrupt flags for combining with a register. */
1.156 +
1.157 +int OC_INT_FLAGS(int unit, uint8_t flags)
1.158 +{
1.159 + return (flags & 0b1) << (OCINTBASE + (unit - OCMIN) * OCINTSTEP);
1.160 +}
1.161 +
1.162 /* Return encoded timer interrupt priorities for combining with a register. */
1.163
1.164 uint32_t TIMER_IPC_PRI(int timer, uint8_t pri, uint8_t sub)