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.

How to use interrupts in Energia??

Other Parts Discussed in Thread: ENERGIA

I want to use ADC and Timer interrupts in Energia. For this i have to modify ISR Table.

Energia has ISR table in Startup_gcc.c file.

So how to modify this file to access interrupts of ADC and Timers.

Or is there any Library to access Interrupts directly.

Board:- TIVA C (TM4C123G)

  • HI Kapadia,

    For this type of question the Energia forum is your best bet.
    Remember, Energia is Arduino-like and you can use functions for GPIO interrupts, I believe nothing else (unless there's a library that I don't know of).
    energia.nu/AttachInterrupt.html

    Now, when I wanted to use timer interrupts or ADC interrupts when I used Energia I had to use TivaWare peripheral driver library. No need to edit any file.
    You need to add the correct header files (I think for some reason in Energia you needed to actually add the .c files). Then you need to well... program.
    I can provide you with some examples for the timer interrupts but in the end you will need to read up in how to use Tivaware functions that require more knowledge about the MCU than Energia.

    But do ask in Energia forums if there is a new library for the purpose.
    forum.43oh.com/.../28-energia
  • Hello Luis Afonso,

    Thank you for your reply.

    I know about Tivaware and i also used it.
    I want to know that when i am using Timer/ADC in interrupt mode, What is the name of my interrupt handler for Timer/ADC??

    I am using CCS with Energia sketches.
  • Hi Kapadia,

    Sincerely I always use TimerIntRegister or ADCIntRegister and change to a custom handler.
  • How to change custom handler? And in which file i have to change?
  • There's no need for any change in the files (besides the main program).

    Look here a timer in periodic mode with a interrupt in every timeout:
    sites.google.com/.../timer-delay
  • Hello Luis Afonso,

    Thanks a Lot !!!!!! I got it.

    I have one more question. How to use multiple ADC using ADCIntRegister ? There are separate Interrupt handlers for each ADC channel or only one for all?????
  • Hi Kapadia,

    Well you can see that in the datasheet.
    Go to the datasheet in marker "13.Analog to Digital Converter (ADC)" (that's page 800 for your MCU) there is the info you need in the first set of pages in a figure.
    I'll leave it to you to find out, guiding you to get familiar with the info in the datasheet is better than I simply giving every piece of info every time you ask a question, check it out and then come back if you have any more questions
  • Hello Luís Afonso,

    I refereed the datasheet.  And i know how to use multiple ADC. I write the code to get 3 ADC values.


    Here is my code:

    #include "../tm4c123gh6pm.h"
    
    volatile unsigned long adcResult[4];
    
    void GPIO_InIt(void)
    {		
    	GPIO_PORTE_DIR_R &= ~(1<<1);										// Make PE1 input
    	GPIO_PORTE_AFSEL_R |= (1<<1);										// Set PE1 as alternate fun.
    	GPIO_PORTE_DEN_R &= ~(1<<1);										// Disable Digital Enable on PE1
    	GPIO_PORTE_AMSEL_R |= (1<<1);										// Enable Analog functionality on PE1
    	
    	GPIO_PORTE_DIR_R &= ~(1<<4);										// Make PE4 input
    	GPIO_PORTE_AFSEL_R |= (1<<4);										// Set PE4 as alternate fun.
    	GPIO_PORTE_DEN_R &= ~(1<<4);										// Disable Digital Enable on PE4
    	GPIO_PORTE_AMSEL_R |= (1<<4);										// Enable Analog functionality on PE4
    	
    	GPIO_PORTE_DIR_R &= ~(1<<5);										// Make PE5 input
    	GPIO_PORTE_AFSEL_R |= (1<<5);										// Set PE5 as alternate fun.
    	GPIO_PORTE_DEN_R &= ~(1<<5);										// Disable Digital Enable on PE5
    	GPIO_PORTE_AMSEL_R |= (1<<5);										// Enable Analog functionality on PE5
    		
    }
    
    void ADC1_InIt(void)
    {	
    	ADC1_PC_R &= ~0xF;															// Clear max sample rate field
    	ADC1_PC_R |= (0x1<<0); 													// Configure for 125K samples/sec
    	ADC1_SSPRI_R = 0x3210;													// Sequencer 3 is lowest priority
    	ADC1_ACTSS_R &= ~(1<<2);												// Disable Sample Sequencer2
    	ADC1_EMUX_R |= (0xF<<8);											  // Configure Trigger event : continuous mode
    	ADC1_SSMUX2_R = 0x0892;													// Select ADC channels; AIN2,AIN8,AIN9
    	ADC1_SSCTL2_R |= (1<<9) | (1<<10);							// Set END bit & Enable Interrupt	
    	ADC1_IM_R |= (1<<2);														// Set MASK bit ; For SS2 -> MASK2
    	ADC1_ACTSS_R |= (1<<2);													// Enable Sample Sequencer
    	
    	ADC1_ISC_R |= (1<<2);														// Clear flag status
    	
    	NVIC_EN1_R |= (1<<18);													// Enable NVIS interrupt bit for ADC
    }
    
    void ADC1Seq2_Handler(void)
    {
    	adcResult[0] = ADC1_SSFIFO2_R;
    	adcResult[1] = ADC1_SSFIFO2_R;
    	adcResult[2] = ADC1_SSFIFO2_R;
    	ADC1_ISC_R |= (1<<2);
    	
    }
    
    int main(void)
    {
    	SYSCTL_RCGCGPIO_R = (1<<4) | (1<<5);						// Enable RCC Clock for PORTE & PORTF
    	SYSCTL_RCGCADC_R = (1<<1);											// Enable RCC Clock for ADC1
    	
    	GPIO_InIt();
    	ADC1_InIt();
    	
    	
    	while(1)
    	{
    		
      }
    }

    But i dont understand how to use multiple ADC at a time using TivaWare peripheral codes.

    I want to use that functions given in TivaWare peripheral codes. And want to store 4 ADC channel values in an array of size 4.

  • Hi Kapadia,


    You have only 2 ADCs? Correct? So you can only do 2 readings at the same time (although you have various sequencers and channels). You can do more of them in sequence, but never at the same time.

    You can take this example to start:
    sites.google.com/.../internal-temperature-sensor

    If you are familiar more with direct register access, the best idea is to check the source files.

    Now you seem to have in your code a interrupt for when the ADC has a sample ready and you have the ADC cycling through 3 samples from 3 channels with the same sequencer.
    The last part is configured with ADCSequenceStepConfigure().
    The Interrupt is ADCIntEnable() - this one is not that hard to use if you are familiar with using interrupts with Tivaware.
    You can consult the Tivaware peripherald driver library user guide for more info about each function
  • Ya TM4C have 2 ADCs. Sorry i dont need the samples at a same time, But in sequence.
    I am using sample sequencer 2 to get 4 ADC samples in sequence. Then how to get these 4 samples using Interrupt handler.
    There is a function to get ADC result ADCSequenceDataGet(), So this function is called for every samples in a single interrupt handler or in different handler????

    I am getting this type of error when i m calling ADCSequenceDataGet(ADC0_BASE, 2, adcResult[0]); function. : "invalid conversion from 'uint32_t {aka long unsigned int}' to 'uint32_t* {aka long unsigned int*}' [-fpermissive]".

    adcResult[0] data type is uint32_t.

  • Hi Kapadia

    Read again the error. Yes adcResult[0] data type is uint32_t but the asked parameteris a uint32_t*, it's a pointer.
    ADCSequencerDataGet, if you read on the user guide or the link I provided, returns the whole sequencer FIFO! You use a pointer to a table with at least the size of the FIFO (doesn't matter if you are using just 1 sample), in this case for sequencer 2 it need to be size 4.

    If you set the sample sequencer to do all 4 samples and then end the interrupt will occur at the end of that, in which you can use ADCSquencerDataGet() to get the 4 samples.

    1 note - careful when using ADC continuous trigger. It's best to start with software trigger for now IMO.
  • Thanks a lot man...... !!! Luís Afonso :) (y)
    I got it.
    Multiple ADC is now working.

    Again Thanks.... :)
  • Glad it's working now :D

    If you could post here the code for future users that search for similar topics (or for me to direct similar questions to this post) I would appreciate it and I'm sure others too
  • Here is the code to read Multiple ADC values.

    Using ADC0 and PE0 to PE3 pins.

    // Multiple ADC.
    // Reads ADC values from PE0 to PE3.
    
    #include "Energia.h"
    
    #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 "tm4c123gh6pm.h"
    
    uint32_t adcResult[4];
    
    void AdcIntHandler(void)
     {
    	 while(!ADCIntStatus(ADC0_BASE, 2, false))                     // Check for ADC is busy or not
    	 {
    	 }
    	 ADCIntClear(ADC0_BASE, 2);                                             // Clear interrupt bit
    
    	 ADCSequenceDataGet(ADC0_BASE, 2, adcResult);     // Get the ADC result in the variable
    
    	 ADCProcessorTrigger(ADC0_BASE, 2);                           // Again trigger the ADC
    
     }
    
    void setup()
    {
    	SysCtlClockSet(SYSCTL_SYSDIV_10|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);      // Setup the clock
    
    	SysCtlDelay(3);                                                                                                                  // Delay 
    
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);                                                 // Enable Peripheral for ADC0
    
       	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);                                                  // Enable Peripheral for GPIOF
    
       	GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);    // Set the ADC Pin which we want to use
                                                                                                                                                                                                   // Here i used PE0-PE3
       	ADCSequenceConfigure(ADC0_BASE, 2, ADC_TRIGGER_PROCESSOR, 0);               // Sequence configuration and Mode of starting of ADC
                                                                                                                                                                      // Here i used SS2 and Processor trigger mode
       	ADCSequenceStepConfigure(ADC0_BASE, 2, 0, ADC_CTL_CH3);                                  // Sequence step configuration; Step 0; For PE0 -> AIN3 -> Channel 3
       	ADCSequenceStepConfigure(ADC0_BASE, 2, 1, ADC_CTL_CH2);                                  // Step 1; For PE1 -> AIN2 -> Channel 2
       	ADCSequenceStepConfigure(ADC0_BASE, 2, 2, ADC_CTL_CH1);                                 // Step 2; For PE2 -> AIN1 -> Channel 1
       	ADCSequenceStepConfigure(ADC0_BASE, 2, 3, ADC_CTL_CH0 | ADC_CTL_IE | ADC_CTL_END);    // Step 3; For PE0 -> AIN0 -> Channel 0; End the Sequence 
                                                                                                                                                                                                    // and Enable the Interrupt
    
       	ADCIntRegister(ADC0_BASE, 2, AdcIntHandler);                                                  // Interrupt handler selector
                                                                                                                                                     // Here i used AdcIntHandler; So whenever interrupt occurs it goes to
                                                                                                                                                     // this handler function.
       	ADCIntEnable(ADC0_BASE, 2);                                                                                // Enable the interrupt.
    
       	ADCSequenceEnable(ADC0_BASE, 2);                                                                 // Enable ADC
    
       	ADCIntClear(ADC0_BASE, 2);                                                                                  // Clear the Interrupt
    
       	ADCProcessorTrigger(ADC0_BASE, 2);
    }
    
    void loop()
    {
    
    }