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.

Setting up an adc interrupt

Other Parts Discussed in Thread: TM4C1294NCPDT, LM3S8971

Hello,

Sorry for the simple question, I'm still new to this. I saw some similar questions posted but they didn't help me much.

I'm working on a TM4C123GL eval board.

I'm trying to invoke adc interrupts by the timer but the program doesn't enter the interrupt routine.

Hope someone can easily help me, I'm probably forgetting a crucial line or something.

This is the relevant code:  (initialize is called at the beginning of main())

void initialize()
{
//
// Enable lazy stacking for interrupt handlers. This allows floating-point
// instructions to be used within interrupt handlers, but at the expense of
// extra stack usage.
//
ROM_FPULazyStackingEnable();

//
// Set the clocking to run directly from the crystal.
//
ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_16MHZ);

//
// Enable processor interrupts.
//
ROM_IntMasterEnable();

// Set up timer
//Timer2 for ADC cpu1
//
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER2);
ROM_TimerConfigure(TIMER2_BASE, TIMER_CFG_PERIODIC);
TimerConfigure(TIMER2_BASE, (TIMER_CFG_A_PERIODIC |TIMER_CFG_B_PERIODIC));
TimerLoadSet(TIMER2_BASE, TIMER_A, (SysCtlClockGet()/50)); //if just clock set so every 1 sec //if /50 every 20 mS
TimerControlTrigger(TIMER2_BASE, TIMER_A, true);
TimerEnable(TIMER2_BASE, TIMER_A);

//
// Configure the ADC.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0)));

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_0| GPIO_PIN_1| GPIO_PIN_2| GPIO_PIN_3);

ADCSequenceConfigure(ADC0_BASE, 2, ADC_TRIGGER_TIMER, 0);
ADCSequenceStepConfigure(ADC0_BASE, 2, 0, ADC_CTL_CH0);
ADCSequenceStepConfigure(ADC0_BASE, 2, 1, ADC_CTL_CH1);
ADCSequenceStepConfigure(ADC0_BASE, 2, 2, ADC_CTL_CH2);
ADCSequenceStepConfigure(ADC0_BASE, 2, 3, ADC_CTL_CH3 | ADC_CTL_END | ADC_CTL_IE);
ADCSequenceEnable(ADC0_BASE, 2);
ADCIntEnable(ADC0_BASE, 2);
}

I have the ISR that only prints a word for now and it is linked to ADC Sequence 2 in the startup_ccs file.

Thanks for the help!

