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.

TM4C123GH6PM: Enabling ADC peripheral

Part Number: TM4C123GH6PM
Other Parts Discussed in Thread: EK-TM4C123GXL

Hello,

I am working EK-TM4C123GXL Evaluation kit. I am facing issue with ADC peripheral configuration.

In my code i am configuring GPIO and ADC peripherals. Both ADC0 and ADC1 peripherals are not enabling after performing reset by pressing reset button on my board. But while i am in debug mode there was no issue with ADC enabling and code was working fine. Once i reset the board, ADC peripheral was not enabling.

Note : Code is developed using IAR embedded workbench and i am attaching the peripheral configuration file.

#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "sysctl.h"
#include "hw_memmap.h"
#include "hw_ints.h"
#include "hw_nvic.h"
#include "gpio.h"
#include "hw_gpio.h"
#include "hw_types.h"
#include "pin_map.h"
#include "adc.h"

void clockInit(void);
void gpioInit(void);
void gpioInterruptConfig(void);
void adcInit(void);
/*
 =================================
 Function Definitions
 =================================
 */

/*!
* @brief The purpose of this function is to configure system clock at 16MHz
* @param[in] None.
* @return None.
*/
void
clockInit(void)
{
    // Set the clock to run directly from the external crystal/oscillator at 16MHz.
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | \
      SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
}


/*!
* @brief The purpose of this function is to initialize and configure the GPIO pins
* @param[in] none	
** @return NA
*/
void
gpioInit(void)
{
	uint32_t gpioPorts[6] = {SYSCTL_PERIPH_GPIOA, SYSCTL_PERIPH_GPIOB, SYSCTL_PERIPH_GPIOC,\
				 SYSCTL_PERIPH_GPIOD, SYSCTL_PERIPH_GPIOE, SYSCTL_PERIPH_GPIOF};
	uint32_t indexCounter;
	
	g_initErrorFlag = false;
   //enable PortA, PortB, PortC, PortD, PortE and PortF
	for(indexCounter = 0; indexCounter < 6; indexCounter++)
	{
	 	SysCtlPeripheralEnable(gpioPorts[indexCounter]);
		while(!SysCtlPeripheralReady(gpioPorts[indexCounter]));
	}

    //Set the direction of the pins

    //Set PB4 to output 
    GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_4);
    //Set PB6 to output
    GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_6);
    //Set PB7 to output 
    GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_7);
    //Set PF2 to output 
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);
    //Set PF3 to output 
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_3);
    //Configure PF4 to 2mA drive with weak pull-up
    GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_4, \
      GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
    //Interrupt configuration
    gpioInterruptConfig();
}

/*!
* @brief The purpose of this function is to Configure GPIO Interrupts
* @param[in] None
* @return None
*/
void
gpioInterruptConfig(void)
{

    //Configure PE4 to 2mA drive with weak pull-down
    GPIOPadConfigSet(GPIO_PORTE_BASE, GPIO_PIN_4, \
      GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPD);
    //Disable if any interrupt is enabled for PE4
    GPIOIntDisable(GPIO_PORTE_BASE, GPIO_PIN_4);
    //Clear interrupts on PE4
    GPIOIntClear(GPIO_PORTE_BASE, GPIO_PIN_4);
    //Register interrupts for PE4 
    GPIOIntRegister(GPIO_PORTE_BASE,GPIOE_Handler);
    //Set the interrupt type to detect on high edge
    GPIOIntTypeSet(GPIO_PORTE_BASE, GPIO_PIN_4, GPIO_HIGH_LEVEL);
    //Enable the interrupt for PE4
    GPIOIntEnable(GPIO_PORTE_BASE, GPIO_PIN_4);
    
    //Configure PB5 to 2mA drive with weak pull-down
    GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_5, \
      GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPD);
    //Disable if any interrupt is enabled for PB5
    GPIOIntDisable(GPIO_PORTB_BASE, GPIO_PIN_5);
    //Clear interrupts on PB5
    GPIOIntClear(GPIO_PORTB_BASE, GPIO_PIN_5);
    //Register interrupts for PB5 
    //GPIOIntRegister(GPIO_PORTB_BASE,GPIOB_Handler);
    //Set the interrupt type to detect on high edge
    GPIOIntTypeSet(GPIO_PORTB_BASE, GPIO_PIN_5, GPIO_HIGH_LEVEL);
    //Enable the interrupt for PE4
    GPIOIntEnable(GPIO_PORTB_BASE, GPIO_PIN_5);
}

