34 #if defined( DMA_PRESENT )
171 static void DMA_Prepare(
unsigned int channel,
172 DMA_CycleCtrl_TypeDef cycleCtrl,
177 unsigned int nMinus1)
201 cb = (DMA_CB_TypeDef *)(primDescr->USER);
204 cb->primary = (uint8_t)primary;
209 inc = (descr->
CTRL & _DMA_CTRL_SRC_INC_MASK) >> _DMA_CTRL_SRC_INC_SHIFT;
210 if (inc == _DMA_CTRL_SRC_INC_NONE)
212 descr->SRCEND = (
volatile void*)src;
216 descr->SRCEND = (
void *)((uint32_t)src + (nMinus1 << inc));
222 inc = (descr->
CTRL & _DMA_CTRL_DST_INC_MASK) >> _DMA_CTRL_DST_INC_SHIFT;
223 if (inc == _DMA_CTRL_DST_INC_NONE)
229 descr->DSTEND = (
void *)((uint32_t)dst + (nMinus1 << inc));
233 chBit = 1 << channel;
236 DMA->CHUSEBURSTS = chBit;
240 DMA->CHUSEBURSTC = chBit;
253 tmp = descr->
CTRL & ~(_DMA_CTRL_CYCLE_CTRL_MASK | _DMA_CTRL_N_MINUS_1_MASK);
254 tmp |= nMinus1 << _DMA_CTRL_N_MINUS_1_SHIFT;
255 tmp |= (uint32_t)cycleCtrl << _DMA_CTRL_CYCLE_CTRL_SHIFT;
265 #ifndef EXCLUDE_DEFAULT_DMA_IRQ_HANDLER
284 void DMA_IRQHandler(
void)
289 uint32_t pendingPrio;
299 EFM_ASSERT(!(pending & DMA_IF_ERR));
304 pendingPrio = pending & prio;
305 for (i = 0; i < 2; i++)
315 uint32_t chmask = 1 << channel;
324 cb = (DMA_CB_TypeDef *)(descr[channel].USER);
329 primaryCpy = cb->primary;
333 cb->cbFunc(channel, (
bool)primaryCpy, cb->userPtr);
343 pendingPrio = pending & ~prio;
386 void DMA_ActivateAuto(
unsigned int channel,
390 unsigned int nMinus1)
395 EFM_ASSERT(nMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
405 chBit = 1 << channel;
407 DMA->CHSWREQ = chBit;
449 void DMA_ActivateBasic(
unsigned int channel,
454 unsigned int nMinus1)
457 EFM_ASSERT(nMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
468 DMA->CHENS = 1 << channel;
521 void DMA_ActivatePingPong(
unsigned int channel,
525 unsigned int primNMinus1,
528 unsigned int altNMinus1)
531 EFM_ASSERT(primNMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
532 EFM_ASSERT(altNMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
536 dmaCycleCtrlPingPong,
545 dmaCycleCtrlPingPong,
553 DMA->CHENS = 1 << channel;
591 void DMA_ActivateScatterGather(
unsigned int channel,
602 EFM_ASSERT(altDescr);
603 EFM_ASSERT(count && (count <= 256));
611 descr->SRCEND = (uint32_t *)altDescr + (count * 4) - 1;
623 cycleCtrl = altDescr->
CTRL & _DMA_CTRL_CYCLE_CTRL_MASK;
624 cycleCtrl &= ~(1 << _DMA_CTRL_CYCLE_CTRL_SHIFT);
626 EFM_ASSERT((cycleCtrl == dmaCycleCtrlMemScatterGather)
627 || (cycleCtrl == dmaCycleCtrlPerScatterGather));
632 altDescr[count - 1].
CTRL &= ~_DMA_CTRL_CYCLE_CTRL_MASK;
633 if (cycleCtrl == dmaCycleCtrlMemScatterGather)
635 altDescr[count - 1].
CTRL |= (uint32_t)dmaCycleCtrlAuto
636 << _DMA_CTRL_CYCLE_CTRL_SHIFT;
640 altDescr[count - 1].
CTRL |= (uint32_t)dmaCycleCtrlBasic
641 << _DMA_CTRL_CYCLE_CTRL_SHIFT;
648 cb = (DMA_CB_TypeDef *)(descr->USER);
655 descr->
CTRL =((uint32_t)dmaDataInc4 << _DMA_CTRL_DST_INC_SHIFT)
656 | ((uint32_t)dmaDataSize4 << _DMA_CTRL_DST_SIZE_SHIFT)
657 | ((uint32_t)dmaDataInc4 << _DMA_CTRL_SRC_INC_SHIFT)
658 | ((uint32_t)dmaDataSize4 << _DMA_CTRL_SRC_SIZE_SHIFT)
660 | (altDescr->
CTRL & _DMA_CTRL_SRC_PROT_CTRL_MASK)
661 | ((uint32_t)dmaArbitrate4 << _DMA_CTRL_R_POWER_SHIFT)
662 | (((count * 4) - 1) << _DMA_CTRL_N_MINUS_1_SHIFT)
663 | (((uint32_t)useBurst & 1) << _DMA_CTRL_NEXT_USEBURST_SHIFT)
666 chBit = 1 << channel;
676 if (cycleCtrl == dmaCycleCtrlMemScatterGather)
678 DMA->CHSWREQ = chBit;
701 void DMA_CfgChannel(
unsigned int channel, DMA_CfgChannel_TypeDef *cfg)
710 descr[channel].USER = (uint32_t)(cfg->cb);
715 DMA->CHPRIS = 1 << channel;
719 DMA->CHPRIC = 1 << channel;
723 DMA->CH[channel].
CTRL = cfg->select;
728 DMA->IFC = (1 << channel);
776 void DMA_CfgDescr(
unsigned int channel,
778 DMA_CfgDescr_TypeDef *cfg)
798 descr->
CTRL = (cfg->dstInc << _DMA_CTRL_DST_INC_SHIFT)
799 | (cfg->size << _DMA_CTRL_DST_SIZE_SHIFT)
800 | (cfg->srcInc << _DMA_CTRL_SRC_INC_SHIFT)
801 | (cfg->size << _DMA_CTRL_SRC_SIZE_SHIFT)
802 | ((uint32_t)(cfg->hprot) << _DMA_CTRL_SRC_PROT_CTRL_SHIFT)
803 | (cfg->arbRate << _DMA_CTRL_R_POWER_SHIFT)
804 | (0 << _DMA_CTRL_N_MINUS_1_SHIFT)
805 | (0 << _DMA_CTRL_NEXT_USEBURST_SHIFT)
806 | DMA_CTRL_CYCLE_CTRL_INVALID;
810 #if defined( _DMA_LOOP0_MASK ) && defined( _DMA_LOOP1_MASK )
824 void DMA_CfgLoop(
unsigned int channel, DMA_CfgLoop_TypeDef *cfg)
826 EFM_ASSERT(channel <= 1);
827 EFM_ASSERT(cfg->nMinus1 <= 1023);
833 DMA->LOOP0 = (cfg->enable << _DMA_LOOP0_EN_SHIFT)
834 | (cfg->nMinus1 << _DMA_LOOP0_WIDTH_SHIFT);
837 DMA->LOOP1 = (cfg->enable << _DMA_LOOP1_EN_SHIFT)
838 | (cfg->nMinus1 << _DMA_LOOP1_WIDTH_SHIFT);
845 #if defined( _DMA_RECT0_MASK )
855 void DMA_CfgRect(
unsigned int channel, DMA_CfgRect_TypeDef *cfg)
859 EFM_ASSERT(channel == 0);
860 EFM_ASSERT(cfg->dstStride <= 2047);
861 EFM_ASSERT(cfg->srcStride <= 2047);
862 EFM_ASSERT(cfg->height <= 1023);
865 DMA->RECT0 = (cfg->dstStride << _DMA_RECT0_DSTSTRIDE_SHIFT)
866 | (cfg->srcStride << _DMA_RECT0_SRCSTRIDE_SHIFT)
867 | (cfg->height << _DMA_RECT0_HEIGHT_SHIFT);
900 DMA_CfgDescrSGAlt_TypeDef *cfg)
910 if (cfg->srcInc == dmaDataIncNone)
912 descr->SRCEND = cfg->src;
916 descr->SRCEND = (
void *)((uint32_t)(cfg->src)
917 + ((uint32_t)(cfg->nMinus1) << cfg->srcInc));
920 if (cfg->dstInc == dmaDataIncNone)
922 descr->DSTEND = cfg->dst;
926 descr->DSTEND = (
void *)((uint32_t)(cfg->dst)
927 + ((uint32_t)(cfg->nMinus1) << cfg->dstInc));
935 cycleCtrl = (uint32_t)dmaCycleCtrlPerScatterGather + 1;
939 cycleCtrl = (uint32_t)dmaCycleCtrlMemScatterGather + 1;
942 descr->
CTRL =(cfg->dstInc << _DMA_CTRL_DST_INC_SHIFT)
943 | (cfg->size << _DMA_CTRL_DST_SIZE_SHIFT)
944 | (cfg->srcInc << _DMA_CTRL_SRC_INC_SHIFT)
945 | (cfg->size << _DMA_CTRL_SRC_SIZE_SHIFT)
946 | ((uint32_t)(cfg->hprot) << _DMA_CTRL_SRC_PROT_CTRL_SHIFT)
947 | (cfg->arbRate << _DMA_CTRL_R_POWER_SHIFT)
948 | ((uint32_t)(cfg->nMinus1) << _DMA_CTRL_N_MINUS_1_SHIFT)
953 | (0 << _DMA_CTRL_NEXT_USEBURST_SHIFT)
954 | (cycleCtrl << _DMA_CTRL_CYCLE_CTRL_SHIFT);
974 void DMA_ChannelEnable(
unsigned int channel,
bool enable)
980 DMA->CHENS = 1<<channel;
984 DMA->CHENC = 1<<channel;
1003 bool DMA_ChannelEnabled(
unsigned int channel)
1007 return (
bool)((DMA->CHENS >> channel) & 1);
1025 void DMA_ChannelRequestEnable(
unsigned int channel,
bool enable)
1057 void DMA_Init(DMA_Init_TypeDef *init)
1062 #if (DMA_CHAN_COUNT <= 4)
1063 EFM_ASSERT(!((uint32_t)(init->controlBlock) & (128 - 1)));
1064 #elif (DMA_CHAN_COUNT <= 8) || (DMA_CHAN_COUNT <= 12)
1065 EFM_ASSERT(!((uint32_t)(init->controlBlock) & (256 - 1)));
1067 #error "Unsupported DMA channel count (em_dma.c)."
1077 NVIC_ClearPendingIRQ(DMA_IRQn);
1078 NVIC_EnableIRQ(DMA_IRQn);
1081 DMA->IEN = DMA_IEN_ERR;
1086 DMA->CTRLBASE = (uint32_t)(init->controlBlock);
1089 DMA->CONFIG = ((uint32_t)(init->hprot) << _DMA_CONFIG_CHPROT_SHIFT)
1135 void DMA_RefreshPingPong(
unsigned int channel,
1140 unsigned int nMinus1,
1143 DMA_CycleCtrl_TypeDef cycleCtrl;
1150 EFM_ASSERT(nMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
1155 cycleCtrl = dmaCycleCtrlBasic;
1159 cycleCtrl = dmaCycleCtrlPingPong;
1174 inc = (descr->
CTRL & _DMA_CTRL_SRC_INC_MASK) >> _DMA_CTRL_SRC_INC_SHIFT;
1175 if (inc == _DMA_CTRL_SRC_INC_NONE)
1177 descr->SRCEND = (
volatile void*)src;
1181 descr->SRCEND = (
void *)((uint32_t)src + (nMinus1 << inc));
1187 inc = (descr->
CTRL & _DMA_CTRL_DST_INC_MASK) >> _DMA_CTRL_DST_INC_SHIFT;
1188 if (inc == _DMA_CTRL_DST_INC_NONE)
1190 descr->DSTEND = dst;
1194 descr->DSTEND = (
void *)((uint32_t)dst + (nMinus1 << inc));
1198 chBit = 1 << channel;
1201 DMA->CHUSEBURSTS = chBit;
1205 DMA->CHUSEBURSTC = chBit;
1209 tmp = descr->
CTRL & ~(_DMA_CTRL_CYCLE_CTRL_MASK | _DMA_CTRL_N_MINUS_1_MASK);
1210 tmp |= nMinus1 << _DMA_CTRL_N_MINUS_1_SHIFT;
1211 tmp |= cycleCtrl << _DMA_CTRL_CYCLE_CTRL_SHIFT;
1227 void DMA_Reset(
void)
1232 NVIC_DisableIRQ(DMA_IRQn);
1235 DMA->CONFIG = _DMA_CONFIG_RESETVALUE;
1236 DMA->CHUSEBURSTC = _DMA_CHUSEBURSTC_MASK;
1237 DMA->CHREQMASKC = _DMA_CHREQMASKC_MASK;
1238 DMA->CHENC = _DMA_CHENC_MASK;
1239 DMA->CHALTC = _DMA_CHALTC_MASK;
1240 DMA->CHPRIC = _DMA_CHPRIC_MASK;
1241 DMA->ERRORC = DMA_ERRORC_ERRORC;
1242 DMA->IEN = _DMA_IEN_RESETVALUE;
1243 DMA->IFC = _DMA_IFC_MASK;
1248 DMA->CH[i].CTRL = _DMA_CH_CTRL_RESETVALUE;
Clock management unit (CMU) API.
Emlib peripheral API "assert" implementation.
RAM and peripheral bit-field set and clear API.
void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable)
Enable/disable a clock.
__STATIC_INLINE void BUS_RegBitWrite(volatile uint32_t *addr, unsigned int bit, unsigned int val)
Perform a single-bit write operation on a peripheral register.
Direct memory access (DMA) API.