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.

Tiva TM4C123G cannot get the timer to generate an ADC read and interrupt

Other Parts Discussed in Thread: TM4C123GH6PM

Hello Folks

Got myself stuck on a problem.

I'm trying to use the TM4C123GH launch pad as a timer and the ADC to sample the size of the object.

basically I'm trying to measure the size of a drop of water using the ADC then start a timer for specified delay.

I got the timer to work, but I cannot figure out how to get the ADC to sample when the Timer has activated the ADC function.

I like to use direct access approach as opposed to API utilities, as this gives me greater flexibility, and speed, plus I learn more in depth function of the processor.

I got the timer working, but now  need the timer  to trigger an ADC read and interrupt to know when it's completed the conversion.

Plus my next project is to use the timer at 4kHz then read the ADC audio time to make a spectrum analyzer.

I appreciate any help I receive

Regards

Roman

Code Composer Studio
 Version: 5.4.0.00091

// ***************************************************************************
//  PF1 = RED led
//  PF2 = BLUE led
//  PF3 = GREEN led
//  PF0 = SW2
//  PF4 = SW1
//
//  PE 0 ~ 5 available
// ****************************************************************************

#include <stdint.h>
#include "inc/tm4c123gh6pm.h"

extern void Timer0IntHandler(void);
void delay_sec(void);
void ADC_Int_Handler(void);
void Flash(void);

volatile uint32_t ui32Loop;
volatile uint32_t ui32Loop2;
volatile uint32_t nope;
volatile uint32_t ADC_cnt = 0;
volatile uint32_t ADC_flash = 511;
#define SYSDIV 2
#define LSB 0
#define timer_int 0x00080000
#define timer0_cnt_dwn 0x000F0000 // TIMER COUNT VALUE
#define red 0x0002
#define blue 0x0004
#define green 0x0008