/*!
* @brief This function is used to initialize and Configure ADC 
* @param[in] None.
* @return NA
*/
void
adcInit(void)
{
    //Enable ADC0 module
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0));
    GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_4|GPIO_PIN_5);
    //Set the clock configuration for ADC
    ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC|ADC_CLOCK_RATE_FULL, ADC_CLOCK_DIV1);
    //Set the reference for ADC
    ADCReferenceSet(ADC0_BASE, ADC_REF_INT);
    //Disable ADC sample sequencers before configuring
    ADCSequenceDisable(ADC0_BASE, ADC_SAMPLE_SEQUENCER1);
    //Configure ADC sample sequencer1 and sample sequencer2
    ADCSequenceConfigure(ADC0_BASE, ADC_SAMPLE_SEQUENCER1, ADC_TRIGGER_PROCESSOR, 0U);
    //Configure inputs of sample sequencer1
    ADCSequenceStepConfigure(ADC0_BASE, ADC_SAMPLE_SEQUENCER1, \
      ADC_SS_STEP0, ADC_CTL_CH10);
    ADCSequenceStepConfigure(ADC0_BASE, ADC_SAMPLE_SEQUENCER1, \
      ADC_SS_STEP1, ADC_CTL_CH11|ADC_CTL_IE|ADC_CTL_END);
    ADCSequenceEnable(ADC0_BASE, ADC_SAMPLE_SEQUENCER1);

}


/*!
* @brief This function is used to initialize GPIO and ADC peripherals
* @param[in] None.
* @return None
*/
None
portInit(void)
{
    //Initialize and configure all GPIO's
    gpioInit();
	//Initialize ADC
    adcInit();
}

/*** end of file ***/

Can anyone help me in sorting this issue please.

Thanks and Regards,

