drivers/dma: stm32: Don't omit IRQ status check
When checking for IRQ flags, we should also check for IRQ status (IsEnabled ?). If this is not done we can end up in Half Transfer interrupt processing while it is not enabled. Additionaly always use the id translation function in LL API calls. Signed-off-by: Erwan Gouriou <erwan.gouriou@linaro.org>
This commit is contained in:
parent
612dad264c
commit
96c92ed93f
@ -97,18 +97,20 @@ static void dma_stm32_irq_handler(const struct device *dev, uint32_t id)
|
||||
callback_arg = id + STREAM_OFFSET;
|
||||
#endif /* CONFIG_DMAMUX_STM32 */
|
||||
|
||||
dma_stm32_dump_stream_irq(dev, id);
|
||||
|
||||
if (!IS_ENABLED(CONFIG_DMAMUX_STM32)) {
|
||||
stream->busy = false;
|
||||
}
|
||||
|
||||
/* the dma stream id is in range from STREAM_OFFSET..<dma-requests> */
|
||||
if (dma_stm32_is_ht_active(dma, id)) {
|
||||
if (stm32_dma_is_ht_irq_active(dma, id)) {
|
||||
/* Let HAL DMA handle flags on its own */
|
||||
if (!stream->hal_override) {
|
||||
dma_stm32_clear_ht(dma, id);
|
||||
}
|
||||
stream->dma_callback(dev, stream->user_data, callback_arg, 0);
|
||||
} else if (dma_stm32_is_tc_active(dma, id)) {
|
||||
} else if (stm32_dma_is_tc_irq_active(dma, id)) {
|
||||
#ifdef CONFIG_DMAMUX_STM32
|
||||
stream->busy = false;
|
||||
#endif
|
||||
|
||||
@ -81,6 +81,8 @@ void dma_stm32_clear_gi(DMA_TypeDef *DMAx, uint32_t id);
|
||||
#endif
|
||||
|
||||
bool stm32_dma_is_irq_active(DMA_TypeDef *dma, uint32_t id);
|
||||
bool stm32_dma_is_ht_irq_active(DMA_TypeDef *dma, uint32_t id);
|
||||
bool stm32_dma_is_tc_irq_active(DMA_TypeDef *dma, uint32_t id);
|
||||
|
||||
void stm32_dma_dump_stream_irq(DMA_TypeDef *dma, uint32_t id);
|
||||
void stm32_dma_clear_stream_irq(DMA_TypeDef *dma, uint32_t id);
|
||||
|
||||
@ -243,33 +243,33 @@ void stm32_dma_dump_stream_irq(DMA_TypeDef *dma, uint32_t id)
|
||||
dma_stm32_is_fe_active(dma, id));
|
||||
}
|
||||
|
||||
static inline bool stm32_dma_is_tc_irq_active(DMA_TypeDef *dma, uint32_t id)
|
||||
inline bool stm32_dma_is_tc_irq_active(DMA_TypeDef *dma, uint32_t id)
|
||||
{
|
||||
return LL_DMA_IsEnabledIT_TC(dma, id) &&
|
||||
return LL_DMA_IsEnabledIT_TC(dma, dma_stm32_id_to_stream(id)) &&
|
||||
dma_stm32_is_tc_active(dma, id);
|
||||
}
|
||||
|
||||
static inline bool stm32_dma_is_ht_irq_active(DMA_TypeDef *dma, uint32_t id)
|
||||
inline bool stm32_dma_is_ht_irq_active(DMA_TypeDef *dma, uint32_t id)
|
||||
{
|
||||
return LL_DMA_IsEnabledIT_HT(dma, id) &&
|
||||
return LL_DMA_IsEnabledIT_HT(dma, dma_stm32_id_to_stream(id)) &&
|
||||
dma_stm32_is_ht_active(dma, id);
|
||||
}
|
||||
|
||||
static inline bool stm32_dma_is_te_irq_active(DMA_TypeDef *dma, uint32_t id)
|
||||
{
|
||||
return LL_DMA_IsEnabledIT_TE(dma, id) &&
|
||||
return LL_DMA_IsEnabledIT_TE(dma, dma_stm32_id_to_stream(id)) &&
|
||||
dma_stm32_is_te_active(dma, id);
|
||||
}
|
||||
|
||||
static inline bool stm32_dma_is_dme_irq_active(DMA_TypeDef *dma, uint32_t id)
|
||||
{
|
||||
return LL_DMA_IsEnabledIT_DME(dma, id) &&
|
||||
return LL_DMA_IsEnabledIT_DME(dma, dma_stm32_id_to_stream(id)) &&
|
||||
dma_stm32_is_dme_active(dma, id);
|
||||
}
|
||||
|
||||
static inline bool stm32_dma_is_fe_irq_active(DMA_TypeDef *dma, uint32_t id)
|
||||
{
|
||||
return LL_DMA_IsEnabledIT_FE(dma, id) &&
|
||||
return LL_DMA_IsEnabledIT_FE(dma, dma_stm32_id_to_stream(id)) &&
|
||||
dma_stm32_is_fe_active(dma, id);
|
||||
}
|
||||
|
||||
@ -291,7 +291,8 @@ void stm32_dma_clear_stream_irq(DMA_TypeDef *dma, uint32_t id)
|
||||
|
||||
bool stm32_dma_is_irq_happened(DMA_TypeDef *dma, uint32_t id)
|
||||
{
|
||||
if (dma_stm32_is_fe_active(dma, id) && LL_DMA_IsEnabledIT_FE(dma, id)) {
|
||||
if (LL_DMA_IsEnabledIT_FE(dma, dma_stm32_id_to_stream(id)) &&
|
||||
dma_stm32_is_fe_active(dma, id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -300,7 +301,8 @@ bool stm32_dma_is_irq_happened(DMA_TypeDef *dma, uint32_t id)
|
||||
|
||||
bool stm32_dma_is_unexpected_irq_happened(DMA_TypeDef *dma, uint32_t id)
|
||||
{
|
||||
if (dma_stm32_is_fe_active(dma, id) && LL_DMA_IsEnabledIT_FE(dma, id)) {
|
||||
if (LL_DMA_IsEnabledIT_FE(dma, dma_stm32_id_to_stream(id)) &&
|
||||
dma_stm32_is_fe_active(dma, id)) {
|
||||
LOG_ERR("FiFo error.");
|
||||
stm32_dma_dump_stream_irq(dma, id);
|
||||
stm32_dma_clear_stream_irq(dma, id);
|
||||
|
||||
@ -241,21 +241,21 @@ void stm32_dma_dump_stream_irq(DMA_TypeDef *dma, uint32_t id)
|
||||
dma_stm32_is_gi_active(dma, id));
|
||||
}
|
||||
|
||||
static inline bool stm32_dma_is_tc_irq_active(DMA_TypeDef *dma, uint32_t id)
|
||||
bool stm32_dma_is_tc_irq_active(DMA_TypeDef *dma, uint32_t id)
|
||||
{
|
||||
return LL_DMA_IsEnabledIT_TC(dma, id) &&
|
||||
return LL_DMA_IsEnabledIT_TC(dma, dma_stm32_id_to_stream(id)) &&
|
||||
dma_stm32_is_tc_active(dma, id);
|
||||
}
|
||||
|
||||
static inline bool stm32_dma_is_ht_irq_active(DMA_TypeDef *dma, uint32_t id)
|
||||
bool stm32_dma_is_ht_irq_active(DMA_TypeDef *dma, uint32_t id)
|
||||
{
|
||||
return LL_DMA_IsEnabledIT_HT(dma, id) &&
|
||||
return LL_DMA_IsEnabledIT_HT(dma, dma_stm32_id_to_stream(id)) &&
|
||||
dma_stm32_is_ht_active(dma, id);
|
||||
}
|
||||
|
||||
static inline bool stm32_dma_is_te_irq_active(DMA_TypeDef *dma, uint32_t id)
|
||||
{
|
||||
return LL_DMA_IsEnabledIT_TE(dma, id) &&
|
||||
return LL_DMA_IsEnabledIT_TE(dma, dma_stm32_id_to_stream(id)) &&
|
||||
dma_stm32_is_te_active(dma, id);
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user