HAL Timebase, Power, Clock: semaphore guarded access to clock and power modes, better sleep mode. (#307)
This commit is contained in:
		
							parent
							
								
									c8aca9ef48
								
							
						
					
					
						commit
						6c4983c6b6
					
				| @ -16,6 +16,9 @@ typedef enum { | |||||||
| /* Initialize drivers */ | /* Initialize drivers */ | ||||||
| void api_hal_power_init(); | void api_hal_power_init(); | ||||||
| 
 | 
 | ||||||
|  | /* Go to deep sleep */ | ||||||
|  | void api_hal_power_deep_sleep(); | ||||||
|  | 
 | ||||||
| /* Get predicted remaining battery capacity in percents */ | /* Get predicted remaining battery capacity in percents */ | ||||||
| uint8_t api_hal_power_get_pct(); | uint8_t api_hal_power_get_pct(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										27
									
								
								firmware/targets/f4/api-hal/api-hal-clock.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								firmware/targets/f4/api-hal/api-hal-clock.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | #include <api-hal-clock.h> | ||||||
|  | 
 | ||||||
|  | #include <stm32wbxx_ll_rcc.h> | ||||||
|  | 
 | ||||||
|  | void api_hal_clock_switch_to_hsi() { | ||||||
|  |     LL_RCC_HSI_Enable( ); | ||||||
|  | 
 | ||||||
|  |     while(!LL_RCC_HSI_IsReady()); | ||||||
|  | 
 | ||||||
|  |     LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI); | ||||||
|  |     LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSI); | ||||||
|  | 
 | ||||||
|  |     while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void api_hal_clock_switch_to_pll() { | ||||||
|  |     LL_RCC_HSE_Enable(); | ||||||
|  |     LL_RCC_PLL_Enable(); | ||||||
|  | 
 | ||||||
|  |     while(!LL_RCC_HSE_IsReady()); | ||||||
|  |     while(!LL_RCC_PLL_IsReady()); | ||||||
|  | 
 | ||||||
|  |     LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); | ||||||
|  |     LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSE); | ||||||
|  | 
 | ||||||
|  |     while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL); | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								firmware/targets/f4/api-hal/api-hal-clock.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								firmware/targets/f4/api-hal/api-hal-clock.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | /* Switch to HSI clock */ | ||||||
|  | void api_hal_clock_switch_to_hsi(); | ||||||
|  | 
 | ||||||
|  | /* Switch to PLL clock */ | ||||||
|  | void api_hal_clock_switch_to_pll(); | ||||||
| @ -1,5 +1,13 @@ | |||||||
| #include <api-hal-power.h> | #include <api-hal-power.h> | ||||||
|  | #include <api-hal-clock.h> | ||||||
|  | 
 | ||||||
|  | #include <stm32wbxx_ll_rcc.h> | ||||||
|  | #include <stm32wbxx_ll_pwr.h> | ||||||
|  | #include <stm32wbxx_ll_hsem.h> | ||||||
|  | #include <stm32wbxx_ll_cortex.h> | ||||||
|  | 
 | ||||||
| #include <main.h> | #include <main.h> | ||||||
|  | #include <hw_conf.h> | ||||||
| #include <bq27220.h> | #include <bq27220.h> | ||||||
| #include <bq25896.h> | #include <bq25896.h> | ||||||
| 
 | 
 | ||||||
| @ -14,6 +22,50 @@ void api_hal_power_init() { | |||||||
|     bq25896_init(); |     bq25896_init(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void api_hal_power_deep_sleep() { | ||||||
|  |   while( LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)); | ||||||
|  | 
 | ||||||
|  |   if (!LL_HSEM_1StepLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID)) { | ||||||
|  |         if(LL_PWR_IsActiveFlag_C2DS()) { | ||||||
|  |             // Release ENTRY_STOP_MODE semaphore
 | ||||||
|  |             LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0); | ||||||
|  | 
 | ||||||
|  |             // The switch on HSI before entering Stop Mode is required 
 | ||||||
|  |             api_hal_clock_switch_to_hsi(); | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         /**
 | ||||||
|  |          * The switch on HSI before entering Stop Mode is required  | ||||||
|  |          */ | ||||||
|  |         api_hal_clock_switch_to_hsi(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /* Release RCC semaphore */ | ||||||
|  |     LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0); | ||||||
|  | 
 | ||||||
|  |     // Prepare deep sleep
 | ||||||
|  |     LL_PWR_SetPowerMode(LL_PWR_MODE_STOP2); | ||||||
|  |     LL_LPM_EnableDeepSleep(); | ||||||
|  | 
 | ||||||
|  | #if defined ( __CC_ARM) | ||||||
|  |     // Force store operations
 | ||||||
|  |     __force_stores(); | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  |     __WFI(); | ||||||
|  | 
 | ||||||
|  |     /* Release ENTRY_STOP_MODE semaphore */ | ||||||
|  |     LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0); | ||||||
|  | 
 | ||||||
|  |     while(LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)); | ||||||
|  | 
 | ||||||
