diff --git a/targets/TARGET_STM/TARGET_STM32WB/TARGET_STM32WB55xG/TARGET_NUCLEO_WB55RG/system_clock.c b/targets/TARGET_STM/TARGET_STM32WB/TARGET_STM32WB55xG/TARGET_NUCLEO_WB55RG/system_clock.c index 9b9cae3fd9..fe14113703 100644 --- a/targets/TARGET_STM/TARGET_STM32WB/TARGET_STM32WB55xG/TARGET_NUCLEO_WB55RG/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32WB/TARGET_STM32WB55xG/TARGET_NUCLEO_WB55RG/system_clock.c @@ -34,6 +34,8 @@ #include "stm32wbxx.h" #include "mbed_error.h" #include "stm32wbxx_ll_hsem.h" +#include "stm32wbxx_ll_hsem.h" +#include "otp.h" #include "hw_conf.h" /* Common BLE file where BLE shared resources are defined */ // Clock source is selected with CLOCK_SOURCE in json config @@ -56,7 +58,59 @@ uint8_t SetSysClock_PLL_HSI(void); uint8_t SetSysClock_PLL_MSI(void); #endif /* ((CLOCK_SOURCE) & USE_PLL_MSI) */ -void Configure_RF_Clock_Sources(void); +static void Configure_RF_Clock_Sources(void) +{ + static uint8_t RF_ON = 0; + + if ( !RF_ON ) { + // Reset backup domain + if ((LL_RCC_IsActiveFlag_PINRST()) && (!LL_RCC_IsActiveFlag_SFTRST())) { + // Write twice the value to flush the APB-AHB bridge + // This bit shall be written in the register before writing the next one + HAL_PWR_EnableBkUpAccess(); + HAL_PWR_EnableBkUpAccess(); + __HAL_RCC_BACKUPRESET_FORCE(); + __HAL_RCC_BACKUPRESET_RELEASE(); + } + + /** + * Select LSE clock + */ + LL_RCC_LSE_Enable(); + while (!LL_RCC_LSE_IsReady()); + + /** + * Select wakeup source of BLE RF + */ + LL_RCC_SetRFWKPClockSource(LL_RCC_RFWKP_CLKSOURCE_LSE); + + /** + * Switch OFF LSI + */ + LL_RCC_LSI1_Disable(); + + RF_ON = 1; + } + + return; +} + +static void Config_HSE(void) +{ + OTP_ID0_t * p_otp; + + /** + * Read HSE_Tuning from OTP + */ + p_otp = (OTP_ID0_t *) OTP_Read(0); + if (p_otp) + { + LL_RCC_HSE_SetCapacitorTuning(p_otp->hse_tuning); + } + + return; +} + /** * @brief Configures the System clock source, PLL Multiplier and Divider factors, AHB/APBx prescalers @@ -112,43 +166,69 @@ void SetSysClock(void) /******************************************************************************/ uint8_t SetSysClock_PLL_HSE(uint8_t bypass) { - LL_RCC_HSE_Enable(); + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; - /** - * Switch to HSE as Sys clok source - * All Peripehrals (HCLK, HCLK2, HCLK4, PCLK1, PCLK2) will be clocked - * @ 32MHZ. This is not optimal but a stable setting for enter and exit - * deep sleep mode (STOP mode). - * - */ - while(!LL_RCC_HSE_IsReady()); - LL_RCC_SetSysClkSource( LL_RCC_SYS_CLKSOURCE_HSE ); - while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE); + Config_HSE(); - /** - * Set RNG on HSI48 - */ - LL_RCC_HSI48_Enable(); - while (!LL_RCC_HSI48_IsReady()); - LL_RCC_SetCLK48ClockSource(LL_RCC_CLK48_CLKSOURCE_HSI48); + /** Configure the main internal regulator output voltage + */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + /** Initializes the CPU, AHB and APB busses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI1 + |RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.LSIState = RCC_LSI_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + return 0; // FAIL + } + /** Configure the SYSCLKSource, HCLK, PCLK1 and PCLK2 clocks dividers + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK4|RCC_CLOCKTYPE_HCLK2 + |RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.AHBCLK2Divider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.AHBCLK4Divider = RCC_SYSCLK_DIV1; - /** - * Switch OFF MSI and HSI - */ - LL_RCC_MSI_Disable(); - LL_RCC_HSI_Disable(); + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) + { + return 0; // FAIL + } + /** Initializes the peripherals clocks + */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SMPS|RCC_PERIPHCLK_RFWAKEUP + |RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_USART1 + |RCC_PERIPHCLK_LPUART1; + PeriphClkInitStruct.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2; + PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1; + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; + PeriphClkInitStruct.RFWakeUpClockSelection = RCC_RFWKPCLKSOURCE_LSI; + PeriphClkInitStruct.SmpsClockSelection = RCC_SMPSCLKSOURCE_HSE; + PeriphClkInitStruct.SmpsDivSelection = RCC_SMPSCLKDIV_RANGE0; - // Output clock on MCO1 pin(PA8) for debugging purpose -#if DEBUG_MCO == 2 - if (bypass == 0) { - HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_4); // 8 MHz - } else { - HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_2); // 4 MHz - } -#endif + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) + { + return 0; // FAIL + } - return 1; + /** + * Select HSI as system clock source after Wake Up from Stop mode + */ + LL_RCC_SetClkAfterWakeFromStop(LL_RCC_STOP_WAKEUPCLOCK_HSI); + + return 1; } + #endif /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */ #if ((CLOCK_SOURCE) & USE_PLL_HSI) @@ -271,33 +351,3 @@ uint8_t SetSysClock_PLL_MSI(void) } #endif /* ((CLOCK_SOURCE) & USE_PLL_MSI) */ -void Configure_RF_Clock_Sources(void) -{ - // Reset backup domain - if ((LL_RCC_IsActiveFlag_PINRST()) && (!LL_RCC_IsActiveFlag_SFTRST())) { - // Write twice the value to flush the APB-AHB bridge - // This bit shall be written in the register before writing the next one - HAL_PWR_EnableBkUpAccess(); - HAL_PWR_EnableBkUpAccess(); - __HAL_RCC_BACKUPRESET_FORCE(); - __HAL_RCC_BACKUPRESET_RELEASE(); - } - - /** - * Select LSE clock - */ - LL_RCC_LSE_Enable(); - while (!LL_RCC_LSE_IsReady()); - - /** - * Select wakeup source of BLE RF - */ - LL_RCC_SetRFWKPClockSource(LL_RCC_RFWKP_CLKSOURCE_LSE); - - /** - * Switch OFF LSI - */ - LL_RCC_LSI1_Disable(); - - return; -} diff --git a/targets/TARGET_STM/TARGET_STM32WB/device/system_stm32wbxx.c b/targets/TARGET_STM/TARGET_STM32WB/device/system_stm32wbxx.c index 9adc012683..caf5651706 100644 --- a/targets/TARGET_STM/TARGET_STM32WB/device/system_stm32wbxx.c +++ b/targets/TARGET_STM/TARGET_STM32WB/device/system_stm32wbxx.c @@ -191,55 +191,53 @@ void SystemInit(void) { OTP_ID0_t * p_otp; - /* FPU settings ------------------------------------------------------------*/ + /* FPU settings ------------------------------------------------------------*/ #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) - SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ + SCB->CPACR |= ((3UL << (10UL*2UL))|(3UL << (11UL*2UL))); /* set CP10 and CP11 Full Access */ #endif - /** - * Read HSE_Tuning from OTP - */ - p_otp = (OTP_ID0_t *) OTP_Read(0); - if (p_otp) - { - LL_RCC_HSE_SetCapacitorTuning(p_otp->hse_tuning); - } + /* Reset the RCC clock configuration to the default reset state ------------*/ - LL_RCC_HSE_Enable(); + /* Set MSION bit */ + RCC->CR |= RCC_CR_MSION; - /** - * Set FLASH latency to 1WS - */ - LL_FLASH_SetLatency( LL_FLASH_LATENCY_1 ); - while( LL_FLASH_GetLatency() != LL_FLASH_LATENCY_1 ); + /* Reset CFGR register */ + RCC->CFGR = 0x00070000U; - /** - * Switch to HSE - * - */ - while(!LL_RCC_HSE_IsReady()); - LL_RCC_SetSysClkSource( LL_RCC_SYS_CLKSOURCE_HSE ); - while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE); + /* Reset PLLSAI1ON, PLLON, HSECSSON, HSEON, HSION, and MSIPLLON bits */ + RCC->CR &= (uint32_t)0xFAF6FEFBU; - /** - * Switch OFF MSI - */ - LL_RCC_MSI_Disable(); + /*!< Reset LSI1 and LSI2 bits */ + RCC->CSR &= (uint32_t)0xFFFFFFFAU; + /*!< Reset HSI48ON bit */ + RCC->CRRCR &= (uint32_t)0xFFFFFFFEU; + + /* Reset PLLCFGR register */ + RCC->PLLCFGR = 0x22041000U; + + /* Reset PLLSAI1CFGR register */ + RCC->PLLSAI1CFGR = 0x22041000U; + + /* Reset HSEBYP bit */ + RCC->CR &= 0xFFFBFFFFU; + + /* Disable all interrupts */ + RCC->CIER = 0x00000000; /* Configure the Vector Table location add offset address ------------------*/ #ifdef CORE_CM0PLUS /* program in SRAM2A */ #if defined(VECT_TAB_SRAM) SCB->VTOR = RAM2A_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM2A for CPU2 */ -#elif defined(VECT_TAB_SRAM2B) +#elif defined(VECT_TAB_SRAM2B) /* program in SRAM2B */ SCB->VTOR = RAM2B_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM2B for CPU2 */ -#else +#else /* program in FLASH */ SCB->VTOR = VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ -#endif /* Program memory type */ -#else +#endif /* Program memory type */ +#else #if defined(VECT_TAB_SRAM) /* program in SRAM1 */ SCB->VTOR = RAM1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM1 for CPU1 */ @@ -294,78 +292,68 @@ void SystemInit(void) */ void SystemCoreClockUpdate(void) { - uint32_t tmp = 0, msirange = 0, pllvco = 0, pllr = 2, pllsource = 0, pllm = 2; + uint32_t tmp, msirange, pllvco, pllr, pllsource , pllm; - /* Get MSI Range frequency--------------------------------------------------*/ + /* Get MSI Range frequency--------------------------------------------------*/ - /*MSI frequency range in Hz*/ - msirange = MSIRangeTable[(RCC->CR & RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos]; + /*MSI frequency range in Hz*/ + msirange = MSIRangeTable[(RCC->CR & RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos]; - /*SystemCoreClock=HAL_RCC_GetSysClockFreq();*/ - /* Get SYSCLK source -------------------------------------------------------*/ - switch (RCC->CFGR & RCC_CFGR_SWS) - { - case 0x00: /* MSI used as system clock source */ - SystemCoreClock = msirange; - break; + /* Get SYSCLK source -------------------------------------------------------*/ + switch (RCC->CFGR & RCC_CFGR_SWS) + { + case 0x00: /* MSI used as system clock source */ + SystemCoreClock = msirange; + break; - case 0x04: /* HSI used as system clock source */ - /* HSI used as system clock source */ - SystemCoreClock = HSI_VALUE; - break; + case 0x04: /* HSI used as system clock source */ + /* HSI used as system clock source */ + SystemCoreClock = HSI_VALUE; + break; - case 0x08: /* HSE used as system clock source */ - SystemCoreClock = HSE_VALUE; - break; + case 0x08: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; - case 0x0C: /* PLL used as system clock source */ - /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN + case 0x0C: /* PLL used as system clock source */ + /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN SYSCLK = PLL_VCO / PLLR - */ - pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); - pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1 ; + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); + pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1UL ; - switch (pllsource) - { - case 0x02: /* HSI used as PLL clock source */ - pllvco = (HSI_VALUE / pllm); - break; + if(pllsource == 0x02UL) /* HSI used as PLL clock source */ + { + pllvco = (HSI_VALUE / pllm); + } + else if(pllsource == 0x03UL) /* HSE used as PLL clock source */ + { + pllvco = (HSE_VALUE / pllm); + } + else /* MSI used as PLL clock source */ + { + pllvco = (msirange / pllm); + } + + pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos); + pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1UL); + + SystemCoreClock = pllvco/pllr; + break; - case 0x03: /* HSE used as PLL clock source */ - pllvco = (HSE_VALUE / pllm); - break; - - default: /* MSI used as PLL clock source */ - pllvco = (msirange / pllm); - break; - } - - pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos); - pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1); - - SystemCoreClock = pllvco/pllr; - break; - - default: - SystemCoreClock = msirange; - break; - } - - /* Compute HCLK clock frequency --------------------------------------------*/ -#ifdef CORE_CM0PLUS - /* Get HCLK2 prescaler */ - tmp = AHBPrescTable[((RCC->EXTCFGR & RCC_EXTCFGR_C2HPRE) >> RCC_EXTCFGR_C2HPRE_Pos)]; - -#else - /* Get HCLK1 prescaler */ - tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)]; -#endif - /* HCLK clock frequency */ - SystemCoreClock = SystemCoreClock / tmp; + default: + SystemCoreClock = msirange; + break; + } + + /* Compute HCLK clock frequency --------------------------------------------*/ + /* Get HCLK1 prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)]; + /* HCLK clock frequency */ + SystemCoreClock = SystemCoreClock / tmp; } - /** * @} */ diff --git a/targets/TARGET_STM/TARGET_STM32WB/wb_sleep.c b/targets/TARGET_STM/TARGET_STM32WB/wb_sleep.c index 34dd5f0d0e..be33f68328 100644 --- a/targets/TARGET_STM/TARGET_STM32WB/wb_sleep.c +++ b/targets/TARGET_STM/TARGET_STM32WB/wb_sleep.c @@ -43,7 +43,6 @@ extern void save_timer_ctx(void); extern void restore_timer_ctx(void); extern int serial_is_tx_ongoing(void); extern int mbed_sdk_inited; -extern void SetSysClock(void); static void Switch_On_HSI( void ) { @@ -63,6 +62,11 @@ static void LPM_EnterStopMode(void) while( LL_HSEM_1StepLock( HSEM, CFG_HW_RCC_SEMID ) ); + /** + * Select HSI as system clock source after Wake Up from Stop mode + */ + LL_RCC_SetClkAfterWakeFromStop(LL_RCC_STOP_WAKEUPCLOCK_HSI); + if ( ! LL_HSEM_1StepLock( HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID ) ) { if( LL_PWR_IsActiveFlag_C2DS() ) @@ -173,9 +177,6 @@ void hal_deepsleep(void) HW_LPM_StopMode(); LPM_ExitStopMode(); - /* After wake-up from STOP reconfigure the whole clock tree */ - SetSysClock(); - restore_timer_ctx(); /* us_ticker context restored, allow HAL_GetTick() to read the us_ticker