diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F401RE/stm32f4xx_hal_conf.h b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F401RE/stm32f4xx_hal_conf.h index 3c9bea7a49..d816e6bf2b 100644 --- a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F401RE/stm32f4xx_hal_conf.h +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F401RE/stm32f4xx_hal_conf.h @@ -98,8 +98,9 @@ * This value is used by the RCC HAL module to compute the system frequency * (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 */ +#if !defined (HSE_VALUE) +/* 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) diff --git a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F401RE/system_stm32f4xx.c b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F401RE/system_stm32f4xx.c index ebea6d46c7..15469c6243 100644 --- a/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F401RE/system_stm32f4xx.c +++ b/libraries/mbed/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F401RE/system_stm32f4xx.c @@ -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(); +} + /** * @} */ diff --git a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F401RE/spi_api.c b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F401RE/spi_api.c index 0cd8347753..46c3e09027 100644 --- a/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F401RE/spi_api.c +++ b/libraries/mbed/targets/hal/TARGET_STM/TARGET_NUCLEO_F401RE/spi_api.c @@ -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); }