Santhosh.

  • Hello Santhosh,

    I reviewed your file but I am not certain what is occurring here still.

    You mention ADC0 and ADC1 are not enabling, but I only see ADC0 configured.

    More importantly, I don't see how ADC0 is used at all.

    How are you evaluating whether it is running or not?

    What is the expected behavior for running?

    What behavior occurs when in debug mode? What occurs when free running?

  • Hi Ralph,

    Thanks for your response.

    Sorry i didn't add the main function.Please find the code in the attachment.

    #include <stdbool.h>
    #include <stdint.h>
    #include <string.h>
    #include <stdlib.h>
    #include <math.h>
    #include "sysctl.h"
    #include "hw_memmap.h"
    #include "hw_ints.h"
    #include "hw_nvic.h"
    #include "gpio.h"
    #include "hw_gpio.h"
    #include "hw_types.h"
    #include "pin_map.h"
    #include "adc.h"
    
    void clockInit(void);
    void gpioInit(void);
    void gpioInterruptConfig(void);
    void adcInit(void);
    /*
     =================================
     Function Definitions
     =================================
     */
    
    
    void main(void)
    {
    	//Initializde system clock at 16 MHz
    	clockInit();
    	//Initialize GPIO and ADC peripherals
    	portInit();
    	//Glow Blue LED
    	GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0xFF);
    	while(1)
    	{
    
    	}	
    }
    /*!
    * @brief The purpose of this function is to configure system clock at 16MHz
    * @param[in] None.
    * @return None.
    */
    void
    clockInit(void)
    {
        // Set the clock to run directly from the external crystal/oscillator at 16MHz.
        SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | \
          SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
    }
    
    
    /*!
    * @brief The purpose of this function is to initialize and configure the GPIO pins
    * @param[in] none	
    ** @return NA
    */
    void
    gpioInit(void)
    {
    	uint32_t gpioPorts[6] = {SYSCTL_PERIPH_GPIOA, SYSCTL_PERIPH_GPIOB, SYSCTL_PERIPH_GPIOC,\
    				 SYSCTL_PERIPH_GPIOD, SYSCTL_PERIPH_GPIOE, SYSCTL_PERIPH_GPIOF};
    	uint32_t indexCounter;
    	
    	g_initErrorFlag = false;
       //enable PortA, PortB, PortC, PortD, PortE and PortF
    	for(indexCounter = 0; indexCounter < 6; indexCounter++)
    	{
    	 	SysCtlPeripheralEnable(gpioPorts[indexCounter]);
    		while(!SysCtlPeripheralReady(gpioPorts[indexCounter]));
    	}
    
        //Set the direction of the pins
    
        //Set PB4 to output 
        GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_4);
        //Set PB6 to output
        GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_6);
        //Set PB7 to output 
        GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_7);
        //Set PF2 to output 
        GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);
        //Set PF3 to output 
        GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_3);
        //Configure PF4 to 2mA drive with weak pull-up
        GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_4, \
          GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
        //Interrupt configuration
        gpioInterruptConfig();
    }
    
    /*!
    * @brief The purpose of this function is to Configure GPIO Interrupts
    * @param[in] None
    * @return None
    */
    void
    gpioInterruptConfig(void)
    {
    
        //Configure PE4 to 2mA drive with weak pull-down
        GPIOPadConfigSet(GPIO_PORTE_BASE, GPIO_PIN_4, \
          GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPD);
        //Disable if any interrupt is enabled for PE4
        GPIOIntDisable(GPIO_PORTE_BASE, GPIO_PIN_4);
        //Clear interrupts on PE4
        GPIOIntClear(GPIO_PORTE_BASE, GPIO_PIN_4);
        //Register interrupts for PE4 
        GPIOIntRegister(GPIO_PORTE_BASE,GPIOE_Handler);
        //Set the interrupt type to detect on high edge
        GPIOIntTypeSet(GPIO_PORTE_BASE, GPIO_PIN_4, GPIO_HIGH_LEVEL);
        //Enable the interrupt for PE4
        GPIOIntEnable(GPIO_PORTE_BASE, GPIO_PIN_4);
        
        //Configure PB5 to 2mA drive with weak pull-down
        GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_5, \
          GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPD);
        //Disable if any interrupt is enabled for PB5
        GPIOIntDisable(GPIO_PORTB_BASE, GPIO_PIN_5);
        //Clear interrupts on PB5
        GPIOIntClear(GPIO_PORTB_BASE, GPIO_PIN_5);
        //Register interrupts for PB5 
        //GPIOIntRegister(GPIO_PORTB_BASE,GPIOB_Handler);
        //Set the interrupt type to detect on high edge
        GPIOIntTypeSet(GPIO_PORTB_BASE, GPIO_PIN_5, GPIO_HIGH_LEVEL);
        //Enable the interrupt for PE4
        GPIOIntEnable(GPIO_PORTB_BASE, GPIO_PIN_5);
    }
    
    /*!
    * @brief This function is used to initialize and Configure ADC 
    * @param[in] None.
    * @return NA
    */
    void
    adcInit(void)
    {
        //Enable ADC0 module
        SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
        while(!SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0));
        GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_4|GPIO_PIN_5);
        //Set the clock configuration for ADC
        ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC|ADC_CLOCK_RATE_FULL, ADC_CLOCK_DIV1);
        //Set the reference for ADC
        ADCReferenceSet(ADC0_BASE, ADC_REF_INT);
        //Disable ADC sample sequencers before configuring
        ADCSequenceDisable(ADC0_BASE, ADC_SAMPLE_SEQUENCER1);
        //Configure ADC sample sequencer1 and sample sequencer2
        ADCSequenceConfigure(ADC0_BASE, ADC_SAMPLE_SEQUENCER1, ADC_TRIGGER_PROCESSOR, 0U);
        //Configure inputs of sample sequencer1
        ADCSequenceStepConfigure(ADC0_BASE, ADC_SAMPLE_SEQUENCER1, \
          ADC_SS_STEP0, ADC_CTL_CH10);
        ADCSequenceStepConfigure(ADC0_BASE, ADC_SAMPLE_SEQUENCER1, \
          ADC_SS_STEP1, ADC_CTL_CH11|ADC_CTL_IE|ADC_CTL_END);
        ADCSequenceEnable(ADC0_BASE, ADC_SAMPLE_SEQUENCER1);
    }
    
    
    /*!
    * @brief This function is used to initialize GPIO and ADC peripherals
    * @param[in] None.
    * @return None
    */
    None
    portInit(void)
    {
        //Initialize and configure all GPIO's
        gpioInit();
        //Initialize ADC
        adcInit();
    }
    
    /*** end of file ***/
    

    I am only using ADC0 for testing purpose and please find the answers below.

    How are you evaluating whether it is running or not?

    I am glowing Blue LED right after configuring GPIO and ADC peripherals. (Just to make sure that Peripherals are configured properly)

    What is the expected behavior for running?

    Blue LED should be glowing when i run the code.

    What behavior occurs when in debug mode? What occurs when free running?

    • Debug Mode - when i am first starting the debug mode everything is going fine (Blue LED is glowing as well as ADC0 peripheral is enabled) and when i am doing system reset in debug mode and restart the code I observed that ADC0 peripheral was not enabling and as a result when i try to access any ADC register using ADC APIs it is ending in hard fault. (Same Behavior is observed when i am pressing reset button on launchpad as it is also performing a core reset).
    • Free running - As long as i am not performing any system reset/Power off, blue LED was glowing and moment after i do any system reset Blue led stops glowing as processor is triggering a hard fault even before writing to GPIO.

    Please let me know if anymore information is required and my problem is only with ADC peripheral enabling. Once it is enabled i can work on my remaining part.

    Thanks and Regards,

    Santhosh.

  • Hello Santhosh,

    Thanks for the added details here, this gives me a much clearer picture to assess.

    I was trying to port your code into my own CCS project to see what happens on my LaunchPad but a number of your ADC configurations seem to be defined by your application and I do not have them. Can you provide those?

    #20 identifier "ADC_CLOCK_DIV1" is undefined blinky.c /blinky_TM4C123G line 61 C/C++ Problem
    #20 identifier "ADC_SAMPLE_SEQUENCER1" is undefined blinky.c /blinky_TM4C123G line 65 C/C++ Problem
    #20 identifier "ADC_SS_STEP0" is undefined blinky.c /blinky_TM4C123G line 70 C/C++ Problem
    #20 identifier "ADC_SS_STEP1" is undefined blinky.c /blinky_TM4C123G line 72 C/C++ Problem

    Also reviewing your code as I was inputting it over, I noticed you have GPIO Port B5 set to be a GPIO with an interrupt, but then you configure it for the ADC:

    GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_4|GPIO_PIN_5);

    I think this may be what is causing the system issue. Are you using GPIO Port B5 as an interruptible input, or as an ADC pin? If the former, please remove GPIO_PIN_5 from your GPIOPinTypeADC call and see if that clears the issue.

  • Hi Ralph,

    I had not configured GPIO Port B5 as interrupt now and executed the code but still i am facing same issue.

    Please find the requested macro definitions below,

    • ADC_CLOCK_DIV1                          1
    • ADC_SAMPLE_SEQUENCER1       1
    • ADC_SS_STEP0                               0
    • ADC_SS_STEP1                               1

    Thanks and Regards,

    Santhosh.

  • Hello Santhosh,

    Thanks, that got me running. The reason the system is hanging is that the ADC peripheral is not enabling properly due to clock configuration issues.

    The ADC can run from PIOSC, but it needs to be initialized with the PLL on.

    If you don't intend to use the PLL for your application, then you will need to turn on the PLL, configure the ADC to run from PIOSC, and then turn off the PLL again.

    The device datasheet has a section for ADC Module Clocking which has the following details:

    The module is clocked by a 16-MHz clock which can be sourced by a divided version of the PLL output, the PIOSC or an external source connected to MOSC (with the PLL in bypass mode). When the PLL is operating, the ADC clock is derived from the PLL ÷ 25 by default. However, the PIOSC can be used for the module clock using the ADC Clock Configuration (ADCCC) register. To use the PIOSC to clock the ADC, first power up the PLL and then enable the PIOSC in the CS bit field in the ADCCC register, then disable the PLL. When the PLL is bypassed, the module clock source clock attached to the MOSC must be 16 MHz unless the PIOSC is used for the clock source. To use the MOSC to clock the ADC, first power up the PLL and then enable the clock to the ADC module, then disable the PLL and switch to the MOSC for the system clock. The ADC module can continue to operate in Deep-Sleep mode if the PIOSC is the ADC module clock source.

    In your source code when I used 

    SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

    then everything ran fine. Otherwise I was stuck in 

    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_ADC0));

  • Hi Ralph,

    Thanks for your suggestion. I will implement the change and get back to you.

    Thanks and Regards,

    Santhosh.

  • Hi Ralph,

    Thank You so much. This resolved my issue.

    Best Regards,

    Santhosh.