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 Maximum ADC sample ratio.

Other Parts Discussed in Thread: TM4C123GH6PM

Hi, i need to sample the ADC in a TM4C123GH6PM, the clock is 80 Mhz. The maximum sampling rate that achievement is 15650 Hz, i can see in the oscilloscope, switching a pin. I using: ROM_ADCHardwareOversampleConfigure(ADC0_BASE, 64); that is correct for 15.6250 kHz, because 1 MHz/64=15625 Hz. But if I use a different multiplier, it does not work the microcontroller, for example: ROM_ADCHardwareOversampleConfigure(ADC0_BASE, 32), not work. Can you helpme, please? I Need sample to maximum speed (1Mhz is great!, but 256 kHz or more is good too, considering that audio cars sampling to 192 khz) for implement a FIR filter. Thanks!

My ISR:

void ADC0IntHandler(void)
{	
	ROM_GPIOPinWrite(GPIO_PORTF_BASE, LED_RED|LED_BLUE|LED_GREEN, LED_RED);
	ROM_ADCIntClear(ADC0_BASE,1);
	ROM_ADCSequenceDataGet(ADC0_BASE,1, &adcValue);
	ROM_GPIOPinWrite(GPIO_PORTF_BASE, LED_RED|LED_BLUE|LED_GREEN, !LED_RED);	
}


My ADC Initialization:

