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.

Tiva ADC Sequencer with different step sources

Hi, I'm trying to measure some ADC channels with the same sequencer. I took a base on the Chapter 5 of Tiva's Workshop. So, my (interrupted) original code is working perfectly:

#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "driverlib/sysctl.h"
#include "driverlib/adc.h"
#include "driverlib/interrupt.h"

uint32_t ui32ADC0Value[4];

volatile uint32_t ui32TempAvg;
volatile uint32_t ui32TempValueC;


int main(void) {

	SysCtlClockSet(
	SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_SYSDIV_5);

	SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

	ADCSequenceDisable(ADC0_BASE, 1);
	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);

	IntEnable(INT_ADC0SS1);
	ADCIntEnable(ADC0_BASE, 1);
	ADCSequenceEnable(ADC0_BASE, 1);

	IntMasterEnable();

	while (1)
	{
	}

}

void ISRHandler(void) {

	ADCIntClear(ADC0_BASE, 1);
	ADCSequenceDataGet(ADC0_BASE, 1, ui32ADC0Value);

	ui32TempAvg = ui32ADC0Value[3]; //(ui32ADC0Value[0] + ui32ADC0Value[1] + ui32ADC0Value[2]	+ ui32ADC0Value[3] + 2) / 4;

	ui32TempValueC = (1475 - ((2475 * ui32TempAvg)) / 4096) / 10;

}

However if I change this part

        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);

by this part (so the steps 0 to 2 read other channels, instead of ADC_CTL_TS):


	ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH0);
	ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH1);
	ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_CH2);
	ADCSequenceStepConfigure(ADC0_BASE, 1, 3,
			ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_END);

