EFR32 Mighty Gecko 13 Software Documentation  efr32mg13-doc-5.1.2
em_dma.c
Go to the documentation of this file.
1 /***************************************************************************/
33 #include "em_dma.h"
34 #if defined( DMA_PRESENT )
35 
36 #include "em_cmu.h"
37 #include "em_assert.h"
38 #include "em_bus.h"
39 
40 /***************************************************************************/
45 /***************************************************************************/
124 /*******************************************************************************
125  ************************** LOCAL FUNCTIONS ********************************
126  ******************************************************************************/
127 
130 /***************************************************************************/
171 static void DMA_Prepare(unsigned int channel,
172  DMA_CycleCtrl_TypeDef cycleCtrl,
173  bool primary,
174  bool useBurst,
175  void *dst,
176  const void *src,
177  unsigned int nMinus1)
178 {
179  DMA_DESCRIPTOR_TypeDef *descr;
180  DMA_DESCRIPTOR_TypeDef *primDescr;
181  DMA_CB_TypeDef *cb;
182  uint32_t inc;
183  uint32_t chBit;
184  uint32_t tmp;
185 
186  primDescr = ((DMA_DESCRIPTOR_TypeDef *)(DMA->CTRLBASE)) + channel;
187 
188  /* Find descriptor to configure */
189  if (primary)
190  {
191  descr = primDescr;
192  }
193  else
194  {
195  descr = ((DMA_DESCRIPTOR_TypeDef *)(DMA->ALTCTRLBASE)) + channel;
196  }
197 
198  /* If callback defined, update info on whether callback is issued */
199  /* for primary or alternate descriptor. Mainly needed for ping-pong */
200  /* cycles. */
201  cb = (DMA_CB_TypeDef *)(primDescr->USER);
202  if (cb)
203  {
204  cb->primary = (uint8_t)primary;
205  }
206 
207  if (src)
208  {
209  inc = (descr->CTRL & _DMA_CTRL_SRC_INC_MASK) >> _DMA_CTRL_SRC_INC_SHIFT;
210  if (inc == _DMA_CTRL_SRC_INC_NONE)
211  {
212  descr->SRCEND = (volatile void*)src;
213  }
214  else
215  {
216  descr->SRCEND = (void *)((uint32_t)src + (nMinus1 << inc));
217  }
218  }
219 
220  if (dst)
221  {
222  inc = (descr->CTRL & _DMA_CTRL_DST_INC_MASK) >> _DMA_CTRL_DST_INC_SHIFT;
223  if (inc == _DMA_CTRL_DST_INC_NONE)
224  {
225  descr->DSTEND = dst;
226  }
227  else
228  {
229  descr->DSTEND = (void *)((uint32_t)dst + (nMinus1 << inc));
230  }
231  }
232 
233  chBit = 1 << channel;
234  if (useBurst)
235  {
236  DMA->CHUSEBURSTS = chBit;
237  }
238  else
239  {
240  DMA->CHUSEBURSTC = chBit;
241  }
242 
243  if (primary)
244  {
245  DMA->CHALTC = chBit;
246  }
247  else
248  {
249  DMA->CHALTS = chBit;
250  }
251 
252  /* Set cycle control */
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;
256  descr->CTRL = tmp;
257 }
258 
261 /*******************************************************************************
262  ************************ INTERRUPT FUNCTIONS ******************************
263  ******************************************************************************/
264 
265 #ifndef EXCLUDE_DEFAULT_DMA_IRQ_HANDLER
266 
267 /***************************************************************************/
284 void DMA_IRQHandler(void)
285 {
286  int channel;
287  DMA_CB_TypeDef *cb;
288  uint32_t pending;
289  uint32_t pendingPrio;
290  uint32_t prio;
291  uint32_t primaryCpy;
292  int i;
293 
294  /* Get all pending and enabled interrupts */
295  pending = DMA->IF;
296  pending &= DMA->IEN;
297 
298  /* Assert on bus error. */
299  EFM_ASSERT(!(pending & DMA_IF_ERR));
300 
301  /* Process all pending channel interrupts. First process channels */
302  /* defined with high priority, then those with default priority. */
303  prio = DMA->CHPRIS;
304  pendingPrio = pending & prio;
305  for (i = 0; i < 2; i++)
306  {
307  channel = 0;
308  /* Process pending interrupts within high/default priority group */
309  /* honouring priority within group. */
310  while (pendingPrio)
311  {
312  if (pendingPrio & 1)
313  {
314  DMA_DESCRIPTOR_TypeDef *descr = (DMA_DESCRIPTOR_TypeDef *)(DMA->CTRLBASE);
315  uint32_t chmask = 1 << channel;
316 
317  /* Clear pending interrupt prior to invoking callback, in case it */
318  /* sets up another DMA cycle. */
319  DMA->IFC = chmask;
320 
321  /* Normally, no point in enabling interrupt without callback, but */
322  /* check if callback is defined anyway. Callback info is always */
323  /* located in primary descriptor. */
324  cb = (DMA_CB_TypeDef *)(descr[channel].USER);
325  if (cb)
326  {
327  /* Toggle next-descriptor indicator always prior to invoking */
328  /* callback (in case callback reconfigurs something) */
329  primaryCpy = cb->primary;
330  cb->primary ^= 1;
331  if (cb->cbFunc)
332  {
333  cb->cbFunc(channel, (bool)primaryCpy, cb->userPtr);
334  }
335  }
336  }
337 
338  pendingPrio >>= 1;
339  channel++;
340  }
341 
342  /* On second iteration, process default priority channels */
343  pendingPrio = pending & ~prio;
344  }
345 }
346 
347 #endif /* EXCLUDE_DEFAULT_DMA_IRQ_HANDLER */
348 
349 
350 /*******************************************************************************
351  ************************** GLOBAL FUNCTIONS *******************************
352  ******************************************************************************/
353 
354 /***************************************************************************/
386 void DMA_ActivateAuto(unsigned int channel,
387  bool primary,
388  void *dst,
389  const void *src,
390  unsigned int nMinus1)
391 {
392  uint32_t chBit;
393 
394  EFM_ASSERT(channel < DMA_CHAN_COUNT);
395  EFM_ASSERT(nMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
396 
397  DMA_Prepare(channel,
398  dmaCycleCtrlAuto,
399  primary,
400  false,
401  dst,
402  src,
403  nMinus1);
404 
405  chBit = 1 << channel;
406  DMA->CHENS = chBit; /* Enable channel */
407  DMA->CHSWREQ = chBit; /* Activate with SW request */
408 }
409 
410 
411 /***************************************************************************/
449 void DMA_ActivateBasic(unsigned int channel,
450  bool primary,
451  bool useBurst,
452  void *dst,
453  const void *src,
454  unsigned int nMinus1)
455 {
456  EFM_ASSERT(channel < DMA_CHAN_COUNT);
457  EFM_ASSERT(nMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
458 
459  DMA_Prepare(channel,
460  dmaCycleCtrlBasic,
461  primary,
462  useBurst,
463  dst,
464  src,
465  nMinus1);
466 
467  /* Enable channel, request signal is provided by peripheral device */
468  DMA->CHENS = 1 << channel;
469 }
470 
471 
472 /***************************************************************************/
521 void DMA_ActivatePingPong(unsigned int channel,
522  bool useBurst,
523  void *primDst,
524  const void *primSrc,
525  unsigned int primNMinus1,
526  void *altDst,
527  const void *altSrc,
528  unsigned int altNMinus1)
529 {
530  EFM_ASSERT(channel < DMA_CHAN_COUNT);
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));
533 
534  /* Prepare alternate descriptor first */
535  DMA_Prepare(channel,
536  dmaCycleCtrlPingPong,
537  false,
538  useBurst,
539  altDst,
540  altSrc,
541  altNMinus1);
542 
543  /* Prepare primary descriptor last in order to start cycle using it */
544  DMA_Prepare(channel,
545  dmaCycleCtrlPingPong,
546  true,
547  useBurst,
548  primDst,
549  primSrc,
550  primNMinus1);
551 
552  /* Enable channel, request signal is provided by peripheral device */
553  DMA->CHENS = 1 << channel;
554 }
555 
556 
557 /***************************************************************************/
591 void DMA_ActivateScatterGather(unsigned int channel,
592  bool useBurst,
593  DMA_DESCRIPTOR_TypeDef *altDescr,
594  unsigned int count)
595 {
596  DMA_DESCRIPTOR_TypeDef *descr;
597  DMA_CB_TypeDef *cb;
598  uint32_t cycleCtrl;
599  uint32_t chBit;
600 
601  EFM_ASSERT(channel < DMA_CHAN_COUNT);
602  EFM_ASSERT(altDescr);
603  EFM_ASSERT(count && (count <= 256));
604 
605  /* We have to configure the primary descriptor properly in order to */
606  /* transfer one complete alternate descriptor from the alternate */
607  /* descriptor table into the actual alternate descriptor. */
608  descr = (DMA_DESCRIPTOR_TypeDef *)(DMA->CTRLBASE) + channel;
609 
610  /* Set source end address to point to alternate descriptor array */
611  descr->SRCEND = (uint32_t *)altDescr + (count * 4) - 1;
612 
613  /* The destination end address in the primary descriptor MUST point */
614  /* to the corresponding alternate descriptor in scatter-gather mode. */
615  descr->DSTEND = (uint32_t *)((DMA_DESCRIPTOR_TypeDef *)(DMA->ALTCTRLBASE) +
616  channel + 1) - 1;
617 
618  /* The user field of the descriptor is used for callback configuration, */
619  /* and already configured when channel is configured. Do not modify it. */
620 
621  /* Determine from alternate configuration whether this is a memory or */
622  /* peripheral scatter-gather, by looking at the first alternate descriptor. */
623  cycleCtrl = altDescr->CTRL & _DMA_CTRL_CYCLE_CTRL_MASK;
624  cycleCtrl &= ~(1 << _DMA_CTRL_CYCLE_CTRL_SHIFT);
625 
626  EFM_ASSERT((cycleCtrl == dmaCycleCtrlMemScatterGather)
627  || (cycleCtrl == dmaCycleCtrlPerScatterGather));
628 
629  /* Set last alternate descriptor to basic or auto-request cycle type in */
630  /* order to have dma_done signal asserted when complete. Otherwise interrupt */
631  /* will not be triggered when done. */
632  altDescr[count - 1].CTRL &= ~_DMA_CTRL_CYCLE_CTRL_MASK;
633  if (cycleCtrl == dmaCycleCtrlMemScatterGather)
634  {
635  altDescr[count - 1].CTRL |= (uint32_t)dmaCycleCtrlAuto
636  << _DMA_CTRL_CYCLE_CTRL_SHIFT;
637  }
638  else
639  {
640  altDescr[count - 1].CTRL |= (uint32_t)dmaCycleCtrlBasic
641  << _DMA_CTRL_CYCLE_CTRL_SHIFT;
642  }
643 
644  /* If callback defined, update info on whether callback is issued for */
645  /* primary or alternate descriptor. Not really useful for scatter-gather, */
646  /* but do for consistency. Always set to alternate, since that is the last */
647  /* descriptor actually used. */
648  cb = (DMA_CB_TypeDef *)(descr->USER);
649  if (cb)
650  {
651  cb->primary = false;
652  }
653 
654  /* Configure primary descriptor control word */
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)
659  /* Use same protection scheme as for alternate descriptors */
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)
664  | cycleCtrl;
665 
666  chBit = 1 << channel;
667 
668  /* Start with primary descriptor */
669  DMA->CHALTC = chBit;
670 
671  /* Enable channel */
672  DMA->CHENS = chBit;
673 
674  /* Send request if memory scatter-gather, otherwise request signal is */
675  /* provided by peripheral. */
676  if (cycleCtrl == dmaCycleCtrlMemScatterGather)
677  {
678  DMA->CHSWREQ = chBit;
679  }
680 }
681 
682 
683 /***************************************************************************/
701 void DMA_CfgChannel(unsigned int channel, DMA_CfgChannel_TypeDef *cfg)
702 {
703  DMA_DESCRIPTOR_TypeDef *descr;
704 
705  EFM_ASSERT(channel < DMA_CHAN_COUNT);
706  EFM_ASSERT(cfg);
707 
708  /* Always keep callback configuration reference in primary descriptor */
709  descr = (DMA_DESCRIPTOR_TypeDef *)(DMA->CTRLBASE);
710  descr[channel].USER = (uint32_t)(cfg->cb);
711 
712  /* Set to specified priority for channel */
713  if (cfg->highPri)
714  {
715  DMA->CHPRIS = 1 << channel;
716  }
717  else
718  {
719  DMA->CHPRIC = 1 << channel;
720  }
721 
722  /* Set DMA signal source select */
723  DMA->CH[channel].CTRL = cfg->select;
724 
725  /* Enable/disable interrupt as specified */
726  if (cfg->enableInt)
727  {
728  DMA->IFC = (1 << channel);
729  BUS_RegBitWrite(&(DMA->IEN), channel, 1);
730  }
731  else
732  {
733  BUS_RegBitWrite(&(DMA->IEN), channel, 0);
734  }
735 }
736 
737 
738 /***************************************************************************/
776 void DMA_CfgDescr(unsigned int channel,
777  bool primary,
778  DMA_CfgDescr_TypeDef *cfg)
779 {
780  DMA_DESCRIPTOR_TypeDef *descr;
781 
782  EFM_ASSERT(channel < DMA_CHAN_COUNT);
783  EFM_ASSERT(cfg);
784 
785  /* Find descriptor to configure */
786  if (primary)
787  {
788  descr = (DMA_DESCRIPTOR_TypeDef *)DMA->CTRLBASE;
789  }
790  else
791  {
792  descr = (DMA_DESCRIPTOR_TypeDef *)DMA->ALTCTRLBASE;
793  }
794  descr += channel;
795 
796  /* Prepare the descriptor */
797  /* Source/destination end addresses set when started */
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) /* Set when activated */
805  | (0 << _DMA_CTRL_NEXT_USEBURST_SHIFT) /* Set when activated */
806  | DMA_CTRL_CYCLE_CTRL_INVALID; /* Set when activated */
807 }
808 
809 
810 #if defined( _DMA_LOOP0_MASK ) && defined( _DMA_LOOP1_MASK )
811 /***************************************************************************/
824 void DMA_CfgLoop(unsigned int channel, DMA_CfgLoop_TypeDef *cfg)
825 {
826  EFM_ASSERT(channel <= 1);
827  EFM_ASSERT(cfg->nMinus1 <= 1023);
828 
829  /* Configure LOOP setting */
830  switch( channel )
831  {
832  case 0:
833  DMA->LOOP0 = (cfg->enable << _DMA_LOOP0_EN_SHIFT)
834  | (cfg->nMinus1 << _DMA_LOOP0_WIDTH_SHIFT);
835  break;
836  case 1:
837  DMA->LOOP1 = (cfg->enable << _DMA_LOOP1_EN_SHIFT)
838  | (cfg->nMinus1 << _DMA_LOOP1_WIDTH_SHIFT);
839  break;
840  }
841 }
842 #endif
843 
844 
845 #if defined( _DMA_RECT0_MASK )
846 /***************************************************************************/
855 void DMA_CfgRect(unsigned int channel, DMA_CfgRect_TypeDef *cfg)
856 {
857  (void)channel; /* Unused parameter */
858 
859  EFM_ASSERT(channel == 0);
860  EFM_ASSERT(cfg->dstStride <= 2047);
861  EFM_ASSERT(cfg->srcStride <= 2047);
862  EFM_ASSERT(cfg->height <= 1023);
863 
864  /* Configure rectangular/2D copy */
865  DMA->RECT0 = (cfg->dstStride << _DMA_RECT0_DSTSTRIDE_SHIFT)
866  | (cfg->srcStride << _DMA_RECT0_SRCSTRIDE_SHIFT)
867  | (cfg->height << _DMA_RECT0_HEIGHT_SHIFT);
868 }
869 #endif
870 
871 
872 /***************************************************************************/
898 void DMA_CfgDescrScatterGather(DMA_DESCRIPTOR_TypeDef *descr,
899  unsigned int indx,
900  DMA_CfgDescrSGAlt_TypeDef *cfg)
901 {
902  uint32_t cycleCtrl;
903 
904  EFM_ASSERT(descr);
905  EFM_ASSERT(cfg);
906 
907  /* Point to selected entry in alternate descriptor table */
908  descr += indx;
909 
910  if (cfg->srcInc == dmaDataIncNone)
911  {
912  descr->SRCEND = cfg->src;
913  }
914  else
915  {
916  descr->SRCEND = (void *)((uint32_t)(cfg->src)
917  + ((uint32_t)(cfg->nMinus1) << cfg->srcInc));
918  }
919 
920  if (cfg->dstInc == dmaDataIncNone)
921  {
922  descr->DSTEND = cfg->dst;
923  }
924  else
925  {
926  descr->DSTEND = (void *)((uint32_t)(cfg->dst)
927  + ((uint32_t)(cfg->nMinus1) << cfg->dstInc));
928  }
929 
930  /* User definable part not used */
931  descr->USER = 0;
932 
933  if (cfg->peripheral)
934  {
935  cycleCtrl = (uint32_t)dmaCycleCtrlPerScatterGather + 1;
936  }
937  else
938  {
939  cycleCtrl = (uint32_t)dmaCycleCtrlMemScatterGather + 1;
940  }
941 
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)
949  /* Never set next useburst bit, since the descriptor used after the */
950  /* alternate descriptor is the primary descriptor which operates on */
951  /* memory. If the alternate descriptors need to have useBurst set, this */
952  /* done when setting up the primary descriptor, ie when activating. */
953  | (0 << _DMA_CTRL_NEXT_USEBURST_SHIFT)
954  | (cycleCtrl << _DMA_CTRL_CYCLE_CTRL_SHIFT);
955 }
956 
957 
958 /***************************************************************************/
974 void DMA_ChannelEnable(unsigned int channel, bool enable)
975 {
976  EFM_ASSERT(channel < DMA_CHAN_COUNT);
977 
978  if (enable)
979  {
980  DMA->CHENS = 1<<channel;
981  }
982  else
983  {
984  DMA->CHENC = 1<<channel;
985  }
986 }
987 
988 
989 /***************************************************************************/
1003 bool DMA_ChannelEnabled(unsigned int channel)
1004 {
1005  EFM_ASSERT(channel < DMA_CHAN_COUNT);
1006 
1007  return (bool)((DMA->CHENS >> channel) & 1);
1008 }
1009 
1010 
1011 /***************************************************************************/
1025 void DMA_ChannelRequestEnable(unsigned int channel, bool enable)
1026 {
1027  EFM_ASSERT(channel < DMA_CHAN_COUNT);
1028 
1029  if (enable)
1030  {
1031  BUS_RegBitWrite (&DMA->CHREQMASKC, channel, 1);
1032  }
1033  else
1034  {
1035  BUS_RegBitWrite (&DMA->CHREQMASKS, channel, 1);
1036  }
1037 }
1038 
1039 
1040 /***************************************************************************/
1057 void DMA_Init(DMA_Init_TypeDef *init)
1058 {
1059  EFM_ASSERT(init);
1060 
1061  /* Make sure control block is properly aligned */
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)));
1066 #else
1067 #error "Unsupported DMA channel count (em_dma.c)."
1068 #endif
1069 
1070  /* Make sure DMA clock is enabled prior to accessing DMA module */
1071  CMU_ClockEnable(cmuClock_DMA, true);
1072 
1073  /* Make sure DMA controller is set to a known reset state */
1074  DMA_Reset();
1075 
1076  /* Clear/enable DMA interrupts */
1077  NVIC_ClearPendingIRQ(DMA_IRQn);
1078  NVIC_EnableIRQ(DMA_IRQn);
1079 
1080  /* Enable bus error interrupt */
1081  DMA->IEN = DMA_IEN_ERR;
1082 
1083  /* Set pointer to control block, notice that this ptr must have been */
1084  /* properly aligned, according to requirements defined in the reference */
1085  /* manual. */
1086  DMA->CTRLBASE = (uint32_t)(init->controlBlock);
1087 
1088  /* Configure and enable the DMA controller */
1089  DMA->CONFIG = ((uint32_t)(init->hprot) << _DMA_CONFIG_CHPROT_SHIFT)
1090  | DMA_CONFIG_EN;
1091 }
1092 
1093 
1094 /***************************************************************************/
1135 void DMA_RefreshPingPong(unsigned int channel,
1136  bool primary,
1137  bool useBurst,
1138  void *dst,
1139  const void *src,
1140  unsigned int nMinus1,
1141  bool stop)
1142 {
1143  DMA_CycleCtrl_TypeDef cycleCtrl;
1144  DMA_DESCRIPTOR_TypeDef *descr;
1145  uint32_t inc;
1146  uint32_t chBit;
1147  uint32_t tmp;
1148 
1149  EFM_ASSERT(channel < DMA_CHAN_COUNT);
1150  EFM_ASSERT(nMinus1 <= (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT));
1151 
1152  /* The ping-pong DMA cycle may be stopped by issuing a basic cycle type */
1153  if (stop)
1154  {
1155  cycleCtrl = dmaCycleCtrlBasic;
1156  }
1157  else
1158  {
1159  cycleCtrl = dmaCycleCtrlPingPong;
1160  }
1161 
1162  /* Find descriptor to configure */
1163  if (primary)
1164  {
1165  descr = ((DMA_DESCRIPTOR_TypeDef *)(DMA->CTRLBASE)) + channel;
1166  }
1167  else
1168  {
1169  descr = ((DMA_DESCRIPTOR_TypeDef *)(DMA->ALTCTRLBASE)) + channel;
1170  }
1171 
1172  if (src)
1173  {
1174  inc = (descr->CTRL & _DMA_CTRL_SRC_INC_MASK) >> _DMA_CTRL_SRC_INC_SHIFT;
1175  if (inc == _DMA_CTRL_SRC_INC_NONE)
1176  {
1177  descr->SRCEND = (volatile void*)src;
1178  }
1179  else
1180  {
1181  descr->SRCEND = (void *)((uint32_t)src + (nMinus1 << inc));
1182  }
1183  }
1184 
1185  if (dst)
1186  {
1187  inc = (descr->CTRL & _DMA_CTRL_DST_INC_MASK) >> _DMA_CTRL_DST_INC_SHIFT;
1188  if (inc == _DMA_CTRL_DST_INC_NONE)
1189  {
1190  descr->DSTEND = dst;
1191  }
1192  else
1193  {
1194  descr->DSTEND = (void *)((uint32_t)dst + (nMinus1 << inc));
1195  }
1196  }
1197 
1198  chBit = 1 << channel;
1199  if (useBurst)
1200  {
1201  DMA->CHUSEBURSTS = chBit;
1202  }
1203  else
1204  {
1205  DMA->CHUSEBURSTC = chBit;
1206  }
1207 
1208  /* Set cycle control */
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;
1212  descr->CTRL = tmp;
1213 }
1214 
1215 
1216 /***************************************************************************/
1227 void DMA_Reset(void)
1228 {
1229  int i;
1230 
1231  /* Disable DMA interrupts */
1232  NVIC_DisableIRQ(DMA_IRQn);
1233 
1234  /* Put the DMA controller into a known state, first disabling it. */
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;
1244 
1245  /* Clear channel control flags */
1246  for (i = 0; i < DMA_CHAN_COUNT; i++)
1247  {
1248  DMA->CH[i].CTRL = _DMA_CH_CTRL_RESETVALUE;
1249  }
1250 }
1251 
1252 
1255 #endif /* defined( DMA_PRESENT ) */
#define DMA_CHAN_COUNT
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.
Definition: em_cmu.c:1453
__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.
Definition: em_bus.h:148
Direct memory access (DMA) API.