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.

Initializing ADC0, jumps to Fault ISR



Hello all,

I am stuck in initialization of the ADC, all that code used to work but now it just stopped working.This code is working fine in Keil IDE and also used to work in CCS.

I tried to debug the code and found at the following instruction it jumps to Fault ISR.

ADCSequenceDisable(ADC0_BASE, 0);

//ADC0_ACTSS_R &= ~(ADC_ACTSS_ASEN0); //Disable Sample Squencer0 before configuring it. 

I also tried to use the direct register access as mentioned above in commented text, but no luck.

The whole code of the program is;

int main(void)
{
	volatile unsigned int ulLoop;
	volatile unsigned long adcvalue;
	SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

	
	ulLoop = SYSCTL_RCGC2_R; //Some delay to stabilize the clock on the GPIO E and F modules

	initadc();
	
	adcvalue = readadc(AIN8); //PE5

	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
	ulLoop = SYSCTL_RCGC2_R; //Some delay to stabilize the clock 
	GPIO_PORTF_DIR_R |= 0x0EU;	
	GPIO_PORTF_DEN_R |= 0x0EU;	
	GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2 |GPIO_PIN_3);

	while(1)
	{
		
		GPIO_PORTF_DATA_R = 0x00;
		
		GPIO_PORTF_DATA_R |= LED_RED;
		for(ulLoop = 0; ulLoop < 1800000; ulLoop++){ } // Delay
		GPIO_PORTF_DATA_R = 0x00;

		for(ulLoop = 0; ulLoop < 1800000; ulLoop++){ }
		GPIO_PORTF_DATA_R |= LED_GREEN;
		for(ulLoop = 0; ulLoop < 1800000; ulLoop++){ }
		GPIO_PORTF_DATA_R = 0x00;

		for(ulLoop = 0; ulLoop < 1800000; ulLoop++){ }
		GPIO_PORTF_DATA_R |= LED_BLUE;
		for(ulLoop = 0; ulLoop < 1800000; ulLoop++){ }


	}


}

and the initadc function is as follow;

#include "inc/hw_types.h"
#include "inc/lm4f120h5qr.h"
#include "driverlib/debug.h"
#include "driverlib/adc.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"



/*initadc() function initializes ADC0 and partially initializes Sample Sequencer 0. It doesnt assign the required adc channel pin.*/

void initadc(void)
{		
	volatile unsigned int ulLoop;
	
	
	//configuring ADC0 module
	SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
	SysCtlADCSpeedSet(SYSCTL_ADCSPEED_250KSPS);
	ulLoop = SYSCTL_RCGC0_R; //Stabilize the clock

	//SYSCTL_RCGC0_R |= SYSCTL_RCGC0_ADC0SPD_250K; //Configure ADC0 to sample at 250kHz
	//SYSCTL_RCGC0_R |= SYSCTL_RCGC0_ADC0; //Enable clock to ADC0 Module
	
	//Configuring Sample Squencer 0
	ADCSequenceDisable(ADC0_BASE, 0);
	//ADC0_ACTSS_R &= ~(ADC_ACTSS_ASEN0); //Disable Sample Squencer0 before configuring it
	
	//Configuring Sample Squencer priorities
	ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_PROCESSOR, 0);
	//ADC0_SSPRI_R = (ADC_SSPRI_SS0_1ST | ADC_SSPRI_SS1_2ND | ADC_SSPRI_SS2_3RD | ADC_SSPRI_SS3_4TH);
	
	//Select Event triggering mode e.g Process triggered, Timer triggered, GPIO triggered etc
	//ADC0_EMUX_R = (ADC_EMUX_EM0_PROCESSOR); //Process triggered
	
	/*
	//Configuring the squence steps (i.e. assigning the adc channels (e.g. AIN0 is adc channel 0 = PE3 pin) that is to read)
	ADC0_SSMUX0_R &= ~(0x0000000F); //Clear MUX0 field
	//Here we can add multiple ADC channels by configuring ADCSSMUX0 register of SS0//
	ADC0_SSMUX0_R |= 0x00000001; //Select AIN1 i.e. PE2 as a first sample of the sample sequencer 0
	
	//Configuring sample sequencer 0 control
	//In case of more then one ADC channel used in SS0. END bit of ADCSSCTL0 register should be made active for the last sample//
	ADC0_SSCTL0_R =  ADC_SSCTL0_END0 | ADC_SSCTL0_IE0; //First sample is END of sampling and interupt is enabled on completing first sample
	
	//Enable the Sample Sequencer 0
	ADC0_ACTSS_R |= (ADC_ACTSS_ASEN0); */
	

		 // Enable the GPIO Port E. PortE is used with AIN8 i.e. PE5 as ADC pin
			SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOE;
			ulLoop = SYSCTL_RCGC2_R; //Stabilize the clock
			GPIO_PORTE_DIR_R &= ~0x10;      // 2) make PE5 input
			GPIO_PORTE_AFSEL_R |= 0x10;     // 3) enable alternate function on PE5
			GPIO_PORTE_DEN_R &= ~0x10;      // 4) disable digital I/O on PE5
			GPIO_PORTE_AMSEL_R |= 0x10;     // 5) enable analog function on PE5

}