#define SYSCTL_PERIPH_ADC0      0xf0003800  // ADC 0
#define SYSCTL_RCGCBASE         0x400fe600
//*****************************************************************************
//
// Blink the on-board LED.
//
//*****************************************************************************
int
main(void)
{
    // Memory Map  p88
    // System Control Registers p228
    // Flash Register Map   p535
    // GPIO Register Map   p654

    SYSCTL_RCC2_R |= SYSCTL_RCC2_USERCC2;
    SYSCTL_RCC2_R |= SYSCTL_RCC2_BYPASS2;
    SYSCTL_RCC_R &= ~SYSCTL_RCC_XTAL_M;        // clear XTAL field
    SYSCTL_RCC_R += SYSCTL_RCC_XTAL_16MHZ;     // configure for 16 MHz crystal
    SYSCTL_RCC2_R &= ~SYSCTL_RCC2_OSCSRC2_M;   // clear oscillator source field
    SYSCTL_RCC2_R += SYSCTL_RCC2_OSCSRC2_MO;   // configure for main oscillator source
    SYSCTL_RCC2_R &= ~SYSCTL_RCC2_PWRDN2;
    SYSCTL_RCC2_R |= SYSCTL_RCC2_DIV400;
    SYSCTL_RCC2_R &= ~SYSCTL_RCC2_SYSDIV2_M;   // clear system clock divider field
    SYSCTL_RCC2_R &= ~SYSCTL_RCC2_SYSDIV2LSB;  // clear bit SYSDIV2LSB

    SYSCTL_RCC2_R += (SYSDIV<<23)|(LSB<<22);   // divide by (2*SYSDIV+1+LSB)

    while((SYSCTL_RIS_R&SYSCTL_RIS_PLLLRIS)==0){};

    SYSCTL_RCC2_R &= ~SYSCTL_RCC2_BYPASS2;

    SYSCTL_RCGCGPIO_R = SYSCTL_RCGCGPIO_R4 + SYSCTL_RCGCGPIO_R5;    // enable GPIO E & F
    SYSCTL_RCGCTIMER_R = SYSCTL_RCGCTIMER_R0 + SYSCTL_RCGCTIMER_R1;  // enable clock for timer 0, p334

    // Do a dummy read to insert a few cycles after enabling the peripheral.
    ui32Loop = SYSCTL_RCGC2_R;

    // Enable the GPIO pin for the LED (PF3).  Set the direction as output, and
    // enable the GPIO pin for digital function.
    GPIO_PORTF_DIR_R = 0x0E;
    GPIO_PORTF_DEN_R = 0x0E;
    ui32Loop = SYSCTL_RCGC2_R;
    GPIO_PORTF_DATA_R &= ~(0x0E);
    delay_sec();
// *************************************************************************
//  timer   698
// *************************************************************************

    TIMER0_CFG_R = TIMER_CFG_32_BIT_TIMER;  // 00000000   p721
    TIMER0_TAILR_R = timer0_cnt_dwn;  //    load timer value  750
    TIMER0_TAMR_R |= TIMER_TAMR_TAMR_PERIOD + TIMER_TAMR_TAMIE; //    0x2       723

    TIMER0_IMR_R = TIMER_IMR_TATOIM; // set interupt 739
    TIMER0_CTL_R |= TIMER_CTL_TAEN + TIMER_CTL_TAOTE; // enable the timer and start counting 731

// *************************************************************************
//  ADC port E page 812  configuration 811
// *************************************************************************
       SYSCTL_RCGCADC_R |= SYSCTL_RCGCADC_R0 | SYSCTL_RCGCADC_R1;  // OK ADC Module 0 Run Mode Clock p348
       ADC0_PC_R |= SYSCTL_RCGC0_ADC0SPD_500K;
       GPIO_PORTE_AFSEL_R |= GPIO_Port3;   //  AIN0 PE3 analog page 666
       GPIO_PORTE_DEN_R &= ~GPIO_Port3;   // make as input  p677  (GPIODEN)
       ADC0_EMUX_R |= ADC_EMUX_EM0_TIMER; // use timer for ADC sample
       ADC0_ACTSS_R &= ~ADC_ACTSS_ASEN0;  // disable Sequencer
       ADC0_SSMUX0_R |= ADC_SSMUX0_MUX0_S;
       ADC0_SSCTL0_R |= ADC_SSCTL0_END0 + ADC_SSCTL0_IE0;
      ADC0_ACTSS_R |=  ADC_ACTSS_ASEN0 + ADC_ACTSS_ASEN1 + ADC_ACTSS_ASEN2 + ADC_ACTSS_ASEN3;
       ADC0_IM_R |= ADC_IM_MASK0;  //ADC Interrupt Mask

// *************************************************************************
//  interrupt
// *************************************************************************
    NVIC_EN0_R = timer_int;
    NVIC_ST_CTRL_R |= NVIC_ST_CTRL_INTEN;
    ADC0_IM_R = ADC_IM_MASK0;  // SS0 Interrupt Mask
    ADC0_ACTSS_R = ADC_ACTSS_ASEN0;  // enable Sequencer


    while(1)  // loop forever
        {
//            delay_sec();
//            GPIO_PORTF_DATA_R |= red;

            GPIO_PORTF_DATA_R &= ~(red);  //  reset off LEDS
            GPIO_PORTF_DATA_R &= ~(green);
            GPIO_PORTF_DATA_R &= ~(blue);
               delay_sec();
          }
}

void delay_sec(void) //  used to see the LEDs flash for testing
{
    for(ui32Loop = 0; ui32Loop < 20000; ui32Loop++)
        {
        }
}
void Timer0IntHandler(void)
{
    GPIO_PORTF_DATA_R |= green;  // proves I've been here this works
    TIMER0_ICR_R = TIMER_ICR_TATOCINT; // clear interrupt
}
void ADC_Int_Handler(void)
{
    ADC0_PSSI_R  |= ADC_PSSI_SS0;
    GPIO_PORTF_DATA_R |= red; // Flash red doesn't flash INT not occurring

    if (ADC0_SSFIFO0_R > ADC_flash) // check if the right size
    {
        Flash();  //trigger the flash
    }

    ADC0_ISC_R |= ADC_ISC_IN0 +ADC_ISC_IN1 + ADC_ISC_IN2 + ADC_ISC_IN3; // clear int flag
}
void Flash(void) // right size detected
{
    GPIO_PORTF_DATA_R |= blue; // Flash Blue led Proves I've been here
    // trigger the flash a variable resistor to vary the delay time after the trigger
    // first have to get ADC 0 working

    for(ui32Loop2 = 0; ui32Loop2 < 200; ui32Loop2++)
            {
            }
    GPIO_PORTF_DATA_R &= ~blue;
}



  • Hi Roman,

         You, can check how the the ADCSequenceDataGet() C API works. The ADC data can be read from the ADCSSFIFOn Register bit fields 11:0 DATA. From my Tivaware copy that is defined as ADC_SSFIFO0_DATA_M and can be found at "TivaWare_C_Series-1.0\inc\hw_adc.h". I don't see where you are reading the ADC FIFO register, from your code. Please, correct me if I am wrong.

    -kel