Nadav

  • Hi Nadav,

    Can you have a look at some of the existing posts on ADC interrupt implementations and see if these can help? Here are some links below or you can simply use the search utility to search for ADC Interrupts.

    e2e.ti.com/.../1220455
    e2e.ti.com/.../274107
    e2e.ti.com/.../448946
    e2e.ti.com/.../387919
    e2e.ti.com/.../472635

    Once you review these, let me know if you have any additional questions or issues and we can help iron out the details.
  • Thanks.
    I'll take a look at these examples when I'm back in the office on sunday.
  • Okay, I managed to get around it.
    for some reason it works when I use
    IntEnable(INT_ADC0SS0);
    Instead of
    ADCIntEnable(ADC0_BASE, 0);
  • Hi Nadav,

    >ADCSequenceStepConfigure(ADC0_BASE, 2, 3, ADC_CTL_CH3 | ADC_CTL_END | ADC_CTL_IE);

    Wouldn't you think it odd that enabling sequencer 0 interrupt has any part of sequencer 2 that has been configured?

    Typically the step above Tivaware programs only the last step with channel no END or IE and a final step is required only to indicate END to the sequencer logic.  Our find has been any step can interrupt IE but not the END step when IE is also being configured to a specific channel.

    Like this:

    ADCSequenceStepConfigure(ADC0_BASE, 2, 3, ADC_CTL_CH3 | ADC_CTL_IE) ;

    ADCSequenceStepConfigure(ADC0_BASE, 2, 4, | ADC_CTL_END);

  • Hi BP,

    Yea its my bad I forgot to mention in the second post that I changed it to sequencer 0 in order to see if it would help.

    I'll try to see if what you said can also help me.

    Thanks.

  • Hello Nadav

    You need to use both ADCIntEnable and IntEnable API. The first API call enables the interrupt bit in the ADC controller and the second API enables the registering of the interrupt from the ADC controller in the NVIC routine.

    Regards
    Amit
  • Hello BP101

    Sequencer 2 has only 4 entries. So the last line

    ADCSequenceStepConfigure(ADC0_BASE, 2, 4, | ADC_CTL_END);

    is not a correct and nor is the use of | ADC_CTL_END.

    Regards
    Amit
  • Okay, great. thanks Amit.
  • Hello Nadav

    Also do note that the interrupt enable API call must have the argument INT_ADCxSSy where X = the ADC instance (0 or 1) and Y is the sample sequencer number (0 to 3)

    Regards
    Amit
  • Hi Amit,

    Arguably the poster inferred Sequencer 0 interrupt was responding to his posted code, SS0 has 8 steps. The point being made regardless of particular TM123 ADC sequencer limited 4 steps was; IE being set to the sample channel with END does not work to trigger an interrupt. That was the point being made not the sequencer step limitation of a particular ADC module.

    Data sheet ADC text mentions sequencer step can END on any step but leaves out words "Except on the channel or step having TS."  At least the TM4C129 has issues with setting END on samples step other than TS samples often being last step. Only stands to reason Tivaware has limitations passing switches to ADC registers in certain combinations.

    Several times have pointed that find this forum and posters seemingly are aware of limitation, are unaffected by it or simply choose to ignore the warning.

  • Hello BP101

    I would disagree. The IE and the END can be set together and on a channel with or without TS. If you can publish a code that shows that it is not true, then I would be more than happy to debug the same.

    Regards
    Amit
  • Function call don't pass the switches if you END on a sampled Channel step. Several times have checked debug registers and they don't get programmed. It could be tool chain related being data sheet suggest we can end on any step. Yet HWA method described here works to program all sequencers accordingly CCS debug register view confirms.

    Oddly we can configure IE on any channel sample step but not sample any channel data on the last step except for internal TS samples. Recently pleased to discovered can IE on any/all channel sample steps, works only to END last step and do no external channel sample on that very last step. That seems to be Tivaware limitation, we have to sacrifice the last sample step END or END/IE. Makes sense to then save very last step dedicated to END with TS.
  • Hello BP101,

    So are you trying to say that if IE and END are used together then the registers corresponding to the steps in the sequencer does not have both the bits set?

    Regards
    Amit
  • Hi Amit,

    Only if you attempt to set a channel in that last step with IE, END. I believe Tivaware may program all but the step prior to last. Have noticed this behavior SS0 even configuring a few steps, the last step must be sacrificed as no channel sample and only configure IE, END yet TS channel configures with IE, END.
  • Hello BP101

    I disagree and there are code example in TivaWare which show that it is not possible, unless you can send over a project which shows that what I am stating is incorrect. Of course the project has to be in CCS (if you are using CCS) and a TivaWare version 2.1.0 or higher.

    Regards
    Amit
  • Hi Amit,

    Just to confirm understanding, the 1st sample works the 2nd does not yet the 3rd does. And your inferring all 3 methods below should work?

    Examples below use compiler v.5.2.7 several earlier compiler revisions, Tivaware v2.1.0.12573 and v2.1.0.1171. For what ever reason the 2nd configuration method no matter the step end, SS0 refuses to configure the sequencer last step shown. A sacrificial step is mandated (no channel) can be programmed for 1st and 3rd sample configuration or the sequencer fails to interrupt and or may even fault the MCU.  

    ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 0, PIN_CH3);
    ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 1, PIN_CH4);
    ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 2, ADC_CTL_END | ADC_CTL_IE);
    ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 0, PIN_CH3);
    ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 1, PIN_CH4);
    ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 2, PIN_CH5 | ADC_CTL_END | ADC_CTL_IE);
    ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 0, PIN_CH6);
    ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 1, PIN_CH7);
    ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 2, ADC_CTL_TS | ADC_CTL_END | ADC_CTL_IE);

  • BTW Stellaris team released SW very same 1st & 3rd method, never 2nd method. Always wondered same as your reason, why can't we sample in that step. There is a reason but the Tivaware sequencer step configuration function is highly complex code so just did the HWA and it works all sequencers every time.
  • This sequence (so to speak) 

    	/* Configure sequence for converter 0.  Channels 0 - 5.  Interrupt on 
    	   completion of channel 5. */
        ADCSequenceStepConfigure(ADC0_BASE, 0, 0, ADC_CTL_CH0);
        ADCSequenceStepConfigure(ADC0_BASE, 0, 1, ADC_CTL_CH1);
        ADCSequenceStepConfigure(ADC0_BASE, 0, 2, ADC_CTL_CH2);
        ADCSequenceStepConfigure(ADC0_BASE, 0, 3, ADC_CTL_CH3);
        ADCSequenceStepConfigure(ADC0_BASE, 0, 4, ADC_CTL_CH4);
    ADCSequenceStepConfigure(ADC0_BASE, 0, 5, ADC_CTL_CH5 | ADC_CTL_IE | ADC_CTL_END);

    has never shown an issue.

    You've not shown how you defined PIN_IPHASEB etc... and ADC_CTRL_TS should be ADC_CTL_TS (I presume a typo) but I see no effective difference between you last two unless you have mis-defined PIN_IPHASEB.

    Robert

  • Hello BP101,

    The above sequence you have shown does not define what the value of PIN_VSENSE, PIN_VBEMFB and PIN_IPHASEB is? Also do note that 1st is "logically" incorrect as it does not specify which channel....

    Regards
    Amit
  • Hello BP101

    I don't know of any Stellaris Team member who has released a software... Please do let me know which Stellaris team are you referring to!!!

    Regards
    Amit
  • Hi Amit,

    >>The above sequence you have shown does not define what the value of PIN_VSENSE, PIN_VBEMFB and PIN_IPHASEB is? Also do note that 1st is "logically" incorrect as it does not specify which channel....

    The channels are arbitrary does not matter. The examples illustrate specific sequencer configuration (patterns) of where END and IE are placed relative to any sampled channel. 

    Illustration seemed fairly self explanatory in the light of posting methodic text suggesting how the configuration pattern failure occurs.  

  • That's very interesting and perhaps your testing on TM4C123 tool chain?

    Perhaps it could be the TM4C1294NCPDT tool chain.

    I simply avoid setting any channel in last step with END and all sequencers configure every time without issues. That same issue is present in all sequencers, must sacrifice last step for END, END/IE and or the latter with TS. Oddly the LM3S8971 tool chain had the very same issue.

    Recall checking Debug register view last time attempted configuring channel last step. Seem to recall SS0 and SS1 very last step was only being configured and the preceding steps in the sequencer register were simply missing.
  • Hi Amit,

    >>Stellaris team are you referring to

    That is to say LM3S forum typically referred Luminary Micro team as Stellaris MCU's support team. Never was aware Stellaris support team mentioned by any other name after the merger.
  • Hello BP101,

    I don't see a simplified CCS project that can reproduce the issue from you yet. TI has code working with the suggested solution for both TM4C129x and TM4C123x as part of the touch library for LCD panel in TivaWare 2.1.3.

    FYI: TM4C1294NCPDT is not a tool chain, it is a micro-controller. Tool chain is referred to the compiler and/or IDE.

    Regards
    Amit
  • BP101 said:
    That's very interesting and perhaps your testing on TM4C123 tool chain?

    Non-sequiter

    BP101 said:
    I simply avoid setting any channel in last step with END

    I don't think so, As Amit noted it's not logically correct but I suspect it nonetheless selects a channel. I just don't have the source here to check. I can think of no reason it's likely for the source to react differently. Even if it was bad, you would very likely need an accompanying source problem to cause your reported symptoms.

    Robert

  • Checked debug and this later compiler is now configuring END step and other steps have nothing listed as noted long ago. What occurs by setting END at channel is the FIFO sits in perpetual overflow condition. The interrupt handler has over under/flow checking and drains the FIFO each pass through prior to disable and reprogramming the sequencer to change the ADC channel selected.

    Not sure why Overflow occurs other than the interrupt array that reads raw FIFO data can not detect the end of sampled data. Defining both arrays 1 less value than previously set for END at no configured channel step made things even worse. Seems to me the END step alone should not and does not actually sample data into the array, it rather sets an end of tail flag in the FIFO and drives an interrupt trigger to indicate the sample is ready for processing.

  • BP101 said:
    Seems to me the END step alone should not and does not actually sample data into the array,

    Nope, it marks the last sample not one past the end. Otherwise an eight entry sequencer could only take 7 samples. A bit of an unnecessary waste.

    Robert

  • Hi Amit,

    >TM4C1294NCPDT is not a tool chain, it is a micro-controller. Tool chain is referred to the compiler and/or IDE.

    Seemingly the variant (TM4C1294NCPDT) is a necessary part of the tool chain for programming vendor provided registers attached to the ARM cortex. Agree C+ compilers require an IDE and in this case the variant is a part of the tool chain. Other wise the compiler would be unable to interpret the unique vendor register programming syntax. So for simple terms the variant is the tool chain required to program the specific peripherals of individual controllers.

    Seemingly again hard code problems in the variant can directly impact the tool chains ability to properly configure peripherals at the pneumonic level of the object. Most everyone calls the variant the tool chain otherwise GNU is only capable to program the ARM Cortex.
  • Hello BP101,

    I disagree. It is the CPU architecture that decides the tool-chain behavior. A Cortex M4 core running a while loop in SRAM will require only information on the CPU core.

    Anyways, Robert and myself at different times in this thread have identified a clear lack of example project that can substantiate your claims of IE and END bits.

    Regards
    Amit
  • Hi Amit,

    >I disagree. It is the CPU architecture that decides the tool-chain behavior.

    Not sure what you are disagreeing to since the (variant-TM4C1294NCPDT) contains the code that programs the peripheral Architecture. What many call the vendor unique tool chain contains the specific variant you previously stated was the controller. Seems we agree the vendor unique tool chain requires the variant to program the peripherals and with out the proper (variant controller) specified in CCS the compiler could create incorrect peripheral codes. So any problems in the variant will reflect in the peripherals odd behavior. 

    > Anyways, Robert and myself at different times in this thread have identified a clear lack of example project that can substantiate your claims of IE and END bits

    The shortest path between to point is a straight line. That said it most likely and found SW developed by Tiva team ADC examples there is absolutely no FIFO overflow/underflow checking being preformed, even simply reading internal TS. That leads to assumptions being made as to accuracy of the channel data being returned into the read array of it being valid. Luminary Micro may have discovered sample data is not the actual data when trying to set channels inside the END step, perhaps the tail pointer is outside the FIFO sample. Data returned in the END + channel sample interrupt is not the actual programmed channel step.

    Code snips are all that is required to prove (FIFO FULL) perpetual failure any channel set END step when watching in CCS debug. It has always been customers who report issues and the vendors lab that checks for failure. In other words expecting the customer to write a program to prove a reported failure when snips are provided is asking a bit much.

    Code snip below is a proper way to VET the FIFO prior to processing the sampled data. I would bet few this forum are actually Vetting FIFO and the samples data are flawed when set channel + END step.  This snip fails to VET the FIFO when setting END on PIN_VBEMFB versus simply setting END, IE on step #2.

       /* Program ADC0 each step of sequencer 0, generating
        * a RAW interrupt and END step 2. */
        ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 0, PIN_VSENSE); //CH8
        ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 1, PIN_VBEMFB); //CH6
        ROM_ADCSequenceStepConfigure(ADC0_BASE, 0, 2, ADC_CTL_END | ADC_CTL_IE); 
       // Disable the sequence.
       HWREG(ADC0_BASE + ADC_O_ACTSS) &= ~(ADC_ACTSS_ASEN0);
    
        /* Read the BusVoltage samples from SS0 step 1 ADC0 FIFO. */
        g_pusADC0DataRaw[0] = HWREG(ADC0_BASE + ADC_O_SSFIFO0);
    
        /* Read the Back EMF samples from SS0 step 2 ACD0 FIFO */
        g_pusBEMFVoltageCount[1] = HWREG(ADC0_BASE + ADC_O_SSFIFO0);
    
        // Drain the Sequence FIFO.
        while(!(HWREG(ADC0_BASE + ADC_O_SSFSTAT0) & ADC_SSFSTAT0_EMPTY))
        {
        	// Zero the circular FIFO sample.
        	ulTemp = HWREG(ADC0_BASE + ADC_O_SSFIFO0);
        }
    
        // Clear any overflow/underflow conditions that might exist.
        HWREG(ADC0_BASE + ADC_O_OSTAT) |= ADC_OSTAT_OV0;
        HWREG(ADC0_BASE + ADC_O_USTAT) |= ADC_USTAT_UV0;
    
        // Enable the sequence and continue processsing ADC
        // interrupt for the previous sampled BEMF crossing.
       	HWREG(ADC0_BASE + ADC_O_ACTSS) |= ADC_ACTSS_ASEN0;
    
        /* Check ADC0 SS0 FIFO (RW1C) Overflow or (RW1C) Underflow status. Or if
         * FIFO-0 is FULL (RO) after reading what should have been all of the data.*/
         if((HWREG(ADC0_BASE + ADC_O_OSTAT) & ADC_OSTAT_OV0) ||
              (HWREG(ADC0_BASE + ADC_O_USTAT) & ADC_USTAT_UV0) ||
                (HWREG(ADC0_BASE + ADC_O_SSFSTAT0) & ADC_SSFSTAT0_FULL))
          {
            // Disable the sequence.
        	 HWREG(ADC0_BASE + ADC_O_ACTSS) &= ~(ADC_ACTSS_ASEN0);
    
            // Drain the Sequence FIFO.
            while(!(HWREG(ADC0_BASE + ADC_O_SSFSTAT0) & ADC_SSFSTAT0_EMPTY))
            {
            	// Zero the circular FIFO sample.
            	ulTemp = HWREG(ADC0_BASE + ADC_O_SSFIFO0);
            }
            
            // Enable the sequence and return.
            HWREG(ADC0_BASE + ADC_O_ACTSS) |= ADC_ACTSS_ASEN0;
    
            /* Clear (RW1C) the FIFO Overflow and Underflow status bits.*/
        	 (HWREGBITW(ADC0_BASE, ADC_O_OSTAT) |= ADC_OSTAT_OV0);
        	 (HWREGBITW(ADC0_BASE, ADC_O_USTAT) |= ADC_USTAT_UV0);
    
            /* Since the data over/under-flowed the FIFO, zero all samples. */
        	g_pusADC0DataRaw[0] = 0; //BusVoltage CH8
        	g_pusBEMFVoltageCount[1] = 0 ;//BEMF CH6
    
            // UARTprintf(">> IntTrap0 Drain FIFO \n\n");
            // Since some sort of overflow/underflow occured just return
            return;
        }
    

     

  • BP101 said:

    > Anyways, Robert and myself at different times in this thread have identified a clear lack of example project that can substantiate your claims of IE and END bits

    The shortest path between to point is a straight line.

    Which you have been either unwilling or unable to provide.

    BP101 said:
    Code snips are all that is required to prove (FIFO FULL) perpetual failure any channel set END step

    Not proof. In this case not enough for anyone to put in the amount of work to see if there was an issue.

    BP101 said:
    >I disagree. It is the CPU architecture that decides the tool-chain behavior.

    I'm with Amit here. The tool chain (in the case of conventional compilers) a compiler, a linker, a locator (the last two generally in a single tool), and generally a tool to produce binary or hex and a librarian.

    Download and debug may be included or separate. An IDE is a separate proposition and often included it is certainly not necessary.

    Since the elements don't change based on the variant separate variants have never in my experience been case to consider a different tool chain. Particularly in the case of Cortex M4 cores the difference between variants can in the cases I've seen be dealt with entirely by the difference in peripherals and thus a few address defines. Hardly a paradigm shift.

    Robert

  • The point the TM4C1294 variant seems to have bugs in several places that make it seem as if the peripheral is failing to respond to the C+ object.

    The vendor could provided variant peripheral machine language object for consumer comparison with debug disassembler results. That Is the only way to know for sure the variant is not bugged when setting END + channel to any step. That simply does not work properly with the TM4C1294 variant to produce correct sequences of circular FIFO sampled data.

    The code SNIPS above post remove questions of any ADC sample sequencer errors from being processed and miss-interpreted for proper analog sampled data.

    VET= Verify - Examine - Transfer the data to the application for processing. Proper vetting of any step or claims of setting END + Channel in any step are (highly speculative) if the sample data contains any errors or simply gibberish.
  • >I'm with Amit here. The tool chain (in the case of conventional compilers) a compiler, a linker, a locator (the last two generally in a single tool), and generally a tool to produce binary or hex and a librarian.

    You can not program the TM4C1294 peripherals without the specific vendor variant which also calls a vendor specific compiler and linker, all part each vendors tool chain and process tree. GNU Beans IDE and ARM4 compiler/linker tools can not interpret peripheral syntax specific to the vendors unique variant, Tried that early on before agreeing to CCS license agreement. Amit FYI suggested the TM4C controller was not the tool chain, nor does the word controller directly relate to the word variant. Most everyone refers to and calls said package "the tool chain" being vendor specific thus contains the variant. I have yet to read any post where the Variant was not referred to as the vendors tool chain.

    Good example, change your variant to C2000, the compiler, linker and variant are completely different than the TM4C. That infers the vendor unique tool chain contains the peripheral variant machine code required to program the peripherals. Likewise the C2000 tool chain is useless to program the TM4C without the proper variant. If the tool chain constitutes only the compiler + linker and the C+ language remains constant in both tool chains, why the different compiler and linker library names?
  • BP101 said:
    You can not program the TM4C1294 peripherals without the specific vendor variant which also calls a vendor specific compiler and linker,

    I've done exactly that multiple times before with different cores.  This is not a particularly difficult thing to do. I prefer setting up the peripheral address in the link/locate step rather than use constants as TI does but I'm in the minority in that preference and both work in a straightforward fashion.

    It certainly make sense to use TIs pre-defined headers, it's a lot of scut work already done and debugged, but it's also not a necessity. And it certainly doesn't require a compiler change.

    BP101 said:
    GNU Beans IDE and ARM4 compiler/linker tools can not interpret peripheral syntax specific to the vendors unique variant,

    There isn't any such peripheral syntax variant.

    BP101 said:
    Good example, change your variant to C2000

    Bad example, that's a completely different core. That does require a different tool chain. The various TM4C variants all use the same core (as do devices from a number of other manufacturers)

    BP101 said:
    C+ language

    There is no such thing as a C+ language. Certainly TI produces no compiler for such a beast.

    BP101 said:
    why the different compiler and linker library names?

    Because it's a different core. You will note that was the point that both Amit and I said that different tool chains would be required. Different core, different tool chain. Same core but different variant, same tool chain.

    Robert

  • BP101 said:
    The code SNIPS above post remove questions of any ADC sample sequencer errors from being processed and miss-interpreted for proper analog sampled data.

    They leave considerable questions since they do not show the code they are in and cannot be run as is.

    Robert

  • >They leave considerable questions since they do not show the code they are in and cannot be run as is.

    Umm Snips are the code placed in any interrupt handler TI FIFO sample, rename arrays to match. Processing the FIFO data is not required to view Debug FIFO register status is severely impacted adding END + channel sample any step.

    Robert if we don't match the exact variant name to the specific core in CCS there is no guarantee of proper register programming.

    BTW: C++ compiler is loaded in my CCS5.4 was inferring (C or C++) Again trying to use the TM4C1294NCPDT variant with C2000 complier loaded will likely cause many if not numerous complier errors if accessing any embedded classes. The point was the variant, not the complier interprets high level C++ object (compiled syntax) for the embedded machine code the compiler and linker access. We should be able to write code for ARM4 core TM4C in Visual Studio without need of the vendors tool chain using only a C++ compiler for ARM4 processors. The program likely can't access any of the vendors embedded peripherals since the variant is missing.

    This vendor peripheral scheme must be top secrete, they never give any details this forum regarding variant, though C2000 forum does and must since C2000 has embedded many peripheral functions into low level object calls.

  • You keep saying it's simple to produce an example but so far you have shown yourself incapable of doing so.

    You are also the only person arguing that the C2000 cores are ARM Cortex M cores.

    There is no top secret vendor peripheral scheme. Really the peripheral address and datasheet/ user guide are all that's required to be able to program the TM4Cs. I wouldn't recommend eschewing all the available pre-built headers and libraries but it's certainly possible and as I said earlier I've done it before

    Robert
  • Hello BP101

    I agree with Robert. There is so much contradictory information regarding compilers and core, "secret" peripheral scheme, and still a lack of a CCS project which can reproduce the ADC issue this thread started with.

    Regards
    Amit
  • Hi Amit/Robert,

    It seems the point being made is multiple elements in a single dimensional array may not appear consistent but may in a single element array.

    That consistency seemlying is lost in the multi element array data being read back in a non existing and proper interrupt handler ADC example. Highly suspect are both Macro and ADCSequencerDataGet if ever declaring an Array[0] of zero elements in a function. That has no direct correlation to the sequencer data being read back.

    Note there is no such thing as a zero element array and CCS ignores that fact. That ties into the issue configuring sequencer step to END + channel. 

    Web link author makes a few good points regarding the number of bytes returned in single versus multi element array types. ADC 12 bit FIFO=2 bytes, author infers 4 bytes 32bits are returned for any single defined array element in C++ language, 8 bytes for 2 elements. How many bytes are read in a single element array in CCS, given C/C++ language syntax consists in the functions array declaration? 

    http://randu.org/tutorials/c/arrays.php

    The ADC examples/peripherals/ (single_ended.c) does not properly test the sequencer but in a mock interrupt handler and single element array. That begs the question how TI engineering simply assumes the compiler or any part of the tool chain is behaving as intended.

    Code SNIP from said project shows mock IE cleared but a single time prior to entering a while loop. How can that ever be considered a valid lab test since the stack is not being included otherwise used in a typical and proper application IE interrupt handler.  TI provided ADC example code snip the array does not care if declared as zero elements the same data is read back. Also waiting for interrupt flag is not a valid test of sequencer timing that otherwise occurs during an typical interrupt vector where the stack pointer is in play around ADC clocking.

        //
        // This array is used for storing the data read from the ADC FIFO. It
        // must be as large as the FIFO for the sequencer in use.  This example
        // uses sequence 3 which has a FIFO depth of 1.  If another sequence
        // was used with a deeper FIFO, then the array size must be changed.
        //
        uint32_t pui32ADC0Value[0];
        //
        // Enable sample sequence 3 with a processor signal trigger.  Sequence 3
        // will do a single sample when the processor sends a signal to start the
        // conversion.  Each ADC module has 4 programmable sequences, sequence 0
        // to sequence 3.  This example is arbitrarily using sequence 3.
        //
        ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);
    
        //
        // Configure step 0 on sequence 3.  Sample channel 0 (ADC_CTL_CH0) in
        // single-ended mode (default) and configure the interrupt flag
        // (ADC_CTL_IE) to be set when the sample is done.  Tell the ADC logic
        // that this is the last conversion on sequence 3 (ADC_CTL_END).  Sequence
        // 3 has only one programmable step.  Sequence 1 and 2 have 4 steps, and
        // sequence 0 has 8 programmable steps.  Since we are only doing a single
        // conversion using sequence 3 we will only configure step 0.  For more
        // information on the ADC sequences and steps, reference the datasheet.
        //
        ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH0 | ADC_CTL_IE |
                                 ADC_CTL_END);
    
        //
        // Since sample sequence 3 is now configured, it must be enabled.
        //
        ADCSequenceEnable(ADC0_BASE, 3);
    
        //
        // Clear the interrupt status flag.  This is done to make sure the
        // interrupt flag is cleared before we sample.
        //
        ADCIntClear(ADC0_BASE, 3);
    
        //
        // Sample AIN0 forever.  Display the value on the console.
        //
        while(1)
        {
            //
            // Trigger ADC to sample analog channel and conversion.
            //
            ADCProcessorTrigger(ADC0_BASE, 3);
    
            //
            // Wait for conversion to be completed.
            //
            while(!ADCIntStatus(ADC0_BASE, 3, false))
            {
            }
    

  • >You are also the only person arguing that the C2000 cores are ARM Cortex M cores.

    You misunderstand the connection was the variant of C2000 is NOT the same as the variant for any TM4C

    >Really the peripheral address and datasheet/ user guide are all that's required to be able to program the TM4Cs

    That is not true for embedded processors unless you are writing code in machine language and or have the vendors unique peripheral macro assembler calls. That is why Beans IDE even with GNU make and ARM compiler can not program TI peripherals as the tool chain has no variant assembler calls for the unique added vendor peripherals.

    >You keep saying it's simple to produce an example but so far you have shown yourself incapable of doing so.

    The vendor ADC (single_ended.c) example is proof vendor has not fully tested multi element array method with TM4C1294NCPDT variant and macro calls. The project variant sets access into portions of (eabi.lib), seemingly handling peripheral registers. Discovered one day we can see (eabi.lib) assembler directives and assumed links are directed by the defined project variant during CCS debug pause state.

    Below it is only a tool chain editor and not the definitive project controller variant set in (CCS General) assumes tool chains accesses of (eabi.lib) to program vendor unique peripherals.

    Notice CCS installed compilers support, various project variant controllers. Agree mismatching different class cores to controller variants is futile. The project variant can consist of a core or not and or controller and often only has the very necessary controller directive.

  • BP101 said:

    It seems the point being made is multiple elements in a single dimensional array may not appear consistent but may in a single element array.

    You're haring off in another direction again. With even less evidence than the previous speculations

    BP101 said:
    Note there is no such thing as a zero element array and CCS ignores that fact.

    No idea what CCS does but this is an over-simplification. Zero sized arrays are undefined, the compiler is free to accept them, ignore them or generate an error. Many do accept them for historical reasons. Personally I prefer an error be generated.

    BP101 said:
    Web link author makes a few good points regarding the number of bytes returned in single versus multi element array types. ADC 12 bit FIFO=2 bytes, author infers 4 bytes 32bits are returned for any single defined array element in C++ language

    Author is probably simplifying (It's possible they don't know but I suspect they are simplifying, or you're misrepresenting them). In fact the sizes are not defined by the language but by the tool chain. The language places some lower bounds on the sizes of various integer types by specifying the minimal acceptable ranges they must be able to represent. From this you can determine the minimum number of bits necessary to represent a particular type once you know the underlying representations. Note that byte is not defined anywhere in the language.

    You should also note that TIVA does not represent the sequencers as arrays to you so all this speculation is to no point whatsoever.

    BP101 said:
    Code SNIP

    Speaking of which you have yet to provide an example for any of your complaints.

    BP101 said:
    IE cleared but a single time prior to entering a while loop. How can that ever be considered a valid lab test since the stack is not being included

    I presume you meant interrupt flag not Interrupt Enable has you have written but even so this makes little to no sense.

    Robert

  • BP101 said:

    >You are also the only person arguing that the C2000 cores are ARM Cortex M cores.

    You misunderstand the connection was the variant of C2000 is NOT the same as the variant for any TM4C

    They are not variants of one another at all the C2000 is a variant of the TM4C in the same way a shark is a variant of a big cat

    BP101 said:

    >Really the peripheral address and datasheet/ user guide are all that's required to be able to program the TM4Cs

    That is not true for embedded processors unless you are writing code in machine language

    It's entirely true. As I keep saying I've done it, no assembly required.

    BP101 said:
    Below it is only a tool chain editor and not the definitive project controller variant set in (CCS General) assumes tool chains accesses of (eabi.lib) to program vendor unique peripherals.

    I can't even parse that.

    Robert

  • There is more going on under the hood of CCS core compilers than you may be aware.  The project variant (controller ID links to specific XML file (under CCS folders) which specifies compiler calls into (eabi.lib) accessing prewritten C functions for peripheral use.

    One such function in the manifest builds an element array the ADC peripheral sequencer can use. If or when setting END + channel data to a sequencer, the array with multiple elements defined do not produce expected results. Again that by posted example occurs when more than a single sequencer channel is being read in macro reads of the IE enabled sequencer FIFO. That alone could explain why ADCSequencerDataGet() cause MCU faults with steps configured END, IE and no channel assigned. 

    That eabi.lib array element function is not explicitly aware FIFO END if an array can be declared with zero elements, compile without error and still read the functions declared array with zero element length. Obviously someone messed up forgot an array value of zero is NOT valid in the C language.

    <!-- Project Wizard Settings -->
    <property id="GEL File" Value="../../../emulation/gel/tm4c1294ncpdt.gel" Type="filepathfield"/>
    <property id="Access Port Designator" Value="0x02000000" Type="numericfield"/>
    <property id="LinkerCmd" Value="tm4c1294ncpdt.cmd" Type="stringfield"/>
    <property id="CompilerBuildOptions" Value=" --silicon_version=7M4 --code_state=16 --abi=eabi --float_support=FPv4SPD16" Type="stringfield"/>
    <property id="LinkerBuildOptions" Value=" -m=app_TM4C1294NCPDT_ccs.map -stack=512 -heap=0" Type="stringfield"/>
    <property id="RTSlib" Value="libc.a" Type="stringfield"/>
    <property id="IsElfDefault" Value="true" Type="stringfield"/>
    <property id="Endianness" Value="little" Type="stringfield"/>
    <property id="MinCodegenVersion" Value="4.9.0" Type="stringfield"/>
    <!-- END Project Wizard Settings -->

  • Still no example.

    BP101 said:
    compiler calls into (eabi.lib) accessing prewritten C functions for peripheral use.

    eabi is the standard C support library for Cortex cores (it's possible it supports a broader spectrum of cores but I would expect at least the Cortex-M4F cores). Peripheral access is done via the TivaWare library

    BP101 said:
    One such function in the manifest builds an element array the ADC peripheral sequencer can use.

    Nope, Nada. Wrong. The addressing of the sequencer is done in the TivaWare library. And, guess what? It doesn't use arrays.

    You have the wrong end of the stick. You are barking up the wrong tree. And there is

    Still no example

    Robert

  • >Nope, Nada. Wrong. The addressing of the sequencer is done in the TivaWare library. And, guess what? It doesn't use arrays.

    Was referring to the application reading of the FIFO sample data into the declared C++ array via HWREG macro, not the programming of the sequencer step. In the latter do agree a typical project may include calls to (driverlib/adc.c) to program the individual sequencer steps but not read the sample data back for processing. The actual C++ DECL of the array[N] are handled by (eabi.lib) calls to a 3rd party written embedded construct not found in (driverlib/adc.c). 

    It was not until digging into this issue this post and past reported this forum did HWREG macro seem more the suspect. HWREG method was being used by LMI Stellaris group avoiding Slower push/pop stack burden of function calls to (ADCSequencerDataGet).

    Could it be past TI masters lead public domain into undocumented Macro HWREG semantics of sequencer configuration, END step placement avoiding a channel configuration?

  • BP101 said:

    >Nope, Nada. Wrong. The addressing of the sequencer is done in the TivaWare library. And, guess what? It doesn't use arrays.

    Was referring to the application reading of the FIFO sample data into the declared C++ array via HWREG macro, not the programming of the sequencer step.

    No, we've been talking about the END flag placement in the sequencer.

    BP101 said:
    The actual C++ DECL of the array[N] are handled by (eabi.lib) calls

    Mostly no. There could be calls to the runtime library if it was on the stack. This is, in any case, not relevant to the question of the END flag.

    BP101 said:
    HWREG method was being used by LMI Stellaris group avoiding Slower push/pop stack burden of function calls to (ADCSequencerDataGet).

    One of the nice things about the Cortex architecture is that the function call overhead is small, particularly for leaf functions.

    BP101 said:
    Could it be past TI masters lead public domain into undocumented Macro HWREG semantics of sequencer configuration, END step placement avoiding a channel configuration?

    Unparseable

    And you still have provided no runnable source showing what you claim is a problem.

    Robert

  • Robert Adsett said:
    No, we've been talking about the END flag placement in the sequencer
    And as a reminder, the original response in context to what it was responding to.
    BP101
    One such function in the manifest builds an element array the ADC peripheral sequencer can use.

    Nope, Nada. Wrong. The addressing of the sequencer is done in the TivaWare library. And, guess what? It doesn't use arrays.

  • Again the END justifies the means of where the END is placed in the sequencer. Obviously that is governed by the method in which the declared array is read as per the posted code SNIP far above.

    Believing (driverlib/adc.c) or (libc.a) has anything at all to do with an declared C++ array is simply a drawn and incorrect conclusion on your part. It is necessary to declare and build an array in order to read any sequencer step data into the application for processing. That build is not being done by Tivaware, the 3rd party who wrote the C++ array decoder is Edisonware group. The END sequencer step placement is relative to the acquisition method and in this case a MACRO call reads the sequencer data not Tivaware. In both cases the 3rd party decoder is called during compile time to build the array.
  • BP101 said:
    Again the END justifies the means of where the END is placed in the sequencer.

    Unparseable

    BP101 said:
    . Obviously that is governed by the method in which the declared array is read as per the posted code SNIP far above.

    This is either absurd or you mean something quite different from what you wrote

    BP101 said:
    Believing (driverlib/adc.c) or (libc.a) has anything at all to do with an declared C++ array is simply a drawn and incorrect conclusion on your part.

    I never said it did.

    BP101 said:
    is necessary to declare and build an array in order to read any sequencer step data into the application for processing

    No, but that is the usual method.

    BP101 said:
    That build is not being done by Tivaware, the 3rd party who wrote the C++ array decoder is Edisonware group.

    No, that is done by the compiler usually. There is no third party needed (or useful) for declaring an array. It is possible to invoke such for walking the array but that would be tremendously inefficient. I haven't seen a C compiler do that for over 20 years except maybe on crippled architectures (it's possible some PIC compilers do that to deal with its address)

    BP101 said:
    The END sequencer step placement is relative to the acquisition method

    Unparsable. If you mean that the End sequencer placement depends on the declaration of the array the final result is read into that's highly absurd.

    BP101 said:
    in this case a MACRO call reads the sequencer data not Tivaware

    That macro is part of TivaWare.

    BP101 said:
    In both cases the 3rd party decoder is called during compile time to build the array.

    'Both' cases????

    Robert

    And still no code to demonstrate the problem