2525 *****************************************************************************/
2626
2727/**
28- * @file dma .h
28+ * @file dmaF4 .h
2929 *
3030 * @author Marti Bolivar <mbolivar@leaflabs.com>;
3131 * Original implementation by Michael Hope
@@ -84,7 +84,7 @@ typedef struct dma_reg_map {
8484 * Register bit definitions
8585 */
8686
87- /* Channel configuration register */
87+ /* Stream configuration register */
8888
8989#define DMA_CR_CH0 (0x0 << 25)
9090#define DMA_CR_CH1 (0x1 << 25)
@@ -136,6 +136,25 @@ typedef struct dma_reg_map {
136136#define DMA_CR_DMEIE (0x1 << 1)
137137#define DMA_CR_EN (0x1)
138138
139+ typedef enum dma_channel {
140+ DMA_CH0 = DMA_CR_CH0 , /**< Channel 0 */
141+ DMA_CH1 = DMA_CR_CH1 , /**< Channel 1 */
142+ DMA_CH2 = DMA_CR_CH2 , /**< Channel 2 */
143+ DMA_CH3 = DMA_CR_CH3 , /**< Channel 3 */
144+ DMA_CH4 = DMA_CR_CH4 , /**< Channel 4 */
145+ DMA_CH5 = DMA_CR_CH5 , /**< Channel 5 */
146+ DMA_CH6 = DMA_CR_CH6 , /**< Channel 6 */
147+ DMA_CH7 = DMA_CR_CH7 , /**< Channel 7 */
148+ } dma_channel ;
149+
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+
139158/*
140159 * Devices
141160 */
@@ -166,25 +185,35 @@ extern dma_dev *DMA2;
166185 * Convenience functions
167186 */
168187
169- void dma_init (dma_dev * dev );
188+ extern void dma_init (dma_dev * dev );
170189
171190/** Flags for DMA transfer configuration. */
172191typedef enum dma_mode_flags {
173- DMA_MEM_2_MEM = 1 << 14 , /**< Memory to memory mode */
174- DMA_MINC_MODE = 1 << 7 , /**< Auto-increment memory address */
175- DMA_PINC_MODE = 1 << 6 , /**< Auto-increment peripheral address */
176- DMA_CIRC_MODE = 1 << 5 , /**< Circular mode */
177- DMA_FROM_MEM = 1 << 4 , /**< Read from memory to peripheral */
178- DMA_TRNS_ERR = 1 << 3 , /**< Interrupt on transfer error */
179- DMA_HALF_TRNS = 1 << 2 , /**< Interrupt on half-transfer */
180- DMA_TRNS_CMPLT = 1 << 1 /**< Interrupt on transfer completion */
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 */
203+ DMA_PRIO_MEDIUM = DMA_CR_PL_MEDIUM , /**< Medium priority */
204+ DMA_PRIO_HIGH = DMA_CR_PL_HIGH , /**< High priority */
205+ 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 */
208+ DMA_TRNS_ERR = DMA_CR_TEIE , /**< Interrupt on transfer error */
209+ DMA_DIR_MODE_ERR = DMA_CR_DMEIE /**< Interrupt on direct mode error */
181210} dma_mode_flags ;
182211
183212/** Source and destination transfer sizes. */
184213typedef enum dma_xfer_size {
185- DMA_SIZE_8BITS = 0 , /**< 8-bit transfers */
186- DMA_SIZE_16BITS = 1 , /**< 16-bit transfers */
187- DMA_SIZE_32BITS = 2 /**< 32-bit transfers */
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 */
188217} dma_xfer_size ;
189218
190219/** DMA channel */
@@ -201,17 +230,17 @@ typedef enum dma_stream {
201230
202231static inline void dma_setup_transfer (dma_dev * dev ,
203232 dma_stream stream ,
233+ dma_channel channel ,
234+ dma_xfer_size trx_size ,
204235 __io void * peripheral_address ,
205236 __io void * memory_address0 ,
206237 __io void * memory_address1 ,
207- uint32 flags ,
208- uint32 fifo_flags ) {
238+ uint32 flags ) {
209239 dev -> regs -> STREAM [stream ].CR &= ~DMA_CR_EN ; // disable
210240 dev -> regs -> STREAM [stream ].PAR = (uint32 )peripheral_address ;
211241 dev -> regs -> STREAM [stream ].M0AR = (uint32 )memory_address0 ;
212242 dev -> regs -> STREAM [stream ].M1AR = (uint32 )memory_address1 ;
213- dev -> regs -> STREAM [stream ].FCR = fifo_flags & 0x87 ; // mask out reserved bits
214- dev -> regs -> STREAM [stream ].CR = flags & 0x0feffffe ; // mask out reserved and enable
243+ dev -> regs -> STREAM [stream ].CR = ((flags |channel |trx_size ) & 0x0feffffe ); // mask out reserved and enable
215244}
216245
217246static inline void dma_set_num_transfers (dma_dev * dev ,
@@ -220,6 +249,12 @@ static inline void dma_set_num_transfers(dma_dev *dev,
220249 dev -> regs -> STREAM [stream ].NDTR = num_transfers ;
221250}
222251
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
256+ }
257+
223258void dma_attach_interrupt (dma_dev * dev ,
224259 dma_stream stream ,
225260 void (* handler )(void ));
@@ -232,6 +267,7 @@ static inline void dma_enable(dma_dev *dev, dma_stream stream) {
232267
233268static inline void dma_disable (dma_dev * dev , dma_stream stream ) {
234269 dev -> regs -> STREAM [stream ].CR &= ~DMA_CR_EN ;
270+ while (dev -> regs -> STREAM [stream ].CR & DMA_CR_EN ); // wait till EN bit is reset, see AN4031, chapter 4.1
235271}
236272
237273/**
0 commit comments