1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

cpu/stm32/periph/dma: dma_setup_ext for extended configuration

The function configures additional features of the DMA stream for F2/F4/F7.
`dma_setup_ext` added to configure F2/F4/F7 specific additional features like `MBURST`, `PBURST`, `FIFO` and Peripheral flow controller. It is supposed to be used after `dma_setup` and `dma_prepare`.
This commit is contained in:
Gunar Schorcht 2023-04-28 10:17:46 +02:00
parent 950a11e736
commit d91f438589
2 changed files with 115 additions and 0 deletions

View File

@ -69,6 +69,26 @@ typedef enum {
DMA_MEM_TO_MEM = 2, /**< Memory to memory */
} dma_mode_t;
/**
* @brief Burst Transfer modes for F2/F4/F7
*/
typedef enum {
DMA_BURST_SINGLE = 0, /**< single transfer */
DMA_BURST_INCR4 = 1, /**< incremental burst of 4 beats */
DMA_BURST_INCR8 = 2, /**< incremental burst of 8 beats */
DMA_BURST_INCR16 = 3, /**< incremental burst of 16 beats */
} dma_burst_t;
/**
* @brief Threshold selection in FIFO mode for F2/F4F7
*/
typedef enum {
DMA_FIFO_FULL_1_4 = 0, /**< 1/4 full FIFO */
DMA_FIFO_FULL_1_2 = 1, /**< 1/2 full FIFO */
DMA_FIFO_FULL_3_4 = 2, /**< 3/4 full FIFO */
DMA_FIFO_FULL = 3, /**< Full FIFO */
} dma_fifo_thresh_t;
/**
* @brief DMA channel/trigger configuration for DMA peripherals without
* channel/trigger filtering such as the stm32f1 and stm32f3.
@ -211,6 +231,29 @@ int dma_configure(dma_t dma, int chan, const volatile void *src, volatile void *
void dma_setup(dma_t dma, int chan, void *periph_addr, dma_mode_t mode,
uint8_t width, bool inc_periph);
/**
* @brief Low level extended initial DMA stream configuration for F2/F4/F7
*
* The function configures additional features of the DMA stream for F2/F4/F7.
* It is supposed to be used after @ref dma_setup and before @ref dma_prepare.
*
* @note This function is only implemented for F2/F4/F7. For other families
* it is only a dummy. It is not used by @ref dma_configure or the
* convenience function @ref dma_transfer.
*
* @warn The combination of FIFO threshold and the memory burst transfer
* has to be valid.
*
* @param[in] dma Logical DMA stream
* @param[in] pburst Peripeheral burst transfer configuration
* @param[in] mburst Memory burst transfer configuration
* @param[in] fifo FIFO mode enable
* @param[in] thresh FIFO threshold
* @param[in] pfctrl Peripheral used as flow controller
*/
void dma_setup_ext(dma_t dma, dma_burst_t pburst, dma_burst_t mburst,
bool fifo, dma_fifo_thresh_t thresh, bool pfctrl);
/**
* @brief Low level DMA transfer configuration
*

View File

@ -416,6 +416,78 @@ void dma_prepare(dma_t dma, void *mem, size_t len, bool incr_mem)
dma_ctx[dma].len = len;
}
void dma_setup_ext(dma_t dma, dma_burst_t pburst, dma_burst_t mburst,
bool fifo, dma_fifo_thresh_t thresh, bool pfctrl)
{
#if CPU_FAM_STM32F2 || CPU_FAM_STM32F4 || CPU_FAM_STM32F7
STM32_DMA_Stream_Type *stream = dma_ctx[dma].stream;
/* configuraition can be done only if DMA stream is disabled */
assert((stream->CR & DMA_EN) == 0);
/* FIFO configuration if enabled */
if (fifo) {
uint8_t width = (stream->CR & DMA_SxCR_MSIZE_Msk) >> DMA_SxCR_MSIZE_Pos;
/* check valid combinations of MSIZE, MBURST and FIFO threshold level */
switch (width) {
case DMA_DATA_WIDTH_BYTE:
switch (thresh) {
case DMA_FIFO_FULL_1_4:
/* fall through */
case DMA_FIFO_FULL_3_4:
assert(mburst == DMA_BURST_INCR4);
break;
case DMA_FIFO_FULL_1_2:
assert((mburst == DMA_BURST_INCR4) || (mburst == DMA_BURST_INCR8));
break;
case DMA_FIFO_FULL: /* all mburst values are valid */
break;
}
break;
case DMA_DATA_WIDTH_HALF_WORD:
switch (thresh) {
case DMA_FIFO_FULL_1_2:
assert(mburst == DMA_BURST_INCR4);
break;
case DMA_FIFO_FULL:
assert((mburst == DMA_BURST_INCR4) || (mburst == DMA_BURST_INCR8));
break;
default:
assert(false); /* all other combinations are invalid) */
break;
}
break;
case DMA_DATA_WIDTH_WORD:
assert((thresh == DMA_FIFO_FULL) && (mburst == DMA_BURST_INCR4));
break;
}
stream->FCR = (fifo << DMA_SxFCR_DMDIS_Pos) |
(thresh << DMA_SxFCR_FTH_Pos);
}
else {
stream->FCR = 0;
}
stream->CR &= ~(DMA_SxCR_PFCTRL | DMA_SxCR_MBURST | DMA_SxCR_PBURST);
stream->CR |= pfctrl ? DMA_SxCR_PFCTRL : 0;
stream->CR |= (mburst << DMA_SxCR_MBURST_Pos);
stream->CR |= (pburst << DMA_SxCR_PBURST_Pos);
#else
(void)dma;
(void)pburst;
(void)pburst;
(void)mburst;
(void)fifo;
(void)thresh;
(void)pfctrl;
#endif
}
int dma_configure(dma_t dma, int chan, const volatile void *src, volatile void *dst, size_t len,
dma_mode_t mode, uint8_t flags)
{