@@ -62,30 +62,30 @@ typedef struct dma_stream_t {
6262 __io uint32 PAR ; /**< Stream peripheral address register */
6363 __io uint32 M0AR ; /**< Stream memory address register 0 */
6464 __io uint32 M1AR ; /**< Stream memory address register 1 */
65- __io uint32 FCR ; /**< Stream FIFO configuration register */
65+ __io uint32 FCR ; /**< Stream FIFO configuration register */
6666} dma_stream_t ;
6767/**
6868 * @brief DMA register map type.
6969 *
7070 */
7171typedef struct dma_reg_map {
72- __io uint32 LISR ; /**< Low interrupt status register */
73- __io uint32 HISR ; /**< High interrupt status register */
74- __io uint32 LIFCR ; /**< Low interrupt flag clear register */
75- __io uint32 HIFCR ; /**< High interrupt flag clear register */
76- dma_stream_t STREAM [8 ];
72+ __io uint32 LISR ; /**< Low interrupt status register */
73+ __io uint32 HISR ; /**< High interrupt status register */
74+ __io uint32 LIFCR ; /**< Low interrupt flag clear register */
75+ __io uint32 HIFCR ; /**< High interrupt flag clear register */
76+ dma_stream_t STREAM [8 ];
7777} dma_reg_map ;
7878
7979/** DMA controller register map base pointers */
8080#define DMA1_BASE ((struct dma_reg_map*)0x40026000)
8181#define DMA2_BASE ((struct dma_reg_map*)0x40026400)
8282
83+
8384/*
8485 * Register bit definitions
8586 */
8687
87- /* Stream configuration register */
88-
88+ // Stream configuration register
8989#define DMA_CR_CH0 (0x0 << 25)
9090#define DMA_CR_CH1 (0x1 << 25)
9191#define DMA_CR_CH2 (0x2 << 25)
@@ -134,7 +134,34 @@ typedef struct dma_reg_map {
134134#define DMA_CR_HTIE (0x1 << 3)
135135#define DMA_CR_TEIE (0x1 << 2)
136136#define DMA_CR_DMEIE (0x1 << 1)
137- #define DMA_CR_EN (0x1)
137+ #define DMA_CR_EN (0x1 << 0)
138+
139+ // Device interrupt status register flags
140+ #define DMA_ISR_TCIF (1 << 5)
141+ #define DMA_ISR_HTIF (1 << 4)
142+ #define DMA_ISR_TEIF (1 << 3)
143+ #define DMA_ISR_DMEIF (1 << 2)
144+ #define DMA_ISR_FEIF (1 << 0)
145+
146+ #define DMA_ISR_ERROR_BITS (DMA_ISR_TEIF | DMA_ISR_DMEIF | DMA_ISR_FEIF)
147+ #define DMA_ISR_BIT_MASK 0x3D
148+
149+ // FIFO control register flags
150+ #define DMA_FCR_FEIE (0x1 << 7) // FIFO error interrupt enable
151+ #define DMA_FCR_FS (0x7 << 3) // FIFO status (READ_ONLY):
152+ #define DMA_FCR_FS_LEVEL_1 (0x0 << 3) // 000: 0 < fifo_level < 1/4
153+ #define DMA_FCR_FS_LEVEL_2 (0x1 << 3) // 001: 1/4 ≤ fifo_level < 1/2
154+ #define DMA_FCR_FS_LEVEL_3 (0x2 << 3) // 010: 1/2 ≤ fifo_level < 3/4
155+ #define DMA_FCR_FS_LEVEL_4 (0x3 << 3) // 011: 3/4 ≤ fifo_level < full
156+ #define DMA_FCR_FS_EMPTY (0x4 << 3) // 100: FIFO is empty
157+ #define DMA_FCR_FS_FULL (0x5 << 3) // 101: FIFO is full
158+ #define DMA_FCR_DMDIS (0x1 << 2) // Direct mode disable
159+ #define DMA_FCR_FTH (0x3 << 0) // FIFO threshold selection
160+ #define DMA_FCR_FTH_1_4 (0x0 << 0) // 1/4 full FIFO
161+ #define DMA_FCR_FTH_2_4 (0x1 << 0) // 2/4 full FIFO
162+ #define DMA_FCR_FTH_3_4 (0x2 << 0) // 3/4 full FIFO
163+ #define DMA_FCR_FTH_FULL (0x3 << 0) // full FIFO
164+
138165
139166typedef enum dma_channel {
140167 DMA_CH0 = DMA_CR_CH0 , /**< Channel 0 */
@@ -147,18 +174,6 @@ typedef enum dma_channel {
147174 DMA_CH7 = DMA_CR_CH7 , /**< Channel 7 */
148175} dma_channel ;
149176
150- /* Device interrupt status register flags */
151-
152- #define DMA_ISR_TCIF (1 << 5)
153- #define DMA_ISR_HTIF (1 << 4)
154- #define DMA_ISR_TEIF (1 << 3)
155- #define DMA_ISR_DMEIF (1 << 2)
156- #define DMA_ISR_FEIF (1 << 0)
157-
158- /*
159- * Devices
160- */
161-
162177/** Encapsulates state related to a DMA channel interrupt. */
163178typedef struct dma_handler_config {
164179 void (* handler )(void ); /**< User-specified channel interrupt
@@ -172,50 +187,53 @@ typedef struct dma_dev {
172187 rcc_clk_id clk_id ; /**< Clock ID */
173188 dma_handler_config handlers []; /**<
174189 * @brief IRQ handlers and NVIC numbers.
175- *
176- * @see dma_attach_interrupt()
177190 * @see dma_detach_interrupt()
178191 */
179192} dma_dev ;
180193
181- extern dma_dev * DMA1 ;
182- extern dma_dev * DMA2 ;
183-
184194/*
185- * Convenience functions
195+ * Devices
186196 */
187-
188- extern void dma_init ( dma_dev * dev ) ;
197+ extern dma_dev * DMA1 ;
198+ extern dma_dev * DMA2 ;
189199
190200/** Flags for DMA transfer configuration. */
191201typedef enum dma_mode_flags {
192- DMA_MEM_BUF_0 = DMA_CR_CT0 , /**< Current memory target buffer 0 */
193- DMA_MEM_BUF_1 = DMA_CR_CT1 , /**< Current memory target buffer 1 */
194- DMA_DBL_BUF_MODE = DMA_CR_DBM , /**< Current memory double buffer mode */
195- DMA_PINC_OFFSET = DMA_CR_PINCOS , /**< Peripheral increment offset size */
196- DMA_MINC_MODE = DMA_CR_MINC , /**< Memory increment mode */
197- DMA_PINC_MODE = DMA_CR_PINC , /**< Peripheral increment mode */
198- DMA_CIRC_MODE = DMA_CR_CIRC , /**< Memory Circular mode */
199- DMA_FROM_PER = DMA_CR_DIR_P2M , /**< Read from memory to peripheral */
200- DMA_FROM_MEM = DMA_CR_DIR_M2P , /**< Read from memory to peripheral */
201- DMA_MEM_TO_MEM = DMA_CR_DIR_M2M , /**< Read from memory to memory */
202- DMA_PERIF_CTRL = DMA_CR_PFCTRL , /**< Peripheral flow controller */
202+ DMA_MEM_BUF_0 = DMA_CR_CT0 , /**< Current memory target buffer 0 */
203+ DMA_MEM_BUF_1 = DMA_CR_CT1 , /**< Current memory target buffer 1 */
204+ DMA_DBL_BUF_MODE = DMA_CR_DBM , /**< Current memory double buffer mode */
205+ DMA_PINC_OFFSET = DMA_CR_PINCOS , /**< Peripheral increment offset size */
206+ DMA_MINC_MODE = DMA_CR_MINC , /**< Memory increment mode */
207+ DMA_PINC_MODE = DMA_CR_PINC , /**< Peripheral increment mode */
208+ DMA_CIRC_MODE = DMA_CR_CIRC , /**< Memory Circular mode */
209+ DMA_FROM_PER = DMA_CR_DIR_P2M , /**< Read from memory to peripheral */
210+ DMA_FROM_MEM = DMA_CR_DIR_M2P , /**< Read from memory to peripheral */
211+ DMA_MEM_TO_MEM = DMA_CR_DIR_M2M , /**< Read from memory to memory */
212+ DMA_PERIF_CTRL = DMA_CR_PFCTRL , /**< Peripheral flow controller */
203213 DMA_PRIO_MEDIUM = DMA_CR_PL_MEDIUM , /**< Medium priority */
204214 DMA_PRIO_HIGH = DMA_CR_PL_HIGH , /**< High priority */
205215 DMA_PRIO_VERY_HIGH = DMA_CR_PL_VERY_HIGH , /**< Very high priority */
206- DMA_TRNS_CMPLT = DMA_CR_TCIE , /**< Interrupt on transfer completion */
207- DMA_TRNS_HALF = DMA_CR_HTIE , /**< Interrupt on half-transfer */
216+ DMA_TRNS_CMPLT = DMA_CR_TCIE , /**< Interrupt on transfer completion */
217+ DMA_TRNS_HALF = DMA_CR_HTIE , /**< Interrupt on half-transfer */
208218 DMA_TRNS_ERR = DMA_CR_TEIE , /**< Interrupt on transfer error */
209219 DMA_DIR_MODE_ERR = DMA_CR_DMEIE /**< Interrupt on direct mode error */
210220} dma_mode_flags ;
211221
212- /** Source and destination transfer sizes. */
222+ // Source and destination transfer sizes.
213223typedef enum dma_xfer_size {
214- DMA_SIZE_8BITS = ( DMA_CR_MSIZE_8BITS |DMA_CR_PSIZE_8BITS ), /**< 8-bit transfers */
215- DMA_SIZE_16BITS = (DMA_CR_MSIZE_16BITS |DMA_CR_PSIZE_16BITS ), /**< 16-bit transfers */
216- DMA_SIZE_32BITS = (DMA_CR_MSIZE_32BITS |DMA_CR_PSIZE_32BITS ) /**< 32-bit transfers */
224+ DMA_SIZE_8BITS = ( DMA_CR_MSIZE_8BITS |DMA_CR_PSIZE_8BITS ), // 8-bit transfers
225+ DMA_SIZE_16BITS = (DMA_CR_MSIZE_16BITS |DMA_CR_PSIZE_16BITS ), // 16-bit transfers
226+ DMA_SIZE_32BITS = (DMA_CR_MSIZE_32BITS |DMA_CR_PSIZE_32BITS ) // 32-bit transfers
217227} dma_xfer_size ;
218228
229+ // Source and destination burst sizes.
230+ typedef enum dma_burst_size {
231+ DMA_BURST_INCR0 = ( DMA_CR_MBURST0 |DMA_CR_PBURST0 ), // single transfer
232+ DMA_BURST_INCR4 = ( DMA_CR_MBURST4 |DMA_CR_PBURST4 ), // incremental burst of 4 beats
233+ DMA_BURST_INCR8 = ( DMA_CR_MBURST8 |DMA_CR_PBURST8 ), // incremental burst of 8 beats
234+ DMA_BURST_INCR16 = (DMA_CR_MBURST16 |DMA_CR_PBURST16 ) // incremental burst of 16 beats
235+ } dma_burst_size ;
236+
219237/** DMA channel */
220238typedef enum dma_stream {
221239 DMA_STREAM0 = 0 , /**< Stream 0 */
@@ -227,32 +245,37 @@ typedef enum dma_stream {
227245 DMA_STREAM6 = 6 , /**< Stream 6 */
228246 DMA_STREAM7 = 7 , /**< Stream 7 */
229247} dma_stream ;
230-
248+
249+ /*
250+ * Convenience functions
251+ */
252+ extern void dma_init (dma_dev * dev );
253+
231254static inline void dma_setup_transfer (dma_dev * dev ,
232255 dma_stream stream ,
233256 dma_channel channel ,
234257 dma_xfer_size trx_size ,
235258 __io void * peripheral_address ,
236259 __io void * memory_address0 ,
237260 __io void * memory_address1 ,
238- uint32 flags ) {
261+ uint32 flags )
262+ {
239263 dev -> regs -> STREAM [stream ].CR &= ~DMA_CR_EN ; // disable
264+ while ( (dev -> regs -> STREAM [stream ].CR )& DMA_CR_EN ); // wait till enable bit is cleared
240265 dev -> regs -> STREAM [stream ].PAR = (uint32 )peripheral_address ;
241266 dev -> regs -> STREAM [stream ].M0AR = (uint32 )memory_address0 ;
242267 dev -> regs -> STREAM [stream ].M1AR = (uint32 )memory_address1 ;
243- dev -> regs -> STREAM [stream ].CR = ((flags |channel |trx_size ) & 0x0feffffe ); // mask out reserved and enable
268+ dev -> regs -> STREAM [stream ].CR = (uint32 )( (flags |channel |trx_size ) & 0x0feffffe ); // mask out reserved and enable
244269}
245270
246- static inline void dma_set_num_transfers (dma_dev * dev ,
247- dma_stream stream ,
248- uint16 num_transfers ) {
249- dev -> regs -> STREAM [stream ].NDTR = num_transfers ;
271+ static inline void dma_set_num_transfers (dma_dev * dev , dma_stream stream , uint16 num_transfers )
272+ {
273+ dev -> regs -> STREAM [stream ].NDTR = (uint32 )num_transfers ;
250274}
251275
252- static inline void dma_set_fifo_flags (dma_dev * dev ,
253- dma_stream stream ,
254- uint8 fifo_flags ) {
255- dev -> regs -> STREAM [stream ].FCR = fifo_flags & 0x87 ; // mask out reserved bits
276+ static inline void dma_set_fifo_flags (dma_dev * dev , dma_stream stream , uint8 fifo_flags )
277+ {
278+ dev -> regs -> STREAM [stream ].FCR = (uint32 )(fifo_flags & 0x87 ); // mask out reserved bits
256279}
257280
258281void dma_attach_interrupt (dma_dev * dev ,
@@ -261,12 +284,14 @@ void dma_attach_interrupt(dma_dev *dev,
261284
262285void dma_detach_interrupt (dma_dev * dev , dma_stream stream );
263286
264- static inline void dma_enable (dma_dev * dev , dma_stream stream ) {
265- dev -> regs -> STREAM [stream ].CR |= DMA_CR_EN ;
287+ static inline void dma_enable (dma_dev * dev , dma_stream stream )
288+ {
289+ dev -> regs -> STREAM [stream ].CR |= (uint32 )DMA_CR_EN ;
266290}
267291
268- static inline void dma_disable (dma_dev * dev , dma_stream stream ) {
269- dev -> regs -> STREAM [stream ].CR &= ~DMA_CR_EN ;
292+ static inline void dma_disable (dma_dev * dev , dma_stream stream )
293+ {
294+ dev -> regs -> STREAM [stream ].CR &= (uint32 )(~DMA_CR_EN );
270295 while (dev -> regs -> STREAM [stream ].CR & DMA_CR_EN ); // wait till EN bit is reset, see AN4031, chapter 4.1
271296}
272297
@@ -289,15 +314,23 @@ static inline uint8 dma_is_stream_enabled(dma_dev *dev, dma_stream stream) {
289314 * @param dev DMA device
290315 * @param stream Stream whose ISR bits to return.
291316 */
292- uint8 dma_get_isr_bits (dma_dev * dev , dma_stream stream );
317+ uint8 dma_get_isr_bit (dma_dev * dev , dma_stream stream , uint8_t mask );
318+
319+ static inline uint8 dma_get_isr_bits (dma_dev * dev , dma_stream stream ) {
320+ return dma_get_isr_bit (dev , stream , DMA_ISR_BIT_MASK );
321+ }
293322
294323/**
295324 * @brief Clear the ISR status bits for a given DMA stream.
296325 *
297326 * @param dev DMA device
298327 * @param stream Stream whose ISR bits to clear.
299328 */
300- void dma_clear_isr_bits (dma_dev * dev , dma_stream stream );
329+ void dma_clear_isr_bit (dma_dev * dev , dma_stream stream , uint8_t mask );
330+
331+ static inline void dma_clear_isr_bits (dma_dev * dev , dma_stream stream ) {
332+ dma_clear_isr_bit (dev , stream , DMA_ISR_BIT_MASK );
333+ }
301334
302335#ifdef __cplusplus
303336} // extern "C"
0 commit comments