From c8aca9ef489c9cdbde97e295da1e1b23c3ae4224 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Mon, 18 Jan 2021 18:08:58 +0300 Subject: [PATCH] [FL-667] Power saving: deep sleep in tickless state (#300) * SYSTEM: tickless mode with deep sleep. * Move FreeRTOS ticks to lptim2. * API: move all sumbodules init routines to one place. * Timebase: working lptim2 at tick source. * API Timebase: lp-timer routines, timer access safe zones prediction and synchronization. * FreeRTOS: adjust configuration for tickless mode. * NFC: support for tickless mode. * API Timebase: improve tick error handling in IRQ. * Apploader: use insomnia mode to run applications. * BLE: prevent sleep while core2 starting. * HAL: nap while in insomnia mode. Co-authored-by: coreglitch --- applications/app-loader/app-loader.c | 3 + applications/gui/gui_event.c | 2 +- applications/nfc/nfc_worker.c | 4 + firmware/targets/api-hal-include/api-hal.h | 3 + firmware/targets/f4/Inc/FreeRTOSConfig.h | 10 +- firmware/targets/f4/Inc/adc.h | 2 +- firmware/targets/f4/Inc/aes.h | 2 +- firmware/targets/f4/Inc/comp.h | 2 +- firmware/targets/f4/Inc/crc.h | 2 +- firmware/targets/f4/Inc/gpio.h | 2 +- firmware/targets/f4/Inc/i2c.h | 2 +- firmware/targets/f4/Inc/pka.h | 2 +- firmware/targets/f4/Inc/rf.h | 2 +- firmware/targets/f4/Inc/rng.h | 2 +- firmware/targets/f4/Inc/rtc.h | 2 +- firmware/targets/f4/Inc/spi.h | 2 +- firmware/targets/f4/Inc/stm32wbxx_it.h | 1 + firmware/targets/f4/Inc/tim.h | 2 +- firmware/targets/f4/Inc/usart.h | 2 +- firmware/targets/f4/Src/adc.c | 2 +- firmware/targets/f4/Src/aes.c | 2 +- firmware/targets/f4/Src/app_freertos.c | 35 ++-- firmware/targets/f4/Src/comp.c | 2 +- firmware/targets/f4/Src/crc.c | 2 +- firmware/targets/f4/Src/gpio.c | 2 +- firmware/targets/f4/Src/i2c.c | 2 +- firmware/targets/f4/Src/main.c | 24 +-- firmware/targets/f4/Src/pka.c | 2 +- firmware/targets/f4/Src/rf.c | 2 +- firmware/targets/f4/Src/rng.c | 2 +- firmware/targets/f4/Src/rtc.c | 2 +- firmware/targets/f4/Src/spi.c | 2 +- .../f4/Src/stm32wbxx_hal_timebase_tim.c | 111 ----------- firmware/targets/f4/Src/stm32wbxx_it.c | 18 +- firmware/targets/f4/Src/tim.c | 2 +- firmware/targets/f4/Src/usart.c | 2 +- .../f4/api-hal/api-hal-timebase-timer.h | 95 ++++++++++ .../targets/f4/api-hal/api-hal-timebase.c | 174 ++++++++++++++++++ .../targets/f4/api-hal/api-hal-timebase.h | 27 +++ firmware/targets/f4/api-hal/api-hal.c | 7 + firmware/targets/f4/ble-glue/app_entry.c | 3 + firmware/targets/f4/f4.ioc | 23 ++- firmware/targets/f4/stm32wb55xx_flash_cm4.ld | 2 +- firmware/targets/f4/target.mk | 1 + 44 files changed, 395 insertions(+), 200 deletions(-) delete mode 100644 firmware/targets/f4/Src/stm32wbxx_hal_timebase_tim.c create mode 100644 firmware/targets/f4/api-hal/api-hal-timebase-timer.h create mode 100644 firmware/targets/f4/api-hal/api-hal-timebase.c create mode 100644 firmware/targets/f4/api-hal/api-hal-timebase.h create mode 100644 firmware/targets/f4/api-hal/api-hal.c diff --git a/applications/app-loader/app-loader.c b/applications/app-loader/app-loader.c index 0038818e..d86d2fb6 100644 --- a/applications/app-loader/app-loader.c +++ b/applications/app-loader/app-loader.c @@ -5,6 +5,7 @@ #include "menu/menu_item.h" #include "applications.h" #include +#include typedef struct { FuriApp* handler; @@ -37,6 +38,7 @@ static void input_callback(InputEvent* input_event, void* _ctx) { if(input_event->state && input_event->input == InputBack) { furiac_kill(ctx->handler); widget_enabled_set(ctx->widget, false); + api_hal_timebase_insomnia_exit(); } } @@ -49,6 +51,7 @@ static void handle_menu(void* _ctx) { // TODO how to call this? // furiac_wait_libs(&FLIPPER_STARTUP[i].libs); + api_hal_timebase_insomnia_enter(); ctx->state->current_app = ctx->app; ctx->state->handler = furiac_start(ctx->app->app, ctx->app->name, NULL); diff --git a/applications/gui/gui_event.c b/applications/gui/gui_event.c index 24707e8d..57346fdf 100644 --- a/applications/gui/gui_event.c +++ b/applications/gui/gui_event.c @@ -42,7 +42,7 @@ GuiEvent* gui_event_alloc() { gui_event->timer = osTimerNew(gui_event_timer_callback, osTimerPeriodic, gui_event, NULL); assert(gui_event->timer); - osTimerStart(gui_event->timer, 1000 / 10); + // osTimerStart(gui_event->timer, 1024 / 4); // Input gui_event->input_event_record = furi_open("input_events"); diff --git a/applications/nfc/nfc_worker.c b/applications/nfc/nfc_worker.c index 97e42497..59ac2601 100644 --- a/applications/nfc/nfc_worker.c +++ b/applications/nfc/nfc_worker.c @@ -1,4 +1,5 @@ #include "nfc_worker_i.h" +#include NfcWorker* nfc_worker_alloc(osMessageQueueId_t message_queue) { NfcWorker* nfc_worker = furi_alloc(sizeof(NfcWorker)); @@ -54,6 +55,8 @@ void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state) { void nfc_worker_task(void* context) { NfcWorker* nfc_worker = context; + api_hal_timebase_insomnia_enter(); + rfalLowPowerModeStop(); if(nfc_worker->state == NfcWorkerStatePoll) { nfc_worker_poll(nfc_worker); @@ -66,6 +69,7 @@ void nfc_worker_task(void* context) { nfc_worker_change_state(nfc_worker, NfcWorkerStateReady); + api_hal_timebase_insomnia_exit(); osThreadExit(); } diff --git a/firmware/targets/api-hal-include/api-hal.h b/firmware/targets/api-hal-include/api-hal.h index 6dcc1878..6884727f 100644 --- a/firmware/targets/api-hal-include/api-hal.h +++ b/firmware/targets/api-hal-include/api-hal.h @@ -4,6 +4,7 @@ template struct STOP_EXTERNING_ME {}; #endif +#include "api-hal-timebase.h" #include "api-hal-boot.h" #include "api-hal-gpio.h" #include "api-hal-delay.h" @@ -16,3 +17,5 @@ template struct STOP_EXTERNING_ME {}; #include "api-hal-bt.h" #include "api-hal-spi.h" #include "api-hal-flash.h" + +void api_hal_init(); diff --git a/firmware/targets/f4/Inc/FreeRTOSConfig.h b/firmware/targets/f4/Inc/FreeRTOSConfig.h index ca8cb033..a864f60b 100644 --- a/firmware/targets/f4/Inc/FreeRTOSConfig.h +++ b/firmware/targets/f4/Inc/FreeRTOSConfig.h @@ -51,6 +51,7 @@ #if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) #include extern uint32_t SystemCoreClock; + void xPortSysTickHandler(void); /* USER CODE BEGIN 0 */ extern void configureTimerForRunTimeStats(void); extern unsigned long getRunTimeCounterValue(void); @@ -65,7 +66,7 @@ #define configUSE_IDLE_HOOK 1 #define configUSE_TICK_HOOK 0 #define configCPU_CLOCK_HZ ( SystemCoreClock ) -#define configTICK_RATE_HZ ((TickType_t)1000) +#define configTICK_RATE_HZ ((TickType_t)1024) #define configMAX_PRIORITIES ( 56 ) #define configMINIMAL_STACK_SIZE ((uint16_t)128) #define configTOTAL_HEAP_SIZE ((size_t)40960) @@ -78,13 +79,16 @@ #define configCHECK_FOR_STACK_OVERFLOW 1 #define configUSE_RECURSIVE_MUTEXES 1 #define configUSE_COUNTING_SEMAPHORES 1 +#define configENABLE_BACKWARD_COMPATIBILITY 0 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configUSE_TICKLESS_IDLE 2 #define configRECORD_STACK_HIGH_ADDRESS 1 /* USER CODE BEGIN MESSAGE_BUFFER_LENGTH_TYPE */ /* Defaults to size_t for backward compatibility, but can be changed if lengths will always be less than the number of bytes in a size_t. */ #define configMESSAGE_BUFFER_LENGTH_TYPE size_t #define configNUM_THREAD_LOCAL_STORAGE_POINTERS 1 +#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 8 /* USER CODE END MESSAGE_BUFFER_LENGTH_TYPE */ /* Co-routine definitions. */ @@ -102,7 +106,7 @@ to exclude the API function. */ #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 #define INCLUDE_vTaskDelete 1 -#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskCleanUpResources 1 #define INCLUDE_vTaskSuspend 1 #define INCLUDE_vTaskDelayUntil 1 #define INCLUDE_vTaskDelay 1 @@ -157,7 +161,7 @@ standard names. */ /* IMPORTANT: This define is commented when used with STM32Cube firmware, when the timebase source is SysTick, to prevent overwriting SysTick_Handler defined within STM32Cube HAL */ -#define xPortSysTickHandler SysTick_Handler +/* #define xPortSysTickHandler SysTick_Handler */ /* USER CODE BEGIN 2 */ /* Definitions needed when configGENERATE_RUN_TIME_STATS is on */ diff --git a/firmware/targets/f4/Inc/adc.h b/firmware/targets/f4/Inc/adc.h index ad6e4ad1..5f945644 100644 --- a/firmware/targets/f4/Inc/adc.h +++ b/firmware/targets/f4/Inc/adc.h @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Inc/aes.h b/firmware/targets/f4/Inc/aes.h index 8e703f9d..bde8ad5a 100644 --- a/firmware/targets/f4/Inc/aes.h +++ b/firmware/targets/f4/Inc/aes.h @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Inc/comp.h b/firmware/targets/f4/Inc/comp.h index 92e61755..5cc7f16e 100644 --- a/firmware/targets/f4/Inc/comp.h +++ b/firmware/targets/f4/Inc/comp.h @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Inc/crc.h b/firmware/targets/f4/Inc/crc.h index cc36b7bc..d1b47518 100644 --- a/firmware/targets/f4/Inc/crc.h +++ b/firmware/targets/f4/Inc/crc.h @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Inc/gpio.h b/firmware/targets/f4/Inc/gpio.h index 220f6191..6b6fe6fb 100644 --- a/firmware/targets/f4/Inc/gpio.h +++ b/firmware/targets/f4/Inc/gpio.h @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Inc/i2c.h b/firmware/targets/f4/Inc/i2c.h index 28396a60..afce630a 100644 --- a/firmware/targets/f4/Inc/i2c.h +++ b/firmware/targets/f4/Inc/i2c.h @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Inc/pka.h b/firmware/targets/f4/Inc/pka.h index 06779391..377ed010 100644 --- a/firmware/targets/f4/Inc/pka.h +++ b/firmware/targets/f4/Inc/pka.h @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Inc/rf.h b/firmware/targets/f4/Inc/rf.h index cfb521db..1796e939 100644 --- a/firmware/targets/f4/Inc/rf.h +++ b/firmware/targets/f4/Inc/rf.h @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Inc/rng.h b/firmware/targets/f4/Inc/rng.h index 08b72883..fa121ad1 100644 --- a/firmware/targets/f4/Inc/rng.h +++ b/firmware/targets/f4/Inc/rng.h @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Inc/rtc.h b/firmware/targets/f4/Inc/rtc.h index 0ae33baa..3e961b71 100644 --- a/firmware/targets/f4/Inc/rtc.h +++ b/firmware/targets/f4/Inc/rtc.h @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Inc/spi.h b/firmware/targets/f4/Inc/spi.h index 7e313320..755c9cfe 100644 --- a/firmware/targets/f4/Inc/spi.h +++ b/firmware/targets/f4/Inc/spi.h @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Inc/stm32wbxx_it.h b/firmware/targets/f4/Inc/stm32wbxx_it.h index 3d30f4d8..43df3f69 100644 --- a/firmware/targets/f4/Inc/stm32wbxx_it.h +++ b/firmware/targets/f4/Inc/stm32wbxx_it.h @@ -53,6 +53,7 @@ void MemManage_Handler(void); void BusFault_Handler(void); void UsageFault_Handler(void); void DebugMon_Handler(void); +void SysTick_Handler(void); void TAMP_STAMP_LSECSS_IRQHandler(void); void RCC_IRQHandler(void); void EXTI1_IRQHandler(void); diff --git a/firmware/targets/f4/Inc/tim.h b/firmware/targets/f4/Inc/tim.h index 6f1e7c78..9d530bce 100644 --- a/firmware/targets/f4/Inc/tim.h +++ b/firmware/targets/f4/Inc/tim.h @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Inc/usart.h b/firmware/targets/f4/Inc/usart.h index 15e65d1e..7a4d7465 100644 --- a/firmware/targets/f4/Inc/usart.h +++ b/firmware/targets/f4/Inc/usart.h @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Src/adc.c b/firmware/targets/f4/Src/adc.c index d924c244..1ad43f2f 100644 --- a/firmware/targets/f4/Src/adc.c +++ b/firmware/targets/f4/Src/adc.c @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Src/aes.c b/firmware/targets/f4/Src/aes.c index 31624851..1a042e9b 100644 --- a/firmware/targets/f4/Src/aes.c +++ b/firmware/targets/f4/Src/aes.c @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Src/app_freertos.c b/firmware/targets/f4/Src/app_freertos.c index b24d522e..0d16ac20 100644 --- a/firmware/targets/f4/Src/app_freertos.c +++ b/firmware/targets/f4/Src/app_freertos.c @@ -26,7 +26,6 @@ /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ - /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ @@ -48,18 +47,11 @@ /* USER CODE BEGIN Variables */ /* USER CODE END Variables */ -/* Definitions for defaultTask */ -osThreadId_t defaultTaskHandle; -const osThreadAttr_t defaultTask_attributes = { - .name = "defaultTask", - .priority = (osPriority_t) osPriorityNormal, - .stack_size = 1024 * 4 -}; /* Definitions for app_main */ osThreadId_t app_mainHandle; const osThreadAttr_t app_main_attributes = { .name = "app_main", - .priority = (osPriority_t) osPriorityLow, + .priority = (osPriority_t) osPriorityNormal, .stack_size = 1024 * 4 }; @@ -68,8 +60,7 @@ const osThreadAttr_t app_main_attributes = { /* USER CODE END FunctionPrototypes */ -void StartDefaultTask(void *argument); -extern void app(void *argument); +void app(void *argument); void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ @@ -77,7 +68,7 @@ void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */ void configureTimerForRunTimeStats(void); unsigned long getRunTimeCounterValue(void); void vApplicationIdleHook(void); -void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName); +void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName); /* USER CODE BEGIN 1 */ /* Functions needed when configGENERATE_RUN_TIME_STATS is on */ @@ -108,7 +99,7 @@ __weak void vApplicationIdleHook( void ) /* USER CODE END 2 */ /* USER CODE BEGIN 4 */ -__weak void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTaskName) +__weak void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName) { /* Run time stack overflow checking is performed if configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook function is @@ -116,6 +107,9 @@ __weak void vApplicationStackOverflowHook(xTaskHandle xTask, signed char *pcTask } /* USER CODE END 4 */ +/* USER CODE BEGIN VPORT_SUPPORT_TICKS_AND_SLEEP */ +/* USER CODE END VPORT_SUPPORT_TICKS_AND_SLEEP */ + /** * @brief FreeRTOS initialization * @param None @@ -143,9 +137,6 @@ void MX_FREERTOS_Init(void) { /* USER CODE END RTOS_QUEUES */ /* Create the thread(s) */ - /* creation of defaultTask */ - defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes); - /* creation of app_main */ app_mainHandle = osThreadNew(app, NULL, &app_main_attributes); @@ -159,22 +150,22 @@ void MX_FREERTOS_Init(void) { } -/* USER CODE BEGIN Header_StartDefaultTask */ +/* USER CODE BEGIN Header_app */ /** - * @brief Function implementing the defaultTask thread. + * @brief Function implementing the app_main thread. * @param argument: Not used * @retval None */ -/* USER CODE END Header_StartDefaultTask */ -void StartDefaultTask(void *argument) +/* USER CODE END Header_app */ +__weak void app(void *argument) { - /* USER CODE BEGIN StartDefaultTask */ + /* USER CODE BEGIN app */ /* Infinite loop */ for(;;) { osDelay(1); } - /* USER CODE END StartDefaultTask */ + /* USER CODE END app */ } /* Private application code --------------------------------------------------*/ diff --git a/firmware/targets/f4/Src/comp.c b/firmware/targets/f4/Src/comp.c index 0182f260..9401ed34 100644 --- a/firmware/targets/f4/Src/comp.c +++ b/firmware/targets/f4/Src/comp.c @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Src/crc.c b/firmware/targets/f4/Src/crc.c index b42b3a1c..42b98724 100644 --- a/firmware/targets/f4/Src/crc.c +++ b/firmware/targets/f4/Src/crc.c @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Src/gpio.c b/firmware/targets/f4/Src/gpio.c index 84634b10..6418ba09 100644 --- a/firmware/targets/f4/Src/gpio.c +++ b/firmware/targets/f4/Src/gpio.c @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Src/i2c.c b/firmware/targets/f4/Src/i2c.c index e3f3f8cd..3f2b619e 100644 --- a/firmware/targets/f4/Src/i2c.c +++ b/firmware/targets/f4/Src/i2c.c @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Src/main.c b/firmware/targets/f4/Src/main.c index b300041a..095b5188 100644 --- a/firmware/targets/f4/Src/main.c +++ b/firmware/targets/f4/Src/main.c @@ -118,10 +118,9 @@ int main(void) MX_AES2_Init(); MX_CRC_Init(); /* USER CODE BEGIN 2 */ + api_hal_init(); MX_FATFS_Init(); delay_us_init_DWT(); - api_hal_vcp_init(); - api_hal_spi_init(); // Errata 2.2.9, Flash OPTVERR flag is always set after system reset __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); /* USER CODE END 2 */ @@ -236,27 +235,6 @@ void SystemClock_Config(void) /* USER CODE END 4 */ - /** - * @brief Period elapsed callback in non blocking mode - * @note This function is called when TIM17 interrupt took place, inside - * HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment - * a global variable "uwTick" used as application time base. - * @param htim : TIM handle - * @retval None - */ -void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) -{ - /* USER CODE BEGIN Callback 0 */ - - /* USER CODE END Callback 0 */ - if (htim->Instance == TIM17) { - HAL_IncTick(); - } - /* USER CODE BEGIN Callback 1 */ - - /* USER CODE END Callback 1 */ -} - /** * @brief This function is executed in case of error occurrence. * @retval None diff --git a/firmware/targets/f4/Src/pka.c b/firmware/targets/f4/Src/pka.c index 3fcf83eb..8377ce57 100644 --- a/firmware/targets/f4/Src/pka.c +++ b/firmware/targets/f4/Src/pka.c @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Src/rf.c b/firmware/targets/f4/Src/rf.c index 00f46606..62daf9b2 100644 --- a/firmware/targets/f4/Src/rf.c +++ b/firmware/targets/f4/Src/rf.c @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Src/rng.c b/firmware/targets/f4/Src/rng.c index 36bc8bb4..c2fb144e 100644 --- a/firmware/targets/f4/Src/rng.c +++ b/firmware/targets/f4/Src/rng.c @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Src/rtc.c b/firmware/targets/f4/Src/rtc.c index 8b7aea42..8a6f4c92 100644 --- a/firmware/targets/f4/Src/rtc.c +++ b/firmware/targets/f4/Src/rtc.c @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Src/spi.c b/firmware/targets/f4/Src/spi.c index fa8f5ef7..2034a3a6 100644 --- a/firmware/targets/f4/Src/spi.c +++ b/firmware/targets/f4/Src/spi.c @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Src/stm32wbxx_hal_timebase_tim.c b/firmware/targets/f4/Src/stm32wbxx_hal_timebase_tim.c deleted file mode 100644 index 745a9c95..00000000 --- a/firmware/targets/f4/Src/stm32wbxx_hal_timebase_tim.c +++ /dev/null @@ -1,111 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file stm32wbxx_hal_timebase_TIM.c - * @brief HAL time base based on the hardware TIM. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Includes ------------------------------------------------------------------*/ -#include "stm32wbxx_hal.h" -#include "stm32wbxx_hal_tim.h" - -/* Private typedef -----------------------------------------------------------*/ -/* Private define ------------------------------------------------------------*/ -/* Private macro -------------------------------------------------------------*/ -/* Private variables ---------------------------------------------------------*/ -TIM_HandleTypeDef htim17; -/* Private function prototypes -----------------------------------------------*/ -/* Private functions ---------------------------------------------------------*/ - -/** - * @brief This function configures the TIM17 as a time base source. - * The time source is configured to have 1ms time base with a dedicated - * Tick interrupt priority. - * @note This function is called automatically at the beginning of program after - * reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig(). - * @param TickPriority: Tick interrupt priority. - * @retval HAL status - */ -HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) -{ - RCC_ClkInitTypeDef clkconfig; - uint32_t uwTimclock = 0; - uint32_t uwPrescalerValue = 0; - uint32_t pFLatency; - /*Configure the TIM17 IRQ priority */ - HAL_NVIC_SetPriority(TIM1_TRG_COM_TIM17_IRQn, TickPriority ,0); - - /* Enable the TIM17 global Interrupt */ - HAL_NVIC_EnableIRQ(TIM1_TRG_COM_TIM17_IRQn); - /* Enable TIM17 clock */ - __HAL_RCC_TIM17_CLK_ENABLE(); - - /* Get clock configuration */ - HAL_RCC_GetClockConfig(&clkconfig, &pFLatency); - - /* Compute TIM17 clock */ - uwTimclock = HAL_RCC_GetPCLK2Freq(); - /* Compute the prescaler value to have TIM17 counter clock equal to 1MHz */ - uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000U) - 1U); - - /* Initialize TIM17 */ - htim17.Instance = TIM17; - - /* Initialize TIMx peripheral as follow: - + Period = [(TIM17CLK/1000) - 1]. to have a (1/1000) s time base. - + Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock. - + ClockDivision = 0 - + Counter direction = Up - */ - htim17.Init.Period = (1000000U / 1000U) - 1U; - htim17.Init.Prescaler = uwPrescalerValue; - htim17.Init.ClockDivision = 0; - htim17.Init.CounterMode = TIM_COUNTERMODE_UP; - if(HAL_TIM_Base_Init(&htim17) == HAL_OK) - { - /* Start the TIM time Base generation in interrupt mode */ - return HAL_TIM_Base_Start_IT(&htim17); - } - - /* Return function status */ - return HAL_ERROR; -} - -/** - * @brief Suspend Tick increment. - * @note Disable the tick increment by disabling TIM17 update interrupt. - * @param None - * @retval None - */ -void HAL_SuspendTick(void) -{ - /* Disable TIM17 update Interrupt */ - __HAL_TIM_DISABLE_IT(&htim17, TIM_IT_UPDATE); -} - -/** - * @brief Resume Tick increment. - * @note Enable the tick increment by Enabling TIM17 update interrupt. - * @param None - * @retval None - */ -void HAL_ResumeTick(void) -{ - /* Enable TIM17 Update interrupt */ - __HAL_TIM_ENABLE_IT(&htim17, TIM_IT_UPDATE); -} - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f4/Src/stm32wbxx_it.c b/firmware/targets/f4/Src/stm32wbxx_it.c index 89c1d754..bd020eb6 100644 --- a/firmware/targets/f4/Src/stm32wbxx_it.c +++ b/firmware/targets/f4/Src/stm32wbxx_it.c @@ -21,6 +21,8 @@ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "stm32wbxx_it.h" +#include "FreeRTOS.h" +#include "task.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ @@ -62,8 +64,6 @@ extern COMP_HandleTypeDef hcomp1; extern RTC_HandleTypeDef hrtc; extern TIM_HandleTypeDef htim1; extern TIM_HandleTypeDef htim2; -extern TIM_HandleTypeDef htim17; - /* USER CODE BEGIN EV */ /* USER CODE END EV */ @@ -160,6 +160,19 @@ void DebugMon_Handler(void) /* USER CODE END DebugMonitor_IRQn 1 */ } +/** + * @brief This function handles System tick timer. + */ +void SysTick_Handler(void) +{ + /* USER CODE BEGIN SysTick_IRQn 0 */ + + /* USER CODE END SysTick_IRQn 0 */ + /* USER CODE BEGIN SysTick_IRQn 1 */ + HAL_IncTick(); + /* USER CODE END SysTick_IRQn 1 */ +} + /******************************************************************************/ /* STM32WBxx Peripheral Interrupt Handlers */ /* Add here the Interrupt Handlers for the used peripherals. */ @@ -288,7 +301,6 @@ void TIM1_TRG_COM_TIM17_IRQHandler(void) /* USER CODE END TIM1_TRG_COM_TIM17_IRQn 0 */ HAL_TIM_IRQHandler(&htim1); - HAL_TIM_IRQHandler(&htim17); /* USER CODE BEGIN TIM1_TRG_COM_TIM17_IRQn 1 */ /* USER CODE END TIM1_TRG_COM_TIM17_IRQn 1 */ diff --git a/firmware/targets/f4/Src/tim.c b/firmware/targets/f4/Src/tim.c index 8ed10ebe..1d558dd5 100644 --- a/firmware/targets/f4/Src/tim.c +++ b/firmware/targets/f4/Src/tim.c @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/Src/usart.c b/firmware/targets/f4/Src/usart.c index 9bf64275..3acecbb3 100644 --- a/firmware/targets/f4/Src/usart.c +++ b/firmware/targets/f4/Src/usart.c @@ -6,7 +6,7 @@ ****************************************************************************** * @attention * - *

© Copyright (c) 2020 STMicroelectronics. + *

© Copyright (c) 2021 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license diff --git a/firmware/targets/f4/api-hal/api-hal-timebase-timer.h b/firmware/targets/f4/api-hal/api-hal-timebase-timer.h new file mode 100644 index 00000000..5b471601 --- /dev/null +++ b/firmware/targets/f4/api-hal/api-hal-timebase-timer.h @@ -0,0 +1,95 @@ +#pragma once + +#include +#include + +static inline void assert(bool value) { + if (!value) asm("bkpt 1"); +} + +// Timer used for system ticks +#define API_HAL_TIMEBASE_TIMER_MAX 0xFFFF +#define API_HAL_TIMEBASE_TIMER_REG_LOAD_DLY 0x1 +#define API_HAL_TIMEBASE_TIMER LPTIM2 +#define API_HAL_TIMEBASE_TIMER_IRQ LPTIM2_IRQn +#define API_HAL_TIMEBASE_TIMER_CLOCK_INIT() \ +{ \ + LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE_LSE); \ + LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPTIM2); \ +} \ + +static inline void api_hal_timebase_timer_init() { + API_HAL_TIMEBASE_TIMER_CLOCK_INIT(); + + LL_LPTIM_Enable(API_HAL_TIMEBASE_TIMER); + while(!LL_LPTIM_IsEnabled(API_HAL_TIMEBASE_TIMER)) {} + + LL_LPTIM_SetClockSource(API_HAL_TIMEBASE_TIMER, LL_LPTIM_CLK_SOURCE_INTERNAL); + LL_LPTIM_SetPrescaler(API_HAL_TIMEBASE_TIMER, LL_LPTIM_PRESCALER_DIV1); + LL_LPTIM_SetPolarity(API_HAL_TIMEBASE_TIMER, LL_LPTIM_OUTPUT_POLARITY_REGULAR); + LL_LPTIM_SetUpdateMode(API_HAL_TIMEBASE_TIMER, LL_LPTIM_UPDATE_MODE_IMMEDIATE); + LL_LPTIM_SetCounterMode(API_HAL_TIMEBASE_TIMER, LL_LPTIM_COUNTER_MODE_INTERNAL); + LL_LPTIM_TrigSw(API_HAL_TIMEBASE_TIMER); + LL_LPTIM_SetInput1Src(API_HAL_TIMEBASE_TIMER, LL_LPTIM_INPUT1_SRC_GPIO); + LL_LPTIM_SetInput2Src(API_HAL_TIMEBASE_TIMER, LL_LPTIM_INPUT2_SRC_GPIO); + + NVIC_SetPriority(API_HAL_TIMEBASE_TIMER_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0)); + NVIC_EnableIRQ(API_HAL_TIMEBASE_TIMER_IRQ); +} + +static inline uint32_t api_hal_timebase_timer_get_cnt() { + uint32_t counter = LL_LPTIM_GetCounter(API_HAL_TIMEBASE_TIMER); + uint32_t counter_shadow = LL_LPTIM_GetCounter(API_HAL_TIMEBASE_TIMER); + while(counter != counter_shadow) { + counter = counter_shadow; + counter_shadow = LL_LPTIM_GetCounter(API_HAL_TIMEBASE_TIMER); + } + return counter; +} + +static inline bool api_hal_timebase_timer_arr_is_ok() { + return LL_LPTIM_IsActiveFlag_ARROK(API_HAL_TIMEBASE_TIMER); +} + +static inline uint32_t api_hal_timebase_timer_get_arr() { + return LL_LPTIM_GetAutoReload(API_HAL_TIMEBASE_TIMER);; +} + +static inline void api_hal_timebase_timer_set_arr(uint32_t value) { + value &= API_HAL_TIMEBASE_TIMER_MAX; + if (value != api_hal_timebase_timer_get_arr()) { + assert(api_hal_timebase_timer_arr_is_ok()); + LL_LPTIM_ClearFlag_ARROK(API_HAL_TIMEBASE_TIMER); + LL_LPTIM_SetAutoReload(API_HAL_TIMEBASE_TIMER, value); + } +} + +static inline bool api_hal_timebase_timer_cmp_is_ok() { + return LL_LPTIM_IsActiveFlag_CMPOK(API_HAL_TIMEBASE_TIMER); +} + +static inline uint32_t api_hal_timebase_timer_get_cmp() { + return LL_LPTIM_GetCompare(API_HAL_TIMEBASE_TIMER);; +} + +static inline void api_hal_timebase_timer_set_cmp(uint32_t value) { + value &= API_HAL_TIMEBASE_TIMER_MAX; + if (value != api_hal_timebase_timer_get_cmp()) { + assert(api_hal_timebase_timer_cmp_is_ok()); + LL_LPTIM_ClearFlag_CMPOK(API_HAL_TIMEBASE_TIMER); + LL_LPTIM_SetCompare(API_HAL_TIMEBASE_TIMER, value); + } +} + +static inline bool api_hal_timebase_timer_is_safe() { + uint16_t cmp = api_hal_timebase_timer_get_cmp(); + uint16_t cnt = api_hal_timebase_timer_get_cnt(); + uint16_t margin = (cmp > cnt) ? cmp - cnt : cnt - cmp; + if (margin < 8) { + return false; + } + if (!api_hal_timebase_timer_cmp_is_ok()) { + return false; + } + return true; +} diff --git a/firmware/targets/f4/api-hal/api-hal-timebase.c b/firmware/targets/f4/api-hal/api-hal-timebase.c new file mode 100644 index 00000000..e7604a08 --- /dev/null +++ b/firmware/targets/f4/api-hal/api-hal-timebase.c @@ -0,0 +1,174 @@ +#include +#include + +#include +#include +#include +#include + +#define API_HAL_TIMEBASE_CLK_FREQUENCY 32768 +#define API_HAL_TIMEBASE_TICK_PER_SECOND 1024 +#define API_HAL_TIMEBASE_CLK_PER_TICK (API_HAL_TIMEBASE_CLK_FREQUENCY / API_HAL_TIMEBASE_TICK_PER_SECOND) +#define API_HAL_TIMEBASE_TICK_PER_EPOCH (API_HAL_TIMEBASE_TIMER_MAX / API_HAL_TIMEBASE_CLK_PER_TICK) +#define API_HAL_TIMEBASE_MAX_SLEEP (API_HAL_TIMEBASE_TICK_PER_EPOCH - 1) + +typedef struct { + // Sleep control + volatile uint16_t insomnia; + // Tick counters + volatile uint32_t in_sleep; + volatile uint32_t in_awake; + // Error counters + volatile uint32_t sleep_error; + volatile uint32_t awake_error; +} ApiHalTimbase; + +ApiHalTimbase api_hal_timebase = { + .insomnia = 0, + .in_sleep = 0, + .in_awake = 0, + .sleep_error = 0, + .awake_error = 0, +}; + +void api_hal_timebase_init() { + api_hal_timebase_timer_init(); + LL_DBGMCU_APB1_GRP2_FreezePeriph(LL_DBGMCU_APB1_GRP2_LPTIM2_STOP); + + LL_LPTIM_EnableIT_CMPM(API_HAL_TIMEBASE_TIMER); + LL_LPTIM_EnableIT_ARRM(API_HAL_TIMEBASE_TIMER); + + LL_LPTIM_SetAutoReload(API_HAL_TIMEBASE_TIMER, API_HAL_TIMEBASE_TIMER_MAX); + LL_LPTIM_SetCompare(API_HAL_TIMEBASE_TIMER, API_HAL_TIMEBASE_CLK_PER_TICK); + + LL_LPTIM_StartCounter(API_HAL_TIMEBASE_TIMER, LL_LPTIM_OPERATING_MODE_CONTINUOUS); +} + +uint16_t api_hal_timebase_insomnia_level() { + return api_hal_timebase.insomnia; +} + +void api_hal_timebase_insomnia_enter() { + api_hal_timebase.insomnia++; +} + +void api_hal_timebase_insomnia_exit() { + api_hal_timebase.insomnia--; +} + +void LPTIM2_IRQHandler(void) { + // Autoreload + const bool arrm_flag = LL_LPTIM_IsActiveFlag_ARRM(API_HAL_TIMEBASE_TIMER); + if(arrm_flag) { + LL_LPTIM_ClearFLAG_ARRM(API_HAL_TIMEBASE_TIMER); + } + if(LL_LPTIM_IsActiveFlag_CMPM(API_HAL_TIMEBASE_TIMER)) { + LL_LPTIM_ClearFLAG_CMPM(API_HAL_TIMEBASE_TIMER); + + // Store important value + uint16_t cnt = api_hal_timebase_timer_get_cnt(); + uint16_t cmp = api_hal_timebase_timer_get_cmp(); + uint16_t current_tick = cnt / API_HAL_TIMEBASE_CLK_PER_TICK; + uint16_t compare_tick = cmp / API_HAL_TIMEBASE_CLK_PER_TICK; + + // Calculate error + // happens when HAL or other high priority IRQ takes our time + int32_t error = (int32_t)compare_tick - current_tick; + api_hal_timebase.awake_error += ((error>0) ? error : -error); + + // Calculate and set next tick + uint16_t next_tick = current_tick + 1; + api_hal_timebase_timer_set_cmp(next_tick * API_HAL_TIMEBASE_CLK_PER_TICK); + + // Notify OS + api_hal_timebase.in_awake ++; + if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { + xPortSysTickHandler(); + } + } +} + +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) { + // Store important value before going to sleep + const uint16_t before_cnt = api_hal_timebase_timer_get_cnt(); + const uint16_t before_tick = before_cnt / API_HAL_TIMEBASE_CLK_PER_TICK; + + // Calculate and set next wakeup compare value + const uint16_t expected_cnt = (before_tick + expected_idle_ticks - 2) * API_HAL_TIMEBASE_CLK_PER_TICK; + api_hal_timebase_timer_set_cmp(expected_cnt); + + // Go to stop2 mode + HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); + + // Spin till we are in timer safe zone + while(!api_hal_timebase_timer_is_safe()) {} + + // Store current counter value, calculate current tick + const uint16_t after_cnt = api_hal_timebase_timer_get_cnt(); + const uint16_t after_tick = after_cnt / API_HAL_TIMEBASE_CLK_PER_TICK; + + // Store and clear interrupt flags + // we don't want handler to be called after renabling IRQ + bool cmpm_flag = LL_LPTIM_IsActiveFlag_CMPM(API_HAL_TIMEBASE_TIMER); + if (cmpm_flag) LL_LPTIM_ClearFLAG_CMPM(API_HAL_TIMEBASE_TIMER); + bool arrm_flag = LL_LPTIM_IsActiveFlag_ARRM(API_HAL_TIMEBASE_TIMER); + if (arrm_flag) LL_LPTIM_ClearFLAG_ARRM(API_HAL_TIMEBASE_TIMER); + + // Calculate and set next wakeup compare value + const uint16_t next_cmp = (after_tick + 1) * API_HAL_TIMEBASE_CLK_PER_TICK; + api_hal_timebase_timer_set_cmp(next_cmp); + + // Calculate ticks count spent in sleep and perform sanity checks + int32_t completed_ticks = arrm_flag ? (int32_t)before_tick - after_tick : (int32_t)after_tick - before_tick; + + return completed_ticks; +} + +void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { + // Limit mount of ticks to maximum that timer can count + if (expected_idle_ticks > API_HAL_TIMEBASE_MAX_SLEEP) { + expected_idle_ticks = API_HAL_TIMEBASE_MAX_SLEEP; + } + + // Stop IRQ handling, no one should disturb us till we finish + __disable_irq(); + + // Confirm OS that sleep is still possible + // And check if timer is in safe zone + // (8 clocks till any IRQ event or ongoing synchronization) + if (eTaskConfirmSleepModeStatus() == eAbortSleep + || !api_hal_timebase_timer_is_safe()) { + __enable_irq(); + return; + } + + uint32_t completed_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); + + // Reenable IRQ + __enable_irq(); + + // Notify system about time spent in sleep + if (completed_ticks > 0) { + api_hal_timebase.in_sleep += completed_ticks; + if (completed_ticks > expected_idle_ticks) { + // We are late, count error + api_hal_timebase.sleep_error += (completed_ticks - expected_idle_ticks); + // Freertos is not happy when we overleep + // But we are not going to tell her + vTaskStepTick(expected_idle_ticks); + } else { + vTaskStepTick(completed_ticks); + } + } +} diff --git a/firmware/targets/f4/api-hal/api-hal-timebase.h b/firmware/targets/f4/api-hal/api-hal-timebase.h new file mode 100644 index 00000000..6c6a992d --- /dev/null +++ b/firmware/targets/f4/api-hal/api-hal-timebase.h @@ -0,0 +1,27 @@ +#pragma once + +#include + +/* Initialize timebase + * Configure and start tick timer + */ +void api_hal_timebase_init(); + +/* Get current insomnia level + * @return insomnia level: 0 - no insomnia, >0 - insomnia, bearer count. + */ +uint16_t api_hal_timebase_insomnia_level(); + +/* Enter insomnia mode + * Prevents device from going to sleep + * @warning Internally increases insomnia level + * Must be paired with api_hal_timebase_insomnia_exit + */ +void api_hal_timebase_insomnia_enter(); + +/* Exit insomnia mode + * Allow device to go to sleep + * @warning Internally decreases insomnia level. + * Must be paired with api_hal_timebase_insomnia_enter + */ +void api_hal_timebase_insomnia_exit(); \ No newline at end of file diff --git a/firmware/targets/f4/api-hal/api-hal.c b/firmware/targets/f4/api-hal/api-hal.c new file mode 100644 index 00000000..ccd55f75 --- /dev/null +++ b/firmware/targets/f4/api-hal/api-hal.c @@ -0,0 +1,7 @@ +#include + +void api_hal_init() { + api_hal_timebase_init(); + api_hal_vcp_init(); + api_hal_spi_init(); +} \ No newline at end of file diff --git a/firmware/targets/f4/ble-glue/app_entry.c b/firmware/targets/f4/ble-glue/app_entry.c index ddf72b8d..4b12d474 100644 --- a/firmware/targets/f4/ble-glue/app_entry.c +++ b/firmware/targets/f4/ble-glue/app_entry.c @@ -8,6 +8,7 @@ #include "shci_tl.h" #include "stm32_lpm.h" #include "app_debug.h" +#include extern RTC_HandleTypeDef hrtc; @@ -51,6 +52,7 @@ void APPE_Init() { HW_TS_Init(hw_ts_InitMode_Full, &hrtc); /**< Initialize the TimerServer */ // APPD_Init(); + api_hal_timebase_insomnia_enter(); appe_Tl_Init(); /* Initialize all transport layers */ @@ -142,6 +144,7 @@ static void APPE_SysUserEvtRx( void * pPayload ) { } else { ble_glue_status = BleGlueStatusBroken; } + api_hal_timebase_insomnia_exit(); } /************************************************************* diff --git a/firmware/targets/f4/f4.ioc b/firmware/targets/f4/f4.ioc index 52b6389c..7e003c6b 100644 --- a/firmware/targets/f4/f4.ioc +++ b/firmware/targets/f4/f4.ioc @@ -30,7 +30,7 @@ PinOutPanel.RotationAngle=0 RCC.MCO1PinFreq_Value=64000000 RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK SH.GPXTI13.0=GPIO_EXTI13 -RCC.LPTIM1Freq_Value=64000000 +RCC.LPTIM1Freq_Value=32768 NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:false\:false\:false\:false FREERTOS.configENABLE_FPU=1 NVIC.EXTI1_IRQn=true\:5\:0\:true\:false\:true\:false\:true\:true @@ -69,7 +69,6 @@ MxDb.Version=DB.6.0.10 PB0.GPIOParameters=GPIO_Label PA1.GPIOParameters=GPIO_Speed,PinState,GPIO_Label,GPIO_ModeDefaultOutputPP ProjectManager.BackupPrevious=false -VP_SYS_VS_tim17.Signal=SYS_VS_tim17 PC4.GPIO_Label=CC1101_G0 FREERTOS.HEAP_NUMBER=4 RCC.LSE_Drive_Capability=RCC_LSEDRIVE_MEDIUMLOW @@ -95,15 +94,14 @@ Mcu.Package=VFQFPN68 TIM2.Prescaler=64-1 PB1.Signal=GPXTI1 PA5.Locked=true -NVIC.TimeBase=TIM1_TRG_COM_TIM17_IRQn SPI2.Mode=SPI_MODE_MASTER PA2.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_OD SH.GPXTI11.0=GPIO_EXTI11 SH.GPXTI8.0=GPIO_EXTI8 VP_PKA_VS_PKA.Mode=PKA_Activate PA14.Locked=true +VP_SYS_VS_Systick.Signal=SYS_VS_Systick SH.GPXTI8.ConfNb=1 -NVIC.TimeBaseIP=TIM17 RCC.LSCOPinFreq_Value=32000 PA10.Signal=I2C1_SDA VP_RTC_VS_RTC_Calendar.Mode=RTC_Calendar @@ -138,12 +136,11 @@ RCC.PLLQoutputFreq_Value=64000000 ProjectManager.ProjectFileName=f4.ioc RCC.SMPSFreq_Value=4000000 PA3.GPIO_ModeDefaultOutputPP=GPIO_MODE_OUTPUT_OD -FREERTOS.Tasks01=defaultTask,24,1024,StartDefaultTask,Default,NULL,Dynamic,NULL,NULL;app_main,8,1024,app,As external,NULL,Dynamic,NULL,NULL +FREERTOS.Tasks01=app_main,24,1024,app,As weak,NULL,Dynamic,NULL,NULL ADC1.Rank-0\#ChannelRegularConversion=1 PA15.GPIOParameters=GPIO_PuPd,GPIO_Label Mcu.PinsNb=69 PC11.Locked=true -VP_SYS_VS_tim17.Mode=TIM17 ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,OffsetNumber-0\#ChannelRegularConversion,NbrOfConversionFlag,master,EnableAnalogWatchDog1,ContinuousConvMode PC13.Locked=true ADC1.OffsetNumber-0\#ChannelRegularConversion=ADC_OFFSET_NONE @@ -170,7 +167,7 @@ Mcu.Pin60=VP_PKA_VS_PKA Mcu.Pin61=VP_RNG_VS_RNG Mcu.Pin66=VP_TIM2_VS_ClockSourceINT Mcu.Pin67=VP_TIM16_VS_ClockSourceINT -Mcu.Pin64=VP_SYS_VS_tim17 +Mcu.Pin64=VP_SYS_VS_Systick Mcu.Pin65=VP_TIM1_VS_ClockSourceINT PD0.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH PC3.GPIOParameters=GPIO_Label @@ -332,6 +329,7 @@ PD0.GPIO_Label=CC1101_CS PC0.GPIO_Label=PC0 PA11.Mode=Device PB0.GPIO_Label=DISPLAY_RST +FREERTOS.configTICK_RATE_HZ=1000 VP_RTC_VS_RTC_Calendar.Signal=RTC_VS_RTC_Calendar PB11.GPIO_PuPd=GPIO_PULLUP PC13.GPIO_Label=BUTTON_BACK @@ -374,7 +372,7 @@ Mcu.Pin7=PC1 Mcu.Pin8=PC2 Mcu.Pin9=PC3 OSC_OUT.Mode=HSE-External-Oscillator -FREERTOS.IPParameters=Tasks01,configTOTAL_HEAP_SIZE,HEAP_NUMBER,configUSE_TIMERS,configUSE_IDLE_HOOK,FootprintOK,configCHECK_FOR_STACK_OVERFLOW,configRECORD_STACK_HIGH_ADDRESS,configGENERATE_RUN_TIME_STATS,configENABLE_FPU +FREERTOS.IPParameters=Tasks01,configTOTAL_HEAP_SIZE,HEAP_NUMBER,configUSE_TIMERS,configUSE_IDLE_HOOK,FootprintOK,configCHECK_FOR_STACK_OVERFLOW,configRECORD_STACK_HIGH_ADDRESS,configGENERATE_RUN_TIME_STATS,configENABLE_FPU,configUSE_TICKLESS_IDLE,configENABLE_BACKWARD_COMPATIBILITY,INCLUDE_vTaskCleanUpResources,configTICK_RATE_HZ OSC_OUT.Signal=RCC_OSC_OUT RCC.AHBFreq_Value=64000000 SPI2.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_16 @@ -392,9 +390,10 @@ FREERTOS.configUSE_TIMERS=1 NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false PH3-BOOT0.GPIOParameters=GPIO_Label,GPIO_ModeDefaultEXTI Mcu.IP10=RCC -NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:false\:true\:false\:true +NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:true\:false\:false Mcu.IP12=RNG Mcu.IP11=RF +FREERTOS.configENABLE_BACKWARD_COMPATIBILITY=0 Mcu.IP18=TIM2 Mcu.IP17=TIM1 NVIC.TIM1_TRG_COM_TIM17_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:true @@ -422,6 +421,7 @@ PB7.Signal=USART1_RX Mcu.IP21=USB PB8.Locked=true Mcu.IP20=USART1 +FREERTOS.INCLUDE_vTaskCleanUpResources=1 Mcu.IP22=USB_DEVICE PE4.Signal=GPIO_Output PB0.Locked=true @@ -474,6 +474,7 @@ USB_DEVICE.VirtualModeFS=Cdc_FS PC4.GPIO_PuPd=GPIO_PULLDOWN NVIC.SavedSvcallIrqHandlerGenerated=false PC11.Signal=GPIO_Output +FREERTOS.configUSE_TICKLESS_IDLE=2 PC4.Signal=GPXTI4 ProjectManager.DefaultFWLocation=true PC2.Mode=Full_Duplex_Master @@ -504,6 +505,7 @@ RCC.HCLKRFFreq_Value=16000000 PC5.GPIOParameters=GPIO_Label PB9.Mode=PWM Generation3 CH3N PB2.GPIOParameters=GPIO_Label +RCC.LPTIM1CLockSelection=RCC_LPTIM1CLKSOURCE_LSE SH.GPXTI12.ConfNb=1 PE4.Locked=true SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,DataSize,BaudRatePrescaler,CLKPhase @@ -535,13 +537,14 @@ RCC.PLLSAI1QoutputFreq_Value=48000000 RCC.ADCFreq_Value=48000000 PC1.GPIO_Label=PC1 PA10.GPIOParameters=GPIO_Speed,GPIO_Label +VP_SYS_VS_Systick.Mode=SysTick VP_ADC1_Vref_Input.Signal=ADC1_Vref_Input SH.SharedAnalog_PC5.1=ADC1_IN14,IN14-Single-Ended OSC_OUT.Locked=true PA4.GPIOParameters=GPIO_Label PH3-BOOT0.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING_FALLING PB15.GPIOParameters=GPIO_Label -RCC.IPParameters=ADCFreq_Value,AHB2CLKDivider,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,APB3Freq_Value,Cortex2Freq_Value,CortexFreq_Value,EnableCSSLSE,EnbaleCSS,FCLK2Freq_Value,FCLKCortexFreq_Value,FamilyName,HCLK2Freq_Value,HCLK3Freq_Value,HCLKFreq_Value,HCLKRFFreq_Value,HSE_VALUE,HSI48_VALUE,HSI_VALUE,I2C1Freq_Value,I2C3Freq_Value,LCDFreq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSE_Drive_Capability,LSE_Timout,LSI_VALUE,MCO1PinFreq_Value,MSIOscState,PLLM,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PLLSAI1N,PLLSAI1PoutputFreq_Value,PLLSAI1QoutputFreq_Value,PLLSAI1RoutputFreq_Value,PLLSourceVirtual,PREFETCH_ENABLE,PWRFreq_Value,RFWKPClockSelection,RFWKPFreq_Value,RNGCLockSelection,RNGFreq_Value,RTCClockSelection,RTCFreq_Value,SAI1Freq_Value,SMPS1Freq_Value,SMPSCLockSelectionVirtual,SMPSDivider,SMPSFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,USART1Freq_Value,USBFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOSAI1OutputFreq_Value +RCC.IPParameters=ADCFreq_Value,AHB2CLKDivider,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,APB3Freq_Value,Cortex2Freq_Value,CortexFreq_Value,EnableCSSLSE,EnbaleCSS,FCLK2Freq_Value,FCLKCortexFreq_Value,FamilyName,HCLK2Freq_Value,HCLK3Freq_Value,HCLKFreq_Value,HCLKRFFreq_Value,HSE_VALUE,HSI48_VALUE,HSI_VALUE,I2C1Freq_Value,I2C3Freq_Value,LCDFreq_Value,LPTIM1CLockSelection,LPTIM1Freq_Value,LPTIM2Freq_Value,LPUART1Freq_Value,LSCOPinFreq_Value,LSE_Drive_Capability,LSE_Timout,LSI_VALUE,MCO1PinFreq_Value,MSIOscState,PLLM,PLLPoutputFreq_Value,PLLQoutputFreq_Value,PLLRCLKFreq_Value,PLLSAI1N,PLLSAI1PoutputFreq_Value,PLLSAI1QoutputFreq_Value,PLLSAI1RoutputFreq_Value,PLLSourceVirtual,PREFETCH_ENABLE,PWRFreq_Value,RFWKPClockSelection,RFWKPFreq_Value,RNGCLockSelection,RNGFreq_Value,RTCClockSelection,RTCFreq_Value,SAI1Freq_Value,SMPS1Freq_Value,SMPSCLockSelectionVirtual,SMPSDivider,SMPSFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,USART1Freq_Value,USBFreq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,VCOSAI1OutputFreq_Value ProjectManager.AskForMigrate=true Mcu.Name=STM32WB55RGVx NVIC.SavedPendsvIrqHandlerGenerated=false diff --git a/firmware/targets/f4/stm32wb55xx_flash_cm4.ld b/firmware/targets/f4/stm32wb55xx_flash_cm4.ld index 07beda76..226505bf 100644 --- a/firmware/targets/f4/stm32wb55xx_flash_cm4.ld +++ b/firmware/targets/f4/stm32wb55xx_flash_cm4.ld @@ -55,7 +55,7 @@ _Min_Stack_Size = 0x1000; /* required amount of stack */ /* Specify the memory areas */ MEMORY { -FLASH (rx) : ORIGIN = 0x08008000, LENGTH = 480K +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 512K RAM1 (xrw) : ORIGIN = 0x20000004, LENGTH = 0x2FFFC RAM_SHARED (xrw) : ORIGIN = 0x20030000, LENGTH = 10K } diff --git a/firmware/targets/f4/target.mk b/firmware/targets/f4/target.mk index f5079283..510d7d40 100644 --- a/firmware/targets/f4/target.mk +++ b/firmware/targets/f4/target.mk @@ -64,6 +64,7 @@ C_SOURCES += \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_tim_ex.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_uart.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_uart_ex.c \ + $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_lptim.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_adc.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usb.c \ $(CUBE_DIR)/Middlewares/Third_Party/FreeRTOS/Source/croutine.c \