stm32h7:DMA Add BDMA support
Apply suggestions from code review Co-authored-by: Mateusz Szafoni <raiden00pl@gmail.com>
This commit is contained in:
parent
a7a272661e
commit
a793369815
@ -49,17 +49,20 @@
|
|||||||
|
|
||||||
/* Register Offsets *****************************************************************/
|
/* Register Offsets *****************************************************************/
|
||||||
|
|
||||||
#define STM32_BDMA_OFFSET(x) (0x08+0x14*(x))
|
|
||||||
#define STM32_BDMA_ISR_OFFSET 0x0000 /* BDMA interrupt status register */
|
#define STM32_BDMA_ISR_OFFSET 0x0000 /* BDMA interrupt status register */
|
||||||
#define STM32_BDMA_IFCR_OFFSET 0x0004 /* BDMA interrupt flag clear register */
|
#define STM32_BDMA_IFCR_OFFSET 0x0004 /* BDMA interrupt flag clear register */
|
||||||
|
|
||||||
#define STM32_BDMACH_CCR_OFFSET 0x0008
|
#define STM32_BDMACH_CCR_OFFSET 0x0008 /* BDMA channel x configuration register */
|
||||||
#define STM32_BDMACH_CNDTR_OFFSET 0x000C
|
#define STM32_BDMACH_CNDTR_OFFSET 0x000C /* BDMA channel x number of data to transfer register */
|
||||||
#define STM32_BDMACH_CPAR_OFFSET 0x0010
|
#define STM32_BDMACH_CPAR_OFFSET 0x0010 /* BDMA channel x peripheral address register */
|
||||||
#define STM32_BDMACH_CM0AR_OFFSET 0x0014
|
#define STM32_BDMACH_CM0AR_OFFSET 0x0014 /* BDMA channel x memory 0 address register */
|
||||||
#define STM32_BDMACH_CM1AR_OFFSET 0x0018
|
#define STM32_BDMACH_CM1AR_OFFSET 0x0018 /* BDMA channel x memory 1 address register */
|
||||||
|
|
||||||
#define STM32_BDMA_CCRX_OFFSET(x) (0x0008+(x*0x0014)) /* BDMA channel x configuration register */
|
#define STM32_BDMA_SPACING 0x14
|
||||||
|
#define STM32_BDMA_OFFSET(x) (STM32_BDMA_SPACING * (x))
|
||||||
|
|
||||||
|
#define STM32_BDMA_CCRX_OFFSET(x) (STM32_BDMACH_CCR_OFFSET + \
|
||||||
|
STM32_BDMA_OFFSET(x))
|
||||||
#define STM32_BDMA_CCR0_OFFSET STM32_BDMA_CCRX_OFFSET(0)
|
#define STM32_BDMA_CCR0_OFFSET STM32_BDMA_CCRX_OFFSET(0)
|
||||||
#define STM32_BDMA_CCR1_OFFSET STM32_BDMA_CCRX_OFFSET(1)
|
#define STM32_BDMA_CCR1_OFFSET STM32_BDMA_CCRX_OFFSET(1)
|
||||||
#define STM32_BDMA_CCR2_OFFSET STM32_BDMA_CCRX_OFFSET(2)
|
#define STM32_BDMA_CCR2_OFFSET STM32_BDMA_CCRX_OFFSET(2)
|
||||||
@ -69,7 +72,8 @@
|
|||||||
#define STM32_BDMA_CCR6_OFFSET STM32_BDMA_CCRX_OFFSET(6)
|
#define STM32_BDMA_CCR6_OFFSET STM32_BDMA_CCRX_OFFSET(6)
|
||||||
#define STM32_BDMA_CCR7_OFFSET STM32_BDMA_CCRX_OFFSET(7)
|
#define STM32_BDMA_CCR7_OFFSET STM32_BDMA_CCRX_OFFSET(7)
|
||||||
|
|
||||||
#define STM32_BDMA_CNDTRX_OFFSET(x) (0x000C+(x*0x0014)) /* BDMA channel x number of data to transfer register */
|
#define STM32_BDMA_CNDTRX_OFFSET(x) (STM32_BDMACH_CNDTR_OFFSET + \
|
||||||
|
STM32_BDMA_OFFSET(x))
|
||||||
#define STM32_BDMA_CNDTR0_OFFSET STM32_BDMA_CNDTRX_OFFSET(0)
|
#define STM32_BDMA_CNDTR0_OFFSET STM32_BDMA_CNDTRX_OFFSET(0)
|
||||||
#define STM32_BDMA_CNDTR1_OFFSET STM32_BDMA_CNDTRX_OFFSET(1)
|
#define STM32_BDMA_CNDTR1_OFFSET STM32_BDMA_CNDTRX_OFFSET(1)
|
||||||
#define STM32_BDMA_CNDTR2_OFFSET STM32_BDMA_CNDTRX_OFFSET(2)
|
#define STM32_BDMA_CNDTR2_OFFSET STM32_BDMA_CNDTRX_OFFSET(2)
|
||||||
@ -79,7 +83,8 @@
|
|||||||
#define STM32_BDMA_CNDTR6_OFFSET STM32_BDMA_CNDTRX_OFFSET(6)
|
#define STM32_BDMA_CNDTR6_OFFSET STM32_BDMA_CNDTRX_OFFSET(6)
|
||||||
#define STM32_BDMA_CNDTR7_OFFSET STM32_BDMA_CNDTRX_OFFSET(7)
|
#define STM32_BDMA_CNDTR7_OFFSET STM32_BDMA_CNDTRX_OFFSET(7)
|
||||||
|
|
||||||
#define STM32_BDMA_CPARX_OFFSET(x) (0x0010+(x*0x0014)) /* BDMA channel x peripheral address register */
|
#define STM32_BDMA_CPARX_OFFSET(x) (STM32_BDMACH_CPAR_OFFSET + \
|
||||||
|
STM32_BDMA_OFFSET(x))
|
||||||
#define STM32_BDMA_CPAR0_OFFSET STM32_BDMA_CPARX_OFFSET(0)
|
#define STM32_BDMA_CPAR0_OFFSET STM32_BDMA_CPARX_OFFSET(0)
|
||||||
#define STM32_BDMA_CPAR1_OFFSET STM32_BDMA_CPARX_OFFSET(1)
|
#define STM32_BDMA_CPAR1_OFFSET STM32_BDMA_CPARX_OFFSET(1)
|
||||||
#define STM32_BDMA_CPAR2_OFFSET STM32_BDMA_CPARX_OFFSET(2)
|
#define STM32_BDMA_CPAR2_OFFSET STM32_BDMA_CPARX_OFFSET(2)
|
||||||
@ -89,7 +94,8 @@
|
|||||||
#define STM32_BDMA_CPAR6_OFFSET STM32_BDMA_CPARX_OFFSET(6)
|
#define STM32_BDMA_CPAR6_OFFSET STM32_BDMA_CPARX_OFFSET(6)
|
||||||
#define STM32_BDMA_CPAR7_OFFSET STM32_BDMA_CPARX_OFFSET(7)
|
#define STM32_BDMA_CPAR7_OFFSET STM32_BDMA_CPARX_OFFSET(7)
|
||||||
|
|
||||||
#define STM32_BDMA_CM0ARX_OFFSET(x) (0x0014+(x*0x0014)) /* BDMA channel x memory 0 address register */
|
#define STM32_BDMA_CM0ARX_OFFSET(x) (STM32_BDMACH_CM0AR_OFFSET + \
|
||||||
|
STM32_BDMA_OFFSET(x))
|
||||||
#define STM32_BDMA_CM0AR0_OFFSET STM32_BDMA_CM0ARX_OFFSET(0)
|
#define STM32_BDMA_CM0AR0_OFFSET STM32_BDMA_CM0ARX_OFFSET(0)
|
||||||
#define STM32_BDMA_CM0AR1_OFFSET STM32_BDMA_CM0ARX_OFFSET(1)
|
#define STM32_BDMA_CM0AR1_OFFSET STM32_BDMA_CM0ARX_OFFSET(1)
|
||||||
#define STM32_BDMA_CM0AR2_OFFSET STM32_BDMA_CM0ARX_OFFSET(2)
|
#define STM32_BDMA_CM0AR2_OFFSET STM32_BDMA_CM0ARX_OFFSET(2)
|
||||||
@ -99,7 +105,8 @@
|
|||||||
#define STM32_BDMA_CM0AR6_OFFSET STM32_BDMA_CM0ARX_OFFSET(6)
|
#define STM32_BDMA_CM0AR6_OFFSET STM32_BDMA_CM0ARX_OFFSET(6)
|
||||||
#define STM32_BDMA_CM0AR7_OFFSET STM32_BDMA_CM0ARX_OFFSET(7)
|
#define STM32_BDMA_CM0AR7_OFFSET STM32_BDMA_CM0ARX_OFFSET(7)
|
||||||
|
|
||||||
#define STM32_BDMA_CM1ARX_OFFSET(x) (0x0018+(x*0x0014)) /* BDMA channel x memory 1 address register */
|
#define STM32_BDMA_CM1ARX_OFFSET(x) (STM32_BDMACH_CM1AR_OFFSET + \
|
||||||
|
STM32_BDMA_OFFSET(x))
|
||||||
#define STM32_BDMA_CM1AR0_OFFSET STM32_BDMA_CM1ARX_OFFSET(0)
|
#define STM32_BDMA_CM1AR0_OFFSET STM32_BDMA_CM1ARX_OFFSET(0)
|
||||||
#define STM32_BDMA_CM1AR1_OFFSET STM32_BDMA_CM1ARX_OFFSET(1)
|
#define STM32_BDMA_CM1AR1_OFFSET STM32_BDMA_CM1ARX_OFFSET(1)
|
||||||
#define STM32_BDMA_CM1AR2_OFFSET STM32_BDMA_CM1ARX_OFFSET(2)
|
#define STM32_BDMA_CM1AR2_OFFSET STM32_BDMA_CM1ARX_OFFSET(2)
|
||||||
@ -172,6 +179,7 @@
|
|||||||
#define BDMA_CHAN_TCIF (1 << 1) /* Bit 1: Transfer complete flag */
|
#define BDMA_CHAN_TCIF (1 << 1) /* Bit 1: Transfer complete flag */
|
||||||
#define BDMA_CHAN_HTIF (1 << 2) /* Bit 2: half transfer complete flag */
|
#define BDMA_CHAN_HTIF (1 << 2) /* Bit 2: half transfer complete flag */
|
||||||
#define BDMA_CHAN_TEIF (1 << 3) /* Bit 3: Transfer error flag */
|
#define BDMA_CHAN_TEIF (1 << 3) /* Bit 3: Transfer error flag */
|
||||||
|
#define BDMA_CCR_ALLINTS (BDMA_CHAN_TCIF | BDMA_CHAN_HTIF | BDMA_CHAN_TEIF)
|
||||||
|
|
||||||
/* BDMA interrupt status register */
|
/* BDMA interrupt status register */
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@
|
|||||||
#define DMA_STREAM_HTIF_BIT (1 << 4) /* Bit 4: Stream Half Transfer flag */
|
#define DMA_STREAM_HTIF_BIT (1 << 4) /* Bit 4: Stream Half Transfer flag */
|
||||||
#define DMA_STREAM_TCIF_BIT (1 << 5) /* Bit 5: Stream Transfer Complete flag */
|
#define DMA_STREAM_TCIF_BIT (1 << 5) /* Bit 5: Stream Transfer Complete flag */
|
||||||
|
|
||||||
/* DMA interrupt status register and interrupt flag clear register field definitions */
|
/* DMA interrupt status and interrupt clear register field definitions */
|
||||||
|
|
||||||
#define DMA_INT_STREAM0_SHIFT (0) /* Bits 0-5: DMA Stream 0 interrupt */
|
#define DMA_INT_STREAM0_SHIFT (0) /* Bits 0-5: DMA Stream 0 interrupt */
|
||||||
#define DMA_INT_STREAM0_MASK (DMA_STREAM_MASK << DMA_INT_STREAM0_SHIFT)
|
#define DMA_INT_STREAM0_MASK (DMA_STREAM_MASK << DMA_INT_STREAM0_SHIFT)
|
||||||
@ -308,6 +308,7 @@
|
|||||||
# define DMA_SCR_DIR_P2M (0 << DMA_SCR_DIR_SHIFT) /* 00: Peripheral-to-memory */
|
# define DMA_SCR_DIR_P2M (0 << DMA_SCR_DIR_SHIFT) /* 00: Peripheral-to-memory */
|
||||||
# define DMA_SCR_DIR_M2P (1 << DMA_SCR_DIR_SHIFT) /* 01: Memory-to-peripheral */
|
# define DMA_SCR_DIR_M2P (1 << DMA_SCR_DIR_SHIFT) /* 01: Memory-to-peripheral */
|
||||||
# define DMA_SCR_DIR_M2M (2 << DMA_SCR_DIR_SHIFT) /* 10: Memory-to-memory */
|
# define DMA_SCR_DIR_M2M (2 << DMA_SCR_DIR_SHIFT) /* 10: Memory-to-memory */
|
||||||
|
|
||||||
#define DMA_SCR_CIRC (1 << 8) /* Bit 8: Circular mode */
|
#define DMA_SCR_CIRC (1 << 8) /* Bit 8: Circular mode */
|
||||||
#define DMA_SCR_PINC (1 << 9) /* Bit 9: Peripheral increment mode */
|
#define DMA_SCR_PINC (1 << 9) /* Bit 9: Peripheral increment mode */
|
||||||
#define DMA_SCR_MINC (1 << 10) /* Bit 10: Memory increment mode */
|
#define DMA_SCR_MINC (1 << 10) /* Bit 10: Memory increment mode */
|
||||||
@ -316,11 +317,13 @@
|
|||||||
# define DMA_SCR_PSIZE_8BITS (0 << DMA_SCR_PSIZE_SHIFT) /* 00: 8-bits */
|
# define DMA_SCR_PSIZE_8BITS (0 << DMA_SCR_PSIZE_SHIFT) /* 00: 8-bits */
|
||||||
# define DMA_SCR_PSIZE_16BITS (1 << DMA_SCR_PSIZE_SHIFT) /* 01: 16-bits */
|
# define DMA_SCR_PSIZE_16BITS (1 << DMA_SCR_PSIZE_SHIFT) /* 01: 16-bits */
|
||||||
# define DMA_SCR_PSIZE_32BITS (2 << DMA_SCR_PSIZE_SHIFT) /* 10: 32-bits */
|
# define DMA_SCR_PSIZE_32BITS (2 << DMA_SCR_PSIZE_SHIFT) /* 10: 32-bits */
|
||||||
|
|
||||||
#define DMA_SCR_MSIZE_SHIFT (13) /* Bits 13-14: Memory size */
|
#define DMA_SCR_MSIZE_SHIFT (13) /* Bits 13-14: Memory size */
|
||||||
#define DMA_SCR_MSIZE_MASK (3 << DMA_SCR_MSIZE_SHIFT)
|
#define DMA_SCR_MSIZE_MASK (3 << DMA_SCR_MSIZE_SHIFT)
|
||||||
# define DMA_SCR_MSIZE_8BITS (0 << DMA_SCR_MSIZE_SHIFT) /* 00: 8-bits */
|
# define DMA_SCR_MSIZE_8BITS (0 << DMA_SCR_MSIZE_SHIFT) /* 00: 8-bits */
|
||||||
# define DMA_SCR_MSIZE_16BITS (1 << DMA_SCR_MSIZE_SHIFT) /* 01: 16-bits */
|
# define DMA_SCR_MSIZE_16BITS (1 << DMA_SCR_MSIZE_SHIFT) /* 01: 16-bits */
|
||||||
# define DMA_SCR_MSIZE_32BITS (2 << DMA_SCR_MSIZE_SHIFT) /* 10: 32-bits */
|
# define DMA_SCR_MSIZE_32BITS (2 << DMA_SCR_MSIZE_SHIFT) /* 10: 32-bits */
|
||||||
|
|
||||||
#define DMA_SCR_PINCOS (1 << 15) /* Bit 15: Peripheral increment offset size */
|
#define DMA_SCR_PINCOS (1 << 15) /* Bit 15: Peripheral increment offset size */
|
||||||
#define DMA_SCR_PL_SHIFT (16) /* Bits 16-17: Stream Priority level */
|
#define DMA_SCR_PL_SHIFT (16) /* Bits 16-17: Stream Priority level */
|
||||||
#define DMA_SCR_PL_MASK (3 << DMA_SCR_PL_SHIFT)
|
#define DMA_SCR_PL_MASK (3 << DMA_SCR_PL_SHIFT)
|
||||||
@ -328,6 +331,7 @@
|
|||||||
# define DMA_SCR_PRIMED (1 << DMA_SCR_PL_SHIFT) /* 01: Medium */
|
# define DMA_SCR_PRIMED (1 << DMA_SCR_PL_SHIFT) /* 01: Medium */
|
||||||
# define DMA_SCR_PRIHI (2 << DMA_SCR_PL_SHIFT) /* 10: High */
|
# define DMA_SCR_PRIHI (2 << DMA_SCR_PL_SHIFT) /* 10: High */
|
||||||
# define DMA_SCR_PRIVERYHI (3 << DMA_SCR_PL_SHIFT) /* 11: Very high */
|
# define DMA_SCR_PRIVERYHI (3 << DMA_SCR_PL_SHIFT) /* 11: Very high */
|
||||||
|
|
||||||
#define DMA_SCR_DBM (1 << 18) /* Bit 15: Double buffer mode */
|
#define DMA_SCR_DBM (1 << 18) /* Bit 15: Double buffer mode */
|
||||||
#define DMA_SCR_CT (1 << 19) /* Bit 19: Current target */
|
#define DMA_SCR_CT (1 << 19) /* Bit 19: Current target */
|
||||||
/* Bit 20: Reserved */
|
/* Bit 20: Reserved */
|
||||||
@ -337,6 +341,7 @@
|
|||||||
# define DMA_SCR_PBURST_INCR4 (1 << DMA_SCR_PBURST_SHIFT) /* 01: Incremental burst of 4 beats */
|
# define DMA_SCR_PBURST_INCR4 (1 << DMA_SCR_PBURST_SHIFT) /* 01: Incremental burst of 4 beats */
|
||||||
# define DMA_SCR_PBURST_INCR8 (2 << DMA_SCR_PBURST_SHIFT) /* 10: Incremental burst of 8 beats */
|
# define DMA_SCR_PBURST_INCR8 (2 << DMA_SCR_PBURST_SHIFT) /* 10: Incremental burst of 8 beats */
|
||||||
# define DMA_SCR_PBURST_INCR16 (3 << DMA_SCR_PBURST_SHIFT) /* 11: Incremental burst of 16 beats */
|
# define DMA_SCR_PBURST_INCR16 (3 << DMA_SCR_PBURST_SHIFT) /* 11: Incremental burst of 16 beats */
|
||||||
|
|
||||||
#define DMA_SCR_MBURST_SHIFT (23) /* Bits 23-24: Memory burst transfer configuration */
|
#define DMA_SCR_MBURST_SHIFT (23) /* Bits 23-24: Memory burst transfer configuration */
|
||||||
#define DMA_SCR_MBURST_MASK (3 << DMA_SCR_MBURST_SHIFT)
|
#define DMA_SCR_MBURST_MASK (3 << DMA_SCR_MBURST_SHIFT)
|
||||||
# define DMA_SCR_MBURST_SINGLE (0 << DMA_SCR_MBURST_SHIFT) /* 00: Single transfer */
|
# define DMA_SCR_MBURST_SINGLE (0 << DMA_SCR_MBURST_SHIFT) /* 00: Single transfer */
|
||||||
@ -360,6 +365,7 @@
|
|||||||
# define DMA_SFCR_FTH_HALF (1 << DMA_SFCR_FTH_SHIFT) /* 1/2 full FIFO */
|
# define DMA_SFCR_FTH_HALF (1 << DMA_SFCR_FTH_SHIFT) /* 1/2 full FIFO */
|
||||||
# define DMA_SFCR_FTH_3QUARTER (2 << DMA_SFCR_FTH_SHIFT) /* 3/4 full FIFO */
|
# define DMA_SFCR_FTH_3QUARTER (2 << DMA_SFCR_FTH_SHIFT) /* 3/4 full FIFO */
|
||||||
# define DMA_SFCR_FTH_FULL (3 << DMA_SFCR_FTH_SHIFT) /* full FIFO */
|
# define DMA_SFCR_FTH_FULL (3 << DMA_SFCR_FTH_SHIFT) /* full FIFO */
|
||||||
|
|
||||||
#define DMA_SFCR_DMDIS (1 << 2) /* Bit 2: Direct mode disable */
|
#define DMA_SFCR_DMDIS (1 << 2) /* Bit 2: Direct mode disable */
|
||||||
#define DMA_SFCR_FS_SHIFT (3) /* Bits 3-5: FIFO status */
|
#define DMA_SFCR_FS_SHIFT (3) /* Bits 3-5: FIFO status */
|
||||||
#define DMA_SFCR_FS_MASK (7 << DMA_SFCR_FS_SHIFT)
|
#define DMA_SFCR_FS_MASK (7 << DMA_SFCR_FS_SHIFT)
|
||||||
|
@ -1381,8 +1381,8 @@ static void stm32_sdma_start(DMA_HANDLE handle, dma_callback_t callback,
|
|||||||
DMA_CHANNEL dmachan = (DMA_CHANNEL)handle;
|
DMA_CHANNEL dmachan = (DMA_CHANNEL)handle;
|
||||||
uint32_t scr = 0;
|
uint32_t scr = 0;
|
||||||
|
|
||||||
DEBUGASSERT(dmachan->ctrl == DMA1 || dmachan->ctrl == DMA2);
|
|
||||||
DEBUGASSERT(handle != NULL);
|
DEBUGASSERT(handle != NULL);
|
||||||
|
DEBUGASSERT(dmachan->ctrl == DMA1 || dmachan->ctrl == DMA2);
|
||||||
|
|
||||||
/* Save the callback info. This will be invoked when the DMA completes */
|
/* Save the callback info. This will be invoked when the DMA completes */
|
||||||
|
|
||||||
@ -1714,12 +1714,23 @@ static void stm32_sdma_dump(DMA_HANDLE handle, const char *msg)
|
|||||||
|
|
||||||
static void stm32_bdma_disable(DMA_CHANNEL dmachan)
|
static void stm32_bdma_disable(DMA_CHANNEL dmachan)
|
||||||
{
|
{
|
||||||
DMA_CHANNEL dmachan = (DMA_CHANNEL)handle;
|
uint32_t regval = 0;
|
||||||
uint8_t controller = dmachan->ctrl;
|
|
||||||
|
|
||||||
DEBUGASSERT(controller == BDMA);
|
DEBUGASSERT(dmachan->ctrl == BDMA);
|
||||||
|
DEBUGASSERT(dmachan->chan < BDMA_NCHAN);
|
||||||
|
|
||||||
#warning stm32_bdma_disable not implemented
|
/* Disable all interrupts at the DMA controller */
|
||||||
|
|
||||||
|
regval = dmachan_getreg(dmachan, STM32_BDMACH_CCR_OFFSET);
|
||||||
|
regval &= ~BDMA_CCR_ALLINTS;
|
||||||
|
|
||||||
|
/* Disable the DMA stream */
|
||||||
|
|
||||||
|
regval &= ~BDMA_CCR_EN;
|
||||||
|
dmachan_putreg(dmachan, STM32_BDMACH_CCR_OFFSET, regval);
|
||||||
|
|
||||||
|
dmabase_putreg(dmachan, STM32_BDMA_IFCR_OFFSET,
|
||||||
|
(BDMA_CHAN_MASK << dmachan->shift));
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -1732,7 +1743,66 @@ static void stm32_bdma_disable(DMA_CHANNEL dmachan)
|
|||||||
|
|
||||||
static int stm32_bdma_interrupt(int irq, void *context, FAR void *arg)
|
static int stm32_bdma_interrupt(int irq, void *context, FAR void *arg)
|
||||||
{
|
{
|
||||||
#warning stm32_bdma_interrupt not implemented
|
DMA_CHANNEL dmachan = NULL;
|
||||||
|
uint32_t status = 0;
|
||||||
|
uint32_t scrstatus = 0;
|
||||||
|
uint8_t stream = irq - STM32_IRQ_BDMACH1;
|
||||||
|
uint8_t controller = BDMA;
|
||||||
|
|
||||||
|
/* Get the channel structure from the stream and controller numbers */
|
||||||
|
|
||||||
|
dmachan = stm32_dma_channel_get(stream, controller);
|
||||||
|
|
||||||
|
/* Get the interrupt status for this stream */
|
||||||
|
|
||||||
|
status = (dmabase_getreg(dmachan, STM32_BDMA_ISR_OFFSET) >> dmachan->shift)
|
||||||
|
& BDMA_CHAN_MASK;
|
||||||
|
|
||||||
|
dmabase_putreg(dmachan, STM32_BDMA_IFCR_OFFSET,
|
||||||
|
(status << dmachan->shift));
|
||||||
|
|
||||||
|
/* Invoke the callback */
|
||||||
|
|
||||||
|
if (dmachan->callback)
|
||||||
|
{
|
||||||
|
/* Map to the SDMA status */
|
||||||
|
|
||||||
|
scrstatus = (status & BDMA_CHAN_TEIF) ? DMA_STREAM_FEIF_BIT : 0;
|
||||||
|
scrstatus |= (status & BDMA_CHAN_TCIF) ? DMA_STREAM_TCIF_BIT : 0;
|
||||||
|
scrstatus |= (status & BDMA_CHAN_HTIF) ? DMA_STREAM_HTIF_BIT : 0;
|
||||||
|
dmachan->callback(dmachan, scrstatus, dmachan->arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: stm32_sdma_scr_2_bdma_ccr
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Maps the DMA SCR bits to the BDMA CCR bits
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
static inline int32_t stm32_sdma_scr_2_bdma_ccr(int32_t scr)
|
||||||
|
{
|
||||||
|
uint32_t ccr = 0;
|
||||||
|
ccr |= (scr & DMA_SCR_CT) ? BDMA_CCR_CT : 0;
|
||||||
|
ccr |= (scr & DMA_SCR_DBM) ? BDMA_CCR_DBM : 0;
|
||||||
|
ccr |= (scr & DMA_SCR_PL_MASK) >> (DMA_SCR_PL_SHIFT - BDMA_CCR_PRILO);
|
||||||
|
ccr |= (scr & DMA_SCR_MSIZE_MASK) >>
|
||||||
|
(DMA_SCR_MSIZE_SHIFT - BDMA_CCR_MSIZE_SHIFT);
|
||||||
|
ccr |= (scr & DMA_SCR_PSIZE_MASK) >>
|
||||||
|
(DMA_SCR_PSIZE_SHIFT - BDMA_CCR_PSIZE_SHIFT);
|
||||||
|
ccr |= (scr & DMA_SCR_MINC) ? BDMA_CCR_MINC : 0;
|
||||||
|
ccr |= (scr & DMA_SCR_PINC) ? BDMA_CCR_PINC : 0;
|
||||||
|
ccr |= (scr & DMA_SCR_CIRC) ? BDMA_CCR_CIRC : 0;
|
||||||
|
ccr |= (scr & DMA_SCR_DIR_M2P) ? BDMA_CCR_DIR : 0;
|
||||||
|
ccr |= (scr & DMA_SCR_DIR_M2M) ? BDMA_CCR_M2M : 0;
|
||||||
|
ccr |= (scr & DMA_SCR_TCIE) ? BDMA_CCR_TCIE : 0;
|
||||||
|
ccr |= (scr & DMA_SCR_HTIE) ? BDMA_CCR_HTIE : 0;
|
||||||
|
ccr |= (scr & DMA_SCR_TEIE) ? BDMA_CCR_TEIE : 0;
|
||||||
|
return ccr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -1746,11 +1816,89 @@ static int stm32_bdma_interrupt(int irq, void *context, FAR void *arg)
|
|||||||
static void stm32_bdma_setup(DMA_HANDLE handle, FAR stm32_dmacfg_t *cfg)
|
static void stm32_bdma_setup(DMA_HANDLE handle, FAR stm32_dmacfg_t *cfg)
|
||||||
{
|
{
|
||||||
DMA_CHANNEL dmachan = (DMA_CHANNEL)handle;
|
DMA_CHANNEL dmachan = (DMA_CHANNEL)handle;
|
||||||
uint8_t controller = dmachan->ctrl;
|
uint32_t regval = 0;
|
||||||
|
uint32_t scr = cfg->cfg1;
|
||||||
|
uint32_t ccr = 0;
|
||||||
|
|
||||||
DEBUGASSERT(controller == BDMA);
|
DEBUGASSERT(handle != NULL);
|
||||||
|
DEBUGASSERT(dmachan->ctrl == BDMA);
|
||||||
|
|
||||||
#warning stm32_bdma_setup not implemented
|
dmainfo("paddr: %08x maddr: %08x ndata: %d scr: %08x\n",
|
||||||
|
cfg->paddr, cfg->maddr, cfg->ndata, cfg->cfg1);
|
||||||
|
|
||||||
|
#ifdef CONFIG_STM32H7_DMACAPABLE
|
||||||
|
DEBUGASSERT(stm32_bdma_capable(cfg));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* "If the stream is enabled, disable it by resetting the EN bit in the
|
||||||
|
* DMA_SxCR register, then read this bit in order to confirm that there is
|
||||||
|
* no ongoing stream operation. Writing this bit to 0 is not immediately
|
||||||
|
* effective since it is actually written to 0 once all the current
|
||||||
|
* transfers have finished. When the EN bit is read as 0, this means that
|
||||||
|
* the stream is ready to be configured. It is therefore necessary to wait
|
||||||
|
* for the EN bit to be cleared before starting any stream configuration."
|
||||||
|
*/
|
||||||
|
|
||||||
|
while ((dmachan_getreg(dmachan, STM32_BDMACH_CCR_OFFSET) &
|
||||||
|
BDMA_CCR_EN) != 0);
|
||||||
|
|
||||||
|
/* "... All the stream dedicated bits set in the status register BDMA_ISR
|
||||||
|
* from the previous data block DMA transfer should be cleared before the
|
||||||
|
* stream can be re-enabled."
|
||||||
|
*
|
||||||
|
* Clear pending stream interrupts by setting bits in the BDMA_IFCR
|
||||||
|
* register.
|
||||||
|
*/
|
||||||
|
|
||||||
|
dmabase_putreg(dmachan, STM32_BDMA_IFCR_OFFSET,
|
||||||
|
(BDMA_CHAN_MASK << dmachan->shift));
|
||||||
|
|
||||||
|
/* "Set the peripheral register address in the BDMA_SPARx register. The
|
||||||
|
* data will be moved from/to this address to/from the memory after the
|
||||||
|
* peripheral event.
|
||||||
|
*/
|
||||||
|
|
||||||
|
dmachan_putreg(dmachan, STM32_BDMACH_CPAR_OFFSET, cfg->paddr);
|
||||||
|
|
||||||
|
/* "Set the memory address in the BDMA_CM1ARx register. The data will be
|
||||||
|
* written to or read from this memory after the peripheral event."
|
||||||
|
*
|
||||||
|
* Note that in double-buffered mode it is explicitly assumed that the
|
||||||
|
* second buffer immediately follows the first.
|
||||||
|
*/
|
||||||
|
|
||||||
|
dmachan_putreg(dmachan, STM32_BDMACH_CM0AR_OFFSET, cfg->maddr);
|
||||||
|
if (scr & DMA_SCR_DBM)
|
||||||
|
{
|
||||||
|
dmachan_putreg(dmachan, STM32_BDMACH_CM1AR_OFFSET,
|
||||||
|
cfg->maddr + cfg->ndata);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* "Configure the total number of data items to be transferred in the
|
||||||
|
* BDMA_CNDTRx register. After each peripheral event, this value will be
|
||||||
|
* decremented."
|
||||||
|
*/
|
||||||
|
|
||||||
|
dmachan_putreg(dmachan, STM32_BDMACH_CNDTR_OFFSET, cfg->ndata);
|
||||||
|
|
||||||
|
/* "Configure the stream priority using the PL[1:0] bits, data transfer
|
||||||
|
* direction, circular mode, peripheral & memory incremented mode,
|
||||||
|
* peripheral & memory data size, and interrupt after
|
||||||
|
* half and/or full transfer in the BDMACH_CCRx register."
|
||||||
|
*
|
||||||
|
* Note: The CT bit is always reset.
|
||||||
|
*/
|
||||||
|
|
||||||
|
regval = dmachan_getreg(dmachan, STM32_BDMACH_CCR_OFFSET);
|
||||||
|
regval &= ~(BDMA_CCR_DIR | BDMA_CCR_CIRC | BDMA_CCR_PINC |
|
||||||
|
BDMA_CCR_MINC | BDMA_CCR_PSIZE_MASK | BDMA_CCR_MSIZE_MASK |
|
||||||
|
BDMA_CCR_PL_MASK | BDMA_CCR_M2M | BDMA_CCR_DBM | BDMA_CCR_CT);
|
||||||
|
ccr = stm32_sdma_scr_2_bdma_ccr(scr);
|
||||||
|
ccr &= (BDMA_CCR_DIR | BDMA_CCR_CIRC | BDMA_CCR_PINC |
|
||||||
|
BDMA_CCR_MINC | BDMA_CCR_PSIZE_MASK | BDMA_CCR_MSIZE_MASK |
|
||||||
|
BDMA_CCR_PL_MASK | BDMA_CCR_M2M | BDMA_CCR_DBM);
|
||||||
|
regval |= ccr;
|
||||||
|
dmachan_putreg(dmachan, STM32_BDMACH_CCR_OFFSET, regval);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -1765,11 +1913,58 @@ static void stm32_bdma_start(DMA_HANDLE handle, dma_callback_t callback,
|
|||||||
void *arg, bool half)
|
void *arg, bool half)
|
||||||
{
|
{
|
||||||
DMA_CHANNEL dmachan = (DMA_CHANNEL)handle;
|
DMA_CHANNEL dmachan = (DMA_CHANNEL)handle;
|
||||||
uint8_t controller = dmachan->ctrl;
|
uint32_t ccr = 0;
|
||||||
|
|
||||||
DEBUGASSERT(controller == BDMA);
|
DEBUGASSERT(handle != NULL);
|
||||||
|
DEBUGASSERT(dmachan->ctrl == BDMA);
|
||||||
|
|
||||||
#warning stm32_bdma_start not implemented
|
/* Save the callback info. This will be invoked when the DMA completes */
|
||||||
|
|
||||||
|
dmachan->callback = callback;
|
||||||
|
dmachan->arg = arg;
|
||||||
|
|
||||||
|
/* Activate the stream by setting the ENABLE bit in the DMA_SCRx register.
|
||||||
|
* As soon as the stream is enabled, it can serve any DMA request from the
|
||||||
|
* peripheral connected on the stream.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ccr = dmachan_getreg(dmachan, STM32_BDMACH_CCR_OFFSET);
|
||||||
|
ccr |= BDMA_CCR_EN;
|
||||||
|
|
||||||
|
/* In normal mode, interrupt at either half or full completion. In circular
|
||||||
|
* and double-buffered modes, always interrupt on buffer wrap, and
|
||||||
|
* optionally interrupt at the halfway point.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((ccr & (BDMA_CCR_DBM | BDMA_CCR_CIRC)) == 0)
|
||||||
|
{
|
||||||
|
/* Once half of the bytes are transferred, the half-transfer flag
|
||||||
|
* (HTIF) is set and an interrupt is generated if the
|
||||||
|
* Half-Transfer Interrupt Enable bit (HTIE) is set. At the end of the
|
||||||
|
* transfer, the Transfer Complete Flag (TCIF) is set and an interrupt
|
||||||
|
* is generated if the Transfer Complete Interrupt Enable bit (TCIE) is
|
||||||
|
* set.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ccr |= (half ? (BDMA_CCR_HTIE | BDMA_CCR_TEIE) :
|
||||||
|
(BDMA_CCR_TCIE | BDMA_CCR_TEIE));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* In non-stop modes, when the transfer completes it immediately resets
|
||||||
|
* and starts again. The transfer-complete interrupt is thus always
|
||||||
|
* enabled, and the half-complete interrupt can be used in circular
|
||||||
|
* mode to determine when the buffer is half-full, or in
|
||||||
|
* double-buffered mode to determine when one of the two buffers is
|
||||||
|
* full
|
||||||
|
*/
|
||||||
|
|
||||||
|
ccr |= (half ? BDMA_CCR_HTIE : 0) | BDMA_CCR_TCIE | BDMA_CCR_TEIE;
|
||||||
|
}
|
||||||
|
|
||||||
|
dmachan_putreg(dmachan, STM32_BDMACH_CCR_OFFSET, ccr);
|
||||||
|
|
||||||
|
stm32_dmadump(handle, "DMA after start");
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -1779,10 +1974,10 @@ static void stm32_bdma_start(DMA_HANDLE handle, dma_callback_t callback,
|
|||||||
static size_t stm32_bdma_residual(DMA_HANDLE handle)
|
static size_t stm32_bdma_residual(DMA_HANDLE handle)
|
||||||
{
|
{
|
||||||
DMA_CHANNEL dmachan = (DMA_CHANNEL)handle;
|
DMA_CHANNEL dmachan = (DMA_CHANNEL)handle;
|
||||||
uint8_t controller = dmachan->ctrl;
|
|
||||||
uint32_t residual = 0
|
uint32_t residual = 0
|
||||||
|
|
||||||
DEBUGASSERT(controller == BDMA);
|
DEBUGASSERT(handle != NULL);
|
||||||
|
DEBUGASSERT(dmachan->ctrl == BDMA);
|
||||||
|
|
||||||
/* Fetch the count of bytes remaining to be transferred */
|
/* Fetch the count of bytes remaining to be transferred */
|
||||||
|
|
||||||
@ -1804,10 +1999,8 @@ static bool stm32_bdma_capable(FAR stm32_dmacfg_t *cfg)
|
|||||||
|
|
||||||
dmainfo("0x%08x/%u 0x%08x\n", cfg->maddr, cfg->ndata, cfg->cfg1);
|
dmainfo("0x%08x/%u 0x%08x\n", cfg->maddr, cfg->ndata, cfg->cfg1);
|
||||||
|
|
||||||
#warning REVISIT
|
|
||||||
|
|
||||||
/* Verify that the address conforms to the memory transfer size.
|
/* Verify that the address conforms to the memory transfer size.
|
||||||
* Transfers to/from memory performed by the DMA controller are
|
* Transfers to/from memory performed by the BDMA controller are
|
||||||
* required to be aligned to their size.
|
* required to be aligned to their size.
|
||||||
*
|
*
|
||||||
* See ST RM0090 rev4, section 9.3.11
|
* See ST RM0090 rev4, section 9.3.11
|
||||||
|
Loading…
Reference in New Issue
Block a user