Skip to content

Commit 59ebf2a

Browse files
committed
improved SPI no DMA block read + added SPI DMA
1 parent 28fa836 commit 59ebf2a

5 files changed

Lines changed: 71 additions & 58 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
/**

STM32F4/cores/maple/libmaple/dma_common.h

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ extern "C"{
5656
* Devices
5757
*/
5858

59-
struct dma_reg_map;
59+
//struct dma_reg_map;
6060

6161
/* Encapsulates state related to user interrupt handlers. You
6262
* shouldn't touch these directly; use dma_attach_interrupt() and
@@ -82,16 +82,6 @@ struct dma_reg_map;
8282
*
8383
* @see dma_tube
8484
*/
85-
typedef enum dma_channel {
86-
DMA_CH0 = 0, /**< Channel 0 */
87-
DMA_CH1 = 1, /**< Channel 1 */
88-
DMA_CH2 = 2, /**< Channel 2 */
89-
DMA_CH3 = 3, /**< Channel 3 */
90-
DMA_CH4 = 4, /**< Channel 4 */
91-
DMA_CH5 = 5, /**< Channel 5 */
92-
DMA_CH6 = 6, /**< Channel 6 */
93-
DMA_CH7 = 7, /**< Channel 7 */
94-
} dma_channel;
9585

9686
/**
9787
* @brief Source and destination transfer sizes.

STM32F4/cores/maple/libmaple/spi_f4.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
/**
2929
* @file libmaple/stm32f1/spi.c
3030
* @author Marti Bolivar <mbolivar@leaflabs.com>
31-
* @brief STM32F1 SPI/I2S.
31+
* @brief STM32F4 SPI/I2S.
3232
*/
3333

3434
#include <libmaple/spi.h>

STM32F4/libraries/SPI/src/SPI.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
#include <libmaple/dma.h>
4343
#include <wirish.h>
4444

45+
#define SPI_DMA
46+
4547
// SPI_HAS_TRANSACTION means SPI has
4648
// - beginTransaction()
4749
// - endTransaction()
@@ -135,11 +137,12 @@ class SPISettings {
135137
uint32_t dataSize;
136138

137139
spi_dev *spi_d;
138-
//uint8_t _SSPin;
139140
uint32_t clockDivider;
141+
140142
#ifdef SPI_DMA
141-
dma_channel spiRxDmaChannel, spiTxDmaChannel;
142143
dma_dev* spiDmaDev;
144+
dma_channel spiDmaChannel;
145+
dma_stream spiRxDmaStream, spiTxDmaStream;
143146
#endif
144147

145148
friend class SPIClass;
@@ -396,5 +399,6 @@ class SPIClass {
396399
*/
397400
};
398401

402+
extern SPIClass SPI;
399403

400404
#endif

0 commit comments

Comments
 (0)