1.1 --- a/init.c Thu Oct 18 17:58:45 2018 +0200
1.2 +++ b/init.c Thu Oct 18 18:24:48 2018 +0200
1.3 @@ -125,18 +125,36 @@
1.4
1.5 /* Initialise the given channel. */
1.6
1.7 -void dma_init(int channel, int auto_enable, uint8_t pri)
1.8 +void dma_init(int channel, uint8_t pri)
1.9 {
1.10 if ((channel < DCHMIN) || (channel > DCHMAX))
1.11 return;
1.12
1.13 /* Initialise a channel. */
1.14
1.15 - REG(DMA_REG(channel, DCHxCON)) = (auto_enable ? (1 << 4) : 0) | (pri & 0b11);
1.16 + REG(DMA_REG(channel, DCHxCON)) = pri & 0b11;
1.17 REG(DMA_REG(channel, DCHxECON)) = 0;
1.18 REG(DMA_REG(channel, DCHxINT)) = 0;
1.19 }
1.20
1.21 +/* Set the channel auto-enable mode. */
1.22 +
1.23 +void dma_set_auto_enable(int channel, int auto_enable)
1.24 +{
1.25 + (auto_enable ? SET_REG : CLR_REG)(DMA_REG(channel, DCHxCON), 1 << 4);
1.26 +}
1.27 +
1.28 +/* Set the channel chaining mode. */
1.29 +
1.30 +void dma_set_chaining(int channel, enum dma_chain chain)
1.31 +{
1.32 + (chain != dma_chain_none ?
1.33 + SET_REG : CLR_REG)(DMA_REG(channel, DCHxCON), 1 << 5);
1.34 +
1.35 + (chain == dma_chain_next ?
1.36 + SET_REG : CLR_REG)(DMA_REG(channel, DCHxCON), 1 << 8);
1.37 +}
1.38 +
1.39 /* Configure a channel's initiation interrupt. */
1.40
1.41 void dma_set_interrupt(int channel, uint8_t int_num, int enable)
1.42 @@ -175,6 +193,11 @@
1.43 if ((channel < DCHMIN) || (channel > DCHMAX))
1.44 return;
1.45
1.46 + /* Disable channel interrupt and clear interrupt flag. */
1.47 +
1.48 + CLR_REG(DMAIEC, DMA_INT_FLAGS(channel, 1));
1.49 + CLR_REG(DMAIFS, DMA_INT_FLAGS(channel, 1));
1.50 +
1.51 /* Produce an interrupt for the provided conditions. */
1.52
1.53 REG(DMA_REG(channel, DCHxINT)) = conditions << 16;
1.54 @@ -186,7 +209,7 @@
1.55
1.56 /* Enable interrupt. */
1.57
1.58 - SET_REG(DMAIEC, 1 << (channel + DMAINTBASE));
1.59 + SET_REG(DMAIEC, DMA_INT_FLAGS(channel, 1));
1.60 }
1.61
1.62 /* Enable a DMA channel. */
1.63 @@ -320,6 +343,13 @@
1.64 return ((pri & 0b111) << 2) | (sub & 0b11);
1.65 }
1.66
1.67 +/* Return the DMA interrupt flags for combining with a register. */
1.68 +
1.69 +int DMA_INT_FLAGS(int channel, uint8_t flags)
1.70 +{
1.71 + return (flags & 0b1) << (DMAINTBASE + (channel - DCHMIN));
1.72 +}
1.73 +
1.74 /* Return encoded DMA interrupt priorities for combining with a register. */
1.75
1.76 uint32_t DMA_IPC_PRI(int channel, uint8_t pri, uint8_t sub)
2.1 --- a/init.h Thu Oct 18 17:58:45 2018 +0200
2.2 +++ b/init.h Thu Oct 18 18:24:48 2018 +0200
2.3 @@ -1,6 +1,8 @@
2.4 #ifndef __INIT_H__
2.5 #define __INIT_H__
2.6
2.7 +#include "pic32_c.h"
2.8 +
2.9 /* Basic initialisation. */
2.10
2.11 void init_memory(void);
2.12 @@ -21,7 +23,11 @@
2.13
2.14 void init_dma(void);
2.15
2.16 -void dma_init(int channel, int auto_enable, uint8_t pri);
2.17 +void dma_init(int channel, uint8_t pri);
2.18 +
2.19 +void dma_set_auto_enable(int channel, int auto_enable);
2.20 +
2.21 +void dma_set_chaining(int channel, enum dma_chain chain);
2.22
2.23 void dma_init_interrupt(int channel, uint8_t conditions,
2.24 uint8_t pri, uint8_t sub);
2.25 @@ -35,6 +41,8 @@
2.26 uint32_t destination_start_address, uint16_t destination_size,
2.27 uint16_t cell_size);
2.28
2.29 +int DMA_INT_FLAGS(int channel, uint8_t flags);
2.30 +
2.31 uint32_t DMA_IPC_PRI(int channel, uint8_t pri, uint8_t sub);
2.32
2.33 /* Timer configuration. */
2.34 @@ -45,11 +53,11 @@
2.35
2.36 void timer_on(int timer);
2.37
2.38 +int TIMER_INT_FLAGS(int timer, uint8_t flags);
2.39 +
2.40 uint32_t TIMER_IPC_PRI(int timer, uint8_t pri, uint8_t sub);
2.41 uint32_t TIMER_IPC_REG(int timer);
2.42
2.43 -int TIMER_INT_FLAGS(int timer, uint8_t flags);
2.44 -
2.45 /* UART configuration. */
2.46
2.47 void uart_init(int uart, uint32_t baudrate);
2.48 @@ -59,9 +67,9 @@
2.49
2.50 void uart_on(int uart);
2.51
2.52 +int UART_INT_FLAGS(int uart, uint8_t flags);
2.53 +
2.54 uint32_t UART_IPC_PRI(int uart, uint8_t pri, uint8_t sub);
2.55 uint32_t UART_IPC_REG(int uart);
2.56
2.57 -int UART_INT_FLAGS(int uart, uint8_t flags);
2.58 -
2.59 #endif /* __INIT_H__ */
3.1 --- a/pic32_c.h Thu Oct 18 17:58:45 2018 +0200
3.2 +++ b/pic32_c.h Thu Oct 18 18:24:48 2018 +0200
3.3 @@ -9,24 +9,62 @@
3.4
3.5 /* Access. */
3.6
3.7 -#define REG(mem) *((volatile uint32_t *) (mem))
3.8 +#define REG(mem) *((volatile uint32_t *) (mem))
3.9
3.10 /* Bit clearing, setting and inverting. */
3.11
3.12 -#define CLR_REG(mem, val) (REG(mem + CLR) = val)
3.13 -#define SET_REG(mem, val) (REG(mem + SET) = val)
3.14 -#define INV_REG(mem, val) (REG(mem + INV) = val)
3.15 +static inline void CLR_REG(uint32_t mem, uint32_t val)
3.16 +{
3.17 + REG(mem + CLR) = val;
3.18 +}
3.19 +
3.20 +static inline void SET_REG(uint32_t mem, uint32_t val)
3.21 +{
3.22 + REG(mem + SET) = val;
3.23 +}
3.24 +
3.25 +static inline void INV_REG(uint32_t mem, uint32_t val)
3.26 +{
3.27 + REG(mem + INV) = val;
3.28 +}
3.29
3.30 /* Address translation. */
3.31
3.32 -#define PHYSICAL(addr) (((uint32_t) addr) - KSEG0_BASE)
3.33 -#define HW_PHYSICAL(addr) (((uint32_t) addr) - KSEG1_BASE)
3.34 +static inline uint32_t PHYSICAL(uint32_t addr)
3.35 +{
3.36 + return ((uint32_t) addr) - KSEG0_BASE;
3.37 +}
3.38 +
3.39 +static inline uint32_t HW_PHYSICAL(uint32_t addr)
3.40 +{
3.41 + return ((uint32_t) addr) - KSEG1_BASE;
3.42 +}
3.43
3.44 /* Register collection access. */
3.45
3.46 -#define DMA_REG(channel, reg) (DCHBASE + reg + (channel - DCHMIN) * DCHSTEP)
3.47 -#define TIMER_REG(channel, reg) (TIMERBASE + reg + (channel - TIMERMIN) * TIMERSTEP)
3.48 -#define UART_REG(channel, reg) (UARTBASE + reg + (channel - UARTMIN) * UARTSTEP)
3.49 +static inline uint32_t DMA_REG(int channel, uint32_t reg)
3.50 +{
3.51 + return DCHBASE + reg + (channel - DCHMIN) * DCHSTEP;
3.52 +}
3.53 +
3.54 +static inline uint32_t TIMER_REG(int channel, uint32_t reg)
3.55 +{
3.56 + return TIMERBASE + reg + (channel - TIMERMIN) * TIMERSTEP;
3.57 +}
3.58 +
3.59 +static inline uint32_t UART_REG(int channel, uint32_t reg)
3.60 +{
3.61 + return UARTBASE + reg + (channel - UARTMIN) * UARTSTEP;
3.62 +}
3.63 +
3.64 +/* Convenience types. */
3.65 +
3.66 +enum dma_chain
3.67 +{
3.68 + dma_chain_none,
3.69 + dma_chain_next,
3.70 + dma_chain_previous,
3.71 +};
3.72
3.73 #endif /* __PIC32_C_H__ */
3.74