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 every one, When I combine ping pong DMA and the ADC (2MSPS) with USB to send this data to my PC I was able to achieve 3.2 Mbps aprox, But I would like to ask for some recomendations to improve the speed, In my case, I send from the host a 64 Bytes message, and in response I get from the MCU 576 Bytes containing ADC Data. I dont know how I can get more speed (if it is possible).
I believe that the MCU is the one who limits the speed, in my computer the delays caused from storing the data that comes from the MCU are irrelevant, here is the code (the principal part), to pass the 12 bit ADC data to the 8 bit USB buffer I have to split it, may be there is a better and fastest option?? :
//***************************************************************************** #ifdef DEBUG void __error__(char *pcFilename, uint32_t ui32Line) { } #endif //***************************************************************************** void uDMAErrorHandler(void) { uint32_t ui32Status; ui32Status = uDMAErrorStatusGet(); // Check for uDMA error bit if(ui32Status) // If there is a uDMA error { uDMAErrorStatusClear(); //Clear the error status } } //***************************************************************************** void ADCseq0Handler() { uint32_t ui32Status = ADCIntStatus(ADC0_BASE, 0, false); uint32_t ui32Mode; ROM_ADCIntClear(ADC0_BASE, 0); //se puede eliminar ADCIntClearEx(ADC0_BASE, ADC_INT_DMA_SS0); ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT); if(ui32Mode == UDMA_MODE_STOP) { w = 0; p = 0; uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + (ADC_O_SSFIFO0)), g_ui8RxBufA, MEM_BUFFER_SIZE); g_pui8USBTxBuffer[p] = g_ui8RxBufA[w] & 0x00FF;p++; g_pui8USBTxBuffer[p] = ((g_ui8RxBufA[w] & 0x0F00) >> 8) | ((g_ui8RxBufA[w+1] & 0x000F) << 4);p++; g_pui8USBTxBuffer[p] = (g_ui8RxBufA[w+1] & 0x0FF0) >> 4;p++; for (w = 2; w < 384; w=w+2) { g_pui8USBTxBuffer[p++] = g_ui8RxBufA[w] & 0x00FF; g_pui8USBTxBuffer[p++] = ((g_ui8RxBufA[w] & 0x0F00) >> 8) | ((g_ui8RxBufA[w+1] & 0x000F) << 4); g_pui8USBTxBuffer[p++] = (g_ui8RxBufA[w+1] & 0x0FF0) >> 4; } jeje = 1; } ui32Mode = uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT); if(ui32Mode == UDMA_MODE_STOP) { w = 0; p = 0; uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + (ADC_O_SSFIFO0)), g_ui8RxBufB, MEM_BUFFER_SIZE); g_pui8USBTxBuffer[p] = g_ui8RxBufB[w] & 0x00FF;p++; g_pui8USBTxBuffer[p] = ((g_ui8RxBufB[w] & 0x0F00) >> 8) | ((g_ui8RxBufB[w+1] & 0x000F) << 4);p++; g_pui8USBTxBuffer[p] = (g_ui8RxBufB[w+1] & 0x0FF0) >> 4;p++; for (w = 2; w < 384; w=w+2) { g_pui8USBTxBuffer[p++] = g_ui8RxBufB[w] & 0x00FF; g_pui8USBTxBuffer[p++] = ((g_ui8RxBufB[w] & 0x0F00) >> 8) | ((g_ui8RxBufB[w+1] & 0x000F) << 4); g_pui8USBTxBuffer[p++] = (g_ui8RxBufB[w+1] & 0x0FF0) >> 4; } jeje = 2; } uDMAChannelEnable(UDMA_CHANNEL_ADC0); } //***************************************************************************** void ADCconfigure1() { SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); //Habilita puerto E SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3|GPIO_PIN_2|GPIO_PIN_1); //PE3 PE2 PE1 tipo ADC SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_ADC0); ADCClockConfigSet(ADC0_BASE,ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_FULL, 1); //Clock source (Precision Internal Clock) // ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 30); ADCSequenceConfigure(ADC0_BASE, 0 , ADC_TRIGGER_ALWAYS, 3); // SS0-SS3 priorities must always be different ADCSequenceStepConfigure(ADC0_BASE, 0 , 0, ADC_CTL_CH0 & 0xFFF0 ); // ADC_CTL_TS = read temp sensor ADCSequenceStepConfigure(ADC0_BASE, 0 , 1, ADC_CTL_CH0 & 0xFFF0 ); ADCSequenceStepConfigure(ADC0_BASE, 0 , 2, ADC_CTL_CH0 & 0xFFF0 ); ADCSequenceStepConfigure(ADC0_BASE, 0 , 3, ADC_CTL_CH0 & 0xFFF0 ); ADCSequenceStepConfigure(ADC0_BASE, 0 , 4, ADC_CTL_CH0 & 0xFFF0 ); ADCSequenceStepConfigure(ADC0_BASE, 0 , 5, ADC_CTL_CH0 & 0xFFF0 ); ADCSequenceStepConfigure(ADC0_BASE, 0 , 6, ADC_CTL_CH0 & 0xFFF0 ); ADCSequenceStepConfigure(ADC0_BASE, 0 , 7, ADC_CTL_CH0 & 0xFFF0 | ADC_CTL_END | ADC_CTL_IE); // ADC_CTL_IE fires every 8 samples ADCSequenceEnable(ADC0_BASE, 0); ADCSequenceDMAEnable(ADC0_BASE, 0); uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC0, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); } //***************************************************************************** // uint32_t sysclock void ADCconfigure2() { uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1024); uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1024); uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + (ADC_O_SSFIFO0)), g_ui8RxBufA, MEM_BUFFER_SIZE); uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + (ADC_O_SSFIFO0)), g_ui8RxBufB, MEM_BUFFER_SIZE); uDMAChannelEnable(UDMA_CHANNEL_ADC0); ADCIntEnableEx(ADC0_BASE, ADC_INT_DMA_SS0); IntEnable(INT_ADC0SS0); } //***************************************************************************** void ConfigGP() { SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION); // GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_2); // GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5); // tiempo = 2000000; } //***************************************************************************** static uint32_t read_USB(tUSBDBulkDevice *psDevice, uint8_t *pi8Data, uint_fast32_t ui32NumBytes) { USBBufferInfoGet(&g_sTxBuffer, &sTxRing); ui32Space = USBBufferSpaceAvailable(&g_sTxBuffer); ui32Loop = (ui32Space < ui32NumBytes) ? ui32Space : ui32NumBytes; ui32Count = ui32Loop; g_ui32RxCount += ui32NumBytes; // ui32ReadIndex = (uint32_t)(pi8Data - g_pui8USBRxBuffer); while(ui32Loop) { receptor[index_R] = g_pui8USBRxBuffer[ui32ReadIndex]; index_R++; ui32ReadIndex++; ui32ReadIndex = ((ui32ReadIndex == BULK_BUFFER_SIZE) ? 0 : ui32ReadIndex); ui32Loop--; } // count++; return(ui32Count); } //***************************************************************************** uint32_t TxHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgValue, void *pvMsgData) { if(ui32Event == USB_EVENT_TX_COMPLETE) { g_ui32TxCount += ui32MsgValue; } return(0); } //***************************************************************************** uint32_t RxHandler(void *pvCBData, uint32_t ui32Event, uint32_t ui32MsgValue,void *pvMsgData) { switch(ui32Event) { case USB_EVENT_CONNECTED: { miFlag = 0; g_bUSBConfigured = true; g_ui32Flags |= COMMAND_STATUS_UPDATE; USBBufferFlush(&g_sTxBuffer); USBBufferFlush(&g_sRxBuffer); break; } case USB_EVENT_DISCONNECTED: { miFlag = 1; g_bUSBConfigured = false; g_ui32Flags |= COMMAND_STATUS_UPDATE; break; } case USB_EVENT_RX_AVAILABLE: { miFlag = 2; tUSBDBulkDevice *psDevice; psDevice = (tUSBDBulkDevice *)pvCBData; index_R = 0; return(read_USB(psDevice, pvMsgData, ui32MsgValue)); } case USB_EVENT_SUSPEND: miFlag = 3; case USB_EVENT_RESUME: miFlag = 4; case USB_EVENT_STALL: miFlag = 5; break; default: miFlag = 5; break; } return(0); } //***************************************************************************** int main(void) { uint32_t ui32SysClock; uint32_t ui32PLLRate; ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); // ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION); // Enable the GPIO port that is used for the on-board LED. // ROM_GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_0); // Enable the GPIO pins for the LED (PN0). // ROM_GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_1); // Enable the GPIO pins for the LED (PN0). PinoutSet(false, true); g_bUSBConfigured = false; SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA); SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA); IntMasterEnable(); IntEnable(INT_UDMAERR); USBBufferInit(&g_sTxBuffer); USBBufferInit(&g_sRxBuffer); SysCtlVCOGet(SYSCTL_XTAL_25MHZ, &ui32PLLRate); USBDCDFeatureSet(0, USBLIB_FEATURE_CPUCLK, &ui32SysClock); USBDCDFeatureSet(0, USBLIB_FEATURE_USBPLL, &ui32PLLRate); USBStackModeSet(0, eUSBModeDevice, 0); USBDBulkInit(0, &g_sBulkDevice); ADCconfigure1(); uDMAEnable(); uDMAControlBaseSet(pui8ControlTable); // int yy; while(1) { SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); // for(yy = 0 ; yy < 10000 ; y++) // ConfigGP(); // tiempo = 2000000; if(miFlag == 2) { if(receptor[0] == 'h') { ADCconfigure2(); if (jeje == 1){ USBBufferDataWritten(&g_sTxBuffer, 577); } if (jeje == 2){ USBBufferDataWritten(&g_sTxBuffer, 577); } ADCSequenceDisable(ADC0_BASE, 0); ADCSequenceDMADisable(ADC0_BASE, 0); } miFlag = 0; } //rcFlag = 0; } }
One more thing, I know that I can use an external PHY to get more speed, I have already buy the USB3300 demo board from WaveShare, but what I need know is to improve the MCU code to make it more efficient, please, I need help to make a more efficient code.
Thanks in advance :D