diff --git a/STM32F4/cores/maple/libmaple/dmaF4.c b/STM32F4/cores/maple/libmaple/dmaF4.c index 4b530af..add3d8e 100644 --- a/STM32F4/cores/maple/libmaple/dmaF4.c +++ b/STM32F4/cores/maple/libmaple/dmaF4.c @@ -117,33 +117,16 @@ void dma_detach_interrupt(dma_dev *dev, dma_stream stream) { dev->handlers[stream].handler = NULL; } +const uint8 dma_isr_bits_shift[] = { 0, 6, 16, 22}; + +uint8 dma_get_isr_bits(dma_dev *dev, dma_stream stream) { + if ( stream&0xFC ) return ((dev->regs->HISR)>>dma_isr_bits_shift[stream&0x03]) & 0x3d; + else return ((dev->regs->LISR)>>dma_isr_bits_shift[stream&0x03]) & 0x3d; +} + void dma_clear_isr_bits(dma_dev *dev, dma_stream stream) { - switch (stream) { - case 0: - dev->regs->LIFCR|=0x0000003d; - break; - case 1: - dev->regs->LIFCR|=0x00000f40; - break; - case 2: - dev->regs->LIFCR|=0x003d0000; - break; - case 3: - dev->regs->LIFCR|=0x0f400000; - break; - case 4: - dev->regs->HIFCR|=0x0000003d; - break; - case 5: - dev->regs->HIFCR|=0x00000f40; - break; - case 6: - dev->regs->HIFCR|=0x003d0000; - break; - case 7: - dev->regs->HIFCR|=0x0f400000; - break; - } + if ( stream&0xFC ) dev->regs->HIFCR = (uint32)0x0000003d << dma_isr_bits_shift[stream&0x03]; + else dev->regs->LIFCR = (uint32)0x0000003d << dma_isr_bits_shift[stream&0x03]; } /* diff --git a/STM32F4/cores/maple/libmaple/dmaF4.h b/STM32F4/cores/maple/libmaple/dmaF4.h index 6f7086f..757906c 100644 --- a/STM32F4/cores/maple/libmaple/dmaF4.h +++ b/STM32F4/cores/maple/libmaple/dmaF4.h @@ -25,7 +25,7 @@ *****************************************************************************/ /** - * @file dma.h + * @file dmaF4.h * * @author Marti Bolivar ; * Original implementation by Michael Hope @@ -84,7 +84,7 @@ typedef struct dma_reg_map { * Register bit definitions */ -/* Channel configuration register */ +/* Stream configuration register */ #define DMA_CR_CH0 (0x0 << 25) #define DMA_CR_CH1 (0x1 << 25) @@ -136,6 +136,25 @@ typedef struct dma_reg_map { #define DMA_CR_DMEIE (0x1 << 1) #define DMA_CR_EN (0x1) +typedef enum dma_channel { + DMA_CH0 = DMA_CR_CH0, /**< Channel 0 */ + DMA_CH1 = DMA_CR_CH1, /**< Channel 1 */ + DMA_CH2 = DMA_CR_CH2, /**< Channel 2 */ + DMA_CH3 = DMA_CR_CH3, /**< Channel 3 */ + DMA_CH4 = DMA_CR_CH4, /**< Channel 4 */ + DMA_CH5 = DMA_CR_CH5, /**< Channel 5 */ + DMA_CH6 = DMA_CR_CH6, /**< Channel 6 */ + DMA_CH7 = DMA_CR_CH7, /**< Channel 7 */ +} dma_channel; + +/* Device interrupt status register flags */ + +#define DMA_ISR_TCIF (1 << 5) +#define DMA_ISR_HTIF (1 << 4) +#define DMA_ISR_TEIF (1 << 3) +#define DMA_ISR_DMEIF (1 << 2) +#define DMA_ISR_FEIF (1 << 0) + /* * Devices */ @@ -166,25 +185,35 @@ extern dma_dev *DMA2; * Convenience functions */ -void dma_init(dma_dev *dev); +extern void dma_init(dma_dev *dev); /** Flags for DMA transfer configuration. */ typedef enum dma_mode_flags { - DMA_MEM_2_MEM = 1 << 14, /**< Memory to memory mode */ - DMA_MINC_MODE = 1 << 7, /**< Auto-increment memory address */ - DMA_PINC_MODE = 1 << 6, /**< Auto-increment peripheral address */ - DMA_CIRC_MODE = 1 << 5, /**< Circular mode */ - DMA_FROM_MEM = 1 << 4, /**< Read from memory to peripheral */ - DMA_TRNS_ERR = 1 << 3, /**< Interrupt on transfer error */ - DMA_HALF_TRNS = 1 << 2, /**< Interrupt on half-transfer */ - DMA_TRNS_CMPLT = 1 << 1 /**< Interrupt on transfer completion */ + DMA_MEM_BUF_0 = DMA_CR_CT0, /**< Current memory target buffer 0 */ + DMA_MEM_BUF_1 = DMA_CR_CT1, /**< Current memory target buffer 1 */ + DMA_DBL_BUF_MODE = DMA_CR_DBM, /**< Current memory double buffer mode */ + DMA_PINC_OFFSET = DMA_CR_PINCOS, /**< Peripheral increment offset size */ + DMA_MINC_MODE = DMA_CR_MINC, /**< Memory increment mode */ + DMA_PINC_MODE = DMA_CR_PINC, /**< Peripheral increment mode */ + DMA_CIRC_MODE = DMA_CR_CIRC, /**< Memory Circular mode */ + DMA_FROM_PER = DMA_CR_DIR_P2M, /**< Read from memory to peripheral */ + DMA_FROM_MEM = DMA_CR_DIR_M2P, /**< Read from memory to peripheral */ + DMA_MEM_TO_MEM = DMA_CR_DIR_M2M, /**< Read from memory to memory */ + DMA_PERIF_CTRL = DMA_CR_PFCTRL, /**< Peripheral flow controller */ + DMA_PRIO_MEDIUM = DMA_CR_PL_MEDIUM, /**< Medium priority */ + DMA_PRIO_HIGH = DMA_CR_PL_HIGH, /**< High priority */ + DMA_PRIO_VERY_HIGH = DMA_CR_PL_VERY_HIGH, /**< Very high priority */ + DMA_TRNS_CMPLT = DMA_CR_TCIE, /**< Interrupt on transfer completion */ + DMA_TRNS_HALF = DMA_CR_HTIE, /**< Interrupt on half-transfer */ + DMA_TRNS_ERR = DMA_CR_TEIE, /**< Interrupt on transfer error */ + DMA_DIR_MODE_ERR = DMA_CR_DMEIE /**< Interrupt on direct mode error */ } dma_mode_flags; /** Source and destination transfer sizes. */ typedef enum dma_xfer_size { - DMA_SIZE_8BITS = 0, /**< 8-bit transfers */ - DMA_SIZE_16BITS = 1, /**< 16-bit transfers */ - DMA_SIZE_32BITS = 2 /**< 32-bit transfers */ + DMA_SIZE_8BITS = ( DMA_CR_MSIZE_8BITS|DMA_CR_PSIZE_8BITS ), /**< 8-bit transfers */ + DMA_SIZE_16BITS = (DMA_CR_MSIZE_16BITS|DMA_CR_PSIZE_16BITS), /**< 16-bit transfers */ + DMA_SIZE_32BITS = (DMA_CR_MSIZE_32BITS|DMA_CR_PSIZE_32BITS) /**< 32-bit transfers */ } dma_xfer_size; /** DMA channel */ @@ -201,17 +230,17 @@ typedef enum dma_stream { static inline void dma_setup_transfer(dma_dev *dev, dma_stream stream, + dma_channel channel, + dma_xfer_size trx_size, __io void *peripheral_address, __io void *memory_address0, __io void *memory_address1, - uint32 flags, - uint32 fifo_flags) { + uint32 flags) { dev->regs->STREAM[stream].CR &= ~DMA_CR_EN; // disable dev->regs->STREAM[stream].PAR = (uint32)peripheral_address; dev->regs->STREAM[stream].M0AR = (uint32)memory_address0; dev->regs->STREAM[stream].M1AR = (uint32)memory_address1; - dev->regs->STREAM[stream].FCR = fifo_flags & 0x87; // mask out reserved bits - dev->regs->STREAM[stream].CR = flags & 0x0feffffe; // mask out reserved and enable + dev->regs->STREAM[stream].CR = ((flags|channel|trx_size) & 0x0feffffe); // mask out reserved and enable } static inline void dma_set_num_transfers(dma_dev *dev, @@ -220,6 +249,12 @@ static inline void dma_set_num_transfers(dma_dev *dev, dev->regs->STREAM[stream].NDTR = num_transfers; } +static inline void dma_set_fifo_flags(dma_dev *dev, + dma_stream stream, + uint8 fifo_flags) { + dev->regs->STREAM[stream].FCR = fifo_flags & 0x87; // mask out reserved bits +} + void dma_attach_interrupt(dma_dev *dev, dma_stream stream, void (*handler)(void)); @@ -232,6 +267,7 @@ static inline void dma_enable(dma_dev *dev, dma_stream stream) { static inline void dma_disable(dma_dev *dev, dma_stream stream) { dev->regs->STREAM[stream].CR &= ~DMA_CR_EN; + while (dev->regs->STREAM[stream].CR & DMA_CR_EN); // wait till EN bit is reset, see AN4031, chapter 4.1 } /** diff --git a/STM32F4/cores/maple/libmaple/dma_common.h b/STM32F4/cores/maple/libmaple/dma_common.h index 15dfab9..5f98921 100644 --- a/STM32F4/cores/maple/libmaple/dma_common.h +++ b/STM32F4/cores/maple/libmaple/dma_common.h @@ -56,7 +56,7 @@ extern "C"{ * Devices */ -struct dma_reg_map; +//struct dma_reg_map; /* Encapsulates state related to user interrupt handlers. You * shouldn't touch these directly; use dma_attach_interrupt() and @@ -82,16 +82,6 @@ struct dma_reg_map; * * @see dma_tube */ -typedef enum dma_channel { - DMA_CH0 = 0, /**< Channel 0 */ - DMA_CH1 = 1, /**< Channel 1 */ - DMA_CH2 = 2, /**< Channel 2 */ - DMA_CH3 = 3, /**< Channel 3 */ - DMA_CH4 = 4, /**< Channel 4 */ - DMA_CH5 = 5, /**< Channel 5 */ - DMA_CH6 = 6, /**< Channel 6 */ - DMA_CH7 = 7, /**< Channel 7 */ -} dma_channel; /** * @brief Source and destination transfer sizes. diff --git a/STM32F4/cores/maple/libmaple/spi_f4.c b/STM32F4/cores/maple/libmaple/spi_f4.c index 43f5092..8e1bc15 100644 --- a/STM32F4/cores/maple/libmaple/spi_f4.c +++ b/STM32F4/cores/maple/libmaple/spi_f4.c @@ -28,7 +28,7 @@ /** * @file libmaple/stm32f1/spi.c * @author Marti Bolivar - * @brief STM32F1 SPI/I2S. + * @brief STM32F4 SPI/I2S. */ #include diff --git a/STM32F4/libraries/SPI/src/SPI.h b/STM32F4/libraries/SPI/src/SPI.h index 39a5a9e..fe728b5 100644 --- a/STM32F4/libraries/SPI/src/SPI.h +++ b/STM32F4/libraries/SPI/src/SPI.h @@ -42,6 +42,8 @@ #include #include +#define SPI_DMA + // SPI_HAS_TRANSACTION means SPI has // - beginTransaction() // - endTransaction() @@ -135,11 +137,12 @@ private: uint32_t dataSize; spi_dev *spi_d; - //uint8_t _SSPin; uint32_t clockDivider; + #ifdef SPI_DMA - dma_channel spiRxDmaChannel, spiTxDmaChannel; dma_dev* spiDmaDev; + dma_channel spiDmaChannel; + dma_stream spiRxDmaStream, spiTxDmaStream; #endif friend class SPIClass; @@ -396,5 +399,6 @@ private: */ }; +extern SPIClass SPI; #endif