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.

ADC - Hung Inside ADCIntStatus - Don't See Issue

Other Parts Discussed in Thread: EK-TM4C123GXL

Hi TI:

After looking through the various forum threads on this issue, I still can't figure out why ADCIntStatus() never returns.  

Here are the basics.

Part# - EK-TM4C123GXL

OSC - PIOSC    I am not using an external clock.

SysCtlClockGet() Returns: 80,000,000

TI-RTOS - 1.10.0.23

ADC - Using "Drivers" Only.

Errata - I went through all of the Errata and "tried" to make sure I was avoiding those issues.  Noted in the code below.

EK_TM4C123GXL.c - This is really where the Init() Code Is.  The code you see was compacted just a bit.

I am very interested in understanding a few issues.

1. If this is a clock issue, is this a matter of associating the PLL with the ADC module?

I understand the Errata issue; but, I can not translate into Code.

I do not know if TI-RTOS likes having the clock changed.

2. The entire Interrupt issue is a mystery.  I so not see what the ADC "driver" code is doing here.

I'm not finding well explained examples for this.

In this environment, I do not seem to have easy access to the Interrupt table.  I'll need a bit of explanation here.

3. If above is not the issue, what is?

Any help would be most appreciated.  

Thank you. 

Rick

Code:

Init(void)
{
  // this code is in: EK_TM4C123GXL.c

  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

  SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);


  GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);
  GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_2);
  GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_1);
  GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_0);
  GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_3);
  GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_2);
}


