diff --git a/cpu/stm32/include/periph_cpu.h b/cpu/stm32/include/periph_cpu.h index a3caf8be85ca..2ca06a49ef97 100644 --- a/cpu/stm32/include/periph_cpu.h +++ b/cpu/stm32/include/periph_cpu.h @@ -965,6 +965,15 @@ void dma_start(dma_t dma); */ uint16_t dma_suspend(dma_t dma); +/** + * @brief Gets the number of bytes that have yet to be transferred + * + * @param[in] dma logical DMA stream + * + * @return the remaining number of bytes to transfer. + */ +uint16_t dma_left(dma_t dma); + /** * @brief Resume a suspended DMA transfer on a stream * @@ -1030,6 +1039,15 @@ void dma_setup(dma_t dma, int chan, void *periph_addr, dma_mode_t mode, */ void dma_prepare(dma_t dma, void *mem, size_t len, bool incr_mem); +/** + * @brief Sets the callback which is executed after a DMA transfer is completed. + * + * @param[in] dma Logical DMA stream + * @param[in] callback Callback to execute during the Transfer Complete interrupt + * @param[in] arg Argument to pass to the callback + */ +void dma_set_transfer_complete_cb(dma_t dma, void (*callback)(void*, dma_t), void* arg); + #endif /* MODULE_PERIPH_DMA */ #ifdef MODULE_PERIPH_CAN diff --git a/cpu/stm32/periph/dma.c b/cpu/stm32/periph/dma.c index c61106f6b815..8fa182691408 100644 --- a/cpu/stm32/periph/dma.c +++ b/cpu/stm32/periph/dma.c @@ -88,6 +88,8 @@ struct dma_ctx { STM32_DMA_Stream_Type *stream; mutex_t conf_lock; mutex_t sync_lock; + void (*callback)(void*, dma_t); + void *callback_arg; uint16_t len; }; @@ -445,6 +447,15 @@ int dma_configure(dma_t dma, int chan, const volatile void *src, volatile void * return 0; } +void dma_set_transfer_complete_cb(dma_t dma, void (*callback)(void*, dma_t), void *arg) +{ + struct dma_ctx *ctx = &dma_ctx[dma]; + unsigned int state = irq_disable(); + ctx->callback = callback; + ctx->callback_arg = arg; + irq_restore(state); +} + void dma_start(dma_t dma) { STM32_DMA_Stream_Type *stream = dma_ctx[dma].stream; @@ -472,6 +483,14 @@ uint16_t dma_suspend(dma_t dma) } +uint16_t dma_left(dma_t dma) +{ + assert(dma < DMA_NUMOF); + + STM32_DMA_Stream_Type *stream = dma_ctx[dma].stream; + return stream->NDTR_REG; +} + void dma_resume(dma_t dma, uint16_t remaining) { assert(dma < DMA_NUMOF); @@ -504,7 +523,11 @@ void dma_isr_handler(dma_t dma) { dma_clear_all_flags(dma); - mutex_unlock(&dma_ctx[dma].sync_lock); + struct dma_ctx *ctx = &dma_ctx[dma]; + mutex_unlock(&ctx->sync_lock); + + if (ctx->callback) + ctx->callback(ctx->callback_arg, dma); cortexm_isr_end(); }