/*long readadc(int) partially initialized the Sample Squencer 0 and assigns the required adc channel pin*/
unsigned long readadc(unsigned int channel)
{
	volatile unsigned long result;
	
	ADC0_SSMUX0_R |= channel; //Select channel i.e. AINn i.e. PE2 as a first sample of the sample sequencer 0
	
	//Configuring sample sequencer 0 control
	//ADCSequenceStepConfigure(ADC0_BASE, 0, 0, ADC_CTL_TS | ADC_CTL_IE | ADC_CTL_END);
	//ADC0_SSCTL0_R =  ADC_SSCTL0_END0 | ADC_SSCTL0_IE0; //First sample is END of sampling and interupt is enabled on completing first sample
	//Enable the Sample Sequencer 0
	ADC0_ACTSS_R |= (ADC_ACTSS_ASEN0);
	
	//initiate SS0
	ADC0_PSSI_R = 0x01; //0x01=SS0, 0x02=SS1, 0x04=SS2, 0x08=SS3
	//Wait for interupt for SS0 conversion complete
	while((ADC0_RIS_R&0x01)==0)
		{//Do nothing
			}
	result = ADC0_SSFIFO0_R;		
	// Acknowlodgement the interupt for SS0
	ADC0_ISC_R |= 0x01; 
			
	//Return the result
	return result;
	
}

  • Cannot tell which MCU - which IDE (appears CCS) and which version of Stellaris/TivaWare you are using!

    If using TivaWare - there is a known bug in the following function:

    SysCtlADCSpeedSet(SYSCTL_ADCSPEED_250KSPS);

    Our group sticks w/StellarisWare as we find it to be more robust and avoids these, "growing pains."

    Commenting out that function - if indeed you're using TivaWare - then testing - seems worthwhile...

    Beyond that - there are many "nooks/crannies" w/in CCS that demand near perfect addressing & data entry.  As you state your code runs well under Keil - and if you are using TivaWare - it may well be that your IDE is imperfectly set-up/configured.  Our group uses IAR - so I'm of no help in IDE config...

  • Hi Sahil,

         See, these posts below.

         ADC0 Configuration with TIVAware

         ADC Speed Set

         The SysCtlADCClockSet function does not work on TM4C devices

         I see you use the old LM4F120 Tivaware library for your program. I suggest you use the latest Tivaware.

    - kel

  • Hello Sahil,

    Looking at the code, I believe you may have run into the ADC Errata #08. I will suggest locking the PLL

    Regards

    Amit

  • @cb1

    I am using LM4F120 Launchpad,

    As I stated, I also tried to use the direct register access method as commented in the code, but it still goes to Fault ISR.

    Since I have the same code used in another project in the same IDE i.e. CCS, that works for me.

    Could that be due to the stack size as I changed it to 1k as a requirement for using UARTprintf functions ?

    I tried different sizes e.g. 500bytes, 1k, 2k but doesnt help.

    @ 

    As an alternative, I tried to configure the adc module with direct register access (tested code), but it leads to the same problem.

    Do you still think it could be due to the library functions ?

    @Amit Ashara

    "Looking at the code, I believe you may have run into the ADC Errata #08. I will suggest locking the PLL"

     

    I can not understand, could you please explain a bit more.

    What modification you mean in the following code;

    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);

    Should that be replaced with;

    SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);

     

     

  • Hello Sahil,

    That is correct the code to use for the Work Around. If it does not help either, can you zip the CCS project that is not working and I will try to re-create the issue and see what is happening.

    Regards

    Amit

  • Dear Amit Ashara,

    I introduced the PLL and it fixed the problem. :)

    i.e.

    SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);

     

    I thank you.