void GetData(void)
{

  uint32_t uiClock;
  uint32_t ui32ADC0Value[8];

  iCount++;

  // Tiva™ C Series TM4C123x Microcontrollers Silicon Revisions 6 and 7 (Errata)

  // ADC#01 - Does not appear to apply
  // ADC#03 - More than one Step is used
  //                    No comparator is in use
  //                    This does not appear to be the issue
  // ADC#04 - Does not appear to apply
  // ADC#07 - Does not appear to apply
  // ADC#08 - Enabling the PLL seems to hang the Board or has no effect
  //                    Appears to be using the Precision Internal Oscillator (PIOSC)
  // ADC#09 - Does not appear to apply
  // ADC#11 - Does not appear to apply
  // ADC#13 - Removed PE3 from usage
  // ADC#14 - Does not appear to apply
  // ADC#16 - Does not appear to apply


  // ADC#08 - this causes the program to hang or has no effect - Commented out
  // SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ);


  // Clock Check - Clock: 80,000,000
  uiClock = SysCtlClockGet();
  System_printf("Clock: %i \n", uiClock);
  System_flush();

  ADCSequenceDisable(ADC0_BASE, ADC_INT_SS0);

  ADCSequenceConfigure(ADC0_BASE, ADC_INT_SS0, ADC_TRIGGER_PROCESSOR, 0);

  // ADC#13 ADCSequenceStepConfigure(ADC0_BASE, ADC_INT_SS0, 0, ADC_CTL_CH0); // PE3 Commented out
  ADCSequenceStepConfigure(ADC0_BASE, ADC_INT_SS0, 0, ADC_CTL_CH1);                                                             // PE2
  ADCSequenceStepConfigure(ADC0_BASE, ADC_INT_SS0, 1, ADC_CTL_CH2);                                                             // PE1
  ADCSequenceStepConfigure(ADC0_BASE, ADC_INT_SS0, 2, ADC_CTL_CH3);                                                             // PE0
  ADCSequenceStepConfigure(ADC0_BASE, ADC_INT_SS0, 3, ADC_CTL_CH4);                                                             // PD3
  ADCSequenceStepConfigure(ADC0_BASE, ADC_INT_SS0, 4, ADC_CTL_CH5 | ADC_CTL_IE | ADC_CTL_END); // PD2

  ADCSequenceEnable(ADC0_BASE, 0);

  //ADCIntRegister(ADC0_BASE, ADC_INT_SS0, &MyISR); // Started thinking about my own interrupt here.
  //ADCIntEnable(ADC0_BASE, ADC_INT_SS0);

  ADCIntClear(ADC0_BASE, ADC_INT_SS0);

  ADCProcessorTrigger(ADC0_BASE, 0);

  // Hangs Right Here!
  while(!ADCIntStatus(ADC0_BASE, ADC_INT_SS0, false))
  {
  }

  //ADCIntClear(ADC0_BASE, ADC_INT_SS0);

  ADCSequenceDataGet(ADC0_BASE, ADC_INT_SS0, ui32ADC0Value); // Watch on ui32ADC0Value

  ADCSequenceDisable(ADC0_BASE, ADC_INT_SS0);

  ADCIntDisable(ADC0_BASE, ADC_INT_SS0);


  System_printf("Data: %i \t %i \t %i \t %i \t %i \t %i \t %i \t \n", iCount, ui32ADC0Value[0], ui32ADC0Value[1], ui32ADC0Value[2], ui32ADC0Value[3],  ui32ADC0Value[4], ui32ADC0Value[5]);
  System_flush();

  return;
}

  • Hi Rick,

    Can I just say that I am more weird out by the fact that you say this:
    SysCtlClockGet() Returns: 80,000,000

    What! There should be a bug with that function that makes it return always 66Mhz when running at 80Mhz.


    Your problem is that you are using ADC_INT_SS0 to name your sequencer! That's for the interrupt macro! It's actually the number 1.
    So you are in fact always configuring sequencer 1 which can't handle more than 4 samples. I think that's the problem.

    About the clock issue I am not sure.
  • Hello Rick,

    The sum of all issues: ADC_INT_SS0 value is 0x1 and not 0x0 for Sequencer-0. So in effect you have configured Sequencer-1 and triggered Sequence-0.

    Regards
    Amit
  • Amit and Luis:

    Per Amit, I configured Sequencer-1; but, triggered  Sequencer-0.  

    Nice catch.   Thank you.  

    It looks like I am not understanding how the following table in the data sheet is (or is not) related to the constants in adc.h

    Table 13-2. Samples and FIFO Depth of Sequencers
    Sequencer    Number of Samples        Depth of FIFO
    SS3                 1                                         1
    SS2                 4                                         4
    SS1                 4                                         4
    SS0                 8                                         8

    #define ADC_INT_SS0 0x00000001
    #define ADC_INT_SS1 0x00000002
    #define ADC_INT_SS2 0x00000004
    #define ADC_INT_SS3 0x00000008

    Is there a correlation here?  Can you provide some insight?

    A parameter in all of the API's is: uint32_t ui32SequenceNum, what #define or CONSTANT should I be using for a Queue Depth of 8?

     

    The program is working.  

    I'll post a working version when I get the concepts straightened out.

    Thank you.

    Rick

  • Hi Rick,

    The macros
    #define ADC_INT_SS0 0x00000001
    #define ADC_INT_SS1 0x00000002
    #define ADC_INT_SS2 0x00000004
    #define ADC_INT_SS3 0x00000008

    Are for each sequencer interrupt. It's for when you use these functions:
    ADCIntDisableEx(), ADCIntEnableEx(), ADCIntClearEx() and ADCIntStatusEx().

    I don't believe there's a macro for that. Simply use 0 when you want to use the sequencer0/SS0, 1 for SS1, 2 for SS2 and 3 for SS3.

    Edit:
    You do the same you do when you trigger the sequencer. Didn't even see that you used 0 in there.

  • Thanks Luis. Let's get back to 101 on the documents.
    Rick,

    When using an API the description of the macro and options are given in the comment section. Referring to it will help

    Regards,
    Amit
  • Thank you everyone!  The working code is as follows:

    // bunch of code

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);

    // bunch of code

    ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_PROCESSOR, 0);

    ADCSequenceStepConfigure(ADC0_BASE, 0, 0, ADC_CTL_CH0);           // PE3
    ADCSequenceStepConfigure(ADC0_BASE, 0, 1, ADC_CTL_CH1);           // PE2
    ADCSequenceStepConfigure(ADC0_BASE, 0, 2, ADC_CTL_CH2);           // PE1
    ADCSequenceStepConfigure(ADC0_BASE, 0, 3, ADC_CTL_CH3);           // PE0
    ADCSequenceStepConfigure(ADC0_BASE, 0, 4, ADC_CTL_CH4);           // PD3
    ADCSequenceStepConfigure(ADC0_BASE, 0, 5, ADC_CTL_CH5 | ADC_CTL_IE | ADC_CTL_END); // PD2

    ADCSequenceEnable(ADC0_BASE, 0);


    ADCSequenceEnable(ADC0_BASE, 0);
    ADCIntClear(ADC0_BASE, 0);
    ADCProcessorTrigger(ADC0_BASE, 0);

    while(!ADCIntStatus(ADC0_BASE, 0, false))
    {
    }

    ADCSequenceDataGet(ADC0_BASE, 0, ui32ADCVerticle);
    ADCSequenceDisable(ADC0_BASE, 0);

    Rick