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.

Sampling using both ADC modules simultaneously

Other Parts Discussed in Thread: TEST2

Hi,

I am using a Tiva C series launchpad. I need to sample 5 different signals in the following succession.

1. Sample from pin D0 once using ADC0

2. Sample from pin D1 once using ADC0

3. Sample from pin D2 once using ADC1

4. Sample from pin D3 and D4 simultaneously using ADC0 and ADC1 for 128 times.

SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); //20 MHz clock

	        
	        ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);
	        ADCSequenceConfigure(ADC1_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);

	        ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH7 | ADC_CTL_IE | ADC_CTL_END);
	        ADCSequenceStepConfigure(ADC1_BASE, 3, 0, ADC_CTL_CH6 | ADC_CTL_IE | ADC_CTL_END);
	        ADCSequenceStepConfigure(ADC1_BASE, 3, 0, ADC_CTL_CH5 | ADC_CTL_IE | ADC_CTL_END);
	        ADCSequenceStepConfigure(ADC1_BASE, 3, 0, ADC_CTL_CH4 | ADC_CTL_IE | ADC_CTL_END);
	        ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH3 | ADC_CTL_IE | ADC_CTL_END);

	        ADCSequenceEnable(ADC0_BASE, 3);
	        ADCSequenceEnable(ADC1_BASE, 3);

	        ADCIntClear(ADC0_BASE, 3);


	    while(1)
	    {
	        ADCSequenceStepConfigure(ADC1_BASE, 3, 0, ADC_CTL_CH5 | ADC_CTL_IE | ADC_CTL_END);
	        ADCIntClear(ADC1_BASE, 3);
	        ADCProcessorTrigger(ADC1_BASE, 3);					// Trigger the ADC conversion.
	        while(!ADCIntStatus(ADC1_BASE, 3, false)){}				// Wait for conversion to be completed.
	        ADCIntClear(ADC1_BASE, 3);						// Clear the ADC interrupt flag.
	        ADCSequenceDataGet(ADC1_BASE, 3, adcbuffer);				// Read ADC Value.
	        timebase = adcbuffer[0];

	        ADCSequenceStepConfigure(ADC1_BASE, 3, 0, ADC_CTL_CH4 | ADC_CTL_IE | ADC_CTL_END);
	        ADCIntClear(ADC1_BASE, 3);
	        ADCProcessorTrigger(ADC1_BASE, 3);					// Trigger the ADC conversion.
	        while(!ADCIntStatus(ADC1_BASE, 3, false)){}				// Wait for conversion to be completed.
	        ADCIntClear(ADC1_BASE, 3);						// Clear the ADC interrupt flag.
	        ADCSequenceDataGet(ADC1_BASE, 3, adcbuffer);				// Read ADC Value.
	        triglvl = adcbuffer[0];

	        ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH3 | ADC_CTL_IE | ADC_CTL_END);
	        ADCIntClear(ADC0_BASE, 3);
	        ADCProcessorTrigger(ADC0_BASE, 3);					// Trigger the ADC conversion.
	        while(!ADCIntStatus(ADC0_BASE, 3, false)){}				// Wait for conversion to be completed.
	        ADCIntClear(ADC0_BASE, 3);						// Clear the ADC interrupt flag.
	        ADCSequenceDataGet(ADC0_BASE, 3, adcbuffer);				// Read ADC Value.
	        xpos = adcbuffer[0];

	    	for (i=0;i<128;i++)
	    	{
	    		ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH7 | ADC_CTL_IE | ADC_CTL_END);
	    		ADCIntClear(ADC0_BASE, 3);
	    		ADCProcessorTrigger(ADC0_BASE, 3);				// Trigger the ADC conversion.
	    		while(!ADCIntStatus(ADC0_BASE, 3, false)){}			// Wait for conversion to be completed.
	    		ADCIntClear(ADC0_BASE, 3);					// Clear the ADC interrupt flag.
	    		ADCSequenceDataGet(ADC0_BASE, 3, adcbuffer);			// Read ADC Value.
	    		adcdata1[i] = adcbuffer[0];

	    		ADCSequenceStepConfigure(ADC1_BASE, 3, 0, ADC_CTL_CH6 | ADC_CTL_IE | ADC_CTL_END);
	    		ADCIntClear(ADC1_BASE, 3);
	    		ADCProcessorTrigger(ADC1_BASE, 3);				// Trigger the ADC conversion.
	    		while(!ADCIntStatus(ADC1_BASE, 3, false)){}			// Wait for conversion to be completed.
	    		ADCIntClear(ADC1_BASE, 3);					// Clear the ADC interrupt flag.
	    		ADCSequenceDataGet(ADC1_BASE, 3, adcbuffer);			// Read ADC Value.
	    		adcdata2[i] = adcbuffer[0];
	    	}

