git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3478 35acf78f-673a-0410-8e92-d51de3d6d3f4
parent
bfcc14cb5c
commit
d3adba6d99
|
@ -22,7 +22,7 @@
|
||||||
* @file STM32F4xx/stm32_dma.c
|
* @file STM32F4xx/stm32_dma.c
|
||||||
* @brief Enhanced DMA helper driver code.
|
* @brief Enhanced DMA helper driver code.
|
||||||
*
|
*
|
||||||
* @addtogroup STM32_DMA
|
* @addtogroup STM32F4xx_DMA
|
||||||
* @details DMA sharing helper driver. In the STM32 the DMA streams are a
|
* @details DMA sharing helper driver. In the STM32 the DMA streams are a
|
||||||
* shared resource, this driver allows to allocate and free DMA
|
* shared resource, this driver allows to allocate and free DMA
|
||||||
* streams at runtime in order to allow all the other device
|
* streams at runtime in order to allow all the other device
|
||||||
|
@ -76,22 +76,22 @@
|
||||||
* instead: @p STM32_DMA1_STREAM0, @p STM32_DMA1_STREAM1 etc.
|
* instead: @p STM32_DMA1_STREAM0, @p STM32_DMA1_STREAM1 etc.
|
||||||
*/
|
*/
|
||||||
const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
|
const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
|
||||||
{0, DMA1, DMA1_Stream0, &DMA1->LIFCR, 0},
|
{DMA1_Stream0, &DMA1->LIFCR, 0, 0, DMA1_Stream0_IRQn},
|
||||||
{1, DMA1, DMA1_Stream1, &DMA1->LIFCR, 6},
|
{DMA1_Stream1, &DMA1->LIFCR, 6, 1, DMA1_Stream1_IRQn},
|
||||||
{2, DMA1, DMA1_Stream2, &DMA1->LIFCR, 16},
|
{DMA1_Stream2, &DMA1->LIFCR, 16, 2, DMA1_Stream2_IRQn},
|
||||||
{3, DMA1, DMA1_Stream3, &DMA1->LIFCR, 22},
|
{DMA1_Stream3, &DMA1->LIFCR, 22, 3, DMA1_Stream3_IRQn},
|
||||||
{4, DMA1, DMA1_Stream4, &DMA1->HIFCR, 0},
|
{DMA1_Stream4, &DMA1->HIFCR, 0, 4, DMA1_Stream4_IRQn},
|
||||||
{5, DMA1, DMA1_Stream5, &DMA1->HIFCR, 6},
|
{DMA1_Stream5, &DMA1->HIFCR, 6, 5, DMA1_Stream5_IRQn},
|
||||||
{6, DMA1, DMA1_Stream6, &DMA1->HIFCR, 16},
|
{DMA1_Stream6, &DMA1->HIFCR, 16, 6, DMA1_Stream6_IRQn},
|
||||||
{7, DMA1, DMA1_Stream7, &DMA1->HIFCR, 22},
|
{DMA1_Stream7, &DMA1->HIFCR, 22, 7, DMA1_Stream7_IRQn},
|
||||||
{8, DMA2, DMA2_Stream0, &DMA2->LIFCR, 0},
|
{DMA2_Stream0, &DMA2->LIFCR, 0, 8, DMA2_Stream0_IRQn},
|
||||||
{9, DMA2, DMA2_Stream1, &DMA2->LIFCR, 6},
|
{DMA2_Stream1, &DMA2->LIFCR, 6, 9, DMA2_Stream1_IRQn},
|
||||||
{10, DMA2, DMA2_Stream2, &DMA2->LIFCR, 16},
|
{DMA2_Stream2, &DMA2->LIFCR, 16, 10, DMA2_Stream2_IRQn},
|
||||||
{11, DMA2, DMA2_Stream3, &DMA2->LIFCR, 22},
|
{DMA2_Stream3, &DMA2->LIFCR, 22, 11, DMA2_Stream3_IRQn},
|
||||||
{12, DMA2, DMA2_Stream4, &DMA2->HIFCR, 0},
|
{DMA2_Stream4, &DMA2->HIFCR, 0, 12, DMA2_Stream4_IRQn},
|
||||||
{13, DMA2, DMA2_Stream5, &DMA2->HIFCR, 6},
|
{DMA2_Stream5, &DMA2->HIFCR, 6, 13, DMA2_Stream5_IRQn},
|
||||||
{14, DMA2, DMA2_Stream6, &DMA2->HIFCR, 16},
|
{DMA2_Stream6, &DMA2->HIFCR, 16, 14, DMA2_Stream6_IRQn},
|
||||||
{15, DMA2, DMA2_Stream7, &DMA2->HIFCR, 22},
|
{DMA2_Stream7, &DMA2->HIFCR, 22, 15, DMA2_Stream7_IRQn},
|
||||||
};
|
};
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -102,8 +102,8 @@ const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
|
||||||
* @brief DMA ISR redirector type.
|
* @brief DMA ISR redirector type.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
stm32_dmaisr_t dma_func;
|
stm32_dmaisr_t dma_func; /**< @brief DMA callback function. */
|
||||||
void *dma_param;
|
void *dma_param; /**< @brief DMA callback parameter. */
|
||||||
} dma_isr_redir_t;
|
} dma_isr_redir_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -467,7 +467,7 @@ bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
|
||||||
chDbgCheck(dmastp != NULL, "dmaAllocate");
|
chDbgCheck(dmastp != NULL, "dmaAllocate");
|
||||||
|
|
||||||
/* Checks if the stream is already taken.*/
|
/* Checks if the stream is already taken.*/
|
||||||
if ((dma_streams_mask & dmastp->mask) != 0)
|
if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* Marks the stream as allocated.*/
|
/* Marks the stream as allocated.*/
|
||||||
|
@ -476,14 +476,10 @@ bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp,
|
||||||
dma_streams_mask |= (1 << dmastp->selfindex);
|
dma_streams_mask |= (1 << dmastp->selfindex);
|
||||||
|
|
||||||
/* Enabling DMA clocks required by the current streams set.*/
|
/* Enabling DMA clocks required by the current streams set.*/
|
||||||
if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) {
|
if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0)
|
||||||
RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
|
rccEnableDMA1(FALSE);
|
||||||
RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA1LPEN;
|
if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0)
|
||||||
}
|
rccEnableDMA2(FALSE);
|
||||||
if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) {
|
|
||||||
RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
|
|
||||||
RCC->AHB1LPENR |= RCC_AHB1LPENR_DMA2LPEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Putting the stream in a safe state.*/
|
/* Putting the stream in a safe state.*/
|
||||||
dmaStreamDisable(dmastp);
|
dmaStreamDisable(dmastp);
|
||||||
|
@ -516,7 +512,7 @@ void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {
|
||||||
chDbgCheck(dmastp != NULL, "dmaRelease");
|
chDbgCheck(dmastp != NULL, "dmaRelease");
|
||||||
|
|
||||||
/* Check if the streams is not taken.*/
|
/* Check if the streams is not taken.*/
|
||||||
chDbgAssert((dma_streams_mask & dmastp->mask) != 0,
|
chDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0,
|
||||||
"dmaRelease(), #1", "not allocated");
|
"dmaRelease(), #1", "not allocated");
|
||||||
|
|
||||||
/* Disables the associated IRQ vector.*/
|
/* Disables the associated IRQ vector.*/
|
||||||
|
@ -526,14 +522,10 @@ void dmaStreamRelease(const stm32_dma_stream_t *dmastp) {
|
||||||
dma_streams_mask &= ~(1 << dmastp->selfindex);
|
dma_streams_mask &= ~(1 << dmastp->selfindex);
|
||||||
|
|
||||||
/* Shutting down clocks that are no more required, if any.*/
|
/* Shutting down clocks that are no more required, if any.*/
|
||||||
if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) {
|
if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0)
|
||||||
RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA1EN;
|
rccDisableDMA1(FALSE);
|
||||||
RCC->AHB1LPENR &= ~RCC_AHB1LPENR_DMA1LPEN;
|
if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0)
|
||||||
}
|
rccDisableDMA2(FALSE);
|
||||||
if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) {
|
|
||||||
RCC->AHB1ENR &= ~RCC_AHB1ENR_DMA2EN;
|
|
||||||
RCC->AHB1LPENR &= ~RCC_AHB1LPENR_DMA2LPEN;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* STM32_DMA_REQUIRED */
|
#endif /* STM32_DMA_REQUIRED */
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
/**
|
/**
|
||||||
* @file STM32F4xx/stm32_dma.h
|
* @file STM32F4xx/stm32_dma.h
|
||||||
* @brief Enhanced-DMA helper driver header.
|
* @brief Enhanced-DMA helper driver header.
|
||||||
* @note This file requires definitions from the ST STM32F2xx header file
|
* @note This file requires definitions from the ST STM32F4xx header file
|
||||||
* stm32f2xx.h.
|
* stm32f4xx.h.
|
||||||
*
|
*
|
||||||
* @addtogroup STM32_DMA
|
* @addtogroup STM32_DMA
|
||||||
* @{
|
* @{
|
||||||
|
@ -95,7 +95,7 @@
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name CR register constants only found in STM32F2xx
|
* @name CR register constants only found in STM32F2xx/STM32F4xx
|
||||||
*/
|
*/
|
||||||
#define STM32_DMA_CR_DMEIE DMA_SxCR_DMEIE
|
#define STM32_DMA_CR_DMEIE DMA_SxCR_DMEIE
|
||||||
#define STM32_DMA_CR_PFCTRL DMA_SxCR_PFCTRL
|
#define STM32_DMA_CR_PFCTRL DMA_SxCR_PFCTRL
|
||||||
|
@ -155,7 +155,7 @@
|
||||||
* @brief STM32 DMA stream descriptor structure.
|
* @brief STM32 DMA stream descriptor structure.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
DMA_Stream_TypeDef *stream; /**< @brief Associated DMA channel. */
|
DMA_Stream_TypeDef *stream; /**< @brief Associated DMA stream. */
|
||||||
volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */
|
volatile uint32_t *ifcr; /**< @brief Associated IFCR reg. */
|
||||||
uint8_t ishift; /**< @brief Bits offset in xIFCR
|
uint8_t ishift; /**< @brief Bits offset in xIFCR
|
||||||
register. */
|
register. */
|
||||||
|
@ -179,6 +179,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
||||||
/**
|
/**
|
||||||
* @brief Associates a peripheral data register to a DMA stream.
|
* @brief Associates a peripheral data register to a DMA stream.
|
||||||
* @note This function can be invoked in both ISR or thread context.
|
* @note This function can be invoked in both ISR or thread context.
|
||||||
|
* @pre The stream must have been allocated using @p dmaStreamAllocate().
|
||||||
|
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||||
*
|
*
|
||||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||||
* @param[in] addr value to be written in the PAR register
|
* @param[in] addr value to be written in the PAR register
|
||||||
|
@ -192,6 +194,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
||||||
/**
|
/**
|
||||||
* @brief Associates a memory destination to a DMA stream.
|
* @brief Associates a memory destination to a DMA stream.
|
||||||
* @note This function can be invoked in both ISR or thread context.
|
* @note This function can be invoked in both ISR or thread context.
|
||||||
|
* @pre The stream must have been allocated using @p dmaStreamAllocate().
|
||||||
|
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||||
*
|
*
|
||||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||||
* @param[in] addr value to be written in the M0AR register
|
* @param[in] addr value to be written in the M0AR register
|
||||||
|
@ -218,6 +222,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
||||||
/**
|
/**
|
||||||
* @brief Sets the number of transfers to be performed.
|
* @brief Sets the number of transfers to be performed.
|
||||||
* @note This function can be invoked in both ISR or thread context.
|
* @note This function can be invoked in both ISR or thread context.
|
||||||
|
* @pre The stream must have been allocated using @p dmaStreamAllocate().
|
||||||
|
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||||
*
|
*
|
||||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||||
* @param[in] size value to be written in the CNDTR register
|
* @param[in] size value to be written in the CNDTR register
|
||||||
|
@ -231,6 +237,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
||||||
/**
|
/**
|
||||||
* @brief Returns the number of transfers to be performed.
|
* @brief Returns the number of transfers to be performed.
|
||||||
* @note This function can be invoked in both ISR or thread context.
|
* @note This function can be invoked in both ISR or thread context.
|
||||||
|
* @pre The stream must have been allocated using @p dmaStreamAllocate().
|
||||||
|
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||||
*
|
*
|
||||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||||
* @return The number of transfers to be performed.
|
* @return The number of transfers to be performed.
|
||||||
|
@ -242,6 +250,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
||||||
/**
|
/**
|
||||||
* @brief Programs the stream mode settings.
|
* @brief Programs the stream mode settings.
|
||||||
* @note This function can be invoked in both ISR or thread context.
|
* @note This function can be invoked in both ISR or thread context.
|
||||||
|
* @pre The stream must have been allocated using @p dmaStreamAllocate().
|
||||||
|
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||||
*
|
*
|
||||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||||
* @param[in] mode value to be written in the CR register
|
* @param[in] mode value to be written in the CR register
|
||||||
|
@ -255,6 +265,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
||||||
/**
|
/**
|
||||||
* @brief Programs the stream FIFO settings.
|
* @brief Programs the stream FIFO settings.
|
||||||
* @note This function can be invoked in both ISR or thread context.
|
* @note This function can be invoked in both ISR or thread context.
|
||||||
|
* @pre The stream must have been allocated using @p dmaStreamAllocate().
|
||||||
|
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||||
*
|
*
|
||||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||||
* @param[in] mode value to be written in the FCR register
|
* @param[in] mode value to be written in the FCR register
|
||||||
|
@ -268,18 +280,22 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
||||||
/**
|
/**
|
||||||
* @brief DMA stream enable.
|
* @brief DMA stream enable.
|
||||||
* @note This function can be invoked in both ISR or thread context.
|
* @note This function can be invoked in both ISR or thread context.
|
||||||
|
* @pre The stream must have been allocated using @p dmaStreamAllocate().
|
||||||
|
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||||
*
|
*
|
||||||
* @param[in] dmachp pointer to a stm32_dma_stream_t structure
|
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||||
*
|
*
|
||||||
* @special
|
* @special
|
||||||
*/
|
*/
|
||||||
#define dmaStreamEnable(dmachp) { \
|
#define dmaStreamEnable(dmastp) { \
|
||||||
(dmastp)->stream->CR |= STM32_DMA_CR_EN; \
|
(dmastp)->stream->CR |= STM32_DMA_CR_EN; \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief DMA stream disable.
|
* @brief DMA stream disable.
|
||||||
* @note This function can be invoked in both ISR or thread context.
|
* @note This function can be invoked in both ISR or thread context.
|
||||||
|
* @pre The stream must have been allocated using @p dmaStreamAllocate().
|
||||||
|
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||||
*
|
*
|
||||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||||
*
|
*
|
||||||
|
@ -292,6 +308,8 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
||||||
/**
|
/**
|
||||||
* @brief DMA stream interrupt sources clear.
|
* @brief DMA stream interrupt sources clear.
|
||||||
* @note This function can be invoked in both ISR or thread context.
|
* @note This function can be invoked in both ISR or thread context.
|
||||||
|
* @pre The stream must have been allocated using @p dmaStreamAllocate().
|
||||||
|
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||||
*
|
*
|
||||||
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||||
*
|
*
|
||||||
|
@ -301,6 +319,45 @@ typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
|
||||||
*(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \
|
*(dmastp)->ifcr = STM32_DMA_ISR_MASK << (dmastp)->ishift; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts a memory to memory operation using the specified stream.
|
||||||
|
* @note The default transfer data mode is "byte to byte" but it can be
|
||||||
|
* changed by specifying extra options in the @p mode parameter.
|
||||||
|
* @pre The stream must have been allocated using @p dmaStreamAllocate().
|
||||||
|
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||||
|
*
|
||||||
|
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||||
|
* @param[in] mode value to be written in the CCR register, this value
|
||||||
|
* is implicitly ORed with:
|
||||||
|
* - @p STM32_DMA_CR_MINC
|
||||||
|
* - @p STM32_DMA_CR_PINC
|
||||||
|
* - @p STM32_DMA_CR_DIR_M2M
|
||||||
|
* - @p STM32_DMA_CR_EN
|
||||||
|
* .
|
||||||
|
* @param[in] src source address
|
||||||
|
* @param[in] dst destination address
|
||||||
|
* @param[in] n number of data units to copy
|
||||||
|
*/
|
||||||
|
#define dmaStartMemCopy(dmastp, mode, src, dst, n) { \
|
||||||
|
dmaStreamSetPeripheral(dmastp, src); \
|
||||||
|
dmaStreamSetMemory0(dmastp, dst); \
|
||||||
|
dmaStreamGetTransactionSize(dmastp, n); \
|
||||||
|
dmaStreamSetMode(dmastp, (mode) | \
|
||||||
|
STM32_DMA_CR_MINC | STM32_DMA_CR_PINC | \
|
||||||
|
STM32_DMA_CR_DIR_M2M | STM32_DMA_CR_EN); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Polled wait for DMA transfer end.
|
||||||
|
* @pre The stream must have been allocated using @p dmaStreamAllocate().
|
||||||
|
* @post After use the stream can be released using @p dmaStreamRelease().
|
||||||
|
*
|
||||||
|
* @param[in] dmastp pointer to a stm32_dma_stream_t structure
|
||||||
|
*/
|
||||||
|
#define dmaWaitCompletion(dmastp) \
|
||||||
|
while (((dmastp)->stream->CNDTR > 0) && \
|
||||||
|
((dmastp)->stream->CCR & STM32_DMA_CR_EN))
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* External declarations. */
|
/* External declarations. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
Loading…
Reference in New Issue