Hi,
I am using my Stellaris LaunchPad to sample the internal temp. sensor and send this data via USB to a host PC.
To do so I use SS1 from ADC0 which is set to continuous mode at 1 MS/s. uDMA is configured to copy data from SS1 fifo directly to the USB tx buffer (I am using the usb code found in usb_dev_bulk). I also tried to copy the data first into extra buffers and thus configured uDMA to operate in Ping-Pong mode.
Furthermore, I configured the systick timer to count every us.
Basically the code is operating. However, I am facing some problems. When I measure the time spend between two ADC interrupts (uDMA transfer complete) I would expect it to be something like
number_of_samples_to_copy * 1 us/sample
However, sometimes I am getting durations which are far below that. For example, if I setup uDMA to copy 64 samples, the expected time would be above 64us but sometimes I measure something like 30us. I measure the time by counting the number of interrupts for a while and than divide the systick counter by this number.
This issue seems to be worth if no USB host is connected.
Furthermore, I am only getting bulk transfer rates around 700kBytes/s but I would require (if I only use 8bit per sample) 1MS/s * 8bit/S = 1Mbyte
As I am pretty new to Stellaris and USB I apologize if this is a stupid question.
Cheers,
Julian
void sysTickIntHandler(void) { us_counter++; } int main(void) { FPULazyStackingEnable(); FPUEnable(); SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ); SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); GPIOPinTypeUSBAnalog(GPIO_PORTD_BASE, GPIO_PIN_4 | GPIO_PIN_5); // Initialize the transmit and receive buffers. // USBBufferInit(&g_sTxBuffer); USBBufferInit(&g_sRxBuffer); // // Set the USB stack mode to Device mode with VBUS monitoring. // USBStackModeSet(0, eUSBModeForceDevice, 0); // // Pass our device information to the USB library and place the device // on the bus. // void* retval = USBDBulkInit(0, &g_sBulkDevice); ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_ALWAYS, 0); ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_TS); ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_TS); ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_TS); ADCSequenceStepConfigure(ADC0_BASE, 1, 3, ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_END); uint32_t i = 0; for(i = 0;i<1024;i++) { currTempVals[i] = 27;//(1475 - ((2475 * pingBuffer[i])) / 4096)/10; } initDMA(); ADCSequenceEnable(ADC0_BASE, 1); IntEnable(INT_ADC0SS1); //ADCIntEnable(ADC0_BASE,1); IntEnable(INT_UDMAERR); SysTickPeriodSet(50); //1us SysTickIntRegister(sysTickIntHandler); SysTickIntEnable(); SysTickEnable(); uint32_t startProcess=0; while(1) { if(pingBufferReady==1) { startProcess = us_counter; if(usbConnected==1) { USBBufferDataWritten(&g_sTxBuffer, 64); } processingTime = us_counter-startProcess; pingBufferReady = 0; g_ui32DataProcessed++; } if(pongBufferReady==1) { if(usbConnected==1) { USBBufferDataWritten(&g_sTxBuffer, 64); } pongBufferReady = 0; } } } #pragma DATA_ALIGN(dmaControlData,1024); uint8_t dmaControlData[1024]; void initDMA() { uDMAEnable(); uDMAControlBaseSet(dmaControlData); uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC1, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); uDMAChannelControlSet(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_4); uDMAChannelControlSet(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_4); uDMAChannelTransferSet(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO1), g_pui8USBTxBuffer, 64); uDMAChannelTransferSet(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO1 ), g_pui8USBTxBuffer, 64); //uDMAChannelAttributeEnable(UDMA_CHANNEL_ADC1,UDMA_ATTR_USEBURST|UDMA_ATTR_REQMASK); uDMAChannelEnable(UDMA_CHANNEL_ADC1); } void ADC0IntHandler(void) { ADCIntClear(ADC0_BASE, 1); uint32_t ui32Mode; g_ui32IntCount++; ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT); if(ui32Mode == UDMA_MODE_STOP) { if(pongBufferReady == 1) { //Error pongbuffer not processed yet! errorCounter++; } pingBufferReady = 1; g_ui32RxPingCount++; uDMAChannelTransferSet(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO1), g_pui8USBTxBuffer, 64); } ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT); if(ui32Mode == UDMA_MODE_STOP) { if(pingBufferReady == 1) { //Error pingbuffer not processed yet! errorCounter++; } pongBufferReady = 1; g_ui32RxPongCount++; uDMAChannelTransferSet(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO1), g_pui8USBTxBuffer, 64); } //uDMAChannelEnable(UDMA_CHANNEL_ADC1); }