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.

bug in ADCClockConfigGet()

Other Parts Discussed in Thread: TM4C129EKCPDT

I am using version version 2.1.1.71 of the TivaWare library (IAR version) on a TM4C129EKCPDT chip.

There appears to be a bug in the ADCClockConfigGet() function. I set breakpoints in the following code and examined some register contents:

void Adc::initialize(void)

{

    U32 divider = 0;

     // the following call should return a setting of 0x00000071, which is the

    // default after a reset

    U32 clkSetting = ADCClockConfigGet((U32)ADC0, &divider);

    //!!! It returns 0x00000070 instead.

    // explicitly set the clock to the reset default value

    ADCClockConfigSet((U32)ADC0, 0x00000071, 1);

    clkSetting = ADCClockConfigGet((U32)ADC0, &divider);

    //!!! It still returns 0x00000070.

}

After the first call to ADCClockConfigGet(), it returns a value of 0x00000070, with a divisor value of 1. This corresponds to ADC_CLOCK_RATE_FULL (0x00000070) + ADC_CLOCK_SRC_PLL (0x00000000). However, the ADC0CC register as viewed from the debugger shows that the clock source is actually ADC_CLOCK_SRC_ALTCLK (0x00000001). The register values match what the data sheet says is the default value on reset.

The call to ADCClockConfigSet() should explicitly set the clock to the default reset value (0x00000071). But a subsequent call to ADCClockConfigGet() has it still returning 0x00000070.

 

I looked at the library source code for the Get function and it looks like the value of the ADC0CC register’s CS field is not getting ORed into the return value:

 

uint32_t

ADCClockConfigGet(uint32_t ui32Base, uint32_t *pui32ClockDiv)

{

    uint32_t ui32Config;

 

    //

    // Check the argument.

    //

    ASSERT(ui32Base == ADC0_BASE);

 

    //

    // Read the current configuration.

    //

    ui32Config = HWREG(ui32Base + ADC_O_CC);

 

    //

    // If the clock divider was requested provide the current value.

    //

    if(pui32ClockDiv)

    {

        *pui32ClockDiv =

                    ((ui32Config & ADC_CC_CLKDIV_M) >> ADC_CC_CLKDIV_S) + 1;

    }

 

    //

    // Clear out the divider bits.

    //

    ui32Config &= ~ADC_CC_CLKDIV_M;

 

    //

    // Add in the sample interval to the configuration.

    //

    ui32Config = (HWREG(ui32Base + ADC_O_PC) & ADC_PC_SR_M) << 4;

 

    return(ui32Config);

}

Regards,

Dave 

 

 

 

  • Hi Dave,

    Thanks for pointing this out. We'll take a closer look and take appropriate actions if there is an issue.
  • Hello Dave,

    I agree on the return value of the ADCClockConfigGet API, but I believe you are incorrectly configuring the ADCCC register during the ADCClockConfigSet call.

    As an example: The following call uses the clock source from the PLL with divider value of 30 to get a 16MHz ADC clock.

    ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PLL | ADC_CLOCK_RATE_FULL, 30);

    Regards
    Amit
  • Hi, Amit,

    According to the chip data sheet, the default register settings upon reset are:

    ADCPC::MCR = 7 (full conversion rate)

    ADCCC::CLKDIV = 0 (divisor = 1)

    ADCCC::CS = 1 (use ALTCLKCFG, which defaults to PIOSC)

    This setting is the same as if I used:

    ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_RATE_FULL + ADC_CLOCK_SRC_ALTCLK, 1);

    which is the same as

    ADCClockConfigSet(0x00000071, 1);

    The example code I used to demonstrate the error simply sets the registers to their default values. Are you suggesting that this is not a valid ADC clock configuration? Seems odd that the default settings would not be correct.

    Regards,

    Dave

  • Hello Dave

    The default setting will work. When the divider value is programmed as 1, the value is subtracted by 1 and then put to the register. On a read back it is not reading the CS bit field and returning the value.

    Regards
    Amit