void setupDMAInput( void ) { cbADC.cbFunc = adcCb; cbADC.userPtr = NULL; DMA_CfgChannel_TypeDef chnlCfg; chnlCfg.highPri = true; chnlCfg.enableInt = true; chnlCfg.select = DMAREQ_ADC0_SCAN; chnlCfg.cb = &cbADC; DMA_CfgChannel(DMA_CHANNEL_ADC, &chnlCfg); DMA_CfgDescr_TypeDef descrCfg; descrCfg.dstInc = dmaDataInc2; descrCfg.srcInc = dmaDataIncNone; descrCfg.size = dmaDataSize2; descrCfg.hprot = 0; DMA_CfgDescr(DMA_CHANNEL_ADC, true, &descrCfg); DMA_CfgDescr(DMA_CHANNEL_ADC, false, &descrCfg); DMA_ActivatePingPong(DMA_CHANNEL_ADC, false, sourceP, (void*)((uint32_t) &(ADC0->SCANDATA)), N - 1, sourceS, (void*)((uint32_t) &(ADC0->SCANDATA)), N - 1); bufferPrimary = true; }
/***************************************************************************//** * @brief * Configure ADC and DMA for this application. *******************************************************************************/ static void guitarADCConfig(void) { DMA_CfgDescr_TypeDef descrCfg; DMA_CfgChannel_TypeDef chnlCfg; ADC_Init_TypeDef init = ADC_INIT_DEFAULT; ADC_InitScan_TypeDef scanInit = ADC_INITSCAN_DEFAULT; /* Configure DMA usage by ADC */ cbInData.cbFunc = guitarDMAInCb; cbInData.userPtr = NULL; /* Set up high pri channel with callback with request from ADC scan complete. */ chnlCfg.highPri = true; chnlCfg.enableInt = true; chnlCfg.select = DMAREQ_ADC0_SCAN; chnlCfg.cb = &cbInData; DMA_CfgChannel(GUITAR_DMA_AUDIO_IN, &chnlCfg); /* Configure datasize, increment and primary, alternate structure for pingpong. */ descrCfg.dstInc = dmaDataInc2; descrCfg.srcInc = dmaDataIncNone; descrCfg.size = dmaDataSize2; descrCfg.arbRate = dmaArbitrate1; descrCfg.hprot = 0; DMA_CfgDescr(GUITAR_DMA_AUDIO_IN, true, &descrCfg); DMA_CfgDescr(GUITAR_DMA_AUDIO_IN, false, &descrCfg); DMA_ActivatePingPong(GUITAR_DMA_AUDIO_IN, false, guitarAudioInBuffer1, (void *)((uint32_t) &(ADC0->SCANDATA)), (GUITAR_AUDIO_BUFFER_SAMPLES * 2) - 1, guitarAudioInBuffer2, (void *)((uint32_t) &(ADC0->SCANDATA)), (GUITAR_AUDIO_BUFFER_SAMPLES * 2) - 1); /* Configure ADC */ /* Keep warm due to "high" frequency sampling */ init.warmUpMode = adcWarmupKeepADCWarm; /* Init common issues for both single conversion and scan mode */ /* 0 means, figure out the base frequency based on current cmu config. */ init.timebase = ADC_TimebaseCalc(0); /* Calculate necessary prescaler to get 4MHz adc clock with current cmu configuration. */ init.prescale = ADC_PrescaleCalc(4000000, 0); /* Sample potentiometer by tailgating in order to not disturb fixed rate */ /* audio sampling. */ init.tailgate = true; ADC_Init(ADC0, &init); /* Init for scan sequence use (audio in right/left channels). */ scanInit.prsSel = adcPRSSELCh0; scanInit.prsEnable = true; scanInit.reference = adcRefVDD; scanInit.input = ADC_SCANCTRL_INPUTMASK_CH6 | ADC_SCANCTRL_INPUTMASK_CH7; ADC_InitScan(ADC0, &scanInit); }
static void ADCConfig(void) { DMA_CfgDescr_TypeDef descrCfg; DMA_CfgChannel_TypeDef chnlCfg; ADC_Init_TypeDef init = ADC_INIT_DEFAULT; ADC_InitScan_TypeDef scanInit = ADC_INITSCAN_DEFAULT; /* Configure DMA usage by ADC */ cbInData.cbFunc = adcCb; cbInData.userPtr = NULL; chnlCfg.highPri = true; chnlCfg.enableInt = true; chnlCfg.select = DMAREQ_ADC0_SCAN; chnlCfg.cb = &cbInData; DMA_CfgChannel(DMA_CHANNEL_ADC, &chnlCfg); descrCfg.dstInc = dmaDataInc2; descrCfg.srcInc = dmaDataIncNone; descrCfg.size = dmaDataSize2; descrCfg.arbRate = dmaArbitrate1; descrCfg.hprot = 0; DMA_CfgDescr(DMA_CHANNEL_ADC, true, &descrCfg); DMA_CfgDescr(DMA_CHANNEL_ADC, false, &descrCfg); DMA_ActivatePingPong(DMA_CHANNEL_ADC, false, sourceP, (void *)((uint32_t) &(ADC0->SCANDATA)), N - 1, sourceS, (void *)((uint32_t) &(ADC0->SCANDATA)), N - 1); /* Indicate starting with primary in-buffer (according to above DMA setup) */ bufferPrimary = true; /* Configure ADC */ /* Keep warm due to "high" frequency sampling */ init.warmUpMode = adcWarmupKeepADCWarm; /* Init common issues for both single conversion and scan mode */ init.timebase = ADC_TimebaseCalc(0); init.prescale = ADC_PrescaleCalc(4000000, 0); /* Sample potentiometer by tailgating in order to not disturb fixed rate */ /* audio sampling. */ init.tailgate = true; ADC_Init(ADC0, &init); /* Init for scan sequence use (audio in right/left channels). */ scanInit.prsSel = adcPRSSELCh0; scanInit.prsEnable = true; scanInit.reference = adcRefVDD; scanInit.input = ADC_SCANCTRL_INPUTMASK_CH6 | ADC_SCANCTRL_INPUTMASK_CH7; ADC_InitScan(ADC0, &scanInit); }
static void DACConfig(void) { DMA_CfgDescr_TypeDef descrCfg; DMA_CfgChannel_TypeDef chnlCfg; DAC_Init_TypeDef dacInit = DAC_INIT_DEFAULT; DAC_InitChannel_TypeDef dacChInit = DAC_INITCHANNEL_DEFAULT; /* Notice: Audio out buffers are by default filled with 0, since */ /* uninitialized data; no need to clear explicitly. */ /* Configure DAC */ /* Init common DAC issues */ dacInit.reference = dacRefVDD; DAC_Init(DAC0, &dacInit); /* Start with "no" signal out */ DAC0->COMBDATA = 0x0; /* Init channels, equal config for both channels. */ dacChInit.enable = true; dacChInit.prsSel = dacPRSSELCh0; dacChInit.prsEnable = true; DAC_InitChannel(DAC0, &dacChInit, 0); /* Right channel */ DAC_InitChannel(DAC0, &dacChInit, 1); /* Left channel */ /* Configure DMA usage by DAC */ cbOutData.cbFunc = dacCb; cbOutData.userPtr = NULL; chnlCfg.highPri = true; chnlCfg.enableInt = true; chnlCfg.select = DMAREQ_DAC0_CH0; chnlCfg.cb = &cbOutData; DMA_CfgChannel(DMA_CHANNEL_DAC, &chnlCfg); descrCfg.dstInc = dmaDataIncNone; descrCfg.srcInc = dmaDataInc4; descrCfg.size = dmaDataSize4; descrCfg.arbRate = dmaArbitrate1; descrCfg.hprot = 0; DMA_CfgDescr(DMA_CHANNEL_DAC, true, &descrCfg); DMA_CfgDescr(DMA_CHANNEL_DAC, false, &descrCfg); DMA_ActivatePingPong(DMA_CHANNEL_DAC, false, (void *)((uint32_t) &(DAC0->COMBDATA)), sourceP, N - 1, (void *)((uint32_t) &(DAC0->COMBDATA)), sourceS, N - 1); }
/**************************************************************************//** * @brief Configure DMA in basic mode for both TX and RX to/from USART *****************************************************************************/ void setupDma(void) { /* Initialization structs */ DMA_Init_TypeDef dmaInit; DMA_CfgChannel_TypeDef rxChnlCfg; DMA_CfgDescr_TypeDef rxDescrCfg; DMA_CfgChannel_TypeDef txChnlCfg; DMA_CfgDescr_TypeDef txDescrCfg; /* Initializing the DMA */ dmaInit.hprot = 0; dmaInit.controlBlock = dmaControlBlock; DMA_Init(&dmaInit); /* Setup call-back function */ dmaCallbackSpi.cbFunc = transferComplete; dmaCallbackSpi.userPtr = NULL; /*** Setting up RX DMA ***/ /* Setting up channel */ rxChnlCfg.highPri = false; rxChnlCfg.enableInt = true; rxChnlCfg.select = DMAREQ_USART1_RXDATAV; rxChnlCfg.cb = &dmaCallbackSpi; DMA_CfgChannel(DMA_CHANNEL_RX, &rxChnlCfg); /* Setting up channel descriptor */ rxDescrCfg.dstInc = dmaDataInc1; rxDescrCfg.srcInc = dmaDataIncNone; rxDescrCfg.size = dmaDataSize1; rxDescrCfg.arbRate = dmaArbitrate1; rxDescrCfg.hprot = 0; DMA_CfgDescr(DMA_CHANNEL_RX, true, &rxDescrCfg); /*** Setting up TX DMA ***/ /* Setting up channel */ txChnlCfg.highPri = false; txChnlCfg.enableInt = true; txChnlCfg.select = DMAREQ_USART1_TXBL; txChnlCfg.cb = &dmaCallbackSpi; DMA_CfgChannel(DMA_CHANNEL_TX, &txChnlCfg); /* Setting up channel descriptor */ txDescrCfg.dstInc = dmaDataIncNone; txDescrCfg.srcInc = dmaDataInc1; txDescrCfg.size = dmaDataSize1; txDescrCfg.arbRate = dmaArbitrate1; txDescrCfg.hprot = 0; DMA_CfgDescr(DMA_CHANNEL_TX, true, &txDescrCfg); }
/***************************************************************************** * @brief Configure DMA to send and receive over I2C *****************************************************************************/ void dmaInit(void) { CMU_ClockEnable(cmuClock_DMA, true); DMA_Init_TypeDef dmaInit; DMA_CfgChannel_TypeDef txChannelConfig; DMA_CfgDescr_TypeDef txDescriptorConfig; DMA_CfgChannel_TypeDef rxChannelConfig; DMA_CfgDescr_TypeDef rxDescriptorConfig; /* Initializing the DMA */ dmaInit.hprot = 0; dmaInit.controlBlock = dmaControlBlock; DMA_Init(&dmaInit); /* Setup call-back function */ dmaCallback.cbFunc = transferComplete; dmaCallback.userPtr = NULL; /* Setting up TX channel */ txChannelConfig.highPri = false; txChannelConfig.enableInt = true; txChannelConfig.select = DMAREQ_I2C0_TXBL; txChannelConfig.cb = &dmaCallback; DMA_CfgChannel(DMA_CHANNEL_I2C_TX, &txChannelConfig); /* Setting up TX channel descriptor */ txDescriptorConfig.dstInc = dmaDataIncNone; txDescriptorConfig.srcInc = dmaDataInc1; txDescriptorConfig.size = dmaDataSize1; txDescriptorConfig.arbRate = dmaArbitrate1; txDescriptorConfig.hprot = 0; DMA_CfgDescr(DMA_CHANNEL_I2C_TX, true, &txDescriptorConfig); /* Setting up RX channel */ rxChannelConfig.highPri = false; rxChannelConfig.enableInt = true; rxChannelConfig.select = DMAREQ_I2C0_RXDATAV; rxChannelConfig.cb = &dmaCallback; DMA_CfgChannel(DMA_CHANNEL_I2C_RX, &rxChannelConfig); /* Setting up RX channel descriptor */ rxDescriptorConfig.dstInc = dmaDataInc1; rxDescriptorConfig.srcInc = dmaDataIncNone; rxDescriptorConfig.size = dmaDataSize1; rxDescriptorConfig.arbRate = dmaArbitrate1; rxDescriptorConfig.hprot = 0; DMA_CfgDescr(DMA_CHANNEL_I2C_RX, true, &rxDescriptorConfig); }
/***************************************************************************//** * @brief * Configure DMA usage for this application. *******************************************************************************/ static void accelDMAConfig(void) { DMA_Init_TypeDef dmaInit; DMA_CfgDescr_TypeDef descrCfg; DMA_CfgChannel_TypeDef chnlCfg; /* Configure general DMA issues */ dmaInit.hprot = 0; dmaInit.controlBlock = dmaControlBlock; DMA_Init(&dmaInit); /* Configure DMA channel used */ chnlCfg.highPri = false; chnlCfg.enableInt = false; chnlCfg.select = DMAREQ_ADC0_SCAN; chnlCfg.cb = NULL; DMA_CfgChannel(ACCEL_DMA_CHANNEL, &chnlCfg); descrCfg.dstInc = dmaDataInc4; descrCfg.srcInc = dmaDataIncNone; descrCfg.size = dmaDataSize4; descrCfg.arbRate = dmaArbitrate1; descrCfg.hprot = 0; DMA_CfgDescr(ACCEL_DMA_CHANNEL, true, &descrCfg); }
extern void DMA_enter_DefaultMode_from_RESET(void) { DMA_Init_TypeDef dmaInit; DMA_CfgDescr_TypeDef descrCfg; DMA_CfgChannel_TypeDef chnlCfg; /* DMA控制器配置 */ dmaInit.hprot = 0; dmaInit.controlBlock = dmaControlBlock; DMA_Init(&dmaInit); /* DMA通道配置 */ chnlCfg.highPri = false; chnlCfg.enableInt = false; chnlCfg.select = DMAREQ_ADC0_SCAN; chnlCfg.cb = NULL; DMA_CfgChannel(DMA_CHANNEL, &chnlCfg); /* DMA通道描述符配置 */ descrCfg.dstInc = dmaDataInc4; descrCfg.srcInc = dmaDataIncNone; descrCfg.size = dmaDataSize4; descrCfg.arbRate = dmaArbitrate1; descrCfg.hprot = 0; DMA_CfgDescr(DMA_CHANNEL, true, &descrCfg); }
void usart2_dma_init(void) { /* Initialization structs */ DMA_CfgChannel_TypeDef rxChnlCfg; DMA_CfgDescr_TypeDef rxDescrCfg; DMA_CfgChannel_TypeDef txChnlCfg; DMA_CfgDescr_TypeDef txDescrCfg; /* Setup call-back function */ cb.cbFunc = &transferComplete; cb.userPtr = NULL; /*** Setting up RX DMA ***/ /* Setting up channel */ rxChnlCfg.highPri = false; rxChnlCfg.enableInt = true; rxChnlCfg.select = DMAREQ_USART2_RXDATAV; rxChnlCfg.cb = &cb; DMA_CfgChannel(DMA_CHANNEL_RX, &rxChnlCfg); /* Setting up channel descriptor */ rxDescrCfg.dstInc = dmaDataInc1; rxDescrCfg.srcInc = dmaDataIncNone; rxDescrCfg.size = dmaDataSize1; rxDescrCfg.arbRate = dmaArbitrate1; rxDescrCfg.hprot = 0; DMA_CfgDescr(DMA_CHANNEL_RX, true, &rxDescrCfg); /*** Setting up TX DMA ***/ /* Setting up channel */ txChnlCfg.highPri = false; txChnlCfg.enableInt = true; txChnlCfg.select = DMAREQ_USART2_TXBL; txChnlCfg.cb = &cb; DMA_CfgChannel(DMA_CHANNEL_TX, &txChnlCfg); /* Setting up channel descriptor */ txDescrCfg.dstInc = dmaDataIncNone; txDescrCfg.srcInc = dmaDataIncNone; txDescrCfg.size = dmaDataSize1; txDescrCfg.arbRate = dmaArbitrate1; txDescrCfg.hprot = 0; DMA_CfgDescr(DMA_CHANNEL_TX, true, &txDescrCfg); }
/** * Configure DMA to send part of, or the entire frame buffer over SPI * to the memory LCD. Rectangle copy is used because it can transfer * the entire frame in one DMA cycle. * (In addition, the extra padding bits needed because emWin v5.16 does * not handle a 144 px width correctly are skipped by rectangle copy * by setting the width to 144 px and stride to 160 px.) */ void configRectangleCopy(USART_TypeDef *usart) { DMA_CfgChannel_TypeDef channelConfig; DMA_CfgDescr_TypeDef descriptorConfig; /* Setting callback function */ dmaCallback.cbFunc = transferComplete; dmaCallback.userPtr = NULL; /* Setting up channel */ channelConfig.highPri = false; /* No high priority */ channelConfig.enableInt = true; /* Enable interrupt */ /* Select USARTx peripheral */ if ( usart == USART0 ) { channelConfig.select = DMAREQ_USART0_TXBL; } else if ( usart == USART1 ) { channelConfig.select = DMAREQ_USART1_TXBL; } else if ( usart == USART2 ) { channelConfig.select = DMAREQ_USART2_TXBL; } channelConfig.cb = &dmaCallback; /* Callback routine */ DMA_CfgChannel(DMA_CHANNEL, &channelConfig); /* Configure descriptor */ descriptorConfig.dstInc = dmaDataIncNone; /* Do not increase destination */ descriptorConfig.srcInc = dmaDataInc2; /* Increase source by 2 bytes */ descriptorConfig.size = dmaDataSize2; /* Element size is 2 bytes */ descriptorConfig.arbRate = dmaArbitrate1; /* Arbiratrate after each transfer */ descriptorConfig.hprot = 0; /* Non-privileged access */ /* Configure the LOOP0 register for 2D copy */ DMA_CfgLoop_TypeDef loopConfig; loopConfig.enable = false; loopConfig.nMinus1 = FRAME_BUFFER_WIDTH/16-1; /* Number of elements (-1) to transfer */ DMA_CfgLoop(DMA_CHANNEL, &loopConfig); /* Configure the RECT0 register for 2D copy */ DMA_CfgRect_TypeDef rectConfig; rectConfig.dstStride = 0; rectConfig.srcStride = FRAME_BUFFER_STRIDE / 8; /* Width of the total frame buffer, in bytes */ rectConfig.height = 128; DMA_CfgRect(DMA_CHANNEL, &rectConfig); /* Create the descriptor */ DMA_CfgDescr(DMA_CHANNEL, true, &descriptorConfig); }
/**************************************************************************//** * @brief Flash transfer function * This function sets up the DMA transfer *****************************************************************************/ void performFlashTransfer(void) { /* Setting call-back function */ DMA_CB_TypeDef cb[DMA_CHAN_COUNT]; cb[DMA_CHANNEL_FLASH].cbFunc = flashTransferComplete; /* usrPtr can be used to send data to the callback function, * but this is not used here, which is indicated by the NULL pointer */ cb[DMA_CHANNEL_FLASH].userPtr = NULL; /* Setting up channel */ DMA_CfgChannel_TypeDef chnlCfg; chnlCfg.highPri = false; chnlCfg.enableInt = true; chnlCfg.select = 0; chnlCfg.cb = &(cb[DMA_CHANNEL_FLASH]); DMA_CfgChannel(DMA_CHANNEL_FLASH, &chnlCfg); /* Setting up channel descriptor */ DMA_CfgDescr_TypeDef descrCfg; descrCfg.dstInc = dmaDataInc1; descrCfg.srcInc = dmaDataInc1; descrCfg.size = dmaDataSize1; descrCfg.arbRate = dmaArbitrate1; descrCfg.hprot = 0; DMA_CfgDescr(DMA_CHANNEL_FLASH, true, &descrCfg); /* Setting flag to indicate that transfer is in progress * will be cleared by call-back function */ flashTransferActive = true; DMA_ActivateBasic(DMA_CHANNEL_FLASH, true, false, (void *) &ramBuffer, (void *) &flashData, FLASHDATA_SIZE - 1); /* Entering EM1 to wait for completion (the DMA requires EM1) */ while (flashTransferActive) { EMU_EnterEM1(); } }
/**************************************************************************//** * @brief Configure DMA for ADC RAM Transfer *****************************************************************************/ void setupDma(void) { DMA_Init_TypeDef dmaInit; DMA_CfgChannel_TypeDef chnlCfg; DMA_CfgDescr_TypeDef descrCfg; /* Initializing the DMA */ dmaInit.hprot = 0; dmaInit.controlBlock = dmaControlBlock; DMA_Init(&dmaInit); /* Setting up call-back function */ cb.cbFunc = transferComplete; cb.userPtr = NULL; /* Setting up channel */ chnlCfg.highPri = false; chnlCfg.enableInt = true; chnlCfg.select = DMAREQ_ADC0_SINGLE; chnlCfg.cb = &cb; DMA_CfgChannel(DMA_CHANNEL_ADC, &chnlCfg); /* Setting up channel descriptor */ descrCfg.dstInc = dmaDataInc2; descrCfg.srcInc = dmaDataIncNone; descrCfg.size = dmaDataSize2; descrCfg.arbRate = dmaArbitrate1; descrCfg.hprot = 0; DMA_CfgDescr(DMA_CHANNEL_ADC, true, &descrCfg); /* Setting flag to indicate that transfer is in progress * will be cleared by call-back function. */ transferActive = true; /* Starting transfer. Using Basic since every transfer must be initiated * by the ADC. */ DMA_ActivateBasic(DMA_CHANNEL_ADC, true, false, (void *)ramBufferAdcData, (void *)&(ADC0->SINGLEDATA), ADCSAMPLES - 1); }
/***************************************************************************//** * @brief * Initialize the specified USART unit * * @details * * @note * * @param[in] device * Pointer to device descriptor * * @param[in] unitNumber * Unit number * * @param[in] location * Pin location number * * @param[in] flag * Configuration flag * * @param[in] dmaChannel * DMA channel number for TX * * @param[in] console * Indicate if using as console * * @return * Pointer to USART device ******************************************************************************/ static struct efm32_usart_device_t *rt_hw_usart_unit_init( rt_device_t device, rt_uint8_t unitNumber, rt_uint8_t location, rt_uint32_t flag, rt_uint32_t dmaChannel, rt_uint8_t config) { struct efm32_usart_device_t *usart; struct efm32_usart_dma_mode_t *dma_mode; DMA_CB_TypeDef *callback; CMU_Clock_TypeDef usartClock; rt_uint32_t txDmaSelect; GPIO_Port_TypeDef port_tx, port_rx, port_clk, port_cs; rt_uint32_t pin_tx, pin_rx, pin_clk, pin_cs; efm32_irq_hook_init_t hook; do { /* Allocate device */ usart = rt_malloc(sizeof(struct efm32_usart_device_t)); if (usart == RT_NULL) { usart_debug("USART%d err: no mem\n", usart->unit); break; } usart->counter = 0; usart->unit = unitNumber; usart->state = config; usart->tx_mode = RT_NULL; usart->rx_mode = RT_NULL; /* Allocate TX */ dma_mode = RT_NULL; if (flag & RT_DEVICE_FLAG_DMA_TX) { usart->tx_mode = dma_mode = rt_malloc(sizeof(struct efm32_usart_dma_mode_t)); if (dma_mode == RT_NULL) { usart_debug("USART%d err: no mem for DMA TX\n", usart->unit); break; } dma_mode->dma_channel = dmaChannel; } /* Allocate RX */ if (flag & RT_DEVICE_FLAG_INT_RX) { usart->rx_mode = rt_malloc(sizeof(struct efm32_usart_int_mode_t)); if (usart->rx_mode == RT_NULL) { usart_debug("USART%d err: no mem for INT RX\n", usart->unit); break; } } /* Initialization */ #if defined(UART_PRESENT) if ((!(config & USART_STATE_ASYNC_ONLY) && (unitNumber >= USART_COUNT)) || \ ((config & USART_STATE_ASYNC_ONLY) && (unitNumber >= UART_COUNT))) #else if (unitNumber >= USART_COUNT) #endif { break; } switch (unitNumber) { case 0: #if defined(UART_PRESENT) if (config & USART_STATE_ASYNC_ONLY) { usart->usart_device = UART0; usartClock = (CMU_Clock_TypeDef)cmuClock_UART0; txDmaSelect = DMAREQ_UART0_TXBL; port_tx = AF_UART0_TX_PORT(location); pin_tx = AF_UART0_TX_PIN(location); port_rx = AF_UART0_RX_PORT(location); pin_rx = AF_UART0_RX_PIN(location); } else #endif { usart->usart_device = USART0; usartClock = (CMU_Clock_TypeDef)cmuClock_USART0; txDmaSelect = DMAREQ_USART0_TXBL; port_tx = AF_USART0_TX_PORT(location); pin_tx = AF_USART0_TX_PIN(location); port_rx = AF_USART0_RX_PORT(location); pin_rx = AF_USART0_RX_PIN(location); port_clk = AF_USART0_CLK_PORT(location); pin_clk = AF_USART0_CLK_PIN(location); port_cs = AF_USART0_CS_PORT(location); pin_cs = AF_USART0_CS_PIN(location); } break; #if ((defined(USART_PRESENT) && (USART_COUNT > 1)) || \ (defined(UART_PRESENT) && (UART_COUNT > 1))) case 1: #if (defined(UART_PRESENT) && (UART_COUNT > 1)) if (config & USART_STATE_ASYNC_ONLY) { usart->usart_device = UART1; usartClock = (CMU_Clock_TypeDef)cmuClock_UART1; txDmaSelect = DMAREQ_UART1_TXBL; port_tx = AF_UART1_TX_PORT(location); pin_tx = AF_UART1_TX_PIN(location); port_rx = AF_UART1_RX_PORT(location); pin_rx = AF_UART1_RX_PIN(location); } else #endif { usart->usart_device = USART1; usartClock = (CMU_Clock_TypeDef)cmuClock_USART1; txDmaSelect = DMAREQ_USART1_TXBL; port_tx = AF_USART1_TX_PORT(location); pin_tx = AF_USART1_TX_PIN(location); port_rx = AF_USART1_RX_PORT(location); pin_rx = AF_USART1_RX_PIN(location); port_clk = AF_USART1_CLK_PORT(location); pin_clk = AF_USART1_CLK_PIN(location); port_cs = AF_USART1_CS_PORT(location); pin_cs = AF_USART1_CS_PIN(location); } break; #endif #if ((defined(USART_PRESENT) && (USART_COUNT > 2)) || \ (defined(UART_PRESENT) && (UART_COUNT > 2))) case 2: #if (defined(UART_PRESENT) && (UART_COUNT > 2)) if (config & USART_STATE_ASYNC_ONLY) { usart->usart_device = UART2; usartClock = (CMU_Clock_TypeDef)cmuClock_UART2; txDmaSelect = DMAREQ_UART2_TXBL; port_tx = AF_UART2_TX_PORT(location); pin_tx = AF_UART2_TX_PIN(location); port_rx = AF_UART2_RX_PORT(location); pin_rx = AF_UART2_RX_PIN(location); } else #endif { usart->usart_device = USART2; usartClock = (CMU_Clock_TypeDef)cmuClock_USART2; txDmaSelect = DMAREQ_USART2_TXBL; port_tx = AF_USART2_TX_PORT(location); pin_tx = AF_USART2_TX_PIN(location); port_rx = AF_USART2_RX_PORT(location); pin_rx = AF_USART2_RX_PIN(location); port_clk = AF_USART2_CLK_PORT(location); pin_clk = AF_USART2_CLK_PIN(location); port_cs = AF_USART2_CS_PORT(location); pin_cs = AF_USART2_CS_PIN(location); } break; #endif default: break; } /* Enable USART clock */ CMU_ClockEnable(usartClock, true); /* Config GPIO */ GPIO_PinModeSet( port_tx, pin_tx, gpioModePushPull, 0); GPIO_PinModeSet( port_rx, pin_rx, gpioModeInputPull, 1); if (config & USART_STATE_SYNC) { GPIO_PinModeSet( port_clk, pin_clk, gpioModePushPull, 0); } if (config & USART_STATE_AUTOCS) { GPIO_PinModeSet( port_cs, pin_cs, gpioModePushPull, 1); } /* Config interrupt and NVIC */ if (flag & RT_DEVICE_FLAG_INT_RX) { hook.type = efm32_irq_type_usart; hook.unit = unitNumber * 2 + 1; #if defined(UART_PRESENT) if (config & USART_STATE_ASYNC_ONLY) { hook.unit += USART_COUNT * 2; } #endif hook.cbFunc = rt_hw_usart_rx_isr; hook.userPtr = device; efm32_irq_hook_register(&hook); } /* Config DMA */ if (flag & RT_DEVICE_FLAG_DMA_TX) { DMA_CfgChannel_TypeDef chnlCfg; DMA_CfgDescr_TypeDef descrCfg; hook.type = efm32_irq_type_dma; hook.unit = dmaChannel; hook.cbFunc = rt_hw_usart_dma_tx_isr; hook.userPtr = device; efm32_irq_hook_register(&hook); callback = (DMA_CB_TypeDef *)rt_malloc(sizeof(DMA_CB_TypeDef)); if (callback == RT_NULL) { usart_debug("USART%d err: no mem for callback\n", usart->unit); break; } callback->cbFunc = DMA_IRQHandler_All; callback->userPtr = RT_NULL; callback->primary = 0; /* Setting up DMA channel */ chnlCfg.highPri = false; /* Can't use with peripherals */ chnlCfg.enableInt = true; /* Interrupt for callback function */ chnlCfg.select = txDmaSelect; chnlCfg.cb = callback; DMA_CfgChannel(dmaChannel, &chnlCfg); /* Setting up DMA channel descriptor */ descrCfg.dstInc = dmaDataIncNone; descrCfg.srcInc = dmaDataInc1; descrCfg.size = dmaDataSize1; descrCfg.arbRate = dmaArbitrate1; descrCfg.hprot = 0; DMA_CfgDescr(dmaChannel, true, &descrCfg); } /* Init specified USART unit */ if (config & USART_STATE_SYNC) { USART_InitSync_TypeDef init_sync = USART_INITSYNC_DEFAULT; init_sync.enable = usartEnable; init_sync.refFreq = 0; init_sync.baudrate = SPI_BAUDRATE; if (config & USART_STATE_9BIT) { init_sync.databits = usartDatabits9; } else { init_sync.databits = usartDatabits8; } if (config & USART_STATE_MASTER) { init_sync.master = true; } else { init_sync.master = false; } init_sync.msbf = true; switch (USART_CLK_MODE_GET(config)) { case 0: init_sync.clockMode = usartClockMode0; break; case 1: init_sync.clockMode = usartClockMode1; break; case 2: init_sync.clockMode = usartClockMode2; break; case 3: init_sync.clockMode = usartClockMode3; break; } USART_InitSync(usart->usart_device, &init_sync); } else { USART_InitAsync_TypeDef init_async = USART_INITASYNC_DEFAULT; init_async.enable = usartEnable; init_async.refFreq = 0; init_async.baudrate = UART_BAUDRATE; init_async.oversampling = USART_CTRL_OVS_X4; init_async.databits = USART_FRAME_DATABITS_EIGHT; init_async.parity = USART_FRAME_PARITY_NONE; init_async.stopbits = USART_FRAME_STOPBITS_ONE; USART_InitAsync(usart->usart_device, &init_async); } /* Enable RX and TX pins and set location */ usart->usart_device->ROUTE = USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | \ (location << _USART_ROUTE_LOCATION_SHIFT); if (config & USART_STATE_SYNC) { usart->usart_device->ROUTE |= USART_ROUTE_CLKPEN; } if (config & USART_STATE_AUTOCS) { usart->usart_device->ROUTE |= USART_ROUTE_CSPEN; if (config & USART_STATE_MASTER) { usart->usart_device->CTRL |= USART_CTRL_AUTOCS; } } /* Clear RX/TX buffers */ usart->usart_device->CMD = USART_CMD_CLEARRX | USART_CMD_CLEARTX; return usart; } while(0); if (usart->rx_mode) { rt_free(usart->rx_mode); } if (usart->tx_mode) { rt_free(usart->tx_mode); } if (usart) { rt_free(usart); } if (callback) { rt_free(callback); } #if defined(UART_PRESENT) if (config & USART_STATE_ASYNC_ONLY) { usart_debug("UART%d err: init failed!\n", unitNumber); } else #endif { usart_debug("USART%d err: init failed!\n", unitNumber); } return RT_NULL; }
/* * Function Name: DMA_setup * Description: Setup DMA channels for ADC,TX,RX */ void DMA_Setup(void) { DMA_CfgChannel_TypeDef chnlCfg_adc; DMA_CfgDescr_TypeDef descrCfg_adc; DMA_CfgChannel_TypeDef chnlCfg_rx; DMA_CfgDescr_TypeDef descrCfg_rx; DMA_CfgChannel_TypeDef chnlCfg_tx; DMA_CfgDescr_TypeDef descrCfg_tx; /* Setting up call-back function */ cb.cbFunc = DMA_CallBack; cb.userPtr = NULL; /* Setting up ADC channel */ chnlCfg_adc.highPri = DMA_PRIORITY_ADC; chnlCfg_adc.enableInt = true; chnlCfg_adc.select = DMAREQ_ADC0_SINGLE; chnlCfg_adc.cb = &cb; DMA_CfgChannel(DMA_CHANNEL_ADC, &chnlCfg_adc); /* Setting up ADC channel descriptor */ descrCfg_adc.dstInc = dmaDataInc2; descrCfg_adc.srcInc = dmaDataIncNone; descrCfg_adc.size = dmaDataSize2; descrCfg_adc.arbRate = DMA_ARBITRATE_ADC; descrCfg_adc.hprot = 0; DMA_CfgDescr(DMA_CHANNEL_ADC, true, &descrCfg_adc); /* Starting DMA transfer using Basic since every transfer must be initiated by the ADC. */ DMA_ActivateBasic(DMA_CHANNEL_ADC, true, false, (void *)ADC_Buffer, (void *)&(ADC0->SINGLEDATA), ADC_SAMPLES - 1); /* Setting up Rx channel */ chnlCfg_rx.highPri = DMA_PRIORITY_RX; chnlCfg_rx.enableInt = true; chnlCfg_rx.select = DMAREQ_LEUART0_RXDATAV; chnlCfg_rx.cb = &cb; DMA_CfgChannel(DMA_CHANNEL_RX, &chnlCfg_rx); /* Setting up Rx channel descriptor */ descrCfg_rx.dstInc = dmaDataInc1; descrCfg_rx.srcInc = dmaDataIncNone; descrCfg_rx.size = dmaDataSize1; descrCfg_rx.arbRate = DMA_ARBITRATE_RX; descrCfg_rx.hprot = 0; DMA_CfgDescr(DMA_CHANNEL_RX, true, &descrCfg_rx); /* Setting up Tx channel */ chnlCfg_tx.highPri = DMA_PRIORITY_TX; chnlCfg_tx.enableInt = true; chnlCfg_tx.select = DMAREQ_LEUART0_TXBL; chnlCfg_tx.cb = &cb; DMA_CfgChannel(DMA_CHANNEL_TX, &chnlCfg_tx); /* Setting up Tx channel descriptor */ descrCfg_tx.dstInc = dmaDataIncNone; descrCfg_tx.srcInc = dmaDataInc1; descrCfg_tx.size = dmaDataSize1; descrCfg_tx.arbRate = DMA_ARBITRATE_TX; descrCfg_tx.hprot = 0; DMA_CfgDescr(DMA_CHANNEL_TX, true, &descrCfg_tx); }
void setupDMAOutput( void ) { cbDAC.cbFunc = dacCb; cbDAC.userPtr = NULL; DMA_CfgChannel_TypeDef chnlCfg = { .highPri = true, .enableInt = true, .select = DMAREQ_DAC0_CH0, .cb = &cbDAC }; DMA_CfgChannel(DMA_CHANNEL_DAC, &chnlCfg); DMA_CfgDescr_TypeDef descrCfg = { .dstInc = dmaDataIncNone, .srcInc = dmaDataInc4, .size = dmaDataSize4, .hprot = 0 }; DMA_CfgDescr(DMA_CHANNEL_DAC, true, &descrCfg); DMA_CfgDescr(DMA_CHANNEL_DAC, false, &descrCfg); DMA_ActivatePingPong(DMA_CHANNEL_DAC, false, (void*)((uint32_t) &DAC0->COMBDATA), sourceP, N - 1, (void*)((uint32_t) &DAC0->COMBDATA), sourceS, N - 1); } /* * Sets up the DMA to copy from src to dst0 and dst1 with the pattern: * * src: | 1, 2, 3, 4, ... | * dst0: | 1, 3, ... | * dst1: | 2, 4, ... | */ void setupDMASplit(void) { DMA_Init_TypeDef dmaInit; dmaInit.hprot = 0; dmaInit.controlBlock = dmaControlBlock; DMA_Init(&dmaInit); DMA_CfgChannel_TypeDef chnlCfgLeft; chnlCfgLeft.highPri = false; chnlCfgLeft.enableInt = true; chnlCfgLeft.select = 0; chnlCfgLeft.cb = NULL; //&cbInLeft; DMA_CfgChannel(DMA_CHANNEL_IN_LEFT, &chnlCfgLeft); DMA_CfgChannel_TypeDef chnlCfgRight; chnlCfgRight.highPri = false; chnlCfgRight.enableInt = true; chnlCfgRight.select = 0; chnlCfgRight.cb = NULL; //&cbInRight; DMA_CfgChannel(DMA_CHANNEL_IN_RIGHT, &chnlCfgRight); DMA_CfgDescr_TypeDef descrCfg; descrCfg.dstInc = dmaDataInc2; descrCfg.srcInc = dmaDataInc4; descrCfg.size = dmaDataSize2; descrCfg.arbRate = dmaArbitrate1; descrCfg.hprot = 0; DMA_CfgDescr(DMA_CHANNEL_IN_LEFT, true, &descrCfg); DMA_CfgDescr(DMA_CHANNEL_IN_RIGHT, false, &descrCfg); DMA_ActivateAuto(DMA_CHANNEL_IN_LEFT, true, left, source, N - 1); DMA_ActivateAuto(DMA_CHANNEL_IN_RIGHT, false, right, (char*)source+sizeof(uint16_t), N - 1); } /* * Sets up the DMA to copy from src0 and src1 to dst with the pattern: * * src0: | 1, 3, ... | * src1: | 2, 4, ... | * dst: | 1, 2, 3, 4, ... | */ void setupDMAMerge(void) { DMA_CfgChannel_TypeDef chnlCfgLeft; chnlCfgLeft.highPri = false; chnlCfgLeft.enableInt = true; chnlCfgLeft.select = 0; chnlCfgLeft.cb = NULL; //&cbOutLeft; DMA_CfgChannel(DMA_CHANNEL_OUT_LEFT, &chnlCfgLeft); DMA_CfgChannel_TypeDef chnlCfgRight; chnlCfgRight.highPri = false; chnlCfgRight.enableInt = true; chnlCfgRight.select = 0; chnlCfgRight.cb = NULL; //&cbOutRight; DMA_CfgChannel(DMA_CHANNEL_OUT_RIGHT, &chnlCfgRight); DMA_CfgDescr_TypeDef descrCfg; descrCfg.dstInc = dmaDataInc4; descrCfg.srcInc = dmaDataInc2; descrCfg.size = dmaDataSize2; descrCfg.arbRate = dmaArbitrate1; descrCfg.hprot = 0; DMA_CfgDescr(DMA_CHANNEL_OUT_LEFT, true, &descrCfg); DMA_CfgDescr(DMA_CHANNEL_OUT_RIGHT, false, &descrCfg); DMA_ActivateAuto(DMA_CHANNEL_OUT_LEFT, true, destination, left, N - 1); DMA_ActivateAuto(DMA_CHANNEL_OUT_RIGHT, false, (char*)destination+sizeof(uint16_t), right, N - 1); }
/***************************************************************************//** * @brief * Configure ADC usage for this application. *******************************************************************************/ static void preampADCConfig(void) { DMA_CfgDescr_TypeDef descrCfg; DMA_CfgChannel_TypeDef chnlCfg; ADC_Init_TypeDef init = ADC_INIT_DEFAULT; ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT; ADC_InitScan_TypeDef scanInit = ADC_INITSCAN_DEFAULT; /* Configure DMA usage by ADC */ cbInData.cbFunc = preampDMAInCb; cbInData.userPtr = NULL; chnlCfg.highPri = true; chnlCfg.enableInt = true; chnlCfg.select = DMAREQ_ADC0_SCAN; chnlCfg.cb = &cbInData; DMA_CfgChannel(PREAMP_DMA_AUDIO_IN, &chnlCfg); descrCfg.dstInc = dmaDataInc2; descrCfg.srcInc = dmaDataIncNone; descrCfg.size = dmaDataSize2; descrCfg.arbRate = dmaArbitrate1; descrCfg.hprot = 0; DMA_CfgDescr(PREAMP_DMA_AUDIO_IN, true, &descrCfg); DMA_CfgDescr(PREAMP_DMA_AUDIO_IN, false, &descrCfg); DMA_ActivatePingPong(PREAMP_DMA_AUDIO_IN, false, preampAudioInBuffer1, (void *)((uint32_t)&(ADC0->SCANDATA)), (PREAMP_AUDIO_BUFFER_SIZE * 2) - 1, preampAudioInBuffer2, (void *)((uint32_t)&(ADC0->SCANDATA)), (PREAMP_AUDIO_BUFFER_SIZE * 2) - 1); /* Indicate starting with primary in-buffer (according to above DMA setup) */ preampProcessPrimary = true; /* Configure ADC */ /* Keep warm due to "high" frequency sampling */ init.warmUpMode = adcWarmupKeepADCWarm; /* Init common issues for both single conversion and scan mode */ init.timebase = ADC_TimebaseCalc(0); init.prescale = ADC_PrescaleCalc(4000000, 0); /* Sample potentiometer by tailgating in order to not disturb fixed rate */ /* audio sampling. */ init.tailgate = true; ADC_Init(ADC0, &init); /* Init for single conversion use (potentiometer). */ singleInit.reference = adcRefVDD; singleInit.input = adcSingleInpCh5; /* According to DVK HW design */ singleInit.resolution = adcRes8Bit; /* Use at least 8 bit since unlinear voltage */ ADC_InitSingle(ADC0, &singleInit); /* Init for scan sequence use (audio in right/left channels). */ scanInit.prsSel = adcPRSSELCh0; scanInit.prsEnable = true; scanInit.reference = adcRefVDD; scanInit.input = ADC_SCANCTRL_INPUTMASK_CH0 | ADC_SCANCTRL_INPUTMASK_CH1; ADC_InitScan(ADC0, &scanInit); }
/***************************************************************************//** * @brief * Start a UDMA transfer. ******************************************************************************/ static Ecode_t StartTransfer( DmaMode_t mode, DmaDirection_t direction, unsigned int channelId, DMADRV_PeripheralSignal_t peripheralSignal, void *buf0, void *buf1, void *buf2, bool bufInc, int len, DMADRV_DataSize_t size, DMADRV_Callback_t callback, void *cbUserParam ) { ChTable_t *ch; DMA_CfgChannel_TypeDef chCfg; DMA_CfgDescr_TypeDef descrCfg; if ( !initialized ) { return ECODE_EMDRV_DMADRV_NOT_INITIALIZED; } if ( ( channelId > EMDRV_DMADRV_DMA_CH_COUNT ) || ( buf0 == NULL ) || ( buf1 == NULL ) || ( len > DMADRV_MAX_XFER_COUNT ) || ( ( mode == dmaModePingPong ) && ( buf2 == NULL ) ) ) { return ECODE_EMDRV_DMADRV_PARAM_ERROR; } ch = &chTable[ channelId ]; if ( ch->allocated == false ) { return ECODE_EMDRV_DMADRV_CH_NOT_ALLOCATED; } /* Setup the interrupt callback routine. */ if ( mode == dmaModeBasic ) { dmaCallBack[ channelId ].cbFunc = DmaBasicCallback; } else { dmaCallBack[ channelId ].cbFunc = DmaPingPongCallback; } dmaCallBack[ channelId ].userPtr = NULL; /* Setup the channel */ chCfg.highPri = false; /* Can't use hi pri with peripherals. */ /* Interrupt needed ? */ if ( ( callback != NULL ) || ( mode == dmaModePingPong ) ) { chCfg.enableInt = true; } else { chCfg.enableInt = false; } chCfg.select = peripheralSignal; chCfg.cb = &dmaCallBack[ channelId ]; DMA_CfgChannel( channelId, &chCfg ); /* Setup channel descriptor. */ if ( direction == dmaDirectionMemToPeripheral ) { if ( bufInc ) { if ( size == dmadrvDataSize1 ) { descrCfg.srcInc = dmaDataInc1; } else if ( size == dmadrvDataSize2 ) { descrCfg.srcInc = dmaDataInc2; } else /* dmadrvDataSize4 */ { descrCfg.srcInc = dmaDataInc4; } } else { descrCfg.srcInc = dmaDataIncNone; } descrCfg.dstInc = dmaDataIncNone; } else { if ( bufInc ) { if ( size == dmadrvDataSize1 ) { descrCfg.dstInc = dmaDataInc1; } else if ( size == dmadrvDataSize2 ) { descrCfg.dstInc = dmaDataInc2; } else /* dmadrvDataSize4 */ { descrCfg.dstInc = dmaDataInc4; } } else { descrCfg.dstInc = dmaDataIncNone; } descrCfg.srcInc = dmaDataIncNone; } descrCfg.size = (DMA_DataSize_TypeDef)size; descrCfg.arbRate = dmaArbitrate1; descrCfg.hprot = 0; DMA_CfgDescr( channelId, true, &descrCfg ); if ( mode == dmaModePingPong ) { DMA_CfgDescr( channelId, false, &descrCfg ); } ch->callback = callback; ch->userParam = cbUserParam; ch->callbackCount = 0; ch->length = len; DMA->IFC = 1 << channelId; /* Start DMA cycle. */ if ( mode == dmaModeBasic ) { DMA_ActivateBasic( channelId, true, false, buf0, buf1, len - 1 ); } else { if ( direction == dmaDirectionMemToPeripheral ) { DMA_ActivatePingPong( channelId, false, buf0, /* dest */ buf1, /* src */ len - 1, buf0, /* dest */ buf2, /* src */ len - 1); } else { DMA_ActivatePingPong( channelId, false, buf0, /* dest */ buf2, /* src */ len - 1, buf1, /* dest */ buf2, /* src */ len - 1); } } return ECODE_EMDRV_DMADRV_OK; }
/**************************************************************************//** * @brief * Setup DMA in ping pong mode * @details * The DMA is set up to transfer data from memory to the DAC, triggered by * PRS (which in turn is triggered by the TIMER). When the DMA finishes, * it will trigger the callback (PingPongTransferComplete). *****************************************************************************/ void DMA_setup(void) { /* DMA configuration structs */ DMA_Init_TypeDef dmaInit; DMA_CfgChannel_TypeDef chnlCfg; DMA_CfgDescr_TypeDef descrCfg; ramBufferTX0Zeros[0] = 0; /* Initializing the DMA */ dmaInit.hprot = 0; dmaInit.controlBlock = dmaControlBlock; DMA_Init(&dmaInit); /* Set the interrupt callback routine */ DMAcallBackTX.cbFunc = PingPongTransferCompleteTX; /* Callback doesn't need userpointer */ DMAcallBackTX.userPtr = NULL; /* Setting up channel */ chnlCfg.highPri = false; /* Can't use with peripherals */ chnlCfg.enableInt = true; /* Interrupt needed when buffers are used */ chnlCfg.select = DMAREQ_USART2_TXBL; chnlCfg.cb = &DMAcallBackTX; DMA_CfgChannel(0, &chnlCfg); // Enable TX DMA Channel /* Set the interrupt callback routine */ DMAcallBackRX.cbFunc = PingPongTransferCompleteRX; /* Callback doesn't need userpointer */ DMAcallBackRX.userPtr = NULL; /* Setting up channel */ chnlCfg.highPri = false; /* Can't use with peripherals */ chnlCfg.enableInt = true; /* Interrupt needed when buffers are used */ /* channel 0 and 1 will need data at the same time, * can use channel 0 as trigger */ chnlCfg.select = DMAREQ_USART2_RXDATAV; chnlCfg.cb = &DMAcallBackRX; DMA_CfgChannel(1, &chnlCfg); /* Setting up channel descriptor */ /* Destination is DAC/USART register and doesn't move */ descrCfg.dstInc = dmaDataIncNone; descrCfg.srcInc = dmaDataIncNone; descrCfg.size = dmaDataSize1; /* We have time to arbitrate again for each sample */ descrCfg.arbRate = dmaArbitrate1; descrCfg.hprot = 0; /* Configure both primary and secondary descriptor alike */ DMA_CfgDescr(0, true, &descrCfg); DMA_CfgDescr(0, false, &descrCfg); /* Setting up channel descriptor */ /* Destination is DAC/USART register and doesn't move */ descrCfg.dstInc = dmaDataInc1; descrCfg.srcInc = dmaDataIncNone; descrCfg.size = dmaDataSize1; /* We have time to arbitrate again for each sample */ descrCfg.arbRate = dmaArbitrate1; descrCfg.hprot = 0; /* Configure both primary and secondary descriptor alike */ DMA_CfgDescr(1, true, &descrCfg); DMA_CfgDescr(1, false, &descrCfg); /* Enabling PingPong Transfer*/ DMA_ActivatePingPong(0, false, (void *) & (USART2->TXDATA), (void *) &ramBufferTX0Zeros, (2 * BUFFERSIZE) - 1, (void *) &(USART2->TXDATA), (void *) &ramBufferTX1Zeros, (2 * BUFFERSIZE) - 1); /* Enabling PingPong Transfer*/ DMA_ActivatePingPong(1, false, (void *) &ramBufferDacData0Stereo, (void *) & (USART2->RXDATA), (2 * BUFFERSIZE) - 1, (void *) &ramBufferDacData1Stereo, (void *) &(USART2->RXDATA), (2 * BUFFERSIZE) - 1); }