/** * @brief Allocates a DMA stream. * @details The stream is allocated and, if required, the DMA clock enabled. * The function also enables the IRQ vector associated to the stream * and initializes its priority. * @pre The stream must not be already in use or an error is returned. * @post The stream is allocated and the default ISR handler redirected * to the specified function. * @post The stream ISR vector is enabled and its priority configured. * @post The stream must be freed using @p dmaStreamRelease() before it can * be reused with another peripheral. * @post The stream is in its post-reset state. * @note This function can be invoked in both ISR or thread context. * * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @param[in] priority IRQ priority mask for the DMA stream * @param[in] func handling function pointer, can be @p NULL * @param[in] param a parameter to be passed to the handling function * @return The operation status. * @retval FALSE no error, stream taken. * @retval TRUE error, stream already taken. * * @special */ bool_t dmaStreamAllocate(const stm32_dma_stream_t *dmastp, uint32_t priority, stm32_dmaisr_t func, void *param) { chDbgCheck(dmastp != NULL, "dmaAllocate"); /* Checks if the stream is already taken.*/ if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0) return TRUE; /* Marks the stream as allocated.*/ dma_isr_redir[dmastp->selfindex].dma_func = func; dma_isr_redir[dmastp->selfindex].dma_param = param; dma_streams_mask |= (1 << dmastp->selfindex); /* Enabling DMA clocks required by the current streams set.*/ if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) rccEnableDMA1(FALSE); #if STM32_HAS_DMA2 if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) rccEnableDMA2(FALSE); #endif /* Putting the stream in a safe state.*/ dmaStreamDisable(dmastp); dmaStreamClearInterrupt(dmastp); dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; /* Enables the associated IRQ vector if a callback is defined.*/ if (func != NULL) NVICEnableVector(dmastp->vector, CORTEX_PRIORITY_MASK(priority)); return FALSE; }
/** * @brief Allocates a DMA stream. * @details The stream is allocated and, if required, the DMA clock enabled. * The function also enables the IRQ vector associated to the stream * and initializes its priority. * @pre The stream must not be already in use or an error is returned. * @post The stream is allocated and the default ISR handler redirected * to the specified function. * @post The stream ISR vector is enabled and its priority configured. * @post The stream must be freed using @p dmaStreamRelease() before it can * be reused with another peripheral. * @post The stream is in its post-reset state. * @note This function can be invoked in both ISR or thread context. * * @param[in] dmastp pointer to a stm32_dma_stream_t structure * @param[in] priority IRQ priority mask for the DMA stream * @param[in] func handling function pointer, can be @p NULL * @param[in] param a parameter to be passed to the handling function * @return The operation status. * @retval false no error, stream taken. * @retval true error, stream already taken. * * @special */ bool dmaStreamAllocate(const stm32_dma_stream_t *dmastp, uint32_t priority, stm32_dmaisr_t func, void *param) { osalDbgCheck(dmastp != NULL); /* Checks if the stream is already taken.*/ if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0) return true; /* Marks the stream as allocated.*/ dma_isr_redir[dmastp->selfindex].dma_func = func; dma_isr_redir[dmastp->selfindex].dma_param = param; dma_streams_mask |= (1 << dmastp->selfindex); /* Enabling DMA clocks required by the current streams set.*/ if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) rccEnableDMA1(false); #if STM32_HAS_DMA2 if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) rccEnableDMA2(false); #endif /* Putting the stream in a safe state.*/ dmaStreamDisable(dmastp); dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; /* Enables the associated IRQ vector if a callback is defined.*/ if (func != NULL) nvicEnableVector(dmastp->vector, priority); return false; }