2014-08-30 01:25 PM
Problem with oscillator source PLL.
Nucleo plate does't have HSE oscillator, and use internal 16 MHz HSII want to reconfigure tacting schematic to use as SYSCLK - PLL (by default for SYSCLK use HSI directly)PLL configuration - M = 16, N = 366, P = 4. Q = 7Here the code (use Keil v5)int main (void){ GPIO_InitTypeDef sGPIO; // Set PLL source to HSI, M div = 16, N mul = 336, P div = 4, Q div = 7 // HSI = 16 MHz, after M div - 1 MHz, after mul - 336 MHz, PLL - /4 = 84 MHz, USB - /7 - 48 MHz RCC_PLLConfig (RCC_PLLSource_HSI, 16, 336, 4, 7); // Turn on PLL and wait for PLL lock RCC->CR |= RCC_CR_PLLON; while (!(RCC->CR & RCC_CR_PLLRDY)); // Set AHB Prescaller /1, APB1 Prescaller /2 RCC->CFGR |= RCC_CFGR_HPRE_DIV1; RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; // Set system clock to PLL and wait for RDY flag RCC->CFGR |= RCC_CFGR_SW_1; while (!(RCC->CFGR & RCC_CFGR_SWS_1)); // Allow clocks RCC_AHB1PeriphClockCmd (RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM2, ENABLE); // Config GPIO pin sGPIO.GPIO_Mode = GPIO_Mode_OUT; sGPIO.GPIO_OType = GPIO_OType_PP; sGPIO.GPIO_Pin = GPIO_Pin_5; sGPIO.GPIO_Speed = GPIO_Speed_50MHz; sGPIO.GPIO_PuPd = GPIO_PuPd_DOWN; GPIO_Init (GPIOA, &sGPIO); while (1) { __nop (); __nop (); __nop (); }}In debug - after switch to SYSCLK to PLL - program drop to handlerIf i set AHB prescaller to /2 - all Ok, but this is not maximum speed.What is wrong in my clock initialization? #nucleo-rcc2014-08-30 07:46 PM
You might want to pay attention to what's actually in the registers before you arbitrarily OR bits into them.
The CMSIS model normally calls SystemInit() to set up the clocks prior to main() being called.2014-08-31 03:26 AM
CMSIS startup turn on the HSI, and HSE. After timeout (because plate don't have HSE, and flag HSE RDY not set) SYSCLK switch to HSI directly.
I need the timer clk not lower 50 MHz, therefore i need the SYSCLK from PLLIn first screenshot - RCC regs after startup: HSI on, HSI ready, HSE on, HSE not ready, PLL off. SW bits - 00 (SYSCLK is HSI)Second screenshot - set the PLL configuration. M = 16, N = 366, P = 4, Q = 7PLL On and PLL readyLast screenshot - after execute command RCC->CFGR |= RCC_CFGR_SW_1;after this program fall to handler (in disassemble window infinite sequence MOVS r0, r0)2014-08-31 04:02 AM
HSE should be viable in BYPASS mode using the 8 MHz output of the ST-LINK and SB16/SB50, etc
Might want to look at flash wait states, and aforementioned SystemInit() in system_stm32f40x.c2014-08-31 11:03 AM
Flash latency after startup set to 0
If I change this to one wait state all be work.Thank you2014-08-31 11:08 AM
I'd think at 84 MHz you'd want 2 wait states (3 cycles) for the flash access to meet specifications.
/**
* @brief Configures the System clock source, PLL Multiplier and Divider factors,
* AHB/APBx prescalers and Flash settings
* @Note This function should be called only once the RCC clock configuration
* is reset to the default reset state (done in SystemInit() function).
* @param None
* @retval None
*/
static void SetSysClock(void)
{
/******************************************************************************/
/* PLL used as System clock source */
/******************************************************************************/
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
#ifdef PLL_SOURCE_HSI
/* Enable HSI */
RCC->CR |= ((uint32_t)RCC_CR_HSION);
/* Configure the main PLL */
RCC->PLLCFGR = PLL_M | (PLL_N <<
6
) | (((PLL_P >> 1) -1) <<
16
) |
(RCC_PLLCFGR_PLLSRC_HSI) | (PLL_Q << 24);
#else /* PLL_SOURCE_HSE_BYPASS or PLL_SOURCE_HSE */
/* Enable HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
#if defined (PLL_SOURCE_HSE_BYPASS)
/* HSE oscillator bypassed with external clock */
RCC->CR |= (uint32_t)(RCC_CR_HSEBYP);
#endif /* PLL_SOURCE_HSE_BYPASS */
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)0x01)
{
/* Configure the main PLL */
RCC->PLLCFGR = PLL_M | (PLL_N <<
6
) | (((PLL_P >> 1) -1) <<
16
) |
(RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
}
else
{ /* If HSE fails to start-up, the application will have wrong clock
configuration. User can add here some code to deal with this error */
}
#endif /* PLL_SOURCE_HSI */
/* Select regulator voltage output Scale 2 mode, System frequency up to 84 MHz */
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
PWR->CR &= (uint32_t)~(PWR_CR_VOS);
/* HCLK = SYSCLK / 1*/
RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK / 1*/
RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;
/* PCLK1 = HCLK / 2*/
RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;
/* Enable the main PLL */
RCC->CR |= RCC_CR_PLLON;
/* Wait till the main PLL is ready */
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}
/* Configure Flash prefetch, Instruction cache, Data cache and wait state */
FLASH->ACR = FLASH_ACR_PRFTEN |FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_2WS;
/* Select the main PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= RCC_CFGR_SW_PLL;
/* Wait till the main PLL is used as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
{
}
}