cancel
Showing results for 
Search instead for 
Did you mean: 

Clocks Initialization wrong (SOLVED).

JAlca
Senior

Hi all!,

I'm, triyng to program using CMSIS in order to learn how registers works.

If I use the SystemClock_Config() generated by STM32CubeIDE all works properly, but if I use my own rutine, the TFT wired to SPI3 dont show the fonts properly (I think it must be something about activate/set some missing clock)

This is the SystemClock_Config():

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
 
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_I2C1;
  PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_SYSCLK;
  PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_HSI;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

And this is my own rutine to set all clocks. Can you see what I'm doing wrong?

void MyClockInit(void)
{
	/*
	 * Use a crystal 8/16MHz on HSE, to work at 64MHz.
	 */
 
	//Start HSI
	RCC->CR |= RCC_CR_HSION;
	while(!(RCC->CR & RCC_CR_HSIRDY));
 
	//SystemClock =l HSI, in order to stop PLL and change it.
	RCC->CFGR &= ~RCC_CFGR_SW;
	while(RCC->CFGR & RCC_CFGR_SWS );
 
	//Stop PLL and wait.
	RCC->CR &= ~RCC_CR_PLLON;
	while(RCC->CR & RCC_CR_PLLRDY);
 
	//PLL = HSE/PreDiv
	RCC->CFGR |= RCC_CFGR_PLLSRC_HSE_PREDIV;
 
	//HSE Input to PLL divided by 1
	RCC->CFGR2 &= ~RCC_CFGR2_PREDIV;
	RCC->CFGR2 |= RCC_CFGR2_PREDIV_DIV1;
 
	//PLL x8 = 64MHz for 8MHz crystal
	//PLL x4 = 64MHz for 16MHz crystal
	RCC->CFGR &= ~RCC_CFGR_PLLMUL;
	RCC->CFGR |= RCC_CFGR_PLLMUL4;
 
	//Frec. AHB = 64MHz
	RCC->CFGR &= ~RCC_CFGR_HPRE;
 
	//Frec. APB1 = 32MHz
	RCC->CFGR &= ~RCC_CFGR_PPRE1;
	RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;
 
	//Frec. APB2 = 64MHz 
	RCC->CFGR &= ~RCC_CFGR_PPRE2;
	RCC->CFGR &= ~RCC_CFGR_PPRE2_DIV1;
 
	//Start HSE and wait for HSE_RDY
	RCC->CR |= RCC_CR_HSEON;
	while(!(RCC->CR & RCC_CR_HSERDY));
 
	//Start PLL and wait for PLL_RDY
	RCC->CR |= RCC_CR_PLLON;
	while(!(RCC->CR & RCC_CR_PLLRDY));
 
	//adjust LATENCY = 2 for 64MHz
	FLASH->ACR &= ~FLASH_ACR_LATENCY;
	FLASH->ACR |= FLASH_ACR_LATENCY_1;
 
	//SystemClock = PLL
	RCC->CFGR &= ~RCC_CFGR_SW;
	RCC->CFGR |= RCC_CFGR_SW_PLL;
	while((RCC->CFGR & RCC_CFGR_SWS_0) && !(RCC->CFGR & RCC_CFGR_SWS_1));
 
	//USART1 = SystemClock
	RCC->CFGR3 |= RCC_CFGR3_USART1SW_0 | RCC_CFGR3_I2C1SW ;
 
	RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN | RCC_APB2ENR_USART1EN ; //hABILITA EL SYSTEM CLOCK.
	RCC->APB1ENR |= RCC_APB1ENR_SPI3EN |  RCC_APB1ENR_I2C1EN|  RCC_APB1ENR_TIM2EN|  RCC_APB1ENR_TIM4EN;
	//Set GPIOA to GPIOF
	RCC->AHBENR |= RCC_AHBENR_ADC12EN | RCC_AHBENR_ADC34EN | RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN | RCC_AHBENR_GPIOCEN | RCC_AHBENR_GPIOFEN;
 
	SystemCoreClockUpdate();
	//Set the SystemCoreClock variable.
}

Thanks in advance!

1 ACCEPTED SOLUTION

Accepted Solutions
JAlca
Senior

I found the solution.

When you initialize the clock by CMSIS, you must call the CMSIS function:

SystemCoreClockUpdate();

in order to update the SystemCoreClock variable. But you also need to call:

 SysTick_Config(SystemCoreClock/1000);

In order to recalculate SysTick ticks, and to make the HAL_Delay() function work properly. I think the SPI HAL functions alse relay on SysTick to make their things.

View solution in original post

4 REPLIES 4

Read out and compare RCC, GPIO, SPI registers for working and non-working case.

JW

Thank you!

I did it with the RCC registers, but not with GPIO and SPI. I'm going to test it now! =)

Maybe is there another system variable set by the SystemClock_Config() that I'm missing?? ( like the call at SystemCoreClockUpdate() )

TDK
Guru

If the RCC registers are the same, then the only thing I can think of that would explain the clock difference is if the SPI prescaler is different. Did you actually look at the signals on the SPI lines?

Could also just be some other bug in the program.

If you feel a post has answered your question, please click "Accept as Solution".
JAlca
Senior

I found the solution.

When you initialize the clock by CMSIS, you must call the CMSIS function:

SystemCoreClockUpdate();

in order to update the SystemCoreClock variable. But you also need to call:

 SysTick_Config(SystemCoreClock/1000);

In order to recalculate SysTick ticks, and to make the HAL_Delay() function work properly. I think the SPI HAL functions alse relay on SysTick to make their things.