Is this the best way to configure the sampling sequence ?

  • Hello Shyam.

    A better way of doing the sequence would be

    1. Use sample sequencer 2 (which has 4 channels) and put the D0, D1 and D2 for conversion so that once triggered it would sample all 3 channels w/o user intervention

    2. Use sample sequencer 0 on ADC0 for D3 and sample sequencer 0 on ADC1 for D4 and set the SYNCWAIT bit in ADC1.Do make sure all channel entries on ADC0.SS0 have D3 and ADC1.SS0 have D4. This will allow for 8 conversions back to back. Then set the ADCPSSI.GSYNC and ADCPSSI.SYNCWAIT along with ADCPSSI.SS0 in ADC0 which will cause both ADC's to start conversion. This can be done 16 times to get 128 conversions.

    The code will be faster in terms of execution.

    Regards

    Amit

  • Hi Amit,

    I am totally new to Tiva Launchpad. The code which I have wrote was based from the 'Tivaware Peripheral Driver Library' file. I know the basic working of the ADC in this Launchpad, but the detailed working with explanation of all the configuration bits are not given anywhere. You suggested to change some bits for faster execution. But how to change those bits ? And is there any document or website where the detailed list of all configuration bits are given and also the steps to follow while configuring an ADC ?

  • Hello Shyam,

    You can refer to the Peripheral Driver Library User Guide for details on API's. Also based on the User Guide you can make ammends to the code and I can help clean up the finer details

    Regards

    Amit

  • Hello Shyam

    This is the rough code to do the same (I will put it at 95% done). Do make sure to read the ADC Data registers with the array size as per the specification for each of the sequencers

    SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); //20 MHz clock

                
            ADCSequenceConfigure(ADC0_BASE, 2, ADC_TRIGGER_PROCESSOR, 0);
            ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_PROCESSOR, 0);
            ADCSequenceConfigure(ADC1_BASE, 0, ADC_TRIGGER_PROCESSOR, 0);

            ADCSequenceStepConfigure(ADC0_BASE, 2, 0, ADC_CTL_CH5);
            ADCSequenceStepConfigure(ADC0_BASE, 2, 1, ADC_CTL_CH4);
            ADCSequenceStepConfigure(ADC0_BASE, 2, 2, ADC_CTL_CH3 | ADC_CTL_IE | ADC_CTL_END);
            ADCSequenceStepConfigure(ADC0_BASE, 0, 0, ADC_CTL_CH7);
            ADCSequenceStepConfigure(ADC0_BASE, 0, 1, ADC_CTL_CH7);
            ADCSequenceStepConfigure(ADC0_BASE, 0, 2, ADC_CTL_CH7);
            ADCSequenceStepConfigure(ADC0_BASE, 0, 3, ADC_CTL_CH7);
            ADCSequenceStepConfigure(ADC0_BASE, 0, 4, ADC_CTL_CH7);
            ADCSequenceStepConfigure(ADC0_BASE, 0, 5, ADC_CTL_CH7);
            ADCSequenceStepConfigure(ADC0_BASE, 0, 6, ADC_CTL_CH7);
            ADCSequenceStepConfigure(ADC0_BASE, 0, 7, ADC_CTL_CH7 | ADC_CTL_IE | ADC_CTL_END);
            ADCSequenceStepConfigure(ADC1_BASE, 0, 0, ADC_CTL_CH6);
            ADCSequenceStepConfigure(ADC1_BASE, 0, 1, ADC_CTL_CH6);
            ADCSequenceStepConfigure(ADC1_BASE, 0, 2, ADC_CTL_CH6);
            ADCSequenceStepConfigure(ADC1_BASE, 0, 3, ADC_CTL_CH6);
            ADCSequenceStepConfigure(ADC1_BASE, 0, 4, ADC_CTL_CH6);
            ADCSequenceStepConfigure(ADC1_BASE, 0, 5, ADC_CTL_CH6);
            ADCSequenceStepConfigure(ADC1_BASE, 0, 6, ADC_CTL_CH6);
            ADCSequenceStepConfigure(ADC1_BASE, 0, 7, ADC_CTL_CH6 | ADC_CTL_IE | ADC_CTL_END);

            ADCSequenceEnable(ADC0_BASE, 2);
            ADCSequenceEnable(ADC0_BASE, 0);
            ADCSequenceEnable(ADC1_BASE, 0);

            ADCIntClear(ADC0_BASE, 2);
            ADCIntClear(ADC0_BASE, 0);
            ADCIntClear(ADC1_BASE, 0);


            while(1)
            {
                ADCIntClear(ADC0_BASE, 2);
                ADCProcessorTrigger(ADC0_BASE, 2);                // Trigger the ADC conversion.
                while(!ADCIntStatus(ADC0_BASE, 2, false)){}        // Wait for conversion to be completed.
                ADCIntClear(ADC0_BASE, 2);                        // Clear the ADC interrupt flag.
                ADCSequenceDataGet(ADC0_BASE, 3, &adcbuffer);    // Read ADC Value.
                ch5data = adcbuffer[0];
                ch4data = adcbuffer[1];
                ch3data = adcbuffer[2];

                for (i=0;i<16;i++)
                {
                    ADCIntClear(ADC0_BASE, 0);
                    ADCIntClear(ADC1_BASE, 0);
                    ADCProcessorTrigger(ADC1_BASE, (0|ADC_TRIGGER_WAIT);                // Put ADC-1 in Trigger Wait
                    ADCProcessorTrigger(ADC0_BASE, (0|ADC_TRIGGER_SIGNAL);                // Put ADC-0 in Global Trigger
                    while(!ADCIntStatus(ADC0_BASE, 0, false)){}            // Wait for conversion to be completed.
                    ADCIntClear(ADC0_BASE, 0);                    // Clear the ADC interrupt flag.
                    ADCIntClear(ADC1_BASE, 0);                    // Clear the ADC interrupt flag.
                    ADCSequenceDataGet(ADC0_BASE, 0, &adc0buffer);            // Read ADC Value.
                    ADCSequenceDataGet(ADC0_BASE, 0, &adc1buffer);            // Read ADC Value.
                }

    Regards

    Amit

  • Hi Amit,

    The code which you suggested was well explained. I understood the working of ADC only now. The only problem I faced was, when running the code, I got the error,

    #169 argument of type "uint32_t (*)[8]" is incompatible with parameter of type "uint32_t *"

    I haven't used pointer datatypes in Tiva until now. I couldn't find how to declare pointer datatypes anywhere.These are how I tried declaring.

    uint32_t adc0buffer[8], adc1buffer[8];

    uint32_t *adc0buffer[8], *adc1buffer[8];

    But all these statements produce errors.  How to declare the variables adc0buffer and adc1buffer ? 

    Thanks in advance.

  • Hello Shyam,

    Please use the following to get the compilation warning out. The code I had sent was just the method to get the sequences that you wanted to work. These compilation issues need to be still sorted.

    ADCSequenceDataGet(ADC0_BASE, 0, &adc0buffer[0]);

    Regards

    Amit

  • Hi Amit,

    I have eliminated that compilation error. I have a doubt in the ADC sampling though. The adc0buffer which I am declaring, is of type - uint32_t. So the 12-bit ADC value will be stored in the last 12 bits of the 32-bit word. If I declare another word, say adc0data of type uint8_t, and perform one of these two statements:

    adc0data = adc0buffer;

    adc0data = adc0buffer/16;

    Which of these statements will store 8 MSB bits of the 12-bit ADC value in adc0data ?

  • Hello Shyam,

    That is correct that the last 12 bits will contain the ADC value. If you want to store the MSB then you would have to store it by using shift operator. It is simpler and much cleaner

    Regards

    Amit

  • I am trying to sample ADC0 and ADC1, but all I can get is the data out of ADC0, I tried changing the channel, but I get nothing unless I use ch4. 

    I am sampling the x and y axis of a joystick. 

    I want to be able to print out the data.

    Here is my code:

    #include <stdint.h> // Variable definitions for the C99 standard.
    #include <stdio.h> // Input and output facilities for the C99 standard.
    #include <stdbool.h> // Boolean definitions for the C99 standard.
    
    #include "inc/tm4c123gh6pm.h" // Definitions for the interrupt and register assignments.
    #include "inc/hw_memmap.h" // Memory map definitions of the Tiva C Series device.
    #include "inc/hw_types.h" // Definitions of common types and macros.
    #include "inc/hw_gpio.h" // Defines and Macros for GPIO hardware.
    
    #include "driverlib/sysctl.h" // Definitions and macros for System Control API of DriverLib.
    #include "driverlib/interrupt.h" // Defines and macros for NVIC Controller API of DriverLib.
    #include "driverlib/gpio.h" // Definitions and macros for GPIO API of DriverLib.
    #include "driverlib/timer.h" // Defines and macros for Timer API of DriverLib.
    #include "driverlib/pin_map.h" //Mapping of peripherals to pins for all parts.
    #include "driverlib/uart.h" // Definitions and macros for UART API of DriverLib.
    #include "driverlib/adc.h" // Definitions for ADC API of DriverLib.
    #include "driverlib/fpu.h" // Prototypes for the FPU manipulation routines.
    
    #include "utils/uartstdio.h" // Prototypes for the UART console functions.
    							 // Needs to add "utils/uartstdio.c" through a relative link.
    
    #define TIMER0_FREQ    2 // Freqency in Hz, for blinking LED.
    #define TIMER1_FREQ    1 // Frequency in Hz, for ADC.
    #define UART0_BAUDRATE    115200 // UART baudrate in bps.
    
    #define ADC0_SEQ_NUM 0 // ADC Sample Sequence Number
    #define ADC1_SEQ_NUM 0
    #define MAX_ADC_SAMP_VAL    0x0FFF // max value for 12-bit ADC
    
    #define RED_LED    GPIO_PIN_1
    #define BLUE_LED    GPIO_PIN_2
    #define GREEN_LED    GPIO_PIN_3
    
    #define DISP_TEXT_LINE_NUM    4
    #define DISP_DATA_STR_LEN    20
    
    
    // function prototypes
    void init_LEDs(void);
    void init_timer(void);
    void init_UART(void);
    void init_ADC(void);
    void Timer0_ISR(void);
    void Timer1_ISR(void);
    
    extern void UARTStdioIntHandler(void);
    
    
    // global variables
    uint32_t sys_clock;
    uint8_t cur_LED = RED_LED;
    
    const char *disp_text[DISP_TEXT_LINE_NUM] = {
    		"\n",
    		"UART and LED Demo\n",
    		"H: help, R: red, G: green, B: blue, S: Sample Data.\n",
    		"> " };
    
    
    uint32_t sig_data=0,sig_data1=0;
    float sig_data_y,sig_data_x ;
    
    char disp_data_str[DISP_DATA_STR_LEN];
    
    
    int main(void)
    {
    	uint32_t i;
    	unsigned char user_cmd;
    
    	// Configure system clock at 40 MHz.
    	SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
    	//SysCtlClockSet(SYSCTL_USE_PLL);
    	sys_clock = SysCtlClockGet();
    
    	// Enable the floating-point unit (FPU).
    	FPUEnable();
    	// Configure FPU to perform lazy stacking of the floating-point state.
    	FPULazyStackingEnable();
    
    	init_LEDs();
    	init_ADC();
    	init_UART();
    	init_timer();
    
    	// Enable the processor to respond to interrupts.
    	IntMasterEnable();
    
    	// Start the timer by enabling operation of the timer module.
    	TimerEnable(TIMER0_BASE, TIMER_A);
    	TimerEnable(TIMER1_BASE, TIMER_A);
    	// Initial display on terminal.
    	for(i=0; i<DISP_TEXT_LINE_NUM; i++)
    		UARTprintf(disp_text[i]);
    
    	while(1) {
    		// Read user inputs from UART if available.
    		if(UARTRxBytesAvail())
    	        user_cmd = UARTgetc();
    		else
    			user_cmd = 0;
    
    		switch(user_cmd){
    		case '\r':
    		case ' ':
    		case 'H':
    		case 'h':
    			for(i=0; i<DISP_TEXT_LINE_NUM; i++)
    				UARTprintf(disp_text[i]);
    			break;
    		case 'R':
    		case 'r':
    			cur_LED = RED_LED;
    			UARTprintf("\n> ");
    			break;
    		case 'B':
    		case 'b':
    			cur_LED = BLUE_LED;
    			UARTprintf("\n> ");
    			break;
    		case 'G':
    		case 'g':
    			cur_LED = GREEN_LED;
    			UARTprintf("\n> ");
    			break;
    		case 'S':
    		case 's':
    		ADCProcessorTrigger(ADC0_BASE, ADC0_SEQ_NUM);
    
    			while(!ADCIntStatus(ADC0_BASE, ADC0_SEQ_NUM, false)) {
    			}
    			ADCIntClear(ADC0_BASE, ADC0_SEQ_NUM);
    
    			ADCSequenceDataGet(ADC0_BASE, ADC0_SEQ_NUM, &sig_data);
    
    			sig_data_y = 3.3*sig_data/MAX_ADC_SAMP_VAL;
    
    			UARTprintf("\ny=%.2f\n", sig_data_y);
    
    
    			ADCProcessorTrigger(ADC1_BASE, ADC1_SEQ_NUM);
    
    			while(!ADCIntStatus(ADC1_BASE, ADC1_SEQ_NUM, false)) {
    			}
    			ADCIntClear(ADC1_BASE, ADC1_SEQ_NUM);
    
    			ADCSequenceDataGet(ADC1_BASE, ADC1_SEQ_NUM, &sig_data1);
    
    			sig_data_x = 3.3*sig_data1/MAX_ADC_SAMP_VAL;
    			UARTprintf("\nx=%.2f\n", sig_data_x);
    
    			// Print data to UART0
    			//snprintf(disp_data_str, DISP_DATA_STR_LEN, "y=%.2f, x=%.2f ", sig_data_y,sig_data_x);
    			//UARTprintf("\n%s\n> ", disp_data_str);
    
    			break;
    		}
    	}
    }
    
    
    void init_LEDs(void)
    {
    	// Enable and configure LED peripheral.
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); // Enable GPIO Port F.
    	// Three onboard LEDs, R:PF1, B:PF2, G:PF3.
    	GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
    }
    
    void init_timer(void)
    {
    
    	// Enable and configure timer peripheral.
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
    
    	// Configure Timer0 as a 32-bit timer in periodic mode.
    	TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
    	// Initialize timer load register.
    	TimerLoadSet(TIMER0_BASE, TIMER_A, sys_clock/TIMER0_FREQ -1);
    
    	// Configure Timer1 as a 32-bit timer in periodic mode.
    	TimerConfigure(TIMER1_BASE, TIMER_CFG_PERIODIC);
    	// Initialize timer load register.
    	TimerLoadSet(TIMER1_BASE, TIMER_A, sys_clock/TIMER1_FREQ -1);
    
    
    	// Registers a function to be called when the interrupt occurs.
    	IntRegister(INT_TIMER0A, Timer0_ISR);
    	// The specified interrupt is enabled in the interrupt controller.
    	IntEnable(INT_TIMER0A);
    	// Enable the indicated timer interrupt source.
    	TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    
    	// Registers a function to be called when the interrupt occurs.
    	IntRegister(INT_TIMER1A, Timer1_ISR);
    	// The specified interrupt is enabled in the interrupt controller.
    	IntEnable(INT_TIMER1A);
    	// Enable the indicated timer interrupt source.
    	TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
    }
    
    
    void init_UART(void)
    {
    	// Enable and configure UART0 for debugging printouts.
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    	GPIOPinConfigure(GPIO_PA0_U0RX);
    	GPIOPinConfigure(GPIO_PA1_U0TX);
    	GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
    	// Registers a function to be called when the interrupt occurs.
    	IntRegister(INT_UART0, UARTStdioIntHandler);
    	UARTStdioConfig(0, UART0_BAUDRATE, sys_clock);
    }
    
    
    void init_ADC(void)
    {
    	// Enable and configure ADC0 and ADC1
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1);
    
    	GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_5);
    	GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_3);
    
    	ADCSequenceConfigure(ADC0_BASE, ADC0_SEQ_NUM, ADC_TRIGGER_PROCESSOR, 0);
    	ADCSequenceConfigure(ADC1_BASE, ADC1_SEQ_NUM, ADC_TRIGGER_PROCESSOR, 0);
    
    
    	ADCSequenceStepConfigure(ADC0_BASE, ADC0_SEQ_NUM, 0, ADC_CTL_IE|ADC_CTL_CH4|ADC_CTL_END);
    	ADCSequenceStepConfigure(ADC1_BASE, ADC1_SEQ_NUM, 0, ADC_CTL_IE|ADC_CTL_CH4|ADC_CTL_END);
    	ADCSequenceEnable(ADC0_BASE, ADC0_SEQ_NUM);
    	ADCSequenceEnable(ADC1_BASE, ADC1_SEQ_NUM);
    }
    
    // Timer0 interrupt service routine
    void Timer0_ISR(void)
    {
    	// Clear the timer interrupt.
    	TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    
    	// Blink LED. Read the current state of GPIO pins and write back the opposite state.
    	if(GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3)) {
    		GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0);
    	}
    	else {
    		GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, cur_LED);
    	}
    }
    
    void Timer1_ISR(void)
    {
    	// Clear the timer interrupt.
    	TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
    
    
    
    	ADCProcessorTrigger(ADC0_BASE, ADC0_SEQ_NUM);
    
    
    	while(!ADCIntStatus(ADC0_BASE, ADC0_SEQ_NUM, false)) {
    	}
    	ADCIntClear(ADC0_BASE, ADC0_SEQ_NUM);
    
    	ADCSequenceDataGet(ADC0_BASE, ADC0_SEQ_NUM, &sig_data);
    
    	sig_data_y = 3.3*sig_data/MAX_ADC_SAMP_VAL;
    	snprintf(disp_data_str, DISP_DATA_STR_LEN, "y=%.2f", sig_data_y);
    	UARTprintf("\n%s\n> ", disp_data_str);
    
    
    
    	ADCProcessorTrigger(ADC1_BASE, ADC1_SEQ_NUM);
    
    	while(!ADCIntStatus(ADC1_BASE, ADC1_SEQ_NUM, false)) {
    	}
    	ADCIntClear(ADC1_BASE, ADC1_SEQ_NUM);
    
    	ADCSequenceDataGet(ADC1_BASE, ADC1_SEQ_NUM, &sig_data1);
    
    	sig_data_x = 3.3*sig_data1/MAX_ADC_SAMP_VAL;
    	snprintf(disp_data_str, DISP_DATA_STR_LEN, "x=%.2f", sig_data_x);
    	UARTprintf("\n%s\n> ", disp_data_str);
    
    
    
    				// Print data to UART0
    				//snprintf(disp_data_str, DISP_DATA_STR_LEN, "y=%.2f, x=%.2f ", sig_data_y,sig_data_x);
    				//UARTprintf("\n%s\n> ", disp_data_str);
    
    
    }
    

  • Hello Jonathan,

    You are using ADC_CTL_CH4 in both ADC's. You need to map the correct ADC Channel to the correct ADC controller to get the result for the channel.

    Regards
    Amit
  • I have tried setting ADC0 with CH4 and then CH0-CH7 and I still only get the data from ADC0, are the analog inputs mapped somewhere? Do I just need to keep guessing. I could not find anything in the Datasheet.
  • Hello all,

    I am facing an issue with ADC. My ADC Channel0 data is affecting data off ADC Channel 4. Please find below code and initialization.


    uint32_t ADC0Val[1];
    uint32_t ADC1Val[1];
    SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
    InitConsole();

    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    GPIOPinTypeADC(GPIO_PORTD_BASE,GPIO_PIN_3);
    ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 1);
    // ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH0);
    ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH4 | ADC_CTL_IE | ADC_CTL_END);
    ADCSequenceEnable(ADC0_BASE, 3);


    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    GPIOPinTypeADC(GPIO_PORTE_BASE,GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_1);
    ADCSequenceConfigure(ADC1_BASE, 3, ADC_TRIGGER_PROCESSOR, 1);
    // ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH0);
    ADCSequenceStepConfigure(ADC1_BASE, 3, 0, ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END);
    ADCSequenceEnable(ADC1_BASE, 3);

    int test = 0;
    int test1 = 0;
    // int test2 = 0;
    while(1)
    {
    ADCSequenceStepConfigure(ADC1_BASE, 3, 0, ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END);
    ADCIntClear(ADC1_BASE, 3);
    ADCProcessorTrigger(ADC1_BASE, 3);
    while(!ADCIntStatus(ADC1_BASE, 3, false))
    {
    }
    ADCIntClear(ADC1_BASE, 3);
    ADCSequenceDataGet(ADC1_BASE,3, ADC0Val);
    // ADCSoftwareOversampleDataGet(ADC0_BASE,1,ADC0Val,1);
    test = ADC0Val[0];

    ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH4 | ADC_CTL_IE | ADC_CTL_END);
    ADCIntClear(ADC0_BASE, 3);
    ADCProcessorTrigger(ADC0_BASE, 3);
    while(!ADCIntStatus(ADC0_BASE, 3, false))
    {
    }
    ADCIntClear(ADC0_BASE, 3);
    ADCSequenceDataGet(ADC0_BASE,3, ADC1Val);
    // ADCSoftwareOversampleDataGet(ADC0_BASE,1,ADC0Val,1);
    test1 = ADC1Val[0];
    UARTprintf("ADC:%d\t\t",test);
    UARTprintf("ADC1:%d\n",test1);
    SysCtlDelay(SysCtlClockGet() / 12);
    }

    This is just to read the data and print on UART. But on the same I am facing the issue of Channel 4 Data.

    Kindly let me know if there is some issue with the code.

    Thanks in advance,

    Mitesh
  • Hello Mitesh

    Why complicate the program. use two different sequencers for the channels. That way only the following needs to be done (X is for the sequencer number)

    ADCProcessorTrigger(ADC0_BASE, X);
    while(!ADCIntStatus(ADC0_BASE, X, false))
    {
    }
    ADCIntClear(ADC0_BASE, X);
    ADCSequenceDataGet(ADC0_BASE,X, ADC1Val);

    Also have you configure the pin corresponding to analog channel 4 as ADC pin, during pin mux configuration?

    Regards
    Amit
  • Hello Amit,

    Ya I have defined Channel 4 pin as ADC pin.

    I have noticed one more point . Issue is not only with channel4 but it is with all the channels. 

    Channel 0 data affects other channel data.

    I will try out with different Sequence number and will update here on the same.

    Thanks,

    Mitesh

  • Hello Mitesh,

    There is a known errata on channel 0 sampling. Please check the errata document

    Regards
    Amit
  • Hello Amit,

    I have tried changing sequencers for both my adc. Now I am having different sequencer for each of my adc but still facing the same issue.
    Also I have observed one more point of ADCChannel 0 data affects ever other channel data above channel 0.
    In same particular manner my channel one data does not affects channel 0 data but it does affects ever other adc data above channel 1.

    Please find below code if you can get any point if I am missing in the code.


    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    GPIOPinTypeADC(GPIO_PORTD_BASE,GPIO_PIN_3);
    ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 1);
    ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH4 | ADC_CTL_IE | ADC_CTL_END);
    ADCSequenceEnable(ADC0_BASE, 3);


    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    GPIOPinTypeADC(GPIO_PORTE_BASE,GPIO_PIN_3);
    ADCSequenceConfigure(ADC1_BASE, 1, ADC_TRIGGER_PROCESSOR, 1);
    ADCSequenceStepConfigure(ADC1_BASE, 1, 0, ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END);
    ADCSequenceEnable(ADC1_BASE, 1);

    int test = 0;
    int test1 = 0;
    while(1)
    {
    ADCSequenceStepConfigure(ADC1_BASE, 1, 0, ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END);

    ADCIntClear(ADC1_BASE, 1);
    ADCProcessorTrigger(ADC1_BASE, 1);
    while(!ADCIntStatus(ADC1_BASE, 1, false))
    {
    }
    ADCIntClear(ADC1_BASE, 1);
    ADCSequenceDataGet(ADC1_BASE,1, ADC0Val);
    // ADCSoftwareOversampleDataGet(ADC0_BASE,1,ADC0Val,1);
    test = ADC0Val[0];

    ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH4 | ADC_CTL_IE | ADC_CTL_END);
    ADCIntClear(ADC0_BASE, 3);
    ADCProcessorTrigger(ADC0_BASE, 3);
    while(!ADCIntStatus(ADC0_BASE, 3, false))
    {
    }
    ADCIntClear(ADC0_BASE, 3);
    ADCSequenceDataGet(ADC0_BASE,3, ADC1Val);
    // ADCSoftwareOversampleDataGet(ADC0_BASE,1,ADC0Val,1);
    test1 = ADC1Val[0];
    UARTprintf("ADC:%d\t\t",test);
    UARTprintf("ADC1:%d\n",test1);
    SysCtlDelay(SysCtlClockGet() / 12);
    }

    Thanks,
    Mitesh
  • Hello Mitesh

    Can you wrap it as a CCS project and attach it to the forum?

    Regards
    Amit
  • Hi Amit,

    I will surely do it tomorrow early morning.

  • Hello Mitesh,

    I ran the test code and it is working fine. When I connect PE3 to 3.3V, it reads 0xFFF and when I connect it to 0V it reads ~ 0x0. The same is the case for PE2 pin. Now looking at your code, I do see that you convert the Analog pin to GPIO and back, which is not a good idea.

    I would suggest configuring the pins once and then using different sequencers to sample it.

    Regards
    Amit
  • Hello Amit,

    Sorry for replying it late. Was out of the town.

    Ya I tried changing ADC pin to GPIO pin as I thought that could be one of the option.

    With my previous code I am alsogetting oxFFF at 3.3V and 0x000 at 0V but actual issue is in between. Like If I keep PE2(Channel 1) at suppose 1.5V and  if I vary Channel 0 from 0v to 3.3V athen Channel 1 data varies. 

    I would like if you can test the same connecting 2 potentiometer.

    Thanks and Regards,

    Mitesh

  • Hi Amit,
    I have also tried with below code in same project. But still facing same issue.
    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_memmap.h"
    #include "driverlib/adc.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"

    void InitConsole(void)
    {
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    UARTStdioConfig(0, 9600, 16000000);
    }

    int main(void)
    {
    uint32_t ADC0Val[8];
    SysCtlClockSet(SYSCTL_SYSDIV_10 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
    InitConsole();

    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    GPIOPinTypeADC(GPIO_PORTE_BASE,GPIO_PIN_3 | GPIO_PIN_2);
    ADCSequenceDisable(ADC0_BASE, 0);
    ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_PROCESSOR, 0);
    ADCSequenceStepConfigure(ADC0_BASE, 0, 0, ADC_CTL_CH1);
    ADCSequenceStepConfigure(ADC0_BASE, 0, 1, ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END);
    ADCIntEnable(ADC0_BASE, 0);
    ADCSequenceEnable(ADC0_BASE, 0);

    int test = 0;
    int test1 = 0;
    while(1)
    {
    ADCIntClear(ADC0_BASE, 0);
    ADCProcessorTrigger(ADC0_BASE, 0);
    while(!ADCIntStatus(ADC0_BASE, 0, false))
    {
    }
    // ADCSequenceDataGet(ADC0_BASE, 0, ADC0Val);
    ADCSoftwareOversampleDataGet(ADC0_BASE,0,ADC0Val,2);
    test = ADC0Val[0];
    test1 = ADC0Val[1];

    UARTprintf("ADC0:%d\t\t",test);
    UARTprintf("ADC1:%d\n",test1);
    SysCtlDelay(SysCtlClockGet() / 12);

    }
    }

    You can check this code with 2 potentiometer.

    Thanks,
    Mitesh
  • Hello Mitesh

    I do not have access to potentiometer as readily as you have. The code looks fine and I think the issue you are seeing is because of the errata where AIN0 is affecting the reading on AIN1.

    ADCSequenceDataGet(ADC0_BASE, 0, ADC0Val); is the correct function to use.

    Regards
    Amit
  • Hi Amit,

    I have tried using both the your bmentioned function earlier which was not working.

    Also I would like to add few more detail if you can test or recollect any thing similar.

    I have tested this issue with with different combinations like ADC Channel 0 and Channel 1, Channel2 and Channel3.

    I have observed that Channel 0 affects Channel1, Channel2, Channel3 and so on. and variation on other channel due to channel 0 is greater on channel 1 and it gets decrease as we move further with Channel2, Channel3, etc.

    In same particular manner Channel 1 data does not affect Channel0 but it affects every other channel from Channel2, Channel 3 etc.

    I have tried this code on different launchpads and also on one of the custom board but issue remains the same.

    Kindly let me know if you get its solution or links related to the same.

    Thanks for support,

    Mitesh