This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hello
We are using imported TI-RTOS TCP Client example to built on top of it. We need to continuously sample ADC with max channel speed 62.5ks and send the data chunks via TCP-IP.
We've been testing two solutions single shot and ping pong DMA from the available forum examples with satisfactory results, however one problem remains persistent , interrupts roughly around 62k times a second as oppose to 62500/1024(transfer size)=61 times a second.
The biggest challenge is to understand the control of the TI RTOS itself as it is using DMA for SPI and we also enabled UART DMA option by enabling the
#define TI_DRIVERS_UART_DMA 1
and calling
void CC3200_LAUNCHXL_initDMA(void)
The "static tDMAControlTable dmaControlTable[64];" is initialized and data visible during transfer and rearm.
Following behavior is observed in the pinpong forum example that has been rated by two members to work OK:
[Note:Similar behaviour is found when using TI-RTOS HWI (Interrupt number 32 for ADC CH2) or ADCIntRegister(ADC_BASE, ADC_CH_2,ADCIntHandler);]
1. The buffers immediately fill with data after the point: ADCDMAEnable(ADC_BASE, ADC_CH_2);
2. Device goes to interrupt after enabling interrupt.
3. It reads ping buffer at the first interrupt
and also resets the control structure
4. Second interrupt is about the pong buffer, again control structure reset.
5. From now on interrupts every 62k times a second, however the interrupt is triggered for other reason then the ping pong activity.
A. What is the flow of the interrupt from the ADC to the DMA and why it can happen so frequently?
B: How other TI-RTOS dma operations affecting the configuration and rearm of the transfer?
Bellow the sample code:
//***************************************************************************** // //! Does the actual Memory transfer //! //! \param ulChannel. DMA Channel to be used //! \param ulMode. DMA Mode to be used //! \param ulItemCount. Items to be transfered in DMA Transfer(should not exceed 1024) //! \param ulArbSize. Arbitration Size to be set //! \param pvSrcBuf. Pointer to the source Buffer //! \param ulSrcInc. Source Increment //! \param pvDstBuf. Pointer to the Destination Buffer //! \param ulDstInc. Destination Increment //! //! This function //! 1. Sets up the uDMA registers to perform the actual transfer //! //! \return None. // //***************************************************************************** void UDMASetupTransfer(unsigned long ulChannel, unsigned long ulMode, unsigned long ulItemCount, unsigned long ulItemSize, unsigned long ulArbSize, void *pvSrcBuf, unsigned long ulSrcInc, void *pvDstBuf, unsigned long ulDstInc) { MAP_uDMAChannelControlSet(ulChannel, ulItemSize | ulSrcInc | ulDstInc | ulArbSize); MAP_uDMAChannelAttributeEnable(ulChannel,UDMA_ATTR_USEBURST); MAP_uDMAChannelTransferSet(ulChannel, ulMode, pvSrcBuf, pvDstBuf, ulItemCount); MAP_uDMAChannelEnable(ulChannel); } uint32_t trans_ctr=0; uint32_t ADCtransactions=0; unsigned long DmaDataDumpPing[1024]; unsigned long DmaDataDumpPong[1024]; void ADCIntHandler(void) { unsigned long ulChannelStructIndex, ulMode, ulControl; tDMAControlTable *pControlTable; unsigned long *pDataDumpBuff = NULL; unsigned short Status; unsigned short uiIndex; //uint32_t key=Hwi_disable(); ADCtransactions++; Status = ADCIntStatus(ADC_BASE, ADC_CH_2); ADCIntClear(ADC_BASE, ADC_CH_2,Status|ADC_DMA_DONE); Status = ADCIntStatus(ADC_BASE, ADC_CH_2); ulMode = MAP_uDMAChannelModeGet(UDMA_CH16_ADC_CH2 | UDMA_PRI_SELECT); if(ulMode == UDMA_MODE_STOP) { ulChannelStructIndex = UDMA_CH16_ADC_CH2 | UDMA_PRI_SELECT; pDataDumpBuff = &(DmaDataDumpPing[0]); } else { ulMode = MAP_uDMAChannelModeGet(UDMA_CH16_ADC_CH2 | UDMA_ALT_SELECT); if(ulMode == UDMA_MODE_STOP) { ulChannelStructIndex = UDMA_CH16_ADC_CH2 | UDMA_ALT_SELECT; pDataDumpBuff = &(DmaDataDumpPong[0]); } } if(pDataDumpBuff != NULL) { ulChannelStructIndex &= 0x3f; pControlTable = uDMAControlBaseGet(); ulControl = (pControlTable[ulChannelStructIndex].ulControl & ~(UDMA_CHCTL_XFERSIZE_M | UDMA_CHCTL_XFERMODE_M)); ulControl |= UDMA_MODE_PINGPONG | ((640 - 1) << 4); uDMAChannelControlSet(ulChannelStructIndex,ulControl); //#if 1 //UART_PRINT("\n\rVoltage is %f\n\r",(((float)((pDataDumpBuff[0] >> 2 ) & 0x0FFF))*1.4)/4096); //#endif } //Hwi_restore(key); } void InitAdcDma( void ) { unsigned short Status; //uint32_t key=Hwi_disable(); MAP_uDMAChannelAssign(UDMA_CH16_ADC_CH2); UDMASetupTransfer(UDMA_CH16_ADC_CH2|UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, 640, UDMA_SIZE_32, UDMA_ARB_1, (void *)(0x4402E874+ADC_CH_2), UDMA_SRC_INC_NONE, (void *)&(DmaDataDumpPing[0]), UDMA_DST_INC_32); UDMASetupTransfer(UDMA_CH16_ADC_CH2|UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, 640, UDMA_SIZE_32, UDMA_ARB_1, (void *)(0x4402E874+ADC_CH_2), UDMA_SRC_INC_NONE, (void *)&(DmaDataDumpPong[0]), UDMA_DST_INC_32); ADCIntEnable(ADC_BASE, ADC_CH_2,ADC_DMA_DONE); ADCDMAEnable(ADC_BASE, ADC_CH_2); ADCIntRegister(ADC_BASE, ADC_CH_2,ADCIntHandler); Status = ADCIntStatus(ADC_BASE, ADC_CH_2); ADCIntClear(ADC_BASE, ADC_CH_2,Status|ADC_DMA_DONE); Status = ADCIntStatus(ADC_BASE, ADC_CH_2); //ADCIntEnable(ADC_BASE, ADC_CH_2,ADC_DMA_DONE); ADCChannelEnable(ADC_BASE, ADC_CH_2); ADCEnable(ADC_BASE); //Hwi_restore(key); } void adcMainDMA(void) { //sl_NetCfgGet(SL_MAC_ADDRESS_GET,NULL,&macAddressLen,(unsigned char *)macAddressVal); Task_sleep(5000); InitAdcDma(); while(1) { Task_sleep(1000); } }
Thanks
Patryk