53 return (dmap->
dmastream->stream->FCR & DMA_SxFCR_FS_Msk);
58 osalDbgCheck(dmap != NULL);
63 #if STM32_DMA_USE_WAIT == TRUE
66 #if STM32_DMA_USE_MUTUAL_EXCLUSION == TRUE
67 osalMutexObjectInit(&dmap->mutex);
69 #if defined( STM32_DMA_DRIVER_EXT_INIT_HOOK)
70 STM32_DMA_DRIVER_EXT_INIT_HOOK(dmap);
72 #if CH_DBG_SYSTEM_STATE_CHECK == TRUE
73 dmap->nbTransferError = dmap->nbDirectModeError = dmap->nbFifoError = 0U;
76 #if STM32_DMA_USE_ASYNC_TIMOUT
77 chVTObjectInit(&dmap->vt);
94 osalDbgCheck((dmap != NULL) && (cfg != NULL));
116 osalDbgCheck(dmap != NULL);
176 osalDbgCheckClassI();
177 #if (CH_DBG_ENABLE_ASSERTS != FALSE)
178 if (size != dmap->
size) {
179 osalDbgCheck((dmap != NULL) && (mem0p != NULL) && (periphp != NULL) &&
180 (size > 0U) && ((size == 1U) || ((size & 1U) == 0U)));
190 osalDbgAssert((
uint32_t) periphp % cfg->
psize == 0,
"peripheral address not aligned");
195 osalDbgAssert((
uint32_t) mem0p % cfg->
msize == 0,
"memory address not aligned");
211 # if STM32_DMA_ADVANCED
213 osalDbgAssert((size % (cfg->mburst * cfg->
msize / cfg->
psize)) == 0,
214 "mburst alignment rule not respected");
215 osalDbgAssert((size % (cfg->mburst * cfg->
msize)) == 0,
216 "mburst alignment rule not respected");
217 osalDbgAssert((((
uint32_t) mem0p) % cfg->mburst) == 0,
218 "memory address alignment rule not respected");
221 osalDbgAssert((size % (cfg->pburst * cfg->
psize)) == 0,
222 "pburst alignment rule not respected");
223 osalDbgAssert((((
uint32_t) periphp) % cfg->pburst) == 0,
224 "peripheral address alignment rule not respected");
229 # endif // STM32_DMA_ADVANCED
232 #endif // CH_DBG_ENABLE_ASSERTS != FALSE
235 #if STM32_DMA_USE_ASYNC_TIMOUT
236 dmap->currPtr = mem0p;
237 if (dmap->
config->timeout != TIME_INFINITE) {
238 chVTSetI(&dmap->vt, dmap->
config->timeout,
239 &dma_lld_serve_timeout_interrupt, (
void *) dmap);
260 osalDbgCheck(dmap != NULL);
287 osalDbgCheckClassI();
288 osalDbgCheck(dmap != NULL);
303 #if (STM32_DMA_USE_WAIT == TRUE) || defined(__DOXYGEN__)
334 osalDbgAssert(dmap->thread == NULL,
"already waiting");
335 osalDbgAssert(dmap->
config->
circular ==
false,
"blocking API is incompatible with circular mode");
337 msg = osalThreadSuspendTimeoutS(&dmap->thread,
timeout);
346 #if (STM32_DMA_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
361 osalDbgCheck(dmap != NULL);
363 osalMutexLock(&dmap->mutex);
378 osalDbgCheck(dmap != NULL);
380 osalMutexUnlock(&dmap->mutex);
415 switch (cfg->
psize) {
416 case 1 : psize_msk = STM32_DMA_CR_PSIZE_BYTE;
break;
417 case 2 : psize_msk = STM32_DMA_CR_PSIZE_HWORD;
break;
418 case 4 : psize_msk = STM32_DMA_CR_PSIZE_WORD;
break;
419 default: osalSysHalt(
"psize should be 1 or 2 or 4");
422 switch (cfg->
msize) {
423 case 1 : msize_msk = STM32_DMA_CR_MSIZE_BYTE;
break;
424 case 2 : msize_msk = STM32_DMA_CR_MSIZE_HWORD;
break;
425 case 4 : msize_msk = STM32_DMA_CR_MSIZE_WORD;
break;
426 default: osalDbgAssert(
false,
"msize should be 1 or 2 or 4");
432 case DMA_DIR_P2M: dir_msk = STM32_DMA_CR_DIR_P2M;
break;
433 case DMA_DIR_M2P: dir_msk = STM32_DMA_CR_DIR_M2P;
break;
434 case DMA_DIR_M2M: dir_msk = STM32_DMA_CR_DIR_M2M;
break;
435 default: osalDbgAssert(
false,
"direction not set or incorrect");
442 isr_flags |= STM32_DMA_CR_TCIE;
444 isr_flags |= STM32_DMA_CR_HTIE;
450 isr_flags |= STM32_DMA_CR_DMEIE | STM32_DMA_CR_TCIE;
453 #if CH_KERNEL_MAJOR < 6
458 #if STM32_DMA_ADVANCED
465 dir_msk | psize_msk | msize_msk | isr_flags |
466 (cfg->
circular ? STM32_DMA_CR_CIRC : 0UL) |
471 | STM32_DMA_CR_CHSEL(cfg->request)
472 #elif STM32_DMA_ADVANCED
473 | STM32_DMA_CR_CHSEL(cfg->channel)
474 | (cfg->periph_inc_size_4 ? STM32_DMA_CR_PINCOS : 0UL) |
475 (cfg->transfert_end_ctrl_by_periph ? STM32_DMA_CR_PFCTRL : 0UL)
480 #if STM32_DMA_ADVANCED
481 uint32_t pburst_msk, mburst_msk, fifo_msk;
482 switch (cfg->pburst) {
483 case 0 : pburst_msk = 0UL;
break;
484 case 4 : pburst_msk = STM32_DMA_CR_PBURST_INCR4;
break;
485 case 8 : pburst_msk = STM32_DMA_CR_PBURST_INCR8;
break;
486 case 16 : pburst_msk = STM32_DMA_CR_PBURST_INCR16;
break;
487 default: osalDbgAssert(
false,
"pburst size should be 0 or 4 or 8 or 16");
490 switch (cfg->mburst) {
491 case 0 : mburst_msk = 0UL;
break;
492 case 4 : mburst_msk = STM32_DMA_CR_MBURST_INCR4;
break;
493 case 8 : mburst_msk = STM32_DMA_CR_MBURST_INCR8;
break;
494 case 16 : mburst_msk = STM32_DMA_CR_MBURST_INCR16;
break;
495 default: osalDbgAssert(
false,
"mburst size should be 0 or 4 or 8 or 16");
499 case 0 : fifo_msk = 0UL;
break;
500 case 1 : fifo_msk = STM32_DMA_FCR_FTH_1Q;
break;
501 case 2 : fifo_msk = STM32_DMA_FCR_FTH_HALF;
break;
502 case 3 : fifo_msk = STM32_DMA_FCR_FTH_3Q;
break;
503 case 4 : fifo_msk = STM32_DMA_FCR_FTH_FULL; ;
break;
504 default: osalDbgAssert(
false,
"fifo threshold should be 1(/4) or 2(/4) or 3(/4) or 4(/4)");
509 # if (CH_DBG_ENABLE_ASSERTS != FALSE)
510 # if STM32_DMA_USE_ASYNC_TIMOUT
511 osalDbgAssert(dmap->
config->timeout != 0,
512 "timeout cannot be 0 if STM32_DMA_USE_ASYNC_TIMOUT is enabled");
513 osalDbgAssert(!((dmap->
config->timeout != TIME_INFINITE) && (dmap->
config->fifo != 0)),
514 "timeout should be dynamicly disabled (dmap->config->timeout = TIME_INFINITE) "
515 "if STM32_DMA_USE_ASYNC_TIMOUT is enabled and fifo is enabled (fifo != 0)");
522 osalDbgAssert(
false,
"psize and msize should be enabled or disabled together");
527 switch (cfg->
msize) {
529 switch (cfg->mburst) {
540 case 1:
goto forbiddenCombination;
542 case 3:
goto forbiddenCombination;
548 case 1:
goto forbiddenCombination;
549 case 2:
goto forbiddenCombination;
550 case 3:
goto forbiddenCombination;
557 switch (cfg->mburst) {
560 case 1:
goto forbiddenCombination;
562 case 3:
goto forbiddenCombination;
568 case 1:
goto forbiddenCombination;
569 case 2:
goto forbiddenCombination;
570 case 3:
goto forbiddenCombination;
576 case 1:
goto forbiddenCombination;
577 case 2:
goto forbiddenCombination;
578 case 3:
goto forbiddenCombination;
579 case 4:
goto forbiddenCombination;
584 switch (cfg->mburst) {
587 case 1:
goto forbiddenCombination;
588 case 2:
goto forbiddenCombination;
589 case 3:
goto forbiddenCombination;
595 case 1:
goto forbiddenCombination;
596 case 2:
goto forbiddenCombination;
597 case 3:
goto forbiddenCombination;
598 case 4:
goto forbiddenCombination;
603 case 1:
goto forbiddenCombination;
604 case 2:
goto forbiddenCombination;
605 case 3:
goto forbiddenCombination;
606 case 4:
goto forbiddenCombination;
613 dmap->
dmamode |= (pburst_msk | mburst_msk);
615 # if (CH_DBG_ENABLE_ASSERTS != FALSE)
625 if (((cfg->pburst * cfg->
psize) == STM32_DMA_FIFO_SIZE) && (cfg->fifo == 3)) {
626 goto forbiddenCombination;
635 osalDbgAssert(dmap->
controller == 2,
"M2M not available on DMA1");
636 osalDbgAssert(cfg->
circular ==
false,
"M2M not available in circular mode");
643 #if STM32_DMA_ADVANCED
645 dmap->fifomode = STM32_DMA_FCR_DMDIS | STM32_DMA_FCR_FEIE | fifo_msk;
649 "msize == psize is mandatory when fifo is disabled");
654 #if CH_KERNEL_MAJOR < 6
655 const bool error = dmaStreamAllocate( dmap->
dmastream,
660 dmap->dmastream = dmaStreamAllocI(dmap->config->stream,
664 bool error = dmap->dmastream == NULL;
667 osalDbgAssert(
false,
"stream already allocated");
673 #if (CH_DBG_ENABLE_ASSERTS != FALSE)
674 #if STM32_DMA_ADVANCED
675 forbiddenCombination:
676 chSysHalt(
"forbidden combination of msize, mburst, fifo, see FIFO threshold "
677 "configuration in reference manuel");
694 if (dmap->
config->dcache_memory_in_use &&
696 cacheBufferFlush(mem0p, size * dmap->
config->
msize);
701 dmap->periphp = periphp;
704 dmaStreamSetPeripheral(dmap->
dmastream, periphp);
705 dmaStreamSetMemory0(dmap->
dmastream, mem0p);
706 dmaStreamSetTransactionSize(dmap->
dmastream, size);
708 #if STM32_DMA_ADVANCED
709 dmaStreamSetFIFO(dmap->
dmastream, dmap->fifomode);
737 #if CH_KERNEL_MAJOR < 6
759 #if CH_DBG_SYSTEM_STATE_CHECK
760 const uint32_t feif_msk = dmap->
config->fifo != 0U ? STM32_DMA_ISR_FEIF : 0U;
762 static const uint32_t feif_msk = 0U;
765 if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF | feif_msk)) != 0U) {
781 if (dmap->
config->dcache_memory_in_use)
785 cacheBufferInvalidate(dmap->
mem0p,
789 cacheBufferInvalidate(dmap->periphp,
795 if ((flags & STM32_DMA_ISR_TCIF) != 0) {
798 }
else if ((flags & STM32_DMA_ISR_HTIF) != 0) {
806 #if STM32_DMA_USE_ASYNC_TIMOUT
812 void dma_lld_serve_timeout_interrupt(
void *arg)
817 chVTSetI(&dmap->vt, dmap->
config->timeout,
818 &dma_lld_serve_timeout_interrupt, (
void *) dmap);
819 chSysUnlockFromISR();
821 async_timout_enabled_call_end_cb(dmap, FROM_TIMOUT_CODE);