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)
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 if (pending & DMA_IF_ERR)
309 pendingPrio = pending & prio;
310 for (i = 0; i < 2; i++)
320 uint32_t chmask = 1 << channel;
329 cb = (DMA_CB_TypeDef *)(descr[channel].USER);
334 primaryCpy = cb->primary;
338 cb->cbFunc(channel, (
bool)primaryCpy, cb->userPtr);
348 pendingPrio = pending & ~prio;
391 void DMA_ActivateAuto(
unsigned int channel,
395 unsigned int nMinus1)
400 EFM_ASSERT(nMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
410 chBit = 1 << channel;
412 DMA->CHSWREQ = chBit;
454 void DMA_ActivateBasic(
unsigned int channel,
459 unsigned int nMinus1)
462 EFM_ASSERT(nMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
473 DMA->CHENS = 1 << channel;
526 void DMA_ActivatePingPong(
unsigned int channel,
530 unsigned int primNMinus1,
533 unsigned int altNMinus1)
536 EFM_ASSERT(primNMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
537 EFM_ASSERT(altNMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
541 dmaCycleCtrlPingPong,
550 dmaCycleCtrlPingPong,
558 DMA->CHENS = 1 << channel;
596 void DMA_ActivateScatterGather(
unsigned int channel,
607 EFM_ASSERT(altDescr);
608 EFM_ASSERT(count && (count <= 256));
616 descr->SRCEND = (uint32_t *)altDescr + (count * 4) - 1;
628 cycleCtrl = altDescr->
CTRL & _DMA_CTRL_CYCLE_CTRL_MASK;
629 cycleCtrl &= ~(1 << _DMA_CTRL_CYCLE_CTRL_SHIFT);
631 EFM_ASSERT((cycleCtrl == dmaCycleCtrlMemScatterGather)
632 || (cycleCtrl == dmaCycleCtrlPerScatterGather));
637 altDescr[count - 1].
CTRL &= ~_DMA_CTRL_CYCLE_CTRL_MASK;
638 if (cycleCtrl == dmaCycleCtrlMemScatterGather)
640 altDescr[count - 1].
CTRL |= (uint32_t)dmaCycleCtrlAuto
641 << _DMA_CTRL_CYCLE_CTRL_SHIFT;
645 altDescr[count - 1].
CTRL |= (uint32_t)dmaCycleCtrlBasic
646 << _DMA_CTRL_CYCLE_CTRL_SHIFT;
653 cb = (DMA_CB_TypeDef *)(descr->USER);
660 descr->
CTRL =((uint32_t)dmaDataInc4 << _DMA_CTRL_DST_INC_SHIFT)
661 | ((uint32_t)dmaDataSize4 << _DMA_CTRL_DST_SIZE_SHIFT)
662 | ((uint32_t)dmaDataInc4 << _DMA_CTRL_SRC_INC_SHIFT)
663 | ((uint32_t)dmaDataSize4 << _DMA_CTRL_SRC_SIZE_SHIFT)
665 | (altDescr->
CTRL & _DMA_CTRL_SRC_PROT_CTRL_MASK)
666 | ((uint32_t)dmaArbitrate4 << _DMA_CTRL_R_POWER_SHIFT)
667 | (((count * 4) - 1) << _DMA_CTRL_N_MINUS_1_SHIFT)
668 | (((uint32_t)useBurst & 1) << _DMA_CTRL_NEXT_USEBURST_SHIFT)
671 chBit = 1 << channel;
681 if (cycleCtrl == dmaCycleCtrlMemScatterGather)
683 DMA->CHSWREQ = chBit;
706 void DMA_CfgChannel(
unsigned int channel, DMA_CfgChannel_TypeDef *cfg)
715 descr[channel].USER = (uint32_t)(cfg->cb);
720 DMA->CHPRIS = 1 << channel;
724 DMA->CHPRIC = 1 << channel;
728 DMA->CH[channel].
CTRL = cfg->select;
733 DMA->IFC = (1 << channel);
781 void DMA_CfgDescr(
unsigned int channel,
783 DMA_CfgDescr_TypeDef *cfg)
803 descr->
CTRL = (cfg->dstInc << _DMA_CTRL_DST_INC_SHIFT)
804 | (cfg->size << _DMA_CTRL_DST_SIZE_SHIFT)
805 | (cfg->srcInc << _DMA_CTRL_SRC_INC_SHIFT)
806 | (cfg->size << _DMA_CTRL_SRC_SIZE_SHIFT)
807 | ((uint32_t)(cfg->hprot) << _DMA_CTRL_SRC_PROT_CTRL_SHIFT)
808 | (cfg->arbRate << _DMA_CTRL_R_POWER_SHIFT)
809 | (0 << _DMA_CTRL_N_MINUS_1_SHIFT)
810 | (0 << _DMA_CTRL_NEXT_USEBURST_SHIFT)
811 | DMA_CTRL_CYCLE_CTRL_INVALID;
815 #if defined( _DMA_LOOP0_MASK ) && defined( _DMA_LOOP1_MASK )
829 void DMA_CfgLoop(
unsigned int channel, DMA_CfgLoop_TypeDef *cfg)
831 EFM_ASSERT(channel <= 1);
832 EFM_ASSERT(cfg->nMinus1 <= 1023);
838 DMA->LOOP0 = (cfg->enable << _DMA_LOOP0_EN_SHIFT)
839 | (cfg->nMinus1 << _DMA_LOOP0_WIDTH_SHIFT);
842 DMA->LOOP1 = (cfg->enable << _DMA_LOOP1_EN_SHIFT)
843 | (cfg->nMinus1 << _DMA_LOOP1_WIDTH_SHIFT);
850 #if defined( _DMA_RECT0_MASK )
860 void DMA_CfgRect(
unsigned int channel, DMA_CfgRect_TypeDef *cfg)
864 EFM_ASSERT(channel == 0);
865 EFM_ASSERT(cfg->dstStride <= 2047);
866 EFM_ASSERT(cfg->srcStride <= 2047);
867 EFM_ASSERT(cfg->height <= 1023);
870 DMA->RECT0 = (cfg->dstStride << _DMA_RECT0_DSTSTRIDE_SHIFT)
871 | (cfg->srcStride << _DMA_RECT0_SRCSTRIDE_SHIFT)
872 | (cfg->height << _DMA_RECT0_HEIGHT_SHIFT);
905 DMA_CfgDescrSGAlt_TypeDef *cfg)
915 if (cfg->srcInc == dmaDataIncNone)
917 descr->SRCEND = cfg->src;
921 descr->SRCEND = (
void *)((uint32_t)(cfg->src)
922 + ((uint32_t)(cfg->nMinus1) << cfg->srcInc));
925 if (cfg->dstInc == dmaDataIncNone)
927 descr->DSTEND = cfg->dst;
931 descr->DSTEND = (
void *)((uint32_t)(cfg->dst)
932 + ((uint32_t)(cfg->nMinus1) << cfg->dstInc));
940 cycleCtrl = (uint32_t)dmaCycleCtrlPerScatterGather + 1;
944 cycleCtrl = (uint32_t)dmaCycleCtrlMemScatterGather + 1;
947 descr->
CTRL =(cfg->dstInc << _DMA_CTRL_DST_INC_SHIFT)
948 | (cfg->size << _DMA_CTRL_DST_SIZE_SHIFT)
949 | (cfg->srcInc << _DMA_CTRL_SRC_INC_SHIFT)
950 | (cfg->size << _DMA_CTRL_SRC_SIZE_SHIFT)
951 | ((uint32_t)(cfg->hprot) << _DMA_CTRL_SRC_PROT_CTRL_SHIFT)
952 | (cfg->arbRate << _DMA_CTRL_R_POWER_SHIFT)
953 | ((uint32_t)(cfg->nMinus1) << _DMA_CTRL_N_MINUS_1_SHIFT)
958 | (0 << _DMA_CTRL_NEXT_USEBURST_SHIFT)
959 | (cycleCtrl << _DMA_CTRL_CYCLE_CTRL_SHIFT);
979 void DMA_ChannelEnable(
unsigned int channel,
bool enable)
985 DMA->CHENS = 1<<channel;
989 DMA->CHENC = 1<<channel;
1008 bool DMA_ChannelEnabled(
unsigned int channel)
1012 return (
bool)((DMA->CHENS >> channel) & 1);
1033 void DMA_Init(DMA_Init_TypeDef *init)
1038 #if (DMA_CHAN_COUNT <= 4)
1039 EFM_ASSERT(!((uint32_t)(init->controlBlock) & (128 - 1)));
1040 #elif (DMA_CHAN_COUNT <= 8) || (DMA_CHAN_COUNT <= 12)
1041 EFM_ASSERT(!((uint32_t)(init->controlBlock) & (256 - 1)));
1043 #error "Unsupported DMA channel count (em_dma.c)."
1053 NVIC_ClearPendingIRQ(DMA_IRQn);
1054 NVIC_EnableIRQ(DMA_IRQn);
1057 DMA->IEN = DMA_IEN_ERR;
1062 DMA->CTRLBASE = (uint32_t)(init->controlBlock);
1065 DMA->CONFIG = ((uint32_t)(init->hprot) << _DMA_CONFIG_CHPROT_SHIFT)
1111 void DMA_RefreshPingPong(
unsigned int channel,
1116 unsigned int nMinus1,
1119 DMA_CycleCtrl_TypeDef cycleCtrl;
1126 EFM_ASSERT(nMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
1131 cycleCtrl = dmaCycleCtrlBasic;
1135 cycleCtrl = dmaCycleCtrlPingPong;
1150 inc = (descr->
CTRL & _DMA_CTRL_SRC_INC_MASK) >> _DMA_CTRL_SRC_INC_SHIFT;
1151 if (inc == _DMA_CTRL_SRC_INC_NONE)
1153 descr->SRCEND = src;
1157 descr->SRCEND = (
void *)((uint32_t)src + (nMinus1 << inc));
1163 inc = (descr->
CTRL & _DMA_CTRL_DST_INC_MASK) >> _DMA_CTRL_DST_INC_SHIFT;
1164 if (inc == _DMA_CTRL_DST_INC_NONE)
1166 descr->DSTEND = dst;
1170 descr->DSTEND = (
void *)((uint32_t)dst + (nMinus1 << inc));
1174 chBit = 1 << channel;
1177 DMA->CHUSEBURSTS = chBit;
1181 DMA->CHUSEBURSTC = chBit;
1185 tmp = descr->
CTRL & ~(_DMA_CTRL_CYCLE_CTRL_MASK | _DMA_CTRL_N_MINUS_1_MASK);
1186 tmp |= nMinus1 << _DMA_CTRL_N_MINUS_1_SHIFT;
1187 tmp |= cycleCtrl << _DMA_CTRL_CYCLE_CTRL_SHIFT;
1203 void DMA_Reset(
void)
1208 NVIC_DisableIRQ(DMA_IRQn);
1211 DMA->CONFIG = _DMA_CONFIG_RESETVALUE;
1212 DMA->CHUSEBURSTC = _DMA_CHUSEBURSTC_MASK;
1213 DMA->CHREQMASKC = _DMA_CHREQMASKC_MASK;
1214 DMA->CHENC = _DMA_CHENC_MASK;
1215 DMA->CHALTC = _DMA_CHALTC_MASK;
1216 DMA->CHPRIC = _DMA_CHPRIC_MASK;
1217 DMA->ERRORC = DMA_ERRORC_ERRORC;
1218 DMA->IEN = _DMA_IEN_RESETVALUE;
1219 DMA->IFC = _DMA_IFC_MASK;
1224 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.