cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F303CB ==> RCC_ADCCLKConfig

william239955_stm1
Associate II
Posted on November 21, 2013 at 16:23

Hello,

I have a problem with the RCC_ADCCLKConfig, I want to change the  ADC frequency and I followed the example from st.

   /* Configure the ADC clock */

  RCC_ADCCLKConfig(RCC_ADC12PLLCLK_Div64);

 

  /* Enable ADC1 clock */

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_ADC12, ENABLE);   

  /* ADC Channel configuration */

  /* GPIOC Periph clock enable */

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

  /* Configure ADC Channel7 as analog input */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 ;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  ADC_StructInit(&ADC_InitStructure);

....

after I check the ADC frequency these commands

    RCC_ClocksTypeDef ClockHw;

  RCC_GetClocksFreq(&ClockHw);

the frequency hasn't modified, 48MHz, so I check step by step and I found a strange part.

in Rcc.h

#define RCC_ADC12PLLCLK_Div64                  ((uint32_t)0x00000190)

in Rcc.c , void RCC_ADCCLKConfig(uint32_t RCC_PLLCLK)

when I call this function I check the writter, and it's ok , RCC->CFGR2 |= RCC_PLLCLK; = 400

When I check the frequency with this function RCC_GetClocksFreq()

 /* Get ADC12CLK prescaler */

  tmp = RCC->CFGR2 & RCC_CFGR2_ADCPRE12;

//here cfgr2 = 0x190 and ADCPRE12 = 0x1F0 , so the result is 0x190 (dec 400)

  tmp = tmp >> 4;

// 400/16 => 25

  presc = ADCPrescTable[tmp];

//here ADCPrescTable is a table with 13 cases, and I try to read the 25 case!!!! //ADCPrescTable[13] = {0, 1, 2, 4, 6, 8, 10, 12, 16, 32, 64, 128, 256};

  if ((presc & 0x10) != 0)

// so the test is false I go in the else part

  {

     /* ADC12CLK clock frequency is derived from PLL clock */

     RCC_Clocks->ADC12CLK_Frequency = pllclk / presc;

  }

  else

  {

   /* ADC12CLK clock frequency is AHB clock */

     RCC_Clocks->ADC12CLK_Frequency = RCC_Clocks->SYSCLK_Frequency;

//same frequency as before 48MHz

  }

My first opinion , I think the mask is wrong RCC_CFGR2_ADCPRE12 the value is 0x1F0 I think with 0xF0 it's best but not perfect...

so I could have an information about that,  maybe I don't use correctly the ADC/RCC function

thanks a lot

5 REPLIES 5
Posted on November 21, 2013 at 19:37

The code definitely appears to be broken, though not perfect I think they were aiming for something like this.

tmp = tmp >> 4;
presc = ADCPrescTable[tmp & 0x0F];
if (((tmp & 0x10) != 0) && (presc != 0))
{
/* ADC12CLK clock frequency is derived from PLL clock */
RCC_Clocks->ADC12CLK_Frequency = pllclk / presc;
}
else
{
/* ADC12CLK clock frequency is AHB clock */
RCC_Clocks->ADC12CLK_Frequency = RCC_Clocks->SYSCLK_Frequency; //same frequency as before 48MHz
}

#define RCC_CFGR2_ADCPRE12_NO ((uint32_t)0x00000000) /*!< ADC12 clock disabled, ADC12 can use AHB clock */
#define RCC_CFGR2_ADCPRE12_DIV1 ((uint32_t)0x00000100) /*!< ADC12 PLL clock divided by 1 */
#define RCC_CFGR2_ADCPRE12_DIV2 ((uint32_t)0x00000110) /*!< ADC12 PLL clock divided by 2 */
#define RCC_CFGR2_ADCPRE12_DIV4 ((uint32_t)0x00000120) /*!< ADC12 PLL clock divided by 4 */
#define RCC_CFGR2_ADCPRE12_DIV6 ((uint32_t)0x00000130) /*!< ADC12 PLL clock divided by 6 */
#define RCC_CFGR2_ADCPRE12_DIV8 ((uint32_t)0x00000140) /*!< ADC12 PLL clock divided by 8 */
#define RCC_CFGR2_ADCPRE12_DIV10 ((uint32_t)0x00000150) /*!< ADC12 PLL clock divided by 10 */
#define RCC_CFGR2_ADCPRE12_DIV12 ((uint32_t)0x00000160) /*!< ADC12 PLL clock divided by 12 */
#define RCC_CFGR2_ADCPRE12_DIV16 ((uint32_t)0x00000170) /*!< ADC12 PLL clock divided by 16 */
#define RCC_CFGR2_ADCPRE12_DIV32 ((uint32_t)0x00000180) /*!< ADC12 PLL clock divided by 32 */
#define RCC_CFGR2_ADCPRE12_DIV64 ((uint32_t)0x00000190) /*!< ADC12 PLL clock divided by 64 */
#define RCC_CFGR2_ADCPRE12_DIV128 ((uint32_t)0x000001A0) /*!< ADC12 PLL clock divided by 128 */
#define RCC_CFGR2_ADCPRE12_DIV256 ((uint32_t)0x000001B0) /*!< ADC12 PLL clock divided by 256 */

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
william239955_stm1
Associate II
Posted on November 21, 2013 at 21:13

thanks for your answer.

yes you solve the mistake, but what do I do?

because I need to control my code and I must check each part, so I must modifie the st library?

Posted on November 21, 2013 at 22:14

yes you solve the mistake, but what do I do? because I need to control my code and I must check each part, so I must modify the st library?

 

That's your call, I've pushed this thread to the moderators. I don't work for ST, just confirming it looks buggy, and that you described the flaw well enough for it to be identified.

I'd keep the whole library within the source management system, and fix the bugs locally, and note the same within my app's description/notes.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
william239955_stm1
Associate II
Posted on November 22, 2013 at 08:26

thanks for your suggestion.

but the modification isn't perfect because if I want to prescale by 64 , with your suggestion

ADCPrescTable[tmp & 0x0F]; //0x19 & 0x0F ==> 0x09 ==>

static __I uint16_t ADCPrescTable[13] = {0, 1, 2, 4, 6, 8, 10, 12, 16, 32, 64, 128, 256};

the result is 32

so I think we need to add 1 when we mask the tmp and it's ok

Posted on November 22, 2013 at 16:22

Ok, so a more considered table

static const uint8_t ADCPrescTable[16] = { 1, 2, 4, 6, 8, 10, 12, 16, 32, 64, 128, 256, 0, 0, 0, 0 };

And fixing the 12 and 34 code paths
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..