|  |     if(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) { | ||||||
|  |         api_hal_clock_switch_to_pll(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| uint8_t api_hal_power_get_pct() { | uint8_t api_hal_power_get_pct() { | ||||||
|     return bq27220_get_state_of_charge(); |     return bq27220_get_state_of_charge(); | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,8 +1,7 @@ | |||||||
| #include <api-hal-timebase.h> | #include <api-hal-timebase.h> | ||||||
| #include <api-hal-timebase-timer.h> | #include <api-hal-timebase-timer.h> | ||||||
|  | #include <api-hal-power.h> | ||||||
| 
 | 
 | ||||||
| #include <stm32wbxx_hal.h> |  | ||||||
| #include <stm32wbxx_ll_gpio.h> |  | ||||||
| #include <FreeRTOS.h> | #include <FreeRTOS.h> | ||||||
| #include <cmsis_os.h> | #include <cmsis_os.h> | ||||||
| 
 | 
 | ||||||
| @ -88,11 +87,6 @@ void LPTIM2_IRQHandler(void) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static inline uint32_t api_hal_timebase_nap(TickType_t expected_idle_ticks) { |  | ||||||
|     __WFI(); |  | ||||||
|     return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static inline uint32_t api_hal_timebase_sleep(TickType_t expected_idle_ticks) { | static inline uint32_t api_hal_timebase_sleep(TickType_t expected_idle_ticks) { | ||||||
|     // Store important value before going to sleep
 |     // Store important value before going to sleep
 | ||||||
|     const uint16_t before_cnt = api_hal_timebase_timer_get_cnt(); |     const uint16_t before_cnt = api_hal_timebase_timer_get_cnt(); | ||||||
| @ -103,7 +97,7 @@ static inline uint32_t api_hal_timebase_sleep(TickType_t expected_idle_ticks) { | |||||||
|     api_hal_timebase_timer_set_cmp(expected_cnt); |     api_hal_timebase_timer_set_cmp(expected_cnt); | ||||||
| 
 | 
 | ||||||
|     // Go to stop2 mode
 |     // Go to stop2 mode
 | ||||||
|     HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); |     api_hal_power_deep_sleep(); | ||||||
| 
 | 
 | ||||||
|     // Spin till we are in timer safe zone
 |     // Spin till we are in timer safe zone
 | ||||||
|     while(!api_hal_timebase_timer_is_safe()) {} |     while(!api_hal_timebase_timer_is_safe()) {} | ||||||
| @ -135,6 +129,9 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { | |||||||
|         expected_idle_ticks = API_HAL_TIMEBASE_MAX_SLEEP; |         expected_idle_ticks = API_HAL_TIMEBASE_MAX_SLEEP; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     if (api_hal_timebase.insomnia)  | ||||||
|  |         return; | ||||||
|  |      | ||||||
|     // Stop IRQ handling, no one should disturb us till we finish 
 |     // Stop IRQ handling, no one should disturb us till we finish 
 | ||||||
|     __disable_irq(); |     __disable_irq(); | ||||||
| 
 | 
 | ||||||
| @ -147,12 +144,7 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { | |||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     uint32_t completed_ticks; |     uint32_t completed_ticks = api_hal_timebase_sleep(expected_idle_ticks); | ||||||
|     if (api_hal_timebase.insomnia) { |  | ||||||
|         completed_ticks = api_hal_timebase_nap(expected_idle_ticks); |  | ||||||
|     } else { |  | ||||||
|         completed_ticks = api_hal_timebase_sleep(expected_idle_ticks); |  | ||||||
|     } |  | ||||||
|     assert(completed_ticks >= 0); |     assert(completed_ticks >= 0); | ||||||
| 
 | 
 | ||||||
|     // Reenable IRQ
 |     // Reenable IRQ
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 あく
						あく