Skip to content

Commit bd3fb68

Browse files
committed
SPI improvements: non-DMA block read + added DMA transfer functions
1 parent fc0ee24 commit bd3fb68

4 files changed

Lines changed: 169 additions & 116 deletions

File tree

STM32F4/cores/maple/libmaple/dmaF4.c

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -117,33 +117,16 @@ void dma_detach_interrupt(dma_dev *dev, dma_stream stream) {
117117
dev->handlers[stream].handler = NULL;
118118
}
119119

120+
const uint8 dma_isr_bits_shift[] = { 0, 6, 16, 22};
121+
122+
uint8 dma_get_isr_bits(dma_dev *dev, dma_stream stream) {
123+
if ( stream&0xFC ) return ((dev->regs->HISR)>>dma_isr_bits_shift[stream&0x03]) & 0x3d;
124+
else return ((dev->regs->LISR)>>dma_isr_bits_shift[stream&0x03]) & 0x3d;
125+
}
126+
120127
void dma_clear_isr_bits(dma_dev *dev, dma_stream stream) {
121-
switch (stream) {
122-
case 0:
123-
dev->regs->LIFCR|=0x0000003d;
124-
break;
125-
case 1:
126-
dev->regs->LIFCR|=0x00000f40;
127-
break;
128-
case 2:
129-
dev->regs->LIFCR|=0x003d0000;
130-
break;
131-
case 3:
132-
dev->regs->LIFCR|=0x0f400000;
133-
break;
134-
case 4:
135-
dev->regs->HIFCR|=0x0000003d;
136-
break;
137-
case 5:
138-
dev->regs->HIFCR|=0x00000f40;
139-
break;
140-
case 6:
141-
dev->regs->HIFCR|=0x003d0000;
142-
break;
143-
case 7:
144-
dev->regs->HIFCR|=0x0f400000;
145-
break;
146-
}
128+
if ( stream&0xFC ) dev->regs->HIFCR = (uint32)0x0000003d << dma_isr_bits_shift[stream&0x03];
129+
else dev->regs->LIFCR = (uint32)0x0000003d << dma_isr_bits_shift[stream&0x03];
147130
}
148131

149132
/*

STM32F4/cores/maple/libmaple/dmaF4.h

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
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. */
172191
typedef 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. */
184213
typedef 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

202231
static 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

217246
static 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+
223258
void 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

233268
static 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

Comments
 (0)