void ROM_ADC_Init(void)
{
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
	
	
	ROM_ADCHardwareOversampleConfigure(ADC0_BASE, 64); // x2, x8, x16, x32 NOT WORK!
	
	ROM_ADCSequenceDisable(ADC0_BASE,1);
	ROM_ADCSequenceConfigure(ADC0_BASE,1, ADC_TRIGGER_ALWAYS,0);
	ROM_ADCSequenceStepConfigure(ADC0_BASE,1,0,ADC_CTL_TS|ADC_CTL_IE|ADC_CTL_END);
	ROM_ADCSequenceEnable(ADC0_BASE,1);
	
	ADCIntRegister(ADC0_BASE,1,ADC0IntHandler);
	ROM_IntEnable(INT_ADC0SS1);

  ROM_ADCIntEnable(ADC0_BASE,1);
  ROM_ADCIntClear(ADC0_BASE, 1);
}

  • I've been there a little research and I found that these two statements are equivalent, correct?

    HWREG(ADC0_BASE + ADC_O_PC) = (ADC_PC_SR_1M);
    ADCClockConfigSet(ADC0_BASE,  ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 1);

    If i use "ADC_CLOCK_SRC_PIOSC" instead "ADC_CLOCK_SRC_PLL", the sample rate is not exactly 15.6250, its value ranges in 15.5xxx kHz. Perhaps it is because it uses the internal oscillator and no XTAL with PLL?

    but equally I can not sample more than 15,6250 kHz.

    What am I avoiding?

  • Hello Fernando,

    Can you let us know what is the value of sampling that is being performed when a value of other than x64 is used?

    Regards
    Amit
  • The TIVA Launchpad is not started. I am using Keil with CMSIS, because i would like to use DSP functions to perform a FIR lowpass.
  • Hello Fernando,

    I understand the use of CMSIS DSP functions to perform Signal processing. But first thing first: what is happening when you change the oversampling rate to values other than 64. If you halt the CPU what does it show the CPU is doing?

    Regards
    Amit
  • When I change the sampling rate to another value other than 64, to program the microcontroller, this does not start, do nothing, do not turn on the LEDs, nothing.

    This is my code:

    //#define TARGET_IS_TM4C123_RB1
    //#define PART_TM4C123GH6PM
    
    #include <stdio.h>
    #include <stdint.h>
    #include <stdbool.h>
    #include <math.h>
    
    //#include "inc/tm4c123gh6pm.h"
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_ints.h"
    #include "inc/hw_nvic.h"
    #include "inc/hw_gpio.h"
    #include "inc/hw_adc.h"
    
    #include "driverlib/adc.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "driverlib/ssi.h"
    #include "driverlib/pwm.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/fpu.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/systick.h"
    
    #include "utils/uartstdio.h"
    
    #include "Nokia5110.h"
    
    // Defines
    #define LED_RED GPIO_PIN_1
    #define LED_BLUE GPIO_PIN_2
    #define LED_GREEN GPIO_PIN_3
    
    // Global variables
    double Temp=0;
    uint32_t adcValues[4];
    uint32_t adcValue;
    
    // Functions prototypes
    void ROM_CLK_Init_80MHz(void);
    void ROM_delay_ms(float ms);
    void ROM_ADC_Init(void);
    void ROM_UART_Init(void);
    void ROM_SSI_Init(void);
    void ROM_PWM_Init(void);
    void ROM_SysTick_Init(void);
    
    // Interrupts
    void ADC0IntHandler(void)
    {	
    	ROM_GPIOPinWrite(GPIO_PORTF_BASE, LED_RED|LED_BLUE|LED_GREEN, LED_RED);
    	ROM_ADCIntClear(ADC0_BASE,1);
    	//while(!ROM_ADCIntStatus(ADC0_BASE, 1, false));
    	ROM_ADCSequenceDataGet(ADC0_BASE,1, &adcValue);
    	
    	//Temp= 147.5-((75*(3.3)*adcValue)/4096.f);
    	ROM_GPIOPinWrite(GPIO_PORTF_BASE, LED_RED|LED_BLUE|LED_GREEN, !LED_RED);	
    }
    
    void SysTickIntHandler(void)
    {	
    	ROM_GPIOPinWrite(GPIO_PORTF_BASE, LED_RED|LED_BLUE|LED_GREEN, LED_RED);
    
    
    	ROM_GPIOPinWrite(GPIO_PORTF_BASE, LED_RED|LED_BLUE|LED_GREEN, !LED_RED);
    }
    
    int main(void)
    {	
    	uint32_t ui32ClockDiv;
    	//Enable lazy stacking
    	ROM_FPUEnable();
    	ROM_FPULazyStackingEnable();
    	
    	ROM_CLK_Init_80MHz();
    //	ROM_UART_Init();
    	ROM_ADC_Init();
    	ROM_SSI_Init();
    	ROM_PWM_Init();
    //	ROM_SysTick_Init();
    	
    	ROM_IntPrioritySet(INT_ADC0SS1, 0x00);
      ROM_IntPrioritySet(INT_SYSCTL, 0x01);
    	
    	ROM_IntMasterEnable();
    	
    	// Initialize the GPIO for the LED.
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    	ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, LED_RED|LED_BLUE|LED_GREEN);
    	
    	// Set Nokia 5110 led light
    	ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_2, 65535./100*100);		// 100% illumitation
    	Nokia5110_Init();
    	
    	Nokia5110_Clear();
    	Nokia5110_DrawFullImage(fernando);
    	ROM_delay_ms(500);
      Nokia5110_Clear();
    	
    //	ROM_SysTickEnable();
    	
    	while(1)
    	{
    		// LED on
    		ROM_GPIOPinWrite(GPIO_PORTF_BASE, LED_RED|LED_BLUE|LED_GREEN, LED_BLUE);
    		
    		Nokia5110_SetCursor(2,0);
    		Nokia5110_OutFloat33(147.5-((75*(3.3)*adcValue)/4096.f));
    		Nokia5110_SetCursor(2,1);
    		Nokia5110_OutU32Dec(ADCClockConfigGet(ADC0_BASE, &ui32ClockDiv));
    		Nokia5110_SetCursor(2,2);
    		Nokia5110_OutU32Dec(ui32ClockDiv);
    		Nokia5110_SetCursor(2,3);
    		Nokia5110_OutU32Dec(HWREG(ADC0_BASE + ADC_O_PP));
    		
    		ROM_delay_ms(100);
    
    		// LED off
    		ROM_GPIOPinWrite(GPIO_PORTF_BASE, LED_RED|LED_BLUE|LED_GREEN, !LED_BLUE);
    
    		// Delay for second
    		ROM_delay_ms(100);
    		
    	}
    	
    }
    
    // Functions
    void ROM_CLK_Init_80MHz(void)
    {
    	// Setup the system clock to run at 80 Mhz from PLL with crystal reference
    	ROM_SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
    }
    
    void ROM_delay_ms(float ms)
    {
    	ROM_SysCtlDelay((ROM_SysCtlClockGet()*(ms/1000.f))/3.f);
    }
    
    void ROM_SysTick_Init(void)
    {
    	ROM_SysTickPeriodSet(ROM_SysCtlClockGet()*0.1);  // 100ms, 10 Hz. Max 200 Hz, because SysClk=80Mhz and SysTick is 24 bits.
    	SysTickIntRegister(SysTickIntHandler);
    	ROM_SysTickIntEnable();
    }
    
    void ROM_ADC_Init(void)
    {
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
    	
    	ROM_ADCHardwareOversampleConfigure(ADC0_BASE, 64);
    	HWREG(ADC0_BASE + ADC_O_PC) = (ADC_PC_SR_1M);
    //	ADCClockConfigSet(ADC0_BASE,  ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 1);
    	
    	
    	ROM_ADCSequenceDisable(ADC0_BASE,1);
    	ROM_ADCSequenceConfigure(ADC0_BASE,1, ADC_TRIGGER_ALWAYS,0);
    //	ROM_ADCSequenceStepConfigure(ADC0_BASE,1,0,ADC_CTL_CH0);
    //	ROM_ADCSequenceStepConfigure(ADC0_BASE,1,1,ADC_CTL_CH1);
    //	ROM_ADCSequenceStepConfigure(ADC0_BASE,1,2,ADC_CTL_CH2);
    	ROM_ADCSequenceStepConfigure(ADC0_BASE,1,0,ADC_CTL_TS|ADC_CTL_IE|ADC_CTL_END);
    	ROM_ADCSequenceEnable(ADC0_BASE,1);
    	
    	ADCIntRegister(ADC0_BASE,1,ADC0IntHandler);
    	ROM_IntEnable(INT_ADC0SS0);
    
      ROM_ADCIntEnable(ADC0_BASE,1);
      ROM_ADCIntClear(ADC0_BASE, 1);
    }
    
    void ROM_UART_Init(void)
    {
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    
    	ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
    	ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
    	ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    
    	ROM_UARTClockSourceSet(UART0_BASE, ROM_SysCtlClockGet());
    	UARTStdioConfig(0, 1000000, ROM_SysCtlClockGet());
    	}
    
    void ROM_SSI_Init(void)
    {
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI0);
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    	
    	ROM_GPIOPinConfigure(GPIO_PA2_SSI0CLK);
    	ROM_GPIOPinConfigure(GPIO_PA3_SSI0FSS);
    	ROM_GPIOPinConfigure(GPIO_PA4_SSI0RX);
    	ROM_GPIOPinConfigure(GPIO_PA5_SSI0TX);
    	
    	ROM_GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7);
    	ROM_GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_6 | GPIO_PIN_7, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD);
    	
    	ROM_GPIOPinTypeSSI(GPIO_PORTA_BASE, GPIO_PIN_5 | GPIO_PIN_4 | GPIO_PIN_3 | GPIO_PIN_2);
    	ROM_SSIConfigSetExpClk(SSI0_BASE, ROM_SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,
    										 SSI_MODE_MASTER, 8000000, 8);
    	
    	ROM_SSIEnable(SSI0_BASE);
    }
    	
    void ROM_PWM_Init(void)
    {	
    	//Configure PWM Clock to match system
    	ROM_SysCtlPWMClockSet(SYSCTL_PWMDIV_1);
    
    	// Enable the peripherals used by this program.
    	//ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_PWM1);
    
    	//Configure PF1,PF2,PF3 Pins as PWM and PE4
    	ROM_GPIOPinConfigure(GPIO_PE4_M1PWM2);
    	//ROM_GPIOPinConfigure(GPIO_PF1_M1PWM5);
    	//ROM_GPIOPinConfigure(GPIO_PF2_M1PWM6);
    	//ROM_GPIOPinConfigure(GPIO_PF3_M1PWM7);
    	//ROM_GPIOPinTypePWM(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
    	ROM_GPIOPinTypePWM(GPIO_PORTE_BASE, GPIO_PIN_4);
    
    	//Configure PWM Options
    	//PWM_GEN_2 Covers M1PWM4 and M1PWM5
    	//PWM_GEN_3 Covers M1PWM6 and M1PWM7 See page 207 4/11/13 DriverLib doc
    	//ROM_PWMGenConfigure(PWM1_BASE, PWM_GEN_2, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
    	//ROM_PWMGenConfigure(PWM1_BASE, PWM_GEN_3, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
    	ROM_PWMGenConfigure(PWM1_BASE, PWM_GEN_1, PWM_GEN_MODE_UP_DOWN | PWM_GEN_MODE_NO_SYNC);
    	
    	//Set the Period (expressed in clock ticks)
    	//ROM_PWMGenPeriodSet(PWM1_BASE, PWM_GEN_2, 65536);
    	//ROM_PWMGenPeriodSet(PWM1_BASE, PWM_GEN_3, 65536);
    	ROM_PWMGenPeriodSet(PWM1_BASE, PWM_GEN_1, 65536);
    
    	//Set PWM duty-00%
    	//ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_5,0);
    	//ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_6,0);
    	//ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_7,0);
    	ROM_PWMPulseWidthSet(PWM1_BASE, PWM_OUT_2,0);
    
    	// Enable the PWM generator
    	//ROM_PWMGenEnable(PWM1_BASE, PWM_GEN_2);
    	//ROM_PWMGenEnable(PWM1_BASE, PWM_GEN_3);
    	ROM_PWMGenEnable(PWM1_BASE, PWM_GEN_1);
    
    	// Turn on the Output pins
    	//ROM_PWMOutputState(PWM1_BASE, PWM_OUT_5_BIT | PWM_OUT_6_BIT | PWM_OUT_7_BIT | PWM_OUT_2_BIT, true);
    	ROM_PWMOutputState(PWM1_BASE, PWM_OUT_2_BIT, true);
    }
    

  • Hi, that is strange, if i exchange the order of peripheral initialization, let me more adc sample ratio. SSI->ADC->PWM=>16 (62.5000 kHz), SSI, PWM, ADC =>8 (125.000 kHz) and 4 (250.000 kHz).

    	ROM_SSI_Init();
    	ROM_PWM_Init();
    	ROM_ADC_Init();


    But equally I can not sample more than 250.000 kHz.
    Why, Mr. Anderson? Why, why? Why this occurs?

  • Hello Fernando,

    It seems that the ADC Speed setting in System Control space is getting modified due to the access order.

    Regards
    Amit
  • Hi Amit, thanks!

    Are well configured the peripherals?, is necessary some additional configuration?, why the access order produce different effects?

    Regards,
    Fernando.

  • Hello Fernando,

    TM4C123 has a common register for configuration of speeds for different peripherals. This did complicate the functions and on TM4C129 the configuration of speeds was moved under peripheral address space.

    Regards
    Amit
  • Thank you very much Amit, still I do not quite understand what the priority setting, but the experience will teach me.
    Best Regards,
    Fernando
  • Hello Fernando,

    Though I would need to investigate the APIs for TM4C123, but from an explanation perspective assume that the register settings which are common for two peripherals P1 and P2 are in register R and the Set Speed functions are written as

    P1SetSpeed{
    R = P1FeatureBit
    }

    P2SetSpeed{
    R |= P2FeatureBit
    }

    So a call of P1 followed by P2 will lead to a correct setting of R and not vice-versa.

    Regards
    Amit
  • Hi Amit,
    I imagined something like that, but it is assumed that the library contemplates.
    I will configure the peripherals with friendly code and records directly.
    Best regards,
    Fernando.
  • Hello Fernando

    And I will investigate why the configuration order is causing the issue

    Regards
    Amit