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.

TM4C1294 2 ADC channels 1Ms/s Ethernet



I am trying to send 1Ms/s of data from 2 ADCs simultaneously to the Ethernet using TCP IPv4 but I am getting very slow data throughputs, something like 1 sample per second for both channels. I have set my ADC's as such to try and sample at 1 megasamples/ s and sending the data out accordingly. 

unsigned int adcValues[4];
Void tcpWorker(UArg arg0, UArg arg1) {
    int  clientfd = (int)arg0;
    int  bytesRcvd;
    int  bytesSent;
    volatile uint32_t adcVal0, adcVal1;
    char recvBuffer[TCPPACKETSIZE];
    char sendBuffer[TCPPACKETSIZE];

    memset(recvBuffer, 0, 1024);
	memset(sendBuffer, 0, 1024);

    System_printf("tcpWorker: start clientfd = 0x%x\n", clientfd);

    for(;;) {
    //while ((bytesRcvd = recv(clientfd, recvBuffer, TCPPACKETSIZE, 0)) > 0) {
    	if ((bytesRcvd = recv(clientfd, recvBuffer, TCPPACKETSIZE, MSG_DONTWAIT)) > 0) {
    		tcpReceiverHandler(recvBuffer);
    		System_printf("%s\n", recvBuffer);
    	} else {
    		// No data received
    	}

		// Flush buffer everytime after printing
    	System_flush();

    	// Send ADC data
    	ReadADC();
	adcVal0 = adcValues[0];
	adcVal1 = adcValues[1];

	sprintf(sendBuffer, "ADC0: %d ADC1: %d", adcVal0, adcVal1);
	System_printf("%s\n", sendBuffer);
	System_flush();

	bytesSent = send(clientfd, sendBuffer, strlen(sendBuffer) + 1, 0);
	if (bytesSent < 0) {
		System_printf("Error: send failed.\n");
		break;
	}
    }
}

void ConfigureADC(void) {
	//SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOE);
	//SysCtlPeripheralReset(SYSCTL_PERIPH_ADC0);

	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
	SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

	GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_0 | GPIO_PIN_1 );

	// Clocked to 120MHz / 6 to get 20MHz ADC clock and takes all samples
	// an ADC clock of 16MHz, generates 1MSps
	//ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 7);

	//SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
	//	SYSCTL_CFG_VCO_480), 120000000);

	ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);
	ADCSequenceStepConfigure(ADC0_BASE,1,0, ADC_CTL_CH0);
	ADCSequenceStepConfigure(ADC0_BASE,1,1, ADC_CTL_CH1 | ADC_CTL_IE | ADC_CTL_END);

	//ADCSequenceEnable(ADC0_BASE, 0);
	ADCSequenceEnable(ADC0_BASE, 1);

}
void ReadADC(void) {
	ADCIntClear(ADC0_BASE, 1);
	ADCProcessorTrigger(ADC0_BASE, 1);
	GPIOPinWrite(GPIO_PORTP_BASE, GPIO_PIN_4, !GPIO_PIN_4);

	// Wait until the sample sequence has completed.
	while(!ADCIntStatus(ADC0_BASE, 1, false)) { }

	// Read the value from the ADC.
	(ADCSequenceDataGet(ADC0_BASE, 1, adcValues));
	GPIOPinWrite(GPIO_PORTP_BASE, GPIO_PIN_4, GPIO_PIN_4);
}

  • Hi Lee,
    When you say 1Ms/s are you trying to sample and send 1 million samples of you ADC data in a second? First thing, the System_printf/flush calls you have between sample reads and socket recv/send will significantly slow things down. Another factor is the speed of your Ethernet, are you sure it can handle sending and recving at that rate? Also how are you clocking your ADC peripheral to sample at that rate, is the commented out code what you're using?

    Thanks,
    Moses
  • I'm pretty sure most Ethernet ports and cables support up to 100Mb/s which more than fast enough since the maximum number of bits I need to send out is 12 * 2 * 1Megasamples = 24 megabits per second. I tried setting up the clock frequency using that commented section of the code but my program doesn't recognise those functions. I just thought that the default speed of the ADCs is 1 megasample/ sec???

  • Hi Lee,
    I've just confirmed from the Datasheet that the device can sample at 1 Msps if it's clocked at 16MHz, so you were right. One way we can simplify things just for test is to remove the ethernet communication code and just set the ADC to sample at 1 Msps and verify if that is happening. Were you using the frequency of the System_printf console output to come up with the 1 sample per second conclusion from what you were seeing? I'll say using System_flush to console between collecting samples adds a considerable amount of delay as well.
    You can do a small test of getting the ADC sample, getting the timestamp (Timestamp_get32 API) of that sample, printing both to the SysMin buffer (using System_printf) and then flushing to console at the end when you're done collecting the test samples. This way we can narrow down what's slowing down the throughput.

    Best,
    Moses

  • I just verified that one of the reasons why my data throughput is really slow is due to the TCPPACKETSIZE. If I reduced the TCPPACKETSIZE down to 24 bits, the throughput it much faster.
  • I've noticed that this part of the code actually takes 4 samples before it I can write to the buffer. Is there a way to reduce this to make it do just 1 sample and send it to the buffer?
    // Wait until the sample sequence has completed.
    while(!ADCIntStatus(ADC0_BASE, 1, false)) { }
  • Hi Lee,

        Sorry for the delay. I'd recommend you make a post on the Tiva forum about the ADC.That's where you'll find more experts on the ADC peripheral for your device. After you've got the ADC working portion working well, I can go from there to help resolve any TI-RTOS/Networking issues you may have.

    Regards,

    Moses