the step 3 (where I measure ADC_CTL_TS) goes crazy, ranging values totally incoherent. Why? (and how should I do it?) Thanks.

  • Hello Pablo,

    Where have you configured the CH0-CH2 to be Analog IO's?

    Regards
    Amit
  • I did not. But that's not the case. At this point I am just interested in step 3. Thanks.
  • Anyway, I have a more complex code where I configure this and other things. As the problem occurred, I did this simpler code using the workshop as basis. I understand that I can use different sources for the steps in the same sequencer, right?
  • Hello Pablo

    Yes, that is correct. Each step can be a different analog channel

    Regards
    Amit
  • Pablo Rego said:
    I have a more complex code where I configure this and other things.

    And - it's revealed here - that the "more complex code" does not run/execute to your satisfaction.   Absence of that code does not (readily) enable your remote helpers to diagnose/assist.

    Are you aware that the temperature you are measuring is that of the MCU's die - and bears little relationship to the temperature of your board?   The fact that you report widely varying - ADC values (likely) indicates that your packing/unpacking of the step sequencer's values has some issue...

  • The behavior is the same. The fact is that if I only change this

    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);

    to this

    ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH0);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH1);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_CH2);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 3,
    ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_END);

    causes the problem. I am reading only the step 3 in both cases. In the first case the temperature is read correctly, and there is no big variations. In the second case, however, does not read anything which makes sense. Since I am reading only step 3 in both cases, I would expect that a change in configuration of the other steps would not interfere in step 3 measurement.
  • Please do not consider the "more complex code" comment. The problem is in the current code.
  • That's a great & quick response - thank you.

    Might you detail how you "read" only step 3?   My understanding is that 4 values are converted (based upon your code) and that you must perform 4 "reads" to extract the value harvested by "step 3!"   (it is a bit confusing - suggest that you look @ several of this vendor's ADC examples) - you'll note that multiple reads are required to extract the higher order values from the step sequencer.

    Dawns further that if you switch to a single step sequencer - or change your code to just perform a single step conversion - results will improve!

  • Hello Pablo,

    The data is sampled for every step and then put in a FIFO. You cannot read just Step-3 data without reading the other Step data.

    Regards
    Amit
  • Yes, I read the 4 steps at once, using

    ADCSequenceDataGet(ADC0_BASE, 1, ui32ADC0Value);

    which is defined as 

    uint32_t ui32ADC0Value[4];

    But I am only interested in ui32ADC0Value[3], which corresponds to the step 3 measurement.

  • Yes Amit, I am reading the 4 steps.
  • Hello Pablo,

    Could it be possible that the the FIFO pointers have been misaligned. Before enabling the clock to the ADC, perform a peripheral reset using SysCtlPeripheralReset API call and then check. Alternatively, connect the Analog Pins to a known voltage source and see if the value being read on the ui32ADC0Value[3] corresponds to the same as it may explain misaligned pointers...

    Regards
    Amit
  • Hello Amit,

    I added
    SysCtlPeripheralReset(ADC0_BASE);

    before the line where I write IntEnable(INT_ADC0SS1);
    but nothing changed.

    Also, ui32ADC0Value[3] reads ADC_CTL_TS, so it's not attached to an analog pin.
  • Hi Amit,

    That's a very original diagnosis (far beyond anything I could come dream up). Don't believe - in our 8-9 year history w/LMI/your parts - that we've ever encountered, "misaligned ADC pointers."

    Would an incomplete sequence of ADC "reads" be likely to cause that? Thanks...
  • Hello cb1

    Yes, an incomplete read of the sequencer could result in that. CCS (I know) when put back into the mode for re-run does not do a core reset but a CPU reset only. Unless the user actually does "System Reset" in the debug environment the result are often misaligned pointers.

    Regards
    Amit
  • Hello Pablo,

    So what are the "crazy" values you read?

    Regards
    Amit
  • Hello Amit,

    I don't think it is the case. I always run the debugger with the "Reset target during program load to Flash memory". Also the SysCtlPeripheralReset did not work.
  • When I run the debugger using the code

    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);

    I get values around 2025, ranging from 2020 to 2038. So I get 25 Celsius degrees correctly.

    When I run the debugger using

    ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH0);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH1);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_CH2);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 3,
    ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_END);

    I get the "crazy" values of step 3, ranging from 1400 to 2800.
  • I am getting something a bit stranger now. For the sake of clearance I decided to configure the GPIOs related to the pin voltage measurements. So I attached channels 5, 6 and 7 to steps 2, 1, and 0, which correspond to GPIO pins D0, D1 and D2. The whole resulting code is

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_ints.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/adc.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"

    uint32_t ui32ADC0Value[4];

    volatile uint32_t ui32TempAvg;
    volatile uint32_t ui32TempValueC;


    int main(void) {

    SysCtlClockSet(
    SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_SYSDIV_5);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

    ADCSequenceDisable(ADC0_BASE, 1);
    ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_ALWAYS, 0);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    GPIOPinTypeADC(GPIO_PORTD_BASE,
    GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2);

    ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH7);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH6);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_CH5);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 3,
    ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_END);

    IntEnable(INT_ADC0SS1);
    ADCIntEnable(ADC0_BASE, 1);
    ADCSequenceEnable(ADC0_BASE, 1);

    IntMasterEnable();

    while (1)
    {
    }

    }

    void ISRHandler(void) {

    ADCIntClear(ADC0_BASE, 1);
    ADCSequenceDataGet(ADC0_BASE, 1, ui32ADC0Value);

    ui32TempAvg = ui32ADC0Value[3];

    ui32TempValueC = (1475 - ((2475 * ui32TempAvg)) / 4096) / 10;

    }

    So. If I run the code, the step 3 problem persists, If I do not check "Reset target during program load to Flash memory". If I DO check it, the ISRHandler is not called, and the interrupt (when I pause the debugger) goes directly to FaultISR handler on NVIC.
  • The NVIC problem is fixed when I put
    SysCtlPeripheralReset(SYSCTL_PERIPH_ADC0);

    right after the call
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

    Now the step 3 problem is again the only problem.
  • Here's my belief - if you "float" those other ADC inputs - rather than properly drive them - the ADC's input capacitor may become "disordered" - and that may explain your improper readings.

    Some "battle fog" has landed here (22 back-forth) now - have you (really) and properly configured those 3 ADC input pins?   If not - and you then run your (failing) code - bets are "off" on code's success.   You have to be very careful not to confuse ADC Channel Number with MCU pinouts or "step" in the step sequencer...
     
    There's a quick/easy and dirty test of my theory - simply tie each of those 3 ADC channels (which precede your temp sense step) to ground - and note (and report) the results...   Bet you that will improve (although may not completely fix) your results...

    Still - do keep in mind that MCU's die temp bears little relationship to your board temp - and will change w/System Clock and current draw of your MCU...

  • Hello Pablo,

    Instead of using ALWAYS TRIGGER, I would suggest moving to PROCESSOR TRIGGER first to see if the conversions happens correctly. Do note that when using ALWAYS_TRIGGER, there are chances that the FIFO OVERRUN may occur.

    Regards
    Amit
  • Hi Amit,

    Re: Always Trigger.

    That's great - wager tall stack (black) that you've just "nailed it."

    We've never/ever employed, "Always Trigger" and never been so plagued by ADC pointer "running amuck."

    In the (unlikely) event that issue remains - I'd apply 4 "stepped voltages" to each of the 4 ADC channels. (do away with "TS" during this test.)

    1V0 - 1V5 - 2V0 - 2V5 (that's 1.0 - 2.5V) works nicely for us - and will quickly pinpoint where the conversions are befouled... (we actually have several small pcbs which provide 8 stepped voltages - used for our test/verification.)   By changing the input voltage @ top of the divider - we can "shift" each signal up/down - as/if required...

  • Hello cb1-,

    I will ground those other 3 ADC channels, but I really hope it doesn't work. Look, imagine that you are feeding the board with 3 analog control signals (and the TS); 1 wire cable breaks; and you might have all 4 channels "disordered", breaking also the other 3 channels instead of only one? I would think it could be a major hardware issue in the board's design; this kind mistake I usually don't see my students to commit... Thus I like to think it's a problem in my code.

  • It didn't work (fortunately). BUT it might have given some clues. I'm using the breakpoint option to "Refresh All Windows", so I see that always 3 values go wandering near 0, and the other value (which could correspond to the TS) keep walking around 1940. It looks like a temporal misalignment.
  • Hi Pablo,

    First - we feel your pain - but you are proceeding in an orderly fashion - that's always good.

    I agree w/your assessment of, "ADC's handling/performance" when enabled ADC channels, "float."   May I note that other - ARM MCU vendors - suffer similar limitations?  

    My small tech firm believes strongly in KISS - that "stepped input voltage" introduced to all 4 of your (properly) enabled ADC channels (please eliminate the TS during this simple test) will best illustrate any, "Pointer disorder!"   That should be high (imho) on your priority list.

    A final point - always distrubing - and a great, "time/effort/money waster" is dreaded, "Single board anomaly!"   Have you a 2nd board with which to duplicate your set-up and test?   Broader findings (always) prove of more interest to vendors (and to outside helpers)...

    Final grasp - your MCU system clock must run at (or beyond) 16 MHz for proper ADC operation.

  • Hello Amit, 

    I changed to ADC_TRIGGER_PROCESSOR, but the results did not change (not a slight change). 

    The resulting code is

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_ints.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/adc.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    
    uint32_t ui32ADC0Value[4];
    
    volatile uint32_t ui32TempAvg;
    volatile uint32_t ui32TempValueC;
    
    int main(void) {
    
    	SysCtlClockSet(
    	SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_SYSDIV_5);
    
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    	SysCtlPeripheralReset(SYSCTL_PERIPH_ADC0);
    
    	ADCSequenceDisable(ADC0_BASE, 1);
    	ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);
    
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    	GPIOPinTypeADC(GPIO_PORTD_BASE,
    	GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2);
    
    	ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH7);
    	ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH6);
    	ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_CH5);
    	ADCSequenceStepConfigure(ADC0_BASE, 1, 3,
    	ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_END);
    
    	IntEnable(INT_ADC0SS1);
    	ADCIntEnable(ADC0_BASE, 1);
    	ADCSequenceEnable(ADC0_BASE, 1);
    
    	IntMasterEnable();
    
    	while (1) {
    		ADCProcessorTrigger(ADC0_BASE, 1);
    	}
    
    }
    
    void ISRHandler(void) {
    
    	ADCIntClear(ADC0_BASE, 1);
    	ADCSequenceDataGet(ADC0_BASE, 1, ui32ADC0Value);
    
    	ui32TempAvg = ui32ADC0Value[3];
    
    	ui32TempValueC = (1475 - ((2475 * ui32TempAvg)) / 4096) / 10;
    
    }
    

  • Pablo Rego said:
    I see that always 3 values go wandering near 0

    Our posts just crossed.   Most any mixed signal ADC will be greatly challenged over 3-4 least significant bits.   If your "wander" is w/in 16 ADC counts - I'd rate that as normal.   (again - this is a weakness of all such MCUs - not confined to this vendor. [we use ARMs from 4 other vendors, too])

    Have you changed to, "Processor Trigger" and are you waiting for conversions to be complete?   May I suggest that you re-read and review, "examples/peripherals/adc/"single_ended_adc.c"  (that file name from memory - should be close - there's a wealth of tips contained - that file...)

    [edit]  I fly shortly - quick read your (most recent) code does not reveal proper "waiting" for conversions to truly complete!  (well illustrated in "single-ended.c")  Suspect strongly that this could be crucial - again I read code quickly - please check...

    [edit]  Alas we crossed (again!)   I see that you have correct system clock & that you are, Processor Triggered - both good.

    Now - please take no offense - but your code:

        ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH7); 

        ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH6);

        ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_CH5);
     
    Are you quite sure that Channels 7-5 appear indeed on your selected Port D pins?   (sometimes the sequence number, step number, MCU pinout number and ADC channel number appear as a maze - many of our clients have "missed" here...)
  • For clarity - here's the relevant portion of file, "single_ended.c"

           // Wait for conversion to be completed.
            //
            while(!ADCIntStatus(ADC0_BASE, 3, false))
            {
            }

            //
            // Clear the ADC interrupt flag.
            //
            ADCIntClear(ADC0_BASE, 3);

            //
            // Read ADC Value.
            //
            ADCSequenceDataGet(ADC0_BASE, 3, ulADC0_Value);

    Now this may not be your step sequence - I wanted to highlight the necessity to "wait" for conversions to complete!  Note that ADCSequenceDataGet() is "held off" until the conversion has had time to (properly) compete...

  • Hi cb1_mobile,

    Thanks for your help. I really appreciate it.

    I don't know for other vendors. In ARM matters, I've been always with TI for a few years, and it's been working. This case surprised me a lot, since it's a very simple case from a very simple code; I think I forgot to include some configuration in this code.

    I removed the TS, put CH5 in its place, and one of the ADC channels put in VCC, so we could trace where the higher measurement would come from. Same result, the high value keeps walking from the steps.

    Also I tried with another board, a new one. But same results too.

    And about the MCU clock, I am already using SYSCTL_XTAL_16MHZ, driving PLL with SYSCTL_SYSDIV_5. So it means that the System Clock is 40 MHz.
  • I would think of it in a one sequence-polling code. Not an interrupted one. Don't the ISR for sequence 1 is called only the the sequence is already finished?
  • Might I suggest you "try" that suggested code block? (you've not achieved satisfaction under current method)
    My preference (always) is KISS - and "single_ended.c" has worked (always) for ALL of our clients!
    Let's get something working - later (if you desire) Amit & you may delve into "fine details" of your present "plague."
  • Hello Pablo,

    Is the Memory or module browser window open when doing the debug in CCS?

    Regards
    Amit
  • A fast read through the thread didn't reveal whether you have checked the errata for your processor? IIRC, the internal temperature sensor circuit has a flaw that causes it's output to the ADC not settle fast enough - you have to read multiple samples from it in a row and discard the first two, or something similar. That would explain why your first example works and the other not.
  • Hi Amit,

    May I note that (my) suggested "single_ended.c" AVOIDS the complications you've just identified by sending results via UART?

    When KISS is deflected - relatively simple ADC issue extends to 30 (or more) back-forth - "fogs learning" for future readers...  (steers you away from other, more vital issues)

  • @Veikko,

    Tres bien! (that's now TWO for you - w/in same week!)

    Everyone here (but for you) missed that.

    RTFM (and chip errata) always makes sense. And especially so when problems visit...

    Still - that "TS" proves of very limited value - poster has never justified "why" it's a big deal...  (we all may have "chased our tail" for little (end) gain...)

  • I did it (include the "while" wait). It did not change. Anyway, single_ended.c is far simpler, it uses only one analog channel. I tested the single_ended.c, it works. Also works when I put in my code only the step 0 to be measured, like
    ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH5 | ADC_CTL_IE | ADC_CTL_END);

    The problem is when we mix the sources.
  • Hello Amit,

    Yes. The memory browser was opened, so I closed. Nothing changed.
  • Hello Veikko,

    The problem arises also when I mix only analog pin channels. Say if I have

    ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH7);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH6);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_CH5);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 3,
    ADC_CTL_CH5 | ADC_CTL_IE | ADC_CTL_END);

    and have grounded CH5 and CH6.
  • Guys, only for clarification, since we have done so many tests, the updated version of the code is the following:

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_ints.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/adc.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    
    uint32_t ui32ADC0Value[4];
    
    volatile uint32_t ui32TempAvg;
    volatile uint32_t ui32TempValueC;
    
    int main(void) {
    
    	SysCtlClockSet(
    	SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_SYSDIV_5);
    
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    	SysCtlPeripheralReset(SYSCTL_PERIPH_ADC0);
    
    	ADCSequenceDisable(ADC0_BASE, 1);
    	ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);
    
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    	GPIOPinTypeADC(GPIO_PORTD_BASE,
    	GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2);
    
    	ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH7);
    	ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH6);
    	ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_CH5);
    	ADCSequenceStepConfigure(ADC0_BASE, 1, 3,
    	ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_END);
    
    	IntEnable(INT_ADC0SS1);
    	ADCIntEnable(ADC0_BASE, 1);
    	ADCSequenceEnable(ADC0_BASE, 1);
    
    	IntMasterEnable();
    
    	while (1) {
    		ADCProcessorTrigger(ADC0_BASE, 1);
    	}
    
    }
    
    void ISRHandler(void) {
    
    	while (!ADCIntStatus(ADC0_BASE, 1, false)){};
    
    	ADCIntClear(ADC0_BASE, 1);
    	ADCSequenceDataGet(ADC0_BASE, 1, ui32ADC0Value);
    
    	ui32TempAvg = ui32ADC0Value[3];
    
    	ui32TempValueC = (1475 - ((2475 * ui32TempAvg)) / 4096) / 10;
    
    }
    

  • cb1_mobile said:
    Still - that "TS" proves of very limited value - poster has never justified "why" it's a big deal...  (we all may have "chased our tail" for little (end) gain...)

    Back in the day when I got my first Stellaris LaunchPad - which was my first touch with an ARM uC btw, it was an easy way to demonstrate that your ADC code works (luckily, I started with hardware averaging = 64, so didn't see the errata'd problem as my first thing) without having to attach anything to the LaunchPad. As for any real use, not much probably - maybe a "free" relative temperature sensor. You could use it to see if the temperature in your case is rapidly rising, for example. Forget it for absolute values.

  • Pablo Rego said:
    I tested the single_ended.c, it works

    Indeed - yet many here knew that.   And this verifies that your basic set-up/config is correct/proper.

    Nothing prevents you from the simple extension of "single_ended.c" to a larger step sequence.

    Far earlier here I suggested that you drive multiple analog channels with known, stepped (proper) voltages.  In compliance w/KISS - that will confirm that some/most/all of your "CUT" (ADC channels under test) work in accord w/your code.   Armed w/that - should you still seek to implement your earlier method - you now enjoy a mechanism to highlight when/where the conversions, "break!"

  • I think that maybe we turned the problem complex unnecessarily. The problem actually is simple. I have an ADC module, ADC0. ADC0 (as well as ADC1) has the sequencer 1 which has 4 measurement steps, which I can attach each one to a different source, according to the datasheet. So I need to attach 3 analog pins to the first steps, and the temperature sensor to the last one.

    So I configured the system clock

    SysCtlClockSet(
    SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_SYSDIV_5);

    After configured and reset the ADC0 peripheral

    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    SysCtlPeripheralReset(SYSCTL_PERIPH_ADC0);
    

    Disabled the sequencer, configured, enabled the ADC0 peripheral, and set the GPIO pins to the ADC type

    ADCSequenceDisable(ADC0_BASE, 1);
    ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2);
    

    So I configured the steps

    ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH7);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH6);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_CH5);
    ADCSequenceStepConfigure(ADC0_BASE, 1, 3, ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_END);
    

    Enabled the interrupt and the sequencer

    IntEnable(INT_ADC0SS1);
    ADCIntEnable(ADC0_BASE, 1);
    ADCSequenceEnable(ADC0_BASE, 1);
    IntMasterEnable();
    

    And in the main while loop, triggered the processor

    while (1) {
    ADCProcessorTrigger(ADC0_BASE, 1);
    }
    

    Also in the ISRHandler I am waiting redundantly for the measurements end, clear the interrupt, and get the data buffer.

    while (!ADCIntStatus(ADC0_BASE, 1, false)){};
    ADCIntClear(ADC0_BASE, 1);
    ADCSequenceDataGet(ADC0_BASE, 1, ui32ADC0Value);

    I think the steps above now are correct, but obviously I forgot to include some configuration. Given all the tests we've done, I may have to conclude that it's not a hardware problem, it's not a TS errata or TS specific problem, it's not a capacitance problem. For me it's clear it's a software problem, maybe a Tivaware library registry lack of configuration (I'm using TivaWare_C_Series-2.1.0.12573), or a simple call that I didn't do. So the problem is: where in the code did I miss a configuration?

  • Hello Pablo

    One comment though. In the main loop of triggering the ADC, you are triggering the ADC before a conversion is completed. What you need to do is to set a flag in the interrupt handler when the read is complete and in the main while loop wait for the flag to be set after ADCProcessorTrigger and then subsequently clear it.

    I suspect you have ADC#01 errata that you are running into even with the Processor Trigger Option.

    Regards
    Amit
  • Hello Amit,

    It worked! I removed the processor trigger from the main while() loop, and included only a call before it, and at the end of the ISR handler. I still cannot use the ADC_TRIGGER_ALWAYS, but this certainly already solves my problem.

    Thank you very much for all help (for all guys).

    Regards
    Pablo.
  • @Pablo,

    Glad that you persisted and resolved issue.   Devil so often in (fine) detail.

    May I commend you for thanking (all guys) along w/Amit?   Most here - too seldom - thank Amit - and rarely extend such to "outsiders."

    Good for you...