55 osalDbgCheck(dmap != NULL);
60 #if STM32_DMA_USE_WAIT == TRUE
63 #if STM32_DMA_USE_MUTUAL_EXCLUSION == TRUE
64 osalMutexObjectInit(&dmap->mutex);
66 #if defined( STM32_DMA_DRIVER_EXT_INIT_HOOK)
67 STM32_DMA_DRIVER_EXT_INIT_HOOK(dmap);
69 #if STM32_DMA_USE_ASYNC_TIMOUT
70 chVTObjectInit(&dmap->vt);
87 osalDbgCheck((dmap != NULL) && (cfg != NULL));
109 osalDbgCheck(dmap != NULL);
169 osalDbgCheckClassI();
170 osalDbgCheck((dmap != NULL) && (mem0p != NULL) && (periphp != NULL) &&
171 (size > 0U) && ((size == 1U) || ((size & 1U) == 0U)));
173 #if (CH_DBG_ENABLE_ASSERTS != FALSE)
180 osalDbgAssert((
uint32_t) periphp % cfg->
psize == 0,
"peripheral address not aligned");
181 osalDbgAssert((
uint32_t) mem0p % cfg->
msize == 0,
"memory address not aligned");
193 # if STM32_DMA_ADVANCED
195 osalDbgAssert((size % (cfg->pburst * cfg->
psize)) == 0,
196 "pburst alignment rule not respected");
197 osalDbgAssert((((
uint32_t) periphp) % (cfg->pburst * cfg->
psize)) == 0,
198 "peripheral address alignment rule not respected");
201 osalDbgAssert((size % (cfg->mburst * cfg->
msize)) == 0,
202 "mburst alignment rule not respected");
203 osalDbgAssert((((
uint32_t) mem0p) % (cfg->mburst * cfg->
msize)) == 0,
204 "memory address alignment rule not respected");
209 #if STM32_DMA_USE_ASYNC_TIMOUT
210 dmap->currPtr = mem0p;
211 if (dmap->
config->timeout != TIME_INFINITE) {
212 chVTSetI(&dmap->vt, dmap->
config->timeout,
213 &dma_lld_serve_timeout_interrupt, (
void *) dmap);
235 osalDbgCheck(dmap != NULL);
262 osalDbgCheckClassI();
263 osalDbgCheck(dmap != NULL);
278 #if (STM32_DMA_USE_WAIT == TRUE) || defined(__DOXYGEN__)
309 osalDbgAssert(dmap->thread == NULL,
"already waiting");
311 msg = osalThreadSuspendTimeoutS(&dmap->thread, timeout);
320 #if (STM32_DMA_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
335 osalDbgCheck(dmap != NULL);
337 osalMutexLock(&dmap->mutex);
352 osalDbgCheck(dmap != NULL);
354 osalMutexUnlock(&dmap->mutex);
389 switch (cfg->
psize) {
390 case 1 : psize_msk = STM32_DMA_CR_PSIZE_BYTE;
break;
391 case 2 : psize_msk = STM32_DMA_CR_PSIZE_HWORD;
break;
392 case 4 : psize_msk = STM32_DMA_CR_PSIZE_WORD;
break;
393 default: osalSysHalt(
"psize should be 1 or 2 or 4");
396 switch (cfg->
msize) {
397 case 1 : msize_msk = STM32_DMA_CR_MSIZE_BYTE;
break;
398 case 2 : msize_msk = STM32_DMA_CR_MSIZE_HWORD;
break;
399 case 4 : msize_msk = STM32_DMA_CR_MSIZE_WORD;
break;
400 default: osalDbgAssert(
false,
"msize should be 1 or 2 or 4");
406 case DMA_DIR_P2M: dir_msk = STM32_DMA_CR_DIR_P2M;
break;
407 case DMA_DIR_M2P: dir_msk = STM32_DMA_CR_DIR_M2P;
break;
408 case DMA_DIR_M2M: dir_msk = STM32_DMA_CR_DIR_M2M;
break;
409 default: osalDbgAssert(
false,
"direction not set or incorrect");
416 isr_flags |= STM32_DMA_CR_TCIE;
418 isr_flags |= STM32_DMA_CR_HTIE;
424 isr_flags |= STM32_DMA_CR_DMEIE | STM32_DMA_CR_TCIE;
431 #if STM32_DMA_ADVANCED
438 dir_msk | psize_msk | msize_msk | isr_flags |
439 (cfg->
circular ? STM32_DMA_CR_CIRC : 0UL) |
444 | STM32_DMA_CR_CHSEL(cfg->request)
445 #elif STM32_DMA_ADVANCED
446 | STM32_DMA_CR_CHSEL(cfg->channel)
447 | (cfg->periph_inc_size_4 ? STM32_DMA_CR_PINCOS : 0UL) |
448 (cfg->transfert_end_ctrl_by_periph ? STM32_DMA_CR_PFCTRL : 0UL)
453 #if STM32_DMA_ADVANCED
454 uint32_t pburst_msk, mburst_msk, fifo_msk;
455 switch (cfg->pburst) {
456 case 0 : pburst_msk = 0UL;
break;
457 case 4 : pburst_msk = STM32_DMA_CR_PBURST_INCR4;
break;
458 case 8 : pburst_msk = STM32_DMA_CR_PBURST_INCR8;
break;
459 case 16 : pburst_msk = STM32_DMA_CR_PBURST_INCR16;
break;
460 default: osalDbgAssert(
false,
"pburst size should be 0 or 4 or 8 or 16");
463 switch (cfg->mburst) {
464 case 0 : mburst_msk = 0UL;
break;
465 case 4 : mburst_msk = STM32_DMA_CR_MBURST_INCR4;
break;
466 case 8 : mburst_msk = STM32_DMA_CR_MBURST_INCR8;
break;
467 case 16 : mburst_msk = STM32_DMA_CR_MBURST_INCR16;
break;
468 default: osalDbgAssert(
false,
"mburst size should be 0 or 4 or 8 or 16");
472 case 0 : fifo_msk = 0UL;
break;
473 case 1 : fifo_msk = STM32_DMA_FCR_FTH_1Q;
break;
474 case 2 : fifo_msk = STM32_DMA_FCR_FTH_HALF;
break;
475 case 3 : fifo_msk = STM32_DMA_FCR_FTH_3Q;
break;
476 case 4 : fifo_msk = STM32_DMA_FCR_FTH_FULL; ;
break;
477 default: osalDbgAssert(
false,
"fifo threshold should be 1(/4) or 2(/4) or 3(/4) or 4(/4)");
482 # if (CH_DBG_ENABLE_ASSERTS != FALSE)
483 # if STM32_DMA_USE_ASYNC_TIMOUT
484 osalDbgAssert(dmap->
config->timeout != 0,
485 "timeout cannot be 0 if STM32_DMA_USE_ASYNC_TIMOUT is enabled");
486 osalDbgAssert(!((dmap->
config->timeout != TIME_INFINITE) && (dmap->
config->fifo != 0)),
487 "timeout should be dynamicly disabled (dmap->config->timeout = TIME_INFINITE) "
488 "if STM32_DMA_USE_ASYNC_TIMOUT is enabled and fifo is enabled (fifo != 0)");
495 osalDbgAssert(
false,
"psize and msize should be enabled or disabled together");
500 switch (cfg->
msize) {
502 switch (cfg->mburst) {
513 case 1:
goto forbiddenCombination;
515 case 3:
goto forbiddenCombination;
521 case 1:
goto forbiddenCombination;
522 case 2:
goto forbiddenCombination;
523 case 3:
goto forbiddenCombination;
530 switch (cfg->mburst) {
533 case 1:
goto forbiddenCombination;
535 case 3:
goto forbiddenCombination;
541 case 1:
goto forbiddenCombination;
542 case 2:
goto forbiddenCombination;
543 case 3:
goto forbiddenCombination;
549 case 1:
goto forbiddenCombination;
550 case 2:
goto forbiddenCombination;
551 case 3:
goto forbiddenCombination;
552 case 4:
goto forbiddenCombination;
557 switch (cfg->mburst) {
560 case 1:
goto forbiddenCombination;
561 case 2:
goto forbiddenCombination;
562 case 3:
goto forbiddenCombination;
568 case 1:
goto forbiddenCombination;
569 case 2:
goto forbiddenCombination;
570 case 3:
goto forbiddenCombination;
571 case 4:
goto forbiddenCombination;
576 case 1:
goto forbiddenCombination;
577 case 2:
goto forbiddenCombination;
578 case 3:
goto forbiddenCombination;
579 case 4:
goto forbiddenCombination;
586 dmap->
dmamode |= (pburst_msk | mburst_msk);
588 # if (CH_DBG_ENABLE_ASSERTS != FALSE)
598 if (((cfg->pburst * cfg->
psize) == STM32_DMA_FIFO_SIZE) && (cfg->fifo == 3)) {
599 goto forbiddenCombination;
608 osalDbgAssert(dmap->
controller == 2,
"M2M not available on DMA1");
609 osalDbgAssert(cfg->
circular ==
false,
"M2M not available in circular mode");
616 const bool error = dmaStreamAllocate(dmap->
dmastream,
621 osalDbgAssert(
false,
"stream already allocated");
625 #if STM32_DMA_ADVANCED
627 dmaStreamSetFIFO(dmap->
dmastream, STM32_DMA_FCR_DMDIS | STM32_DMA_FCR_FEIE | fifo_msk);
630 osalDbgAssert(cfg->
psize == cfg->
msize,
"msize == psize is mandatory when fifo is disabled");
638 #if (CH_DBG_ENABLE_ASSERTS != FALSE)
639 #if STM32_DMA_ADVANCED
640 forbiddenCombination:
641 chSysHalt(
"forbidden combination of msize, mburst, fifo, see FIFO threshold "
642 "configuration in reference manuel");
660 dmaStreamSetPeripheral(dmap->
dmastream, periphp);
661 dmaStreamSetMemory0(dmap->
dmastream, mem0p);
662 dmaStreamSetTransactionSize(dmap->
dmastream, size);
708 if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF | STM32_DMA_ISR_FEIF)) != 0) {
722 if ((flags & STM32_DMA_ISR_TCIF) != 0) {
725 }
else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
733 #if STM32_DMA_USE_ASYNC_TIMOUT
739 void dma_lld_serve_timeout_interrupt(
void *arg)
744 chVTSetI(&dmap->vt, dmap->
config->timeout,
745 &dma_lld_serve_timeout_interrupt, (
void *) dmap);
746 chSysUnlockFromISR();
748 async_timout_enabled_call_end_cb(dmap, FROM_TIMOUT_CODE);
static void dma_lld_serve_interrupt(DMADriver *dmap, uint32_t flags)
DMA ISR service routine.
msg_t dmaTransfertTimeout(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size, sysinterval_t timeout)
Performs a DMA transaction.
void dmaStop(DMADriver *dmap)
Deactivates the DMA peripheral.
STM32 DMA subsystem driver header.
void dmaStopTransfertI(DMADriver *dmap)
Stops an ongoing transaction.
static void _dma_isr_full_code(DMADriver *dmap)
Common ISR code, full buffer event.
bool inc_peripheral_addr
Enable increment of peripheral address after each transfert.
bool dmaStart(DMADriver *dmap, const DMAConfig *cfg)
Configures and activates the DMA peripheral.
void dmaReleaseBus(DMADriver *dmap)
Releases exclusive access to the DMA peripheral.
dmaerrormask_t
Possible DMA failure causes.
DMA FIFO overrun or underrun.
uint32_t dmamode
hold DMA CR register for the stream
uint32_t stream
stream associated with transaction
bool inc_memory_addr
Enable increment of memory address after each transfert.
dmaerrorcallback_t error_cb
Error callback or NULL.
bool dma_lld_start(DMADriver *dmap)
Configures and activates the DMA peripheral.
dmadirection_t direction
DMA transaction direction.
dmacallback_t end_cb
Callback function associated to the stream or NULL.
dmastate_t state
Driver state.
void dma_lld_stop(DMADriver *dmap)
Deactivates the DMA peripheral.
uint8_t psize
DMA peripheral data granurality in bytes (1,2,4)
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 .
#define STM32_DMA_SUPPORTS_CSELR
void dmaStopTransfert(DMADriver *dmap)
Stops an ongoing transaction.
size_t size
hold size of current transaction
void dmaAcquireBus(DMADriver *dmap)
Gains exclusive access to the DMA peripheral.
bool dmaStartTransfert(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size)
Starts a DMA transaction.
const stm32_dma_stream_t * dmastream
DMA stream associated with peripheral or memory.
void dma_lld_stop_transfert(DMADriver *dmap)
Stops an ongoing transaction.
uint8_t irq_priority
DMA IRQ priority (2 .
void dmaObjectInit(DMADriver *dmap)
#define _dma_reset_i(dmap)
Resumes a thread waiting for a dma transfert completion.
uint8_t msize
DMA memory data granurality in bytes (1,2,4)
uint8_t controller
controller associated with stream
bool dmaStartTransfertI(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size)
Starts a DMA transaction.
uint8_t msg[10]
Buffer used for general comunication over SPI (out buffer)
bool dma_lld_start_transfert(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size)
Starts a DMA transaction.
static void _dma_isr_error_code(DMADriver *dmap, dmaerrormask_t err)
Common ISR code, error event.
#define _dma_reset_s(dmap)
Resumes a thread waiting for a dma transfert completion.
void * mem0p
memory address
const DMAConfig * config
Current configuration data.
Structure representing a DMA driver.