39 #if !defined(STM32_DMA_USE_WAIT) || defined(__DOXYGEN__)
40 #define STM32_DMA_USE_WAIT TRUE
47 #if !defined(STM32_DMA_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
48 #define STM32_DMA_USE_MUTUAL_EXCLUSION FALSE
51 #if !defined(STM32_DMA_SUPPORTS_CSELR) || defined(__DOXYGEN__)
52 #define STM32_DMA_SUPPORTS_CSELR FALSE
118 #if (STM32_DMA_USE_WAIT == TRUE) || defined(__DOXYGEN__)
131 #define _dma_reset_i(dmap) \
132 osalThreadResumeI(&(dmap)->thread, MSG_RESET)
141 #define _dma_reset_s(dmap) \
142 osalThreadResumeS(&(dmap)->thread, MSG_RESET)
151 #define _dma_wakeup_isr(dmap) { \
152 osalSysLockFromISR(); \
153 osalThreadResumeI(&(dmap)->thread, MSG_OK); \
154 osalSysUnlockFromISR(); \
164 #define _dma_timeout_isr(dmap) { \
165 osalSysLockFromISR(); \
166 osalThreadResumeI(&(dmap)->thread, MSG_TIMEOUT); \
167 osalSysUnlockFromISR(); \
170 #define _dma_reset_i(dmap)
171 #define _dma_reset_s(dmap)
172 #define _dma_wakeup_isr(dmap)
173 #define _dma_timeout_isr(dmap)
246 #if STM32_DMA_SUPPORTS_CSELR
255 #elif STM32_DMA_ADVANCED
286 #if STM32_DMA_USE_ASYNC_TIMOUT
320 #if STM32_DMA_ADVANCED
321 #define STM32_DMA_FIFO_SIZE 4 // hardware specification for dma V2
341 bool periph_inc_size_4;
346 bool transfert_end_ctrl_by_periph;
365 #if STM32_DMA_USE_WAIT || defined(__DOXYGEN__)
369 thread_reference_t thread;
371 #if STM32_DMA_USE_MUTUAL_EXCLUSION || defined(__DOXYGEN__)
377 #if STM32_DMA_USE_ASYNC_TIMOUT
423 #if STM32_DMA_USE_WAIT == TRUE
432 #if STM32_DMA_USE_MUTUAL_EXCLUSION == TRUE
454 #if STM32_DMA_USE_ASYNC_TIMOUT
455 void dma_lld_serve_timeout_interrupt(
void *arg);
458 #if STM32_DMA_USE_ASYNC_TIMOUT
459 typedef enum {FROM_TIMOUT_CODE, FROM_HALF_CODE, FROM_FULL_CODE, FROM_NON_CIRCULAR_CODE} CbCallContext;
460 static inline void async_timout_enabled_call_end_cb(
DMADriver *dmap,
const CbCallContext context)
462 uint8_t *
const baseAddr = dmap->currPtr;
463 const size_t fullSize = dmap->
size;
464 const size_t halfSize = fullSize / 2;
472 case (FROM_HALF_CODE) :
473 if (midPtr > baseAddr) {
475 dmap->currPtr = midPtr;
479 case (FROM_FULL_CODE) :
480 case (FROM_NON_CIRCULAR_CODE) :
482 dmap->currPtr = basePtr;
485 case (FROM_TIMOUT_CODE) : {
486 const size_t dmaCNT = dmaStreamGetTransactionSize(dmap->
dmastream);
487 const size_t index = (baseAddr - basePtr) / dmap->
config->
msize;
492 if (fullSize >= (dmaCNT + index)) {
493 rem = (fullSize - dmaCNT - index);
494 dmap->currPtr = baseAddr + (rem * dmap->
config->
msize);
508 #if STM32_DMA_USE_ASYNC_TIMOUT
509 if (dmap->
config->timeout != TIME_INFINITE) {
511 chVTSetI(&dmap->vt, dmap->
config->timeout,
512 &dma_lld_serve_timeout_interrupt, (
void *) dmap);
513 chSysUnlockFromISR();
515 async_timout_enabled_call_end_cb(dmap, FROM_HALF_CODE);
526 #if STM32_DMA_USE_ASYNC_TIMOUT
527 if (dmap->
config->timeout != TIME_INFINITE) {
529 chVTSetI(&dmap->vt, dmap->
config->timeout,
530 &dma_lld_serve_timeout_interrupt, (
void *) dmap);
531 chSysUnlockFromISR();
533 async_timout_enabled_call_end_cb(dmap, FROM_FULL_CODE);
537 if (dmap->
size > 1) {
539 const size_t half_index = dmap->
size / 2;
542 dmap->
config->
end_cb(dmap, (
void *) byte_array_p, half_index);
551 #if STM32_DMA_USE_ASYNC_TIMOUT
552 if (dmap->
config->timeout != TIME_INFINITE) {
554 chVTResetI(&dmap->vt);
555 chSysUnlockFromISR();
562 #if STM32_DMA_USE_ASYNC_TIMOUT
563 async_timout_enabled_call_end_cb(dmap, FROM_NON_CIRCULAR_CODE);
void(* dmacallback_t)(DMADriver *dmap, void *buffer, const size_t n)
DMA notification callback type.
bool dmaStart(DMADriver *dmap, const DMAConfig *cfg)
Configures and activates the DMA peripheral.
void dmaObjectInit(DMADriver *dmap)
void dmaStop(DMADriver *dmap)
Deactivates the DMA peripheral.
static void _dma_isr_full_code(DMADriver *dmap)
Common ISR code, full buffer event.
dmadirection_t
DMA transfert direction.
bool inc_peripheral_addr
Enable increment of peripheral address after each transfert.
dmaerrormask_t
Possible DMA failure causes.
#define _dma_timeout_isr(dmap)
Wakes up the waiting thread with a timeout message.
bool dma_lld_start(DMADriver *dmap)
Configures and activates the DMA peripheral.
DMA FIFO overrun or underrun.
uint32_t dmamode
hold DMA CR register for the stream
bool dmaStartTransfert(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size)
Starts a DMA transaction.
void dmaAcquireBus(DMADriver *dmap)
Gains exclusive access to the DMA peripheral.
void dmaStopTransfertI(DMADriver *dmap)
Stops an ongoing transaction.
bool dmaStartTransfertI(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size)
Starts a DMA transaction.
void dma_lld_stop_transfert(DMADriver *dmap)
Stops an ongoing transaction.
uint32_t stream
stream associated with transaction
void dma_lld_stop(DMADriver *dmap)
Deactivates the DMA peripheral.
void dmaReleaseBus(DMADriver *dmap)
Releases exclusive access to the DMA peripheral.
#define _dma_wakeup_isr(dmap)
Wakes up the waiting thread.
bool inc_memory_addr
Enable increment of memory address after each transfert.
static pthread_mutex_t mutex
dmaerrorcallback_t error_cb
Error callback or NULL.
dmadirection_t direction
DMA transaction direction.
dmacallback_t end_cb
Callback function associated to the stream or NULL.
dmastate_t state
Driver state.
msg_t dmaTransfertTimeout(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size, sysinterval_t timeout)
Performs a DMA transaction.
dmastate_t
Driver state machine possible states.
uint8_t psize
DMA peripheral data granurality in bytes (1,2,4)
bool dma_lld_start_transfert(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size)
Starts a DMA transaction.
bool circular
Enables the circular buffer mode for the stream.
DMA stream configuration structure.
static void _dma_isr_half_code(DMADriver *dmap)
Common ISR code, half buffer event.
uint8_t dma_priority
DMA priority (1 .
size_t size
hold size of current transaction
const stm32_dma_stream_t * dmastream
DMA stream associated with peripheral or memory.
uint8_t irq_priority
DMA IRQ priority (2 .
void(* dmaerrorcallback_t)(DMADriver *dmap, dmaerrormask_t err)
DMA error callback type.
void dmaStopTransfert(DMADriver *dmap)
Stops an ongoing transaction.
uint8_t msize
DMA memory data granurality in bytes (1,2,4)
uint8_t controller
controller associated with stream
static void _dma_isr_error_code(DMADriver *dmap, dmaerrormask_t err)
Common ISR code, error event.
static msg_t dmaTransfert(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size)
void * mem0p
memory address
const DMAConfig * config
Current configuration data.
Structure representing a DMA driver.