2020-09-09 08:50 AM
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!
Solved! Go to Solution.
2020-09-13 03:11 PM
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.
2020-09-09 09:39 AM
Read out and compare RCC, GPIO, SPI registers for working and non-working case.
JW
2020-09-09 10:56 AM
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() )
2020-09-09 12:05 PM
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.
2020-09-13 03:11 PM
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.