NUCLEO_F401RE: Change system clock to 84 MHz using HSI + PLL

Update also HSE_VALUE and SPI prescaler value.
pull/215/head
bcostm 2014-03-10 11:40:27 +01:00
parent f285e44f05
commit bb57ddc0c3
3 changed files with 94 additions and 38 deletions

View File

@ -99,7 +99,8 @@
* (when HSE is used as system clock source, directly or through the PLL).
*/
#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
/* MBED: Put here the value of the Xtal you use */
#define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSE_STARTUP_TIMEOUT)

View File

@ -64,6 +64,7 @@
*/
#include "stm32f4xx_hal.h"
#include "error.h" /* [ADDED FOR MBED] */
/**
* @}
@ -113,7 +114,7 @@
is no need to call the 2 first functions listed above, since SystemCoreClock
variable is updated automatically.
*/
uint32_t SystemCoreClock = 16000000;
uint32_t SystemCoreClock = 84000000; /* [CHANGED FOR MBED] */
__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
/**
@ -124,6 +125,9 @@
* @{
*/
/* [ADDED FOR MBED] */
static void SystemClock_Config(void);
/**
* @}
*/
@ -171,21 +175,9 @@ void SystemInit(void)
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
// [ADDED FOR MBED]
/* [ADDED FOR MBED] */
HAL_Init();
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 16 MHz
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; // 16 MHz
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; // 8 MHz for the SPI
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
}
// [ADDED FOR MBED]
void SysTick_Handler(void)
{
HAL_IncTick();
SystemClock_Config();
}
/**
@ -272,6 +264,64 @@ void SystemCoreClockUpdate(void)
SystemCoreClock >>= tmp;
}
/* [ADDED FOR MBED]
Configure the System clock to 84 MHz (max value) using the internal HSI 16 MHz clock */
static void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
/* The voltage scaling allows optimizing the power consumption when the device is
clocked below the maximum system frequency, to update the voltage scaling value
regarding system frequency refer to product datasheet. */
__PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
/* Enable HSI Oscillator and activate PLL with HSI as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSEState = RCC_HSE_OFF;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 16;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
RCC_OscInitStruct.PLL.PLLQ = 7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
error("System clock initialization failed.");
}
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 84 MHz
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; // 42 MHz
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // 84 MHz (SPI1 clock...)
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
error("System clock initialization failed.");
}
/* Update the SystemCoreClock variable
- Not needed because the variable is already set on top of this file.
- Warning: this function call is removed by the compiler with -O3/-Otime options. */
//SystemCoreClockUpdate();
/* Output SYSCLK on MCO2 pin(PC9) for debugging purpose */
//HAL_RCC_MCOConfig(RCC_MCO2, RCC_MCO2SOURCE_SYSCLK, RCC_MCODIV_4); // 84 MHz / 4 = 21 MHz
}
/* [ADDED FOR MBED]
Used for the different timeouts in the HAL */
void SysTick_Handler(void)
{
HAL_IncTick();
}
/**
* @}
*/

View File

@ -112,7 +112,7 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel
obj->bits = SPI_DATASIZE_8BIT;
obj->cpol = SPI_POLARITY_LOW;
obj->cpha = SPI_PHASE_1EDGE;
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 1MHz (with HSI=16MHz and APB2CLKDivider=2)
obj->br_presc = SPI_BAUDRATEPRESCALER_256;
if (ssel == NC) { // Master
obj->mode = SPI_MODE_MASTER;
@ -173,26 +173,31 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) {
}
void spi_frequency(spi_t *obj, int hz) {
// Get SPI clock frequency
uint32_t PCLK = SystemCoreClock >> 1;
// Choose the baud rate divisor (between 2 and 256)
uint32_t divisor = PCLK / hz;
// Find the nearest power-of-2
divisor = (divisor > 0 ? divisor-1 : 0);
divisor |= divisor >> 1;
divisor |= divisor >> 2;
divisor |= divisor >> 4;
divisor |= divisor >> 8;
divisor |= divisor >> 16;
divisor++;
uint32_t baud_rate = __builtin_ffs(divisor) - 2;
// Save new value
obj->br_presc = ((baud_rate > 7) ? (7 << 3) : (baud_rate << 3));
// Note: The frequencies are obtained with SPI1 clock = 84 MHz (APB2 clock)
if (hz < 500000) {
obj->br_presc = SPI_BAUDRATEPRESCALER_256; // 331 kHz
}
else if ((hz >= 500000) && (hz < 1000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_128; // 663 kHz
}
else if ((hz >= 1000000) && (hz < 2000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_64; // 1.3 MHz
}
else if ((hz >= 2000000) && (hz < 5000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_32; // 2.65 MHz
}
else if ((hz >= 5000000) && (hz < 10000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_16; // 5.3 MHz
}
else if ((hz >= 10000000) && (hz < 20000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_8; // 10.6 MHz
}
else if ((hz >= 20000000) && (hz < 40000000)) {
obj->br_presc = SPI_BAUDRATEPRESCALER_4; // 21.2 MHz
}
else { // >= 40000000
obj->br_presc = SPI_BAUDRATEPRESCALER_2; // 42 MHz
}
init_spi(obj);
}