25 #if defined( EMDRV_DMADRV_UDMA )
31 #if !defined( EMDRV_DMADRV_DMA_CH_COUNT ) \
32 || ( EMDRV_DMADRV_DMA_CH_COUNT > DMA_CHAN_COUNT )
33 #define EMDRV_DMADRV_DMA_CH_COUNT DMA_CHAN_COUNT
38 dmaDirectionMemToPeripheral,
39 dmaDirectionPeripheralToMem
48 #if defined( EMDRV_DMADRV_USE_NATIVE_API ) && defined( EMDRV_DMADRV_UDMA )
54 #elif defined( EMDRV_DMADRV_USE_NATIVE_API ) && defined( EMDRV_DMADRV_LDMA )
59 unsigned int callbackCount;
68 unsigned int callbackCount;
69 #if defined( EMDRV_DMADRV_UDMA )
73 #if defined( EMDRV_DMADRV_LDMA )
80 static ChTable_t chTable[ EMDRV_DMADRV_DMA_CH_COUNT ];
82 #if defined( EMDRV_DMADRV_UDMA ) && !defined( EMDRV_DMADRV_USE_NATIVE_API )
83 static DMA_CB_TypeDef dmaCallBack[ EMDRV_DMADRV_DMA_CH_COUNT ];
86 #if defined( EMDRV_DMADRV_LDMA ) && !defined( EMDRV_DMADRV_USE_NATIVE_API )
96 static DmaXfer_t dmaXfer[ EMDRV_DMADRV_DMA_CH_COUNT ];
99 #if !defined( EMDRV_DMADRV_USE_NATIVE_API )
100 static Ecode_t StartTransfer( DmaMode_t mode,
101 DmaDirection_t direction,
102 unsigned int channelId,
141 if ( channelId == NULL )
147 for ( i=0; i < EMDRV_DMADRV_DMA_CH_COUNT; i++ )
149 if ( !chTable[ i ].allocated )
152 chTable[ i ].allocated =
true;
153 #if !defined( EMDRV_DMADRV_USE_NATIVE_API ) || defined( EMDRV_DMADRV_LDMA )
154 chTable[ i ].callback = NULL;
184 for ( i=0; i < EMDRV_DMADRV_DMA_CH_COUNT; i++ )
186 if ( chTable[ i ].allocated )
195 #if defined( EMDRV_DMADRV_UDMA )
196 NVIC_DisableIRQ( DMA_IRQn );
197 DMA->IEN = _DMA_IEN_RESETVALUE;
198 DMA->CONFIG = _DMA_CONFIG_RESETVALUE;
200 #elif defined( EMDRV_DMADRV_LDMA )
230 if ( channelId > EMDRV_DMADRV_DMA_CH_COUNT )
236 if ( chTable[ channelId ].allocated )
238 chTable[ channelId ].allocated =
false;
261 #if defined( EMDRV_DMADRV_UDMA )
262 DMA_Init_TypeDef dmaInit;
263 #elif defined( EMDRV_DMADRV_LDMA )
278 if ( EMDRV_DMADRV_DMA_IRQ_PRIORITY > 7 )
283 for ( i=0; i < EMDRV_DMADRV_DMA_CH_COUNT; i++ )
285 chTable[ i ].allocated =
false;
288 #if defined( EMDRV_DMADRV_UDMA )
289 NVIC_SetPriority( DMA_IRQn, EMDRV_DMADRV_DMA_IRQ_PRIORITY );
292 DMA_Init( &dmaInit );
293 #elif defined( EMDRV_DMADRV_LDMA )
301 #if defined( EMDRV_DMADRV_LDMA ) && defined( EMDRV_DMADRV_USE_NATIVE_API )
344 if ( channelId > EMDRV_DMADRV_DMA_CH_COUNT )
349 ch = &chTable[ channelId ];
350 if ( ch->allocated ==
false )
355 ch->callback = callback;
356 ch->userParam = cbUserParam;
357 ch->callbackCount = 0;
364 #if !defined( EMDRV_DMADRV_USE_NATIVE_API ) || defined( DOXY_DOC_ONLY )
413 return StartTransfer( dmaModeBasic,
414 dmaDirectionMemToPeripheral,
428 #if !defined( EMDRV_DMADRV_USE_NATIVE_API ) || defined( DOXY_DOC_ONLY )
470 unsigned int channelId,
482 return StartTransfer( dmaModePingPong,
483 dmaDirectionMemToPeripheral,
497 #if !defined( EMDRV_DMADRV_USE_NATIVE_API ) || defined( DOXY_DOC_ONLY )
546 return StartTransfer( dmaModeBasic,
547 dmaDirectionPeripheralToMem,
561 #if !defined( EMDRV_DMADRV_USE_NATIVE_API ) || defined( DOXY_DOC_ONLY )
603 unsigned int channelId,
615 return StartTransfer( dmaModePingPong,
616 dmaDirectionPeripheralToMem,
648 if ( channelId > EMDRV_DMADRV_DMA_CH_COUNT )
653 if ( chTable[ channelId ].allocated ==
false )
658 #if defined( EMDRV_DMADRV_UDMA )
659 DMA_ChannelEnable( channelId,
false );
660 #elif defined( EMDRV_DMADRV_LDMA )
688 if ( ( channelId > EMDRV_DMADRV_DMA_CH_COUNT )
689 || ( active == NULL ) )
694 if ( chTable[ channelId ].allocated ==
false )
699 #if defined( EMDRV_DMADRV_UDMA )
700 if ( DMA_ChannelEnabled( channelId ) )
701 #elif defined( EMDRV_DMADRV_LDMA )
702 if (
LDMA->CHEN & ( 1 << channelId ) )
740 if ( ( channelId > EMDRV_DMADRV_DMA_CH_COUNT )
741 || ( pending == NULL ) )
746 if ( chTable[ channelId ].allocated ==
false )
751 #if defined( EMDRV_DMADRV_UDMA )
752 if ( DMA->IF & ( 1 << channelId ) )
753 #elif defined( EMDRV_DMADRV_LDMA )
754 if (
LDMA->IF & ( 1 << channelId ) )
788 #if defined( EMDRV_DMADRV_UDMA )
789 uint32_t remaining, iflag;
797 if ( ( channelId > EMDRV_DMADRV_DMA_CH_COUNT )
798 || ( done == NULL ) )
803 if ( chTable[ channelId ].allocated ==
false )
808 #if defined( EMDRV_DMADRV_UDMA )
812 & _DMA_CTRL_N_MINUS_1_MASK )
813 >> _DMA_CTRL_N_MINUS_1_SHIFT;
817 if ( ( remaining == 0 ) && ( iflag & ( 1 << channelId ) ) )
825 #elif defined( EMDRV_DMADRV_LDMA )
855 #if defined( EMDRV_DMADRV_UDMA )
856 uint32_t remain, iflag;
864 if ( ( channelId > EMDRV_DMADRV_DMA_CH_COUNT )
865 || ( remaining == NULL ) )
870 if ( chTable[ channelId ].allocated ==
false )
875 #if defined( EMDRV_DMADRV_UDMA )
879 & _DMA_CTRL_N_MINUS_1_MASK )
880 >> _DMA_CTRL_N_MINUS_1_SHIFT;
884 if ( ( remain == 0 ) && ( iflag & ( 1 << channelId ) ) )
890 *remaining = 1 + remain;
892 #elif defined( EMDRV_DMADRV_LDMA )
901 #if defined( EMDRV_DMADRV_LDMA )
906 void LDMA_IRQHandler(
void )
908 #if !defined( EMDRV_DMADRV_USE_NATIVE_API )
912 uint32_t pending, chnum, chmask;
916 pending &=
LDMA->IEN;
929 for ( chnum = 0, chmask = 1;
930 chnum < EMDRV_DMADRV_DMA_CH_COUNT;
931 chnum++, chmask <<= 1 )
933 if ( pending & chmask )
938 ch = &chTable[ chnum ];
939 if ( ch->callback != NULL )
942 #if defined( EMDRV_DMADRV_USE_NATIVE_API )
943 ch->callback( chnum, ch->callbackCount, ch->userParam );
945 stop = !ch->callback( chnum, ch->callbackCount, ch->userParam );
947 if ( ( ch->mode == dmaModePingPong ) && stop )
949 dmaXfer[ chnum ].desc[0].xfer.link = 0;
950 dmaXfer[ chnum ].desc[1].xfer.link = 0;
959 #if defined( EMDRV_DMADRV_UDMA ) && !defined( EMDRV_DMADRV_USE_NATIVE_API )
964 static void DmaBasicCallback(
unsigned int channel,
bool primary,
void *user )
966 ChTable_t *ch = &chTable[ channel ];
970 if ( ch->callback != NULL )
973 ch->callback( channel, ch->callbackCount, ch->userParam );
978 #if defined( EMDRV_DMADRV_UDMA ) && !defined( EMDRV_DMADRV_USE_NATIVE_API )
983 static void DmaPingPongCallback(
unsigned int channel,
bool primary,
void *user )
986 ChTable_t *ch = &chTable[ channel ];
990 if ( ch->callback != NULL )
993 stop = !ch->callback( channel, ch->callbackCount, ch->userParam );
996 DMA_RefreshPingPong( 0,
1006 #if defined( EMDRV_DMADRV_UDMA ) && !defined( EMDRV_DMADRV_USE_NATIVE_API )
1011 static Ecode_t StartTransfer( DmaMode_t mode,
1012 DmaDirection_t direction,
1013 unsigned int channelId,
1026 DMA_CfgChannel_TypeDef chCfg;
1027 DMA_CfgDescr_TypeDef descrCfg;
1034 if ( ( channelId > EMDRV_DMADRV_DMA_CH_COUNT )
1038 || ( ( mode == dmaModePingPong ) && ( buf2 == NULL ) ) )
1043 ch = &chTable[ channelId ];
1044 if ( ch->allocated ==
false )
1050 if ( mode == dmaModeBasic )
1052 dmaCallBack[ channelId ].cbFunc = DmaBasicCallback;
1056 dmaCallBack[ channelId ].cbFunc = DmaPingPongCallback;
1058 dmaCallBack[ channelId ].userPtr = NULL;
1061 chCfg.highPri =
false;
1064 if ( ( callback != NULL ) || ( mode == dmaModePingPong ) )
1066 chCfg.enableInt =
true;
1070 chCfg.enableInt =
false;
1072 chCfg.select = peripheralSignal;
1073 chCfg.cb = &dmaCallBack[ channelId ];
1074 DMA_CfgChannel( channelId, &chCfg );
1077 if ( direction == dmaDirectionMemToPeripheral )
1083 descrCfg.srcInc = dmaDataInc1;
1087 descrCfg.srcInc = dmaDataInc2;
1091 descrCfg.srcInc = dmaDataInc4;
1096 descrCfg.srcInc = dmaDataIncNone;
1098 descrCfg.dstInc = dmaDataIncNone;
1106 descrCfg.dstInc = dmaDataInc1;
1110 descrCfg.dstInc = dmaDataInc2;
1114 descrCfg.dstInc = dmaDataInc4;
1119 descrCfg.dstInc = dmaDataIncNone;
1121 descrCfg.srcInc = dmaDataIncNone;
1123 descrCfg.size = (DMA_DataSize_TypeDef)size;
1124 descrCfg.arbRate = dmaArbitrate1;
1126 DMA_CfgDescr( channelId,
true, &descrCfg );
1127 if ( mode == dmaModePingPong )
1129 DMA_CfgDescr( channelId,
false, &descrCfg );
1132 ch->callback = callback;
1133 ch->userParam = cbUserParam;
1134 ch->callbackCount = 0;
1137 DMA->IFC = 1 << channelId;
1140 if ( mode == dmaModeBasic )
1142 DMA_ActivateBasic( channelId,
true,
false, buf0, buf1, len - 1 );
1146 if ( direction == dmaDirectionMemToPeripheral )
1148 DMA_ActivatePingPong( channelId,
1159 DMA_ActivatePingPong( channelId,
1174 #if defined( EMDRV_DMADRV_LDMA ) && !defined( EMDRV_DMADRV_USE_NATIVE_API )
1179 static Ecode_t StartTransfer( DmaMode_t mode,
1180 DmaDirection_t direction,
1181 unsigned int channelId,
1202 if ( ( channelId > EMDRV_DMADRV_DMA_CH_COUNT )
1206 || ( ( mode == dmaModePingPong ) && ( buf2 == NULL ) ) )
1211 ch = &chTable[ channelId ];
1212 if ( ch->allocated ==
false )
1218 desc = &dmaXfer[ channelId ].desc[0];
1220 if ( direction == dmaDirectionMemToPeripheral )
1242 if ( mode == dmaModePingPong )
1249 dmaXfer[ channelId ].desc[1] = *desc;
1252 dmaXfer[ channelId ].desc[1].xfer.srcAddr = (uint32_t)buf2;
1254 if ( direction == dmaDirectionPeripheralToMem )
1256 dmaXfer[ channelId ].desc[1].xfer.dstAddr = (uint32_t)buf1;
1262 if ( ( callback == NULL ) && ( mode == dmaModeBasic ) )
1267 ch->callback = callback;
1268 ch->userParam = cbUserParam;
1269 ch->callbackCount = 0;
Clock management unit (CMU) API.
DMA transfer configuration structure.
uint32_t LDMA_TransferRemainingCount(int ch)
Get number of items remaining in a transfer.
Ecode_t DMADRV_PeripheralMemory(unsigned int channelId, DMADRV_PeripheralSignal_t peripheralSignal, void *dst, void *src, bool dstInc, int len, DMADRV_DataSize_t size, DMADRV_Callback_t callback, void *cbUserParam)
Start a peripheral to memory DMA transfer.
#define LDMA_INIT_DEFAULT
Default DMA initialization structure.
#define LDMA_TRANSFER_CFG_PERIPHERAL(signal)
Generic DMA transfer configuration for memory to/from peripheral transfers.
Ecode_t DMADRV_TransferActive(unsigned int channelId, bool *active)
Check if a transfer is running.
bool(* DMADRV_Callback_t)(unsigned int channel, unsigned int sequenceNo, void *userParam)
DMADRV transfer completion callback function.
__STATIC_INLINE uint32_t INT_Enable(void)
Enable interrupts.
Ecode_t DMADRV_StopTransfer(unsigned int channelId)
Stop an ongoing DMA transfer.
#define ECODE_EMDRV_DMADRV_NOT_INITIALIZED
DMA is not initialized.
CMSIS Cortex-M Peripheral Access Layer for Silicon Laboratories microcontroller devices.
DMADRV_DataSize_t
Data size of one LDMA transfer item.
#define ECODE_EMDRV_DMADRV_ALREADY_FREED
DMA channel was free.
Ecode_t DMADRV_TransferDone(unsigned int channelId, bool *done)
Check if a transfer has completed.
void LDMA_StopTransfer(int ch)
Stop a DMA transfer.
void LDMA_Init(LDMA_Init_t *init)
Initialize the LDMA controller.
Ecode_t DMADRV_TransferRemainingCount(unsigned int channelId, int *remaining)
Get number of items remaining in a transfer.
struct LDMA_Descriptor_t::@1 xfer
Interrupt enable/disable unit API.
Ecode_t DMADRV_LdmaStartTransfer(int channelId, LDMA_TransferCfg_t *transfer, LDMA_Descriptor_t *descriptor, DMADRV_Callback_t callback, void *cbUserParam)
Start a LDMA transfer.
#define ECODE_EMDRV_DMADRV_CH_NOT_ALLOCATED
The channel is not reserved.
void LDMA_DeInit(void)
De-initialize the LDMA controller.
#define ECODE_EMDRV_DMADRV_CHANNELS_EXHAUSTED
No DMA channels available.
Ecode_t DMADRV_MemoryPeripheralPingPong(unsigned int channelId, DMADRV_PeripheralSignal_t peripheralSignal, void *dst, void *src0, void *src1, bool srcInc, int len, DMADRV_DataSize_t size, DMADRV_Callback_t callback, void *cbUserParam)
Start a memory to peripheral ping-pong DMA transfer.
DMA_DESCRIPTOR_TypeDef dmaControlBlock[DMACTRL_CH_CNT *2]
#define DMADRV_MAX_XFER_COUNT
Maximum length of one DMA transfer.
#define LDMA_DESCRIPTOR_SINGLE_P2M_BYTE(src, dest, count)
DMA descriptor initializer for byte transfers from a peripheral to memory.
void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable)
Enable/disable a clock.
Ecode_t DMADRV_Init(void)
Initialize DMADRV.
bool LDMA_TransferDone(int ch)
Check if a DMA transfer has completed.
#define ECODE_EMDRV_DMADRV_OK
Success return value.
Ecode_t DMADRV_DeInit(void)
Deinitialize DMADRV.
LDMA initialization configuration structure.
#define ECODE_EMDRV_DMADRV_IN_USE
DMA is in use.
Ecode_t DMADRV_AllocateChannel(unsigned int *channelId, void *capabilities)
Allocate (reserve) a DMA channel.
uint8_t ldmaInitCtrlNumFixed
#define ECODE_EMDRV_DMADRV_ALREADY_INITIALIZED
DMA has already been initialized.
Ecode_t DMADRV_MemoryPeripheral(unsigned int channelId, DMADRV_PeripheralSignal_t peripheralSignal, void *dst, void *src, bool srcInc, int len, DMADRV_DataSize_t size, DMADRV_Callback_t callback, void *cbUserParam)
Start a memory to peripheral DMA transfer.
uint8_t ldmaInitIrqPriority
#define ECODE_EMDRV_DMADRV_PARAM_ERROR
Illegal input parameter.
DMADRV_PeripheralSignal_t
Peripherals that can trigger LDMA transfers.
uint32_t Ecode_t
Typedef for API function errorcode return values.
Ecode_t DMADRV_TransferCompletePending(unsigned int channelId, bool *pending)
Check if a transfer complete is pending.
__STATIC_INLINE uint32_t INT_Disable(void)
Disable interrupts.
void LDMA_StartTransfer(int ch, LDMA_TransferCfg_t *transfer, LDMA_Descriptor_t *descriptor)
Start a DMA transfer.
#define LDMA_DESCRIPTOR_SINGLE_M2P_BYTE(src, dest, count)
DMA descriptor initializer for byte transfers from memory to a peripheral.
Ecode_t DMADRV_PeripheralMemoryPingPong(unsigned int channelId, DMADRV_PeripheralSignal_t peripheralSignal, void *dst0, void *dst1, void *src, bool dstInc, int len, DMADRV_DataSize_t size, DMADRV_Callback_t callback, void *cbUserParam)
Start a peripheral to memory ping-pong DMA transfer.
Ecode_t DMADRV_FreeChannel(unsigned int channelId)
Free an allocate (reserved) DMA channel.