Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/flipperzero-firmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorあく <alleteam@gmail.com>2021-12-15 01:39:59 +0300
committerGitHub <noreply@github.com>2021-12-15 01:39:59 +0300
commit6579368053a0572d1fff38ca3a91ab209df1a1d2 (patch)
treefe32d41301876edee2ef3af6002b2d005b42dbc2 /firmware
parent965067b5bd7fb3fbb77d0459cc9ea10492168ad7 (diff)
[FL-1818] System setting and debug options. RTC HAL refactoring. (#902)
* FuriHal: RTC API refactoring. System Setting application. FuriCore: adjustable log levels. Minor code cleanup. * Storage: change logging levels for internal storage. * FuriCore: fix broken trace logging level
Diffstat (limited to 'firmware')
-rw-r--r--firmware/targets/f6/Inc/rtc.h52
-rw-r--r--firmware/targets/f6/Inc/stm32wbxx_hal_conf.h2
-rw-r--r--firmware/targets/f6/Src/rtc.c123
-rw-r--r--firmware/targets/f6/Src/stm32wbxx_it.c5
-rw-r--r--firmware/targets/f6/ble-glue/hw_if.h159
-rw-r--r--firmware/targets/f6/ble-glue/hw_timerserver.c893
-rw-r--r--firmware/targets/f6/furi-hal/furi-hal-bootloader.c8
-rw-r--r--firmware/targets/f6/furi-hal/furi-hal-clock.c9
-rw-r--r--firmware/targets/f6/furi-hal/furi-hal-interrupt.c3
-rw-r--r--firmware/targets/f6/furi-hal/furi-hal-rtc.c122
-rw-r--r--firmware/targets/f6/furi-hal/furi-hal.c10
-rw-r--r--firmware/targets/f6/target.mk4
-rw-r--r--firmware/targets/f7/Inc/rtc.h52
-rw-r--r--firmware/targets/f7/Inc/stm32wbxx_hal_conf.h2
-rw-r--r--firmware/targets/f7/Src/rtc.c123
-rw-r--r--firmware/targets/f7/Src/stm32wbxx_it.c5
-rw-r--r--firmware/targets/f7/ble-glue/hw_if.h159
-rw-r--r--firmware/targets/f7/ble-glue/hw_timerserver.c893
-rw-r--r--firmware/targets/f7/furi-hal/furi-hal-bootloader.c8
-rw-r--r--firmware/targets/f7/furi-hal/furi-hal-clock.c9
-rw-r--r--firmware/targets/f7/furi-hal/furi-hal-interrupt.c3
-rw-r--r--firmware/targets/f7/furi-hal/furi-hal-rtc.c122
-rw-r--r--firmware/targets/f7/furi-hal/furi-hal.c10
-rw-r--r--firmware/targets/f7/target.mk2
-rw-r--r--firmware/targets/furi-hal-include/furi-hal-bootloader.h18
-rw-r--r--firmware/targets/furi-hal-include/furi-hal-rtc.h52
-rw-r--r--firmware/targets/furi-hal-include/furi-hal.h1
27 files changed, 310 insertions, 2539 deletions
diff --git a/firmware/targets/f6/Inc/rtc.h b/firmware/targets/f6/Inc/rtc.h
deleted file mode 100644
index 6dd24df4..00000000
--- a/firmware/targets/f6/Inc/rtc.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- ******************************************************************************
- * @file rtc.h
- * @brief This file contains all the function prototypes for
- * the rtc.c file
- ******************************************************************************
- * @attention
- *
- * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * 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
- *
- ******************************************************************************
- */
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __RTC_H__
-#define __RTC_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "main.h"
-
-/* USER CODE BEGIN Includes */
-
-/* USER CODE END Includes */
-
-extern RTC_HandleTypeDef hrtc;
-
-/* USER CODE BEGIN Private defines */
-
-/* USER CODE END Private defines */
-
-void MX_RTC_Init(void);
-
-/* USER CODE BEGIN Prototypes */
-
-/* USER CODE END Prototypes */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __RTC_H__ */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/firmware/targets/f6/Inc/stm32wbxx_hal_conf.h b/firmware/targets/f6/Inc/stm32wbxx_hal_conf.h
index 4d5ad791..dc6a7ae4 100644
--- a/firmware/targets/f6/Inc/stm32wbxx_hal_conf.h
+++ b/firmware/targets/f6/Inc/stm32wbxx_hal_conf.h
@@ -48,7 +48,7 @@
#define HAL_PKA_MODULE_ENABLED
/*#define HAL_QSPI_MODULE_ENABLED */
#define HAL_RNG_MODULE_ENABLED
-#define HAL_RTC_MODULE_ENABLED
+/*#define HAL_RTC_MODULE_ENABLED */
/*#define HAL_SAI_MODULE_ENABLED */
/*#define HAL_SMBUS_MODULE_ENABLED */
/*#define HAL_SMARTCARD_MODULE_ENABLED */
diff --git a/firmware/targets/f6/Src/rtc.c b/firmware/targets/f6/Src/rtc.c
deleted file mode 100644
index 8487c1e0..00000000
--- a/firmware/targets/f6/Src/rtc.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/**
- ******************************************************************************
- * @file rtc.c
- * @brief This file provides code for the configuration
- * of the RTC instances.
- ******************************************************************************
- * @attention
- *
- * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * 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
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "rtc.h"
-
-/* USER CODE BEGIN 0 */
-
-/* USER CODE END 0 */
-
-RTC_HandleTypeDef hrtc;
-
-/* RTC init function */
-void MX_RTC_Init(void)
-{
- RTC_TimeTypeDef sTime = {0};
- RTC_DateTypeDef sDate = {0};
-
- /** Initialize RTC Only
- */
- hrtc.Instance = RTC;
- hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
- hrtc.Init.AsynchPrediv = 127;
- hrtc.Init.SynchPrediv = 255;
- hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
- hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
- hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
- hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
- if (HAL_RTC_Init(&hrtc) != HAL_OK)
- {
- Error_Handler();
- }
-
- /* USER CODE BEGIN Check_RTC_BKUP */
- return;
- /* USER CODE END Check_RTC_BKUP */
-
- /** Initialize RTC and set the Time and Date
- */
- sTime.Hours = 0x0;
- sTime.Minutes = 0x0;
- sTime.Seconds = 0x0;
- sTime.SubSeconds = 0x0;
- sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
- sTime.StoreOperation = RTC_STOREOPERATION_RESET;
- if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
- {
- Error_Handler();
- }
- sDate.WeekDay = RTC_WEEKDAY_MONDAY;
- sDate.Month = RTC_MONTH_JANUARY;
- sDate.Date = 0x1;
- sDate.Year = 0x0;
-
- if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
- {
- Error_Handler();
- }
-
-}
-
-void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle)
-{
-
- if(rtcHandle->Instance==RTC)
- {
- /* USER CODE BEGIN RTC_MspInit 0 */
-
- /* USER CODE END RTC_MspInit 0 */
- /* RTC clock enable */
- __HAL_RCC_RTC_ENABLE();
- __HAL_RCC_RTCAPB_CLK_ENABLE();
-
- /* RTC interrupt Init */
- HAL_NVIC_SetPriority(TAMP_STAMP_LSECSS_IRQn, 5, 0);
- HAL_NVIC_EnableIRQ(TAMP_STAMP_LSECSS_IRQn);
- /* USER CODE BEGIN RTC_MspInit 1 */
-
- /* USER CODE END RTC_MspInit 1 */
- }
-}
-
-void HAL_RTC_MspDeInit(RTC_HandleTypeDef* rtcHandle)
-{
-
- if(rtcHandle->Instance==RTC)
- {
- /* USER CODE BEGIN RTC_MspDeInit 0 */
-
- /* USER CODE END RTC_MspDeInit 0 */
- /* Peripheral clock disable */
- __HAL_RCC_RTC_DISABLE();
- __HAL_RCC_RTCAPB_CLK_DISABLE();
-
- /* RTC interrupt Deinit */
- HAL_NVIC_DisableIRQ(TAMP_STAMP_LSECSS_IRQn);
- /* USER CODE BEGIN RTC_MspDeInit 1 */
-
- /* USER CODE END RTC_MspDeInit 1 */
- }
-}
-
-/* USER CODE BEGIN 1 */
-
-/* USER CODE END 1 */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/firmware/targets/f6/Src/stm32wbxx_it.c b/firmware/targets/f6/Src/stm32wbxx_it.c
index 1051e074..d4f71267 100644
--- a/firmware/targets/f6/Src/stm32wbxx_it.c
+++ b/firmware/targets/f6/Src/stm32wbxx_it.c
@@ -6,7 +6,6 @@
extern usbd_device udev;
extern COMP_HandleTypeDef hcomp1;
-extern RTC_HandleTypeDef hrtc;
extern TIM_HandleTypeDef htim1;
extern TIM_HandleTypeDef htim2;
extern TIM_HandleTypeDef htim16;
@@ -40,10 +39,6 @@ void HSEM_IRQHandler(void) {
HAL_HSEM_IRQHandler();
}
-void RTC_WKUP_IRQHandler(void){
- HW_TS_RTC_Wakeup_Handler();
-}
-
void IPCC_C1_TX_IRQHandler(void){
HW_IPCC_Tx_Handler();
}
diff --git a/firmware/targets/f6/ble-glue/hw_if.h b/firmware/targets/f6/ble-glue/hw_if.h
index 271a222a..f9dc0a6d 100644
--- a/firmware/targets/f6/ble-glue/hw_if.h
+++ b/firmware/targets/f6/ble-glue/hw_if.h
@@ -82,165 +82,6 @@ extern "C" {
void HW_UART_Interrupt_Handler(hw_uart_id_t hw_uart_id);
void HW_UART_DMA_Interrupt_Handler(hw_uart_id_t hw_uart_id);
- /******************************************************************************
- * HW TimerServer
- ******************************************************************************/
- /* Exported types ------------------------------------------------------------*/
- /**
- * This setting is used when standby mode is supported.
- * hw_ts_InitMode_Limited should be used when the device restarts from Standby Mode. In that case, the Timer Server does
- * not re-initialized its context. Only the Hardware register which content has been lost is reconfigured
- * Otherwise, hw_ts_InitMode_Full should be requested (Start from Power ON) and everything is re-initialized.
- */
- typedef enum
- {
- hw_ts_InitMode_Full,
- hw_ts_InitMode_Limited,
- } HW_TS_InitMode_t;
-
- /**
- * When a Timer is created as a SingleShot timer, it is not automatically restarted when the timeout occurs. However,
- * the timer is kept reserved in the list and could be restarted at anytime with HW_TS_Start()
- *
- * When a Timer is created as a Repeated timer, it is automatically restarted when the timeout occurs.
- */
- typedef enum
- {
- hw_ts_SingleShot,
- hw_ts_Repeated
- } HW_TS_Mode_t;
-
- /**
- * hw_ts_Successful is returned when a Timer has been successfully created with HW_TS_Create(). Otherwise, hw_ts_Failed
- * is returned. When hw_ts_Failed is returned, that means there are not enough free slots in the list to create a
- * Timer. In that case, CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER should be increased
- */
- typedef enum
- {
- hw_ts_Successful,
- hw_ts_Failed,
- }HW_TS_ReturnStatus_t;
-
- typedef void (*HW_TS_pTimerCb_t)(void);
-
- /**
- * @brief Initialize the timer server
- * This API shall be called by the application before any timer is requested to the timer server. It
- * configures the RTC module to be connected to the LSI input clock.
- *
- * @param TimerInitMode: When the device restarts from Standby, it should request hw_ts_InitMode_Limited so that the
- * Timer context is not re-initialized. Otherwise, hw_ts_InitMode_Full should be requested
- * @param hrtc: RTC Handle
- * @retval None
- */
- void HW_TS_Init(HW_TS_InitMode_t TimerInitMode, RTC_HandleTypeDef *hrtc);
-
- /**
- * @brief Interface to create a virtual timer
- * The user shall call this API to create a timer. Once created, the timer is reserved to the module until it
- * has been deleted. When creating a timer, the user shall specify the mode (single shot or repeated), the
- * callback to be notified when the timer expires and a module ID to identify in the timer interrupt handler
- * which module is concerned. In return, the user gets a timer ID to handle it.
- *
- * @param TimerProcessID: This is an identifier provided by the user and returned in the callback to allow
- * identification of the requester
- * @param pTimerId: Timer Id returned to the user to request operation (start, stop, delete)
- * @param TimerMode: Mode of the virtual timer (Single shot or repeated)
- * @param pTimerCallBack: Callback when the virtual timer expires
- * @retval HW_TS_ReturnStatus_t: Return whether the creation is sucessfull or not
- */
- HW_TS_ReturnStatus_t HW_TS_Create(uint32_t TimerProcessID, uint8_t *pTimerId, HW_TS_Mode_t TimerMode, HW_TS_pTimerCb_t pTimerCallBack);
-
- /**
- * @brief Stop a virtual timer
- * This API may be used to stop a running timer. A timer which is stopped is move to the pending state.
- * A pending timer may be restarted at any time with a different timeout value but the mode cannot be changed.
- * Nothing is done when it is called to stop a timer which has been already stopped
- *
- * @param TimerID: Id of the timer to stop
- * @retval None
- */
- void HW_TS_Stop(uint8_t TimerID);
-
- /**
- * @brief Start a virtual timer
- * This API shall be used to start a timer. The timeout value is specified and may be different each time.
- * When the timer is in the single shot mode, it will move to the pending state when it expires. The user may
- * restart it at any time with a different timeout value. When the timer is in the repeated mode, it always
- * stay in the running state. When the timer expires, it will be restarted with the same timeout value.
- * This API shall not be called on a running timer.
- *
- * @param TimerID: The ID Id of the timer to start
- * @param timeout_ticks: Number of ticks of the virtual timer (Maximum value is (0xFFFFFFFF-0xFFFF = 0xFFFF0000)
- * @retval None
- */
- void HW_TS_Start(uint8_t TimerID, uint32_t timeout_ticks);
-
- /**
- * @brief Delete a virtual timer from the list
- * This API should be used when a timer is not needed anymore by the user. A deleted timer is removed from
- * the timer list managed by the timer server. It cannot be restarted again. The user has to go with the
- * creation of a new timer if required and may get a different timer id
- *
- * @param TimerID: The ID of the timer to remove from the list
- * @retval None
- */
- void HW_TS_Delete(uint8_t TimerID);
-
- /**
- * @brief Schedule the timer list on the timer interrupt handler
- * This interrupt handler shall be called by the application in the RTC interrupt handler. This handler takes
- * care of clearing all status flag required in the RTC and EXTI peripherals
- *
- * @param None
- * @retval None
- */
- void HW_TS_RTC_Wakeup_Handler(void);
-
- /**
- * @brief Return the number of ticks to count before the interrupt
- * This API returns the number of ticks left to be counted before an interrupt is generated by the
- * Timer Server. This API may be used by the application for power management optimization. When the system
- * enters low power mode, the mode selection is a tradeoff between the wakeup time where the CPU is running
- * and the time while the CPU will be kept in low power mode before next wakeup. The deeper is the
- * low power mode used, the longer is the wakeup time. The low power mode management considering wakeup time
- * versus time in low power mode is implementation specific
- * When the timer is disabled (No timer in the list), it returns 0xFFFF
- *
- * @param None
- * @retval The number of ticks left to count
- */
- uint16_t HW_TS_RTC_ReadLeftTicksToCount(void);
-
- /**
- * @brief Notify the application that a registered timer has expired
- * This API shall be implemented by the user application.
- * This API notifies the application that a timer expires. This API is running in the RTC Wakeup interrupt
- * context. The application may implement an Operating System to change the context priority where the timer
- * callback may be handled. This API provides the module ID to identify which module is concerned and to allow
- * sending the information to the correct task
- *
- * @param TimerProcessID: The TimerProcessId associated with the timer when it has been created
- * @param TimerID: The TimerID of the expired timer
- * @param pTimerCallBack: The Callback associated with the timer when it has been created
- * @retval None
- */
- void HW_TS_RTC_Int_AppNot(uint32_t TimerProcessID, uint8_t TimerID, HW_TS_pTimerCb_t pTimerCallBack);
-
- /**
- * @brief Notify the application that the wakeupcounter has been updated
- * This API should be implemented by the user application
- * This API notifies the application that the counter has been updated. This is expected to be used along
- * with the HW_TS_RTC_ReadLeftTicksToCount () API. It could be that the counter has been updated since the
- * last call of HW_TS_RTC_ReadLeftTicksToCount () and before entering low power mode. This notification
- * provides a way to the application to solve that race condition to reevaluate the counter value before
- * entering low power mode
- *
- * @param None
- * @retval None
- */
- void HW_TS_RTC_CountUpdated_AppNot(void);
-
#ifdef __cplusplus
}
#endif
diff --git a/firmware/targets/f6/ble-glue/hw_timerserver.c b/firmware/targets/f6/ble-glue/hw_timerserver.c
deleted file mode 100644
index e0e4fcb5..00000000
--- a/firmware/targets/f6/ble-glue/hw_timerserver.c
+++ /dev/null
@@ -1,893 +0,0 @@
-/**
- ******************************************************************************
- * File Name : hw_timerserver.c
- * Description : Hardware timerserver source file for STM32WPAN Middleware.
- *
- ******************************************************************************
- * @attention
- *
- * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * 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
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "app_common.h"
-#include "hw_conf.h"
-
-/* Private typedef -----------------------------------------------------------*/
-typedef enum
-{
- TimerID_Free,
- TimerID_Created,
- TimerID_Running
-}TimerIDStatus_t;
-
-typedef enum
-{
- SSR_Read_Requested,
- SSR_Read_Not_Requested
-}RequestReadSSR_t;
-
-typedef enum
-{
- WakeupTimerValue_Overpassed,
- WakeupTimerValue_LargeEnough
-}WakeupTimerLimitation_Status_t;
-
-typedef struct
-{
- HW_TS_pTimerCb_t pTimerCallBack;
- uint32_t CounterInit;
- uint32_t CountLeft;
- TimerIDStatus_t TimerIDStatus;
- HW_TS_Mode_t TimerMode;
- uint32_t TimerProcessID;
- uint8_t PreviousID;
- uint8_t NextID;
-}TimerContext_t;
-
-/* Private defines -----------------------------------------------------------*/
-#define SSR_FORBIDDEN_VALUE 0xFFFFFFFF
-#define TIMER_LIST_EMPTY 0xFFFF
-
-/* Private macros ------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-
-/**
- * START of Section TIMERSERVER_CONTEXT
- */
-
-PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile TimerContext_t aTimerContext[CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER];
-PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile uint8_t CurrentRunningTimerID;
-PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile uint8_t PreviousRunningTimerID;
-PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile uint32_t SSRValueOnLastSetup;
-PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile WakeupTimerLimitation_Status_t WakeupTimerLimitation;
-
-/**
- * END of Section TIMERSERVER_CONTEXT
- */
-
-static RTC_HandleTypeDef *phrtc; /**< RTC handle */
-static uint8_t WakeupTimerDivider;
-static uint8_t AsynchPrescalerUserConfig;
-static uint16_t SynchPrescalerUserConfig;
-static volatile uint16_t MaxWakeupTimerSetup;
-
-/* Global variables ----------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-static void RestartWakeupCounter(uint16_t Value);
-static uint16_t ReturnTimeElapsed(void);
-static void RescheduleTimerList(void);
-static void UnlinkTimer(uint8_t TimerID, RequestReadSSR_t RequestReadSSR);
-static void LinkTimerBefore(uint8_t TimerID, uint8_t RefTimerID);
-static void LinkTimerAfter(uint8_t TimerID, uint8_t RefTimerID);
-static uint16_t linkTimer(uint8_t TimerID);
-static uint32_t ReadRtcSsrValue(void);
-
-__weak void HW_TS_RTC_CountUpdated_AppNot(void);
-
-/* Functions Definition ------------------------------------------------------*/
-
-/**
- * @brief Read the RTC_SSR value
- * As described in the reference manual, the RTC_SSR shall be read twice to ensure
- * reliability of the value
- * @param None
- * @retval SSR value read
- */
-static uint32_t ReadRtcSsrValue(void)
-{
- uint32_t first_read;
- uint32_t second_read;
-
- first_read = (uint32_t)(READ_BIT(RTC->SSR, RTC_SSR_SS));
-
- second_read = (uint32_t)(READ_BIT(RTC->SSR, RTC_SSR_SS));
-
- while(first_read != second_read)
- {
- first_read = second_read;
-
- second_read = (uint32_t)(READ_BIT(RTC->SSR, RTC_SSR_SS));
- }
-
- return second_read;
-}
-
-/**
- * @brief Insert a Timer in the list after the Timer ID specified
- * @param TimerID: The ID of the Timer
- * @param RefTimerID: The ID of the Timer to be linked after
- * @retval None
- */
-static void LinkTimerAfter(uint8_t TimerID, uint8_t RefTimerID)
-{
- uint8_t next_id;
-
- next_id = aTimerContext[RefTimerID].NextID;
-
- if(next_id != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
- {
- aTimerContext[next_id].PreviousID = TimerID;
- }
- aTimerContext[TimerID].NextID = next_id;
- aTimerContext[TimerID].PreviousID = RefTimerID ;
- aTimerContext[RefTimerID].NextID = TimerID;
-
- return;
-}
-
-/**
- * @brief Insert a Timer in the list before the ID specified
- * @param TimerID: The ID of the Timer
- * @param RefTimerID: The ID of the Timer to be linked before
- * @retval None
- */
-static void LinkTimerBefore(uint8_t TimerID, uint8_t RefTimerID)
-{
- uint8_t previous_id;
-
- if(RefTimerID != CurrentRunningTimerID)
- {
- previous_id = aTimerContext[RefTimerID].PreviousID;
-
- aTimerContext[previous_id].NextID = TimerID;
- aTimerContext[TimerID].NextID = RefTimerID;
- aTimerContext[TimerID].PreviousID = previous_id ;
- aTimerContext[RefTimerID].PreviousID = TimerID;
- }
- else
- {
- aTimerContext[TimerID].NextID = RefTimerID;
- aTimerContext[RefTimerID].PreviousID = TimerID;
- }
-
- return;
-}
-
-/**
- * @brief Insert a Timer in the list
- * @param TimerID: The ID of the Timer
- * @retval None
- */
-static uint16_t linkTimer(uint8_t TimerID)
-{
- uint32_t time_left;
- uint16_t time_elapsed;
- uint8_t timer_id_lookup;
- uint8_t next_id;
-
- if(CurrentRunningTimerID == CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
- {
- /**
- * No timer in the list
- */
- PreviousRunningTimerID = CurrentRunningTimerID;
- CurrentRunningTimerID = TimerID;
- aTimerContext[TimerID].NextID = CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER;
-
- SSRValueOnLastSetup = SSR_FORBIDDEN_VALUE;
- time_elapsed = 0;
- }
- else
- {
- time_elapsed = ReturnTimeElapsed();
-
- /**
- * update count of the timer to be linked
- */
- aTimerContext[TimerID].CountLeft += time_elapsed;
- time_left = aTimerContext[TimerID].CountLeft;
-
- /**
- * Search for index where the new timer shall be linked
- */
- if(aTimerContext[CurrentRunningTimerID].CountLeft <= time_left)
- {
- /**
- * Search for the ID after the first one
- */
- timer_id_lookup = CurrentRunningTimerID;
- next_id = aTimerContext[timer_id_lookup].NextID;
- while((next_id != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) && (aTimerContext[next_id].CountLeft <= time_left))
- {
- timer_id_lookup = aTimerContext[timer_id_lookup].NextID;
- next_id = aTimerContext[timer_id_lookup].NextID;
- }
-
- /**
- * Link after the ID
- */
- LinkTimerAfter(TimerID, timer_id_lookup);
- }
- else
- {
- /**
- * Link before the first ID
- */
- LinkTimerBefore(TimerID, CurrentRunningTimerID);
- PreviousRunningTimerID = CurrentRunningTimerID;
- CurrentRunningTimerID = TimerID;
- }
- }
-
- return time_elapsed;
-}
-
-/**
- * @brief Remove a Timer from the list
- * @param TimerID: The ID of the Timer
- * @param RequestReadSSR: Request to read the SSR register or not
- * @retval None
- */
-static void UnlinkTimer(uint8_t TimerID, RequestReadSSR_t RequestReadSSR)
-{
- uint8_t previous_id;
- uint8_t next_id;
-
- if(TimerID == CurrentRunningTimerID)
- {
- PreviousRunningTimerID = CurrentRunningTimerID;
- CurrentRunningTimerID = aTimerContext[TimerID].NextID;
- }
- else
- {
- previous_id = aTimerContext[TimerID].PreviousID;
- next_id = aTimerContext[TimerID].NextID;
-
- aTimerContext[previous_id].NextID = aTimerContext[TimerID].NextID;
- if(next_id != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
- {
- aTimerContext[next_id].PreviousID = aTimerContext[TimerID].PreviousID;
- }
- }
-
- /**
- * Timer is out of the list
- */
- aTimerContext[TimerID].TimerIDStatus = TimerID_Created;
-
- if((CurrentRunningTimerID == CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) && (RequestReadSSR == SSR_Read_Requested))
- {
- SSRValueOnLastSetup = SSR_FORBIDDEN_VALUE;
- }
-
- return;
-}
-
-/**
- * @brief Return the number of ticks counted by the wakeuptimer since it has been started
- * @note The API is reading the SSR register to get how many ticks have been counted
- * since the time the timer has been started
- * @param None
- * @retval Time expired in Ticks
- */
-static uint16_t ReturnTimeElapsed(void)
-{
- uint32_t return_value;
- uint32_t wrap_counter;
-
- if(SSRValueOnLastSetup != SSR_FORBIDDEN_VALUE)
- {
- return_value = ReadRtcSsrValue(); /**< Read SSR register first */
-
- if (SSRValueOnLastSetup >= return_value)
- {
- return_value = SSRValueOnLastSetup - return_value;
- }
- else
- {
- wrap_counter = SynchPrescalerUserConfig - return_value;
- return_value = SSRValueOnLastSetup + wrap_counter;
- }
-
- /**
- * At this stage, ReturnValue holds the number of ticks counted by SSR
- * Need to translate in number of ticks counted by the Wakeuptimer
- */
- return_value = return_value*AsynchPrescalerUserConfig;
- return_value = return_value >> WakeupTimerDivider;
- }
- else
- {
- return_value = 0;
- }
-
- return (uint16_t)return_value;
-}
-
-/**
- * @brief Set the wakeup counter
- * @note The API is writing the counter value so that the value is decreased by one to cope with the fact
- * the interrupt is generated with 1 extra clock cycle (See RefManuel)
- * It assumes all condition are met to be allowed to write the wakeup counter
- * @param Value: Value to be written in the counter
- * @retval None
- */
-static void RestartWakeupCounter(uint16_t Value)
-{
- /**
- * The wakeuptimer has been disabled in the calling function to reduce the time to poll the WUTWF
- * FLAG when the new value will have to be written
- * __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc);
- */
-
- if(Value == 0)
- {
- SSRValueOnLastSetup = ReadRtcSsrValue();
-
- /**
- * Simulate that the Timer expired
- */
- HAL_NVIC_SetPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID);
- }
- else
- {
- if((Value > 1) ||(WakeupTimerDivider != 1))
- {
- Value -= 1;
- }
-
- while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == RESET);
-
- /**
- * make sure to clear the flags after checking the WUTWF.
- * It takes 2 RTCCLK between the time the WUTE bit is disabled and the
- * time the timer is disabled. The WUTWF bit somehow guarantee the system is stable
- * Otherwise, when the timer is periodic with 1 Tick, it may generate an extra interrupt in between
- * due to the autoreload feature
- */
- __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(phrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */
- __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */
- HAL_NVIC_ClearPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Clear pending bit in NVIC */
-
- MODIFY_REG(RTC->WUTR, RTC_WUTR_WUT, Value);
-
- /**
- * Update the value here after the WUTWF polling that may take some time
- */
- SSRValueOnLastSetup = ReadRtcSsrValue();
-
- __HAL_RTC_WAKEUPTIMER_ENABLE(phrtc); /**< Enable the Wakeup Timer */
-
- HW_TS_RTC_CountUpdated_AppNot();
- }
-
- return ;
-}
-
-/**
- * @brief Reschedule the list of timer
- * @note 1) Update the count left for each timer in the list
- * 2) Setup the wakeuptimer
- * @param None
- * @retval None
- */
-static void RescheduleTimerList(void)
-{
- uint8_t localTimerID;
- uint32_t timecountleft;
- uint16_t wakeup_timer_value;
- uint16_t time_elapsed;
-
- /**
- * The wakeuptimer is disabled now to reduce the time to poll the WUTWF
- * FLAG when the new value will have to be written
- */
- if((READ_BIT(RTC->CR, RTC_CR_WUTE) == (RTC_CR_WUTE)) == SET)
- {
- /**
- * Wait for the flag to be back to 0 when the wakeup timer is enabled
- */
- while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == SET);
- }
- __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc); /**< Disable the Wakeup Timer */
-
- localTimerID = CurrentRunningTimerID;
-
- /**
- * Calculate what will be the value to write in the wakeuptimer
- */
- timecountleft = aTimerContext[localTimerID].CountLeft;
-
- /**
- * Read how much has been counted
- */
- time_elapsed = ReturnTimeElapsed();
-
- if(timecountleft < time_elapsed )
- {
- /**
- * There is no tick left to count
- */
- wakeup_timer_value = 0;
- WakeupTimerLimitation = WakeupTimerValue_LargeEnough;
- }
- else
- {
- if(timecountleft > (time_elapsed + MaxWakeupTimerSetup))
- {
- /**
- * The number of tick left is greater than the Wakeuptimer maximum value
- */
- wakeup_timer_value = MaxWakeupTimerSetup;
-
- WakeupTimerLimitation = WakeupTimerValue_Overpassed;
- }
- else
- {
- wakeup_timer_value = timecountleft - time_elapsed;
- WakeupTimerLimitation = WakeupTimerValue_LargeEnough;
- }
-
- }
-
- /**
- * update ticks left to be counted for each timer
- */
- while(localTimerID != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
- {
- if (aTimerContext[localTimerID].CountLeft < time_elapsed)
- {
- aTimerContext[localTimerID].CountLeft = 0;
- }
- else
- {
- aTimerContext[localTimerID].CountLeft -= time_elapsed;
- }
- localTimerID = aTimerContext[localTimerID].NextID;
- }
-
- /**
- * Write next count
- */
- RestartWakeupCounter(wakeup_timer_value);
-
- return ;
-}
-
-/* Public functions ----------------------------------------------------------*/
-
-/**
- * For all public interface except that may need write access to the RTC, the RTC
- * shall be unlock at the beginning and locked at the output
- * In order to ease maintainability, the unlock is done at the top and the lock at then end
- * in case some new implementation is coming in the future
- */
-
-void HW_TS_RTC_Wakeup_Handler(void)
-{
- HW_TS_pTimerCb_t ptimer_callback;
- uint32_t timer_process_id;
- uint8_t local_current_running_timer_id;
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- uint32_t primask_bit;
-#endif
-
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
- __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
-#endif
-
-/* Disable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc );
-
- /**
- * Disable the Wakeup Timer
- * This may speed up a bit the processing to wait the timer to be disabled
- * The timer is still counting 2 RTCCLK
- */
- __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc);
-
- local_current_running_timer_id = CurrentRunningTimerID;
-
- if(aTimerContext[local_current_running_timer_id].TimerIDStatus == TimerID_Running)
- {
- ptimer_callback = aTimerContext[local_current_running_timer_id].pTimerCallBack;
- timer_process_id = aTimerContext[local_current_running_timer_id].TimerProcessID;
-
- /**
- * It should be good to check whether the TimeElapsed is greater or not than the tick left to be counted
- * However, due to the inaccuracy of the reading of the time elapsed, it may return there is 1 tick
- * to be left whereas the count is over
- * A more secure implementation has been done with a flag to state whereas the full count has been written
- * in the wakeuptimer or not
- */
- if(WakeupTimerLimitation != WakeupTimerValue_Overpassed)
- {
- if(aTimerContext[local_current_running_timer_id].TimerMode == hw_ts_Repeated)
- {
- UnlinkTimer(local_current_running_timer_id, SSR_Read_Not_Requested);
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
-#endif
- HW_TS_Start(local_current_running_timer_id, aTimerContext[local_current_running_timer_id].CounterInit);
-
- /* Disable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc );
- }
- else
- {
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
-#endif
- HW_TS_Stop(local_current_running_timer_id);
-
- /* Disable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc );
- }
-
- HW_TS_RTC_Int_AppNot(timer_process_id, local_current_running_timer_id, ptimer_callback);
- }
- else
- {
- RescheduleTimerList();
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
-#endif
- }
- }
- else
- {
- /**
- * We should never end up in this case
- * However, if due to any bug in the timer server this is the case, the mistake may not impact the user.
- * We could just clean the interrupt flag and get out from this unexpected interrupt
- */
- while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == RESET);
-
- /**
- * make sure to clear the flags after checking the WUTWF.
- * It takes 2 RTCCLK between the time the WUTE bit is disabled and the
- * time the timer is disabled. The WUTWF bit somehow guarantee the system is stable
- * Otherwise, when the timer is periodic with 1 Tick, it may generate an extra interrupt in between
- * due to the autoreload feature
- */
- __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(phrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */
- __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */
-
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
-#endif
- }
-
- /* Enable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_ENABLE( phrtc );
-
- return;
-}
-
-void HW_TS_Init(HW_TS_InitMode_t TimerInitMode, RTC_HandleTypeDef *hrtc)
-{
- uint8_t loop;
- uint32_t localmaxwakeuptimersetup;
-
- /**
- * Get RTC handler
- */
- phrtc = hrtc;
-
- /* Disable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc );
-
- SET_BIT(RTC->CR, RTC_CR_BYPSHAD);
-
- /**
- * Readout the user config
- */
- WakeupTimerDivider = (4 - ((uint32_t)(READ_BIT(RTC->CR, RTC_CR_WUCKSEL))));
-
- AsynchPrescalerUserConfig = (uint8_t)(READ_BIT(RTC->PRER, RTC_PRER_PREDIV_A) >> (uint32_t)POSITION_VAL(RTC_PRER_PREDIV_A)) + 1;
-
- SynchPrescalerUserConfig = (uint16_t)(READ_BIT(RTC->PRER, RTC_PRER_PREDIV_S)) + 1;
-
- /**
- * Margin is taken to avoid wrong calculation when the wrap around is there and some
- * application interrupts may have delayed the reading
- */
- localmaxwakeuptimersetup = ((((SynchPrescalerUserConfig - 1)*AsynchPrescalerUserConfig) - CFG_HW_TS_RTC_HANDLER_MAX_DELAY) >> WakeupTimerDivider);
-
- if(localmaxwakeuptimersetup >= 0xFFFF)
- {
- MaxWakeupTimerSetup = 0xFFFF;
- }
- else
- {
- MaxWakeupTimerSetup = (uint16_t)localmaxwakeuptimersetup;
- }
-
- /**
- * Configure EXTI module
- */
- LL_EXTI_EnableRisingTrig_0_31(RTC_EXTI_LINE_WAKEUPTIMER_EVENT);
- LL_EXTI_EnableIT_0_31(RTC_EXTI_LINE_WAKEUPTIMER_EVENT);
-
- if(TimerInitMode == hw_ts_InitMode_Full)
- {
- WakeupTimerLimitation = WakeupTimerValue_LargeEnough;
- SSRValueOnLastSetup = SSR_FORBIDDEN_VALUE;
-
- /**
- * Initialize the timer server
- */
- for(loop = 0; loop < CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER; loop++)
- {
- aTimerContext[loop].TimerIDStatus = TimerID_Free;
- }
-
- CurrentRunningTimerID = CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER; /**< Set ID to non valid value */
-
- __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc); /**< Disable the Wakeup Timer */
- __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(phrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */
- __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */
- HAL_NVIC_ClearPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Clear pending bit in NVIC */
- __HAL_RTC_WAKEUPTIMER_ENABLE_IT(phrtc, RTC_IT_WUT); /**< Enable interrupt in RTC module */
- }
- else
- {
- if(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTF) != RESET)
- {
- /**
- * Simulate that the Timer expired
- */
- HAL_NVIC_SetPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID);
- }
- }
-
- /* Enable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_ENABLE( phrtc );
-
- HAL_NVIC_SetPriority(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID, CFG_HW_TS_NVIC_RTC_WAKEUP_IT_PREEMPTPRIO, CFG_HW_TS_NVIC_RTC_WAKEUP_IT_SUBPRIO); /**< Set NVIC priority */
- HAL_NVIC_EnableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Enable NVIC */
-
- return;
-}
-
-HW_TS_ReturnStatus_t HW_TS_Create(uint32_t TimerProcessID, uint8_t *pTimerId, HW_TS_Mode_t TimerMode, HW_TS_pTimerCb_t pftimeout_handler)
-{
- HW_TS_ReturnStatus_t localreturnstatus;
- uint8_t loop = 0;
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- uint32_t primask_bit;
-#endif
-
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
- __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
-#endif
-
- while((loop < CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) && (aTimerContext[loop].TimerIDStatus != TimerID_Free))
- {
- loop++;
- }
-
- if(loop != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
- {
- aTimerContext[loop].TimerIDStatus = TimerID_Created;
-
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
-#endif
-
- aTimerContext[loop].TimerProcessID = TimerProcessID;
- aTimerContext[loop].TimerMode = TimerMode;
- aTimerContext[loop].pTimerCallBack = pftimeout_handler;
- *pTimerId = loop;
-
- localreturnstatus = hw_ts_Successful;
- }
- else
- {
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
-#endif
-
- localreturnstatus = hw_ts_Failed;
- }
-
- return(localreturnstatus);
-}
-
-void HW_TS_Delete(uint8_t timer_id)
-{
- HW_TS_Stop(timer_id);
-
- aTimerContext[timer_id].TimerIDStatus = TimerID_Free; /**< release ID */
-
- return;
-}
-
-void HW_TS_Stop(uint8_t timer_id)
-{
- uint8_t localcurrentrunningtimerid;
-
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- uint32_t primask_bit;
-#endif
-
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
- __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
-#endif
-
- HAL_NVIC_DisableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Disable NVIC */
-
- /* Disable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc );
-
- if(aTimerContext[timer_id].TimerIDStatus == TimerID_Running)
- {
- UnlinkTimer(timer_id, SSR_Read_Requested);
- localcurrentrunningtimerid = CurrentRunningTimerID;
-
- if(localcurrentrunningtimerid == CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
- {
- /**
- * List is empty
- */
-
- /**
- * Disable the timer
- */
- if((READ_BIT(RTC->CR, RTC_CR_WUTE) == (RTC_CR_WUTE)) == SET)
- {
- /**
- * Wait for the flag to be back to 0 when the wakeup timer is enabled
- */
- while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == SET);
- }
- __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc); /**< Disable the Wakeup Timer */
-
- while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == RESET);
-
- /**
- * make sure to clear the flags after checking the WUTWF.
- * It takes 2 RTCCLK between the time the WUTE bit is disabled and the
- * time the timer is disabled. The WUTWF bit somehow guarantee the system is stable
- * Otherwise, when the timer is periodic with 1 Tick, it may generate an extra interrupt in between
- * due to the autoreload feature
- */
- __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(phrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */
- __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */
- HAL_NVIC_ClearPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Clear pending bit in NVIC */
- }
- else if(PreviousRunningTimerID != localcurrentrunningtimerid)
- {
- RescheduleTimerList();
- }
- }
-
- /* Enable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_ENABLE( phrtc );
-
- HAL_NVIC_EnableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Enable NVIC */
-
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
-#endif
-
- return;
-}
-
-void HW_TS_Start(uint8_t timer_id, uint32_t timeout_ticks)
-{
- uint16_t time_elapsed;
- uint8_t localcurrentrunningtimerid;
-
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- uint32_t primask_bit;
-#endif
-
- if(aTimerContext[timer_id].TimerIDStatus == TimerID_Running)
- {
- HW_TS_Stop( timer_id );
- }
-
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
- __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
-#endif
-
- HAL_NVIC_DisableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Disable NVIC */
-
- /* Disable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc );
-
- aTimerContext[timer_id].TimerIDStatus = TimerID_Running;
-
- aTimerContext[timer_id].CountLeft = timeout_ticks;
- aTimerContext[timer_id].CounterInit = timeout_ticks;
-
- time_elapsed = linkTimer(timer_id);
-
- localcurrentrunningtimerid = CurrentRunningTimerID;
-
- if(PreviousRunningTimerID != localcurrentrunningtimerid)
- {
- RescheduleTimerList();
- }
- else
- {
- aTimerContext[timer_id].CountLeft -= time_elapsed;
- }
-
- /* Enable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_ENABLE( phrtc );
-
- HAL_NVIC_EnableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Enable NVIC */
-
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
-#endif
-
- return;
-}
-
-uint16_t HW_TS_RTC_ReadLeftTicksToCount(void)
-{
- uint32_t primask_bit;
- uint16_t return_value, auro_reload_value, elapsed_time_value;
-
- primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
- __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
-
- if((READ_BIT(RTC->CR, RTC_CR_WUTE) == (RTC_CR_WUTE)) == SET)
- {
- auro_reload_value = (uint32_t)(READ_BIT(RTC->WUTR, RTC_WUTR_WUT));
-
- elapsed_time_value = ReturnTimeElapsed();
-
- if(auro_reload_value > elapsed_time_value)
- {
- return_value = auro_reload_value - elapsed_time_value;
- }
- else
- {
- return_value = 0;
- }
- }
- else
- {
- return_value = TIMER_LIST_EMPTY;
- }
-
- __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
-
- return (return_value);
-}
-
-__weak void HW_TS_RTC_Int_AppNot(uint32_t TimerProcessID, uint8_t TimerID, HW_TS_pTimerCb_t pTimerCallBack)
-{
- pTimerCallBack();
-
- return;
-}
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/firmware/targets/f6/furi-hal/furi-hal-bootloader.c b/firmware/targets/f6/furi-hal/furi-hal-bootloader.c
index e8ea913e..b5e7cb5c 100644
--- a/firmware/targets/f6/furi-hal/furi-hal-bootloader.c
+++ b/firmware/targets/f6/furi-hal/furi-hal-bootloader.c
@@ -23,11 +23,3 @@ void furi_hal_bootloader_set_mode(FuriHalBootloaderMode mode) {
LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_DFU);
}
}
-
-void furi_hal_bootloader_set_flags(FuriHalBootloaderFlag flags) {
- LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR2, flags);
-}
-
-FuriHalBootloaderFlag furi_hal_bootloader_get_flags() {
- return LL_RTC_BAK_GetRegister(RTC, LL_RTC_BKP_DR2);
-} \ No newline at end of file
diff --git a/firmware/targets/f6/furi-hal/furi-hal-clock.c b/firmware/targets/f6/furi-hal/furi-hal-clock.c
index 7a124049..ddbeaa0b 100644
--- a/firmware/targets/f6/furi-hal/furi-hal-clock.c
+++ b/firmware/targets/f6/furi-hal/furi-hal-clock.c
@@ -77,14 +77,6 @@ void furi_hal_clock_init() {
Error_Handler();
}
- if(LL_RCC_GetRTCClockSource() != LL_RCC_RTC_CLKSOURCE_LSE) {
- LL_RCC_ForceBackupDomainReset();
- LL_RCC_ReleaseBackupDomainReset();
- LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE);
- }
-
- LL_RCC_EnableRTC();
-
LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK2);
LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_PCLK1);
LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSOURCE_PLLSAI1);
@@ -118,7 +110,6 @@ void furi_hal_clock_init() {
LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_AES2);
// APB1
- LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB);
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPUART1);
diff --git a/firmware/targets/f6/furi-hal/furi-hal-interrupt.c b/firmware/targets/f6/furi-hal/furi-hal-interrupt.c
index 2685edab..4ff2bc7b 100644
--- a/firmware/targets/f6/furi-hal/furi-hal-interrupt.c
+++ b/firmware/targets/f6/furi-hal/furi-hal-interrupt.c
@@ -158,7 +158,6 @@ void DMA2_Channel8_IRQHandler(void) {
if (furi_hal_dma_channel_isr[1][7]) furi_hal_dma_channel_isr[1][7]();
}
-
void TAMP_STAMP_LSECSS_IRQHandler(void) {
if (LL_RCC_IsActiveFlag_LSECSS()) {
LL_RCC_ClearFlag_LSECSS();
@@ -174,7 +173,6 @@ void TAMP_STAMP_LSECSS_IRQHandler(void) {
void RCC_IRQHandler(void) {
}
-
void NMI_Handler(void) {
if (LL_RCC_IsActiveFlag_HSECSS()) {
LL_RCC_ClearFlag_HSECSS();
@@ -206,5 +204,4 @@ void UsageFault_Handler(void) {
}
void DebugMon_Handler(void) {
-
}
diff --git a/firmware/targets/f6/furi-hal/furi-hal-rtc.c b/firmware/targets/f6/furi-hal/furi-hal-rtc.c
new file mode 100644
index 00000000..13bb17cb
--- /dev/null
+++ b/firmware/targets/f6/furi-hal/furi-hal-rtc.c
@@ -0,0 +1,122 @@
+#include <furi-hal-rtc.h>
+#include <stm32wbxx_ll_rcc.h>
+#include <stm32wbxx_ll_rtc.h>
+
+#include <furi.h>
+
+#define TAG "FuriHalRtc"
+
+#define FURI_HAL_RTC_BOOT_FLAGS_REG LL_RTC_BKP_DR0
+#define FURI_HAL_RTC_BOOT_VERSION_REG LL_RTC_BKP_DR1
+#define FURI_HAL_RTC_SYSTEM_REG LL_RTC_BKP_DR2
+
+typedef struct {
+ uint8_t log_level:4;
+ uint8_t log_reserved:4;
+ uint8_t flags;
+ uint16_t reserved;
+} DeveloperReg;
+
+void furi_hal_rtc_init() {
+ if(LL_RCC_GetRTCClockSource() != LL_RCC_RTC_CLKSOURCE_LSE) {
+ LL_RCC_ForceBackupDomainReset();
+ LL_RCC_ReleaseBackupDomainReset();
+ LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE);
+ }
+
+ LL_RCC_EnableRTC();
+ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB);
+
+ LL_RTC_InitTypeDef RTC_InitStruct = {0};
+ RTC_InitStruct.HourFormat = LL_RTC_HOURFORMAT_24HOUR;
+ RTC_InitStruct.AsynchPrescaler = 127;
+ RTC_InitStruct.SynchPrescaler = 255;
+ LL_RTC_Init(RTC, &RTC_InitStruct);
+
+ furi_log_set_level(furi_hal_rtc_get_log_level());
+
+ FURI_LOG_I(TAG, "Init OK");
+}
+
+void furi_hal_rtc_set_log_level(uint8_t level) {
+ uint32_t data = LL_RTC_BAK_GetRegister(RTC, FURI_HAL_RTC_SYSTEM_REG);
+ ((DeveloperReg*)&data)->log_level = level;
+ LL_RTC_BAK_SetRegister(RTC, FURI_HAL_RTC_SYSTEM_REG, data);
+ furi_log_set_level(level);
+}
+
+uint8_t furi_hal_rtc_get_log_level() {
+ uint32_t data = LL_RTC_BAK_GetRegister(RTC, FURI_HAL_RTC_SYSTEM_REG);
+ return ((DeveloperReg*)&data)->log_level;
+}
+
+void furi_hal_rtc_set_flag(FuriHalRtcFlag flag) {
+ uint32_t data = LL_RTC_BAK_GetRegister(RTC, FURI_HAL_RTC_SYSTEM_REG);
+ ((DeveloperReg*)&data)->flags |= flag;
+ LL_RTC_BAK_SetRegister(RTC, FURI_HAL_RTC_SYSTEM_REG, data);
+}
+
+void furi_hal_rtc_reset_flag(FuriHalRtcFlag flag) {
+ uint32_t data = LL_RTC_BAK_GetRegister(RTC, FURI_HAL_RTC_SYSTEM_REG);
+ ((DeveloperReg*)&data)->flags &= ~flag;
+ LL_RTC_BAK_SetRegister(RTC, FURI_HAL_RTC_SYSTEM_REG, data);
+}
+
+bool furi_hal_rtc_is_flag_set(FuriHalRtcFlag flag) {
+ uint32_t data = LL_RTC_BAK_GetRegister(RTC, FURI_HAL_RTC_SYSTEM_REG);
+ return ((DeveloperReg*)&data)->flags & flag;
+}
+
+void furi_hal_rtc_set_datetime(FuriHalRtcDateTime* datetime) {
+ furi_assert(datetime);
+
+ /* Disable write protection */
+ LL_RTC_DisableWriteProtection(RTC);
+
+ /* Enter Initialization mode and wait for INIT flag to be set */
+ LL_RTC_EnableInitMode(RTC);
+ while(!LL_RTC_IsActiveFlag_INIT(RTC)) {}
+
+ /* Set time */
+ LL_RTC_TIME_Config(RTC,
+ LL_RTC_TIME_FORMAT_AM_OR_24,
+ __LL_RTC_CONVERT_BIN2BCD(datetime->hour),
+ __LL_RTC_CONVERT_BIN2BCD(datetime->minute),
+ __LL_RTC_CONVERT_BIN2BCD(datetime->second)
+ );
+
+ /* Set date */
+ LL_RTC_DATE_Config(RTC,
+ datetime->weekday,
+ __LL_RTC_CONVERT_BIN2BCD(datetime->day),
+ __LL_RTC_CONVERT_BIN2BCD(datetime->month),
+ __LL_RTC_CONVERT_BIN2BCD(datetime->year - 2000)
+ );
+
+ /* Exit Initialization mode */
+ LL_RTC_DisableInitMode(RTC);
+
+ /* If RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */
+ if (!LL_RTC_IsShadowRegBypassEnabled(RTC)) {
+ LL_RTC_ClearFlag_RS(RTC);
+ while(!LL_RTC_IsActiveFlag_RS(RTC)) {};
+ }
+
+ /* Enable write protection */
+ LL_RTC_EnableWriteProtection(RTC);
+}
+
+void furi_hal_rtc_get_datetime(FuriHalRtcDateTime* datetime) {
+ furi_assert(datetime);
+
+ uint32_t time = LL_RTC_TIME_Get(RTC); // 0x00HHMMSS
+ uint32_t date = LL_RTC_DATE_Get(RTC); // 0xWWDDMMYY
+
+ datetime->second = __LL_RTC_CONVERT_BCD2BIN((time>>0) & 0xFF);
+ datetime->minute = __LL_RTC_CONVERT_BCD2BIN((time>>8) & 0xFF);
+ datetime->hour = __LL_RTC_CONVERT_BCD2BIN((time>>16) & 0xFF);
+ datetime->year = __LL_RTC_CONVERT_BCD2BIN((date >> 0) & 0xFF) + 2000;
+ datetime->month = __LL_RTC_CONVERT_BCD2BIN((date >> 8) & 0xFF);
+ datetime->day = __LL_RTC_CONVERT_BCD2BIN((date >> 16) & 0xFF);
+ datetime->weekday = __LL_RTC_CONVERT_BCD2BIN((date >> 24) & 0xFF);
+}
diff --git a/firmware/targets/f6/furi-hal/furi-hal.c b/firmware/targets/f6/furi-hal/furi-hal.c
index d213af95..3f41684f 100644
--- a/firmware/targets/f6/furi-hal/furi-hal.c
+++ b/firmware/targets/f6/furi-hal/furi-hal.c
@@ -1,7 +1,6 @@
#include <furi-hal.h>
#include <comp.h>
-#include <rtc.h>
#include <tim.h>
#include <gpio.h>
@@ -13,18 +12,14 @@
void furi_hal_init() {
furi_hal_clock_init();
+ furi_hal_rtc_init();
furi_hal_console_init();
furi_hal_interrupt_init();
furi_hal_delay_init();
- // FreeRTOS glue
- furi_hal_os_init();
-
MX_GPIO_Init();
FURI_LOG_I(TAG, "GPIO OK");
- MX_RTC_Init();
- FURI_LOG_I(TAG, "RTC OK");
furi_hal_bootloader_init();
furi_hal_version_init();
@@ -59,6 +54,9 @@ void furi_hal_init() {
furi_hal_bt_init();
furi_hal_compress_icon_init();
+ // FreeRTOS glue
+ furi_hal_os_init();
+
// FatFS driver initialization
MX_FATFS_Init();
FURI_LOG_I(TAG, "FATFS OK");
diff --git a/firmware/targets/f6/target.mk b/firmware/targets/f6/target.mk
index cad7d33f..e642e2aa 100644
--- a/firmware/targets/f6/target.mk
+++ b/firmware/targets/f6/target.mk
@@ -24,7 +24,7 @@ LDFLAGS += $(MCU_FLAGS) -specs=nosys.specs -specs=nano.specs -u _printf_float
CPPFLAGS += -fno-rtti -fno-use-cxa-atexit -fno-exceptions
LDFLAGS += -Wl,--start-group -lstdc++ -lsupc++ -Wl,--end-group
-HARDWARE_TARGET = 6
+HARDWARE_TARGET = 7
MXPROJECT_DIR = $(TARGET_DIR)
@@ -57,7 +57,6 @@ C_SOURCES += \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr_ex.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc.c \
- $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rtc.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rtc_ex.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_tim.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_tim_ex.c \
@@ -67,6 +66,7 @@ C_SOURCES += \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_i2c.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_lptim.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_rcc.c \
+ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_rtc.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_spi.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_tim.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usart.c \
diff --git a/firmware/targets/f7/Inc/rtc.h b/firmware/targets/f7/Inc/rtc.h
deleted file mode 100644
index 6dd24df4..00000000
--- a/firmware/targets/f7/Inc/rtc.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- ******************************************************************************
- * @file rtc.h
- * @brief This file contains all the function prototypes for
- * the rtc.c file
- ******************************************************************************
- * @attention
- *
- * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * 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
- *
- ******************************************************************************
- */
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __RTC_H__
-#define __RTC_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "main.h"
-
-/* USER CODE BEGIN Includes */
-
-/* USER CODE END Includes */
-
-extern RTC_HandleTypeDef hrtc;
-
-/* USER CODE BEGIN Private defines */
-
-/* USER CODE END Private defines */
-
-void MX_RTC_Init(void);
-
-/* USER CODE BEGIN Prototypes */
-
-/* USER CODE END Prototypes */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __RTC_H__ */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/firmware/targets/f7/Inc/stm32wbxx_hal_conf.h b/firmware/targets/f7/Inc/stm32wbxx_hal_conf.h
index 4d5ad791..dc6a7ae4 100644
--- a/firmware/targets/f7/Inc/stm32wbxx_hal_conf.h
+++ b/firmware/targets/f7/Inc/stm32wbxx_hal_conf.h
@@ -48,7 +48,7 @@
#define HAL_PKA_MODULE_ENABLED
/*#define HAL_QSPI_MODULE_ENABLED */
#define HAL_RNG_MODULE_ENABLED
-#define HAL_RTC_MODULE_ENABLED
+/*#define HAL_RTC_MODULE_ENABLED */
/*#define HAL_SAI_MODULE_ENABLED */
/*#define HAL_SMBUS_MODULE_ENABLED */
/*#define HAL_SMARTCARD_MODULE_ENABLED */
diff --git a/firmware/targets/f7/Src/rtc.c b/firmware/targets/f7/Src/rtc.c
deleted file mode 100644
index 8487c1e0..00000000
--- a/firmware/targets/f7/Src/rtc.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/**
- ******************************************************************************
- * @file rtc.c
- * @brief This file provides code for the configuration
- * of the RTC instances.
- ******************************************************************************
- * @attention
- *
- * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * 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
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "rtc.h"
-
-/* USER CODE BEGIN 0 */
-
-/* USER CODE END 0 */
-
-RTC_HandleTypeDef hrtc;
-
-/* RTC init function */
-void MX_RTC_Init(void)
-{
- RTC_TimeTypeDef sTime = {0};
- RTC_DateTypeDef sDate = {0};
-
- /** Initialize RTC Only
- */
- hrtc.Instance = RTC;
- hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
- hrtc.Init.AsynchPrediv = 127;
- hrtc.Init.SynchPrediv = 255;
- hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
- hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
- hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
- hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
- if (HAL_RTC_Init(&hrtc) != HAL_OK)
- {
- Error_Handler();
- }
-
- /* USER CODE BEGIN Check_RTC_BKUP */
- return;
- /* USER CODE END Check_RTC_BKUP */
-
- /** Initialize RTC and set the Time and Date
- */
- sTime.Hours = 0x0;
- sTime.Minutes = 0x0;
- sTime.Seconds = 0x0;
- sTime.SubSeconds = 0x0;
- sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
- sTime.StoreOperation = RTC_STOREOPERATION_RESET;
- if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
- {
- Error_Handler();
- }
- sDate.WeekDay = RTC_WEEKDAY_MONDAY;
- sDate.Month = RTC_MONTH_JANUARY;
- sDate.Date = 0x1;
- sDate.Year = 0x0;
-
- if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
- {
- Error_Handler();
- }
-
-}
-
-void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle)
-{
-
- if(rtcHandle->Instance==RTC)
- {
- /* USER CODE BEGIN RTC_MspInit 0 */
-
- /* USER CODE END RTC_MspInit 0 */
- /* RTC clock enable */
- __HAL_RCC_RTC_ENABLE();
- __HAL_RCC_RTCAPB_CLK_ENABLE();
-
- /* RTC interrupt Init */
- HAL_NVIC_SetPriority(TAMP_STAMP_LSECSS_IRQn, 5, 0);
- HAL_NVIC_EnableIRQ(TAMP_STAMP_LSECSS_IRQn);
- /* USER CODE BEGIN RTC_MspInit 1 */
-
- /* USER CODE END RTC_MspInit 1 */
- }
-}
-
-void HAL_RTC_MspDeInit(RTC_HandleTypeDef* rtcHandle)
-{
-
- if(rtcHandle->Instance==RTC)
- {
- /* USER CODE BEGIN RTC_MspDeInit 0 */
-
- /* USER CODE END RTC_MspDeInit 0 */
- /* Peripheral clock disable */
- __HAL_RCC_RTC_DISABLE();
- __HAL_RCC_RTCAPB_CLK_DISABLE();
-
- /* RTC interrupt Deinit */
- HAL_NVIC_DisableIRQ(TAMP_STAMP_LSECSS_IRQn);
- /* USER CODE BEGIN RTC_MspDeInit 1 */
-
- /* USER CODE END RTC_MspDeInit 1 */
- }
-}
-
-/* USER CODE BEGIN 1 */
-
-/* USER CODE END 1 */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/firmware/targets/f7/Src/stm32wbxx_it.c b/firmware/targets/f7/Src/stm32wbxx_it.c
index 1051e074..d4f71267 100644
--- a/firmware/targets/f7/Src/stm32wbxx_it.c
+++ b/firmware/targets/f7/Src/stm32wbxx_it.c
@@ -6,7 +6,6 @@
extern usbd_device udev;
extern COMP_HandleTypeDef hcomp1;
-extern RTC_HandleTypeDef hrtc;
extern TIM_HandleTypeDef htim1;
extern TIM_HandleTypeDef htim2;
extern TIM_HandleTypeDef htim16;
@@ -40,10 +39,6 @@ void HSEM_IRQHandler(void) {
HAL_HSEM_IRQHandler();
}
-void RTC_WKUP_IRQHandler(void){
- HW_TS_RTC_Wakeup_Handler();
-}
-
void IPCC_C1_TX_IRQHandler(void){
HW_IPCC_Tx_Handler();
}
diff --git a/firmware/targets/f7/ble-glue/hw_if.h b/firmware/targets/f7/ble-glue/hw_if.h
index 271a222a..f9dc0a6d 100644
--- a/firmware/targets/f7/ble-glue/hw_if.h
+++ b/firmware/targets/f7/ble-glue/hw_if.h
@@ -82,165 +82,6 @@ extern "C" {
void HW_UART_Interrupt_Handler(hw_uart_id_t hw_uart_id);
void HW_UART_DMA_Interrupt_Handler(hw_uart_id_t hw_uart_id);
- /******************************************************************************
- * HW TimerServer
- ******************************************************************************/
- /* Exported types ------------------------------------------------------------*/
- /**
- * This setting is used when standby mode is supported.
- * hw_ts_InitMode_Limited should be used when the device restarts from Standby Mode. In that case, the Timer Server does
- * not re-initialized its context. Only the Hardware register which content has been lost is reconfigured
- * Otherwise, hw_ts_InitMode_Full should be requested (Start from Power ON) and everything is re-initialized.
- */
- typedef enum
- {
- hw_ts_InitMode_Full,
- hw_ts_InitMode_Limited,
- } HW_TS_InitMode_t;
-
- /**
- * When a Timer is created as a SingleShot timer, it is not automatically restarted when the timeout occurs. However,
- * the timer is kept reserved in the list and could be restarted at anytime with HW_TS_Start()
- *
- * When a Timer is created as a Repeated timer, it is automatically restarted when the timeout occurs.
- */
- typedef enum
- {
- hw_ts_SingleShot,
- hw_ts_Repeated
- } HW_TS_Mode_t;
-
- /**
- * hw_ts_Successful is returned when a Timer has been successfully created with HW_TS_Create(). Otherwise, hw_ts_Failed
- * is returned. When hw_ts_Failed is returned, that means there are not enough free slots in the list to create a
- * Timer. In that case, CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER should be increased
- */
- typedef enum
- {
- hw_ts_Successful,
- hw_ts_Failed,
- }HW_TS_ReturnStatus_t;
-
- typedef void (*HW_TS_pTimerCb_t)(void);
-
- /**
- * @brief Initialize the timer server
- * This API shall be called by the application before any timer is requested to the timer server. It
- * configures the RTC module to be connected to the LSI input clock.
- *
- * @param TimerInitMode: When the device restarts from Standby, it should request hw_ts_InitMode_Limited so that the
- * Timer context is not re-initialized. Otherwise, hw_ts_InitMode_Full should be requested
- * @param hrtc: RTC Handle
- * @retval None
- */
- void HW_TS_Init(HW_TS_InitMode_t TimerInitMode, RTC_HandleTypeDef *hrtc);
-
- /**
- * @brief Interface to create a virtual timer
- * The user shall call this API to create a timer. Once created, the timer is reserved to the module until it
- * has been deleted. When creating a timer, the user shall specify the mode (single shot or repeated), the
- * callback to be notified when the timer expires and a module ID to identify in the timer interrupt handler
- * which module is concerned. In return, the user gets a timer ID to handle it.
- *
- * @param TimerProcessID: This is an identifier provided by the user and returned in the callback to allow
- * identification of the requester
- * @param pTimerId: Timer Id returned to the user to request operation (start, stop, delete)
- * @param TimerMode: Mode of the virtual timer (Single shot or repeated)
- * @param pTimerCallBack: Callback when the virtual timer expires
- * @retval HW_TS_ReturnStatus_t: Return whether the creation is sucessfull or not
- */
- HW_TS_ReturnStatus_t HW_TS_Create(uint32_t TimerProcessID, uint8_t *pTimerId, HW_TS_Mode_t TimerMode, HW_TS_pTimerCb_t pTimerCallBack);
-
- /**
- * @brief Stop a virtual timer
- * This API may be used to stop a running timer. A timer which is stopped is move to the pending state.
- * A pending timer may be restarted at any time with a different timeout value but the mode cannot be changed.
- * Nothing is done when it is called to stop a timer which has been already stopped
- *
- * @param TimerID: Id of the timer to stop
- * @retval None
- */
- void HW_TS_Stop(uint8_t TimerID);
-
- /**
- * @brief Start a virtual timer
- * This API shall be used to start a timer. The timeout value is specified and may be different each time.
- * When the timer is in the single shot mode, it will move to the pending state when it expires. The user may
- * restart it at any time with a different timeout value. When the timer is in the repeated mode, it always
- * stay in the running state. When the timer expires, it will be restarted with the same timeout value.
- * This API shall not be called on a running timer.
- *
- * @param TimerID: The ID Id of the timer to start
- * @param timeout_ticks: Number of ticks of the virtual timer (Maximum value is (0xFFFFFFFF-0xFFFF = 0xFFFF0000)
- * @retval None
- */
- void HW_TS_Start(uint8_t TimerID, uint32_t timeout_ticks);
-
- /**
- * @brief Delete a virtual timer from the list
- * This API should be used when a timer is not needed anymore by the user. A deleted timer is removed from
- * the timer list managed by the timer server. It cannot be restarted again. The user has to go with the
- * creation of a new timer if required and may get a different timer id
- *
- * @param TimerID: The ID of the timer to remove from the list
- * @retval None
- */
- void HW_TS_Delete(uint8_t TimerID);
-
- /**
- * @brief Schedule the timer list on the timer interrupt handler
- * This interrupt handler shall be called by the application in the RTC interrupt handler. This handler takes
- * care of clearing all status flag required in the RTC and EXTI peripherals
- *
- * @param None
- * @retval None
- */
- void HW_TS_RTC_Wakeup_Handler(void);
-
- /**
- * @brief Return the number of ticks to count before the interrupt
- * This API returns the number of ticks left to be counted before an interrupt is generated by the
- * Timer Server. This API may be used by the application for power management optimization. When the system
- * enters low power mode, the mode selection is a tradeoff between the wakeup time where the CPU is running
- * and the time while the CPU will be kept in low power mode before next wakeup. The deeper is the
- * low power mode used, the longer is the wakeup time. The low power mode management considering wakeup time
- * versus time in low power mode is implementation specific
- * When the timer is disabled (No timer in the list), it returns 0xFFFF
- *
- * @param None
- * @retval The number of ticks left to count
- */
- uint16_t HW_TS_RTC_ReadLeftTicksToCount(void);
-
- /**
- * @brief Notify the application that a registered timer has expired
- * This API shall be implemented by the user application.
- * This API notifies the application that a timer expires. This API is running in the RTC Wakeup interrupt
- * context. The application may implement an Operating System to change the context priority where the timer
- * callback may be handled. This API provides the module ID to identify which module is concerned and to allow
- * sending the information to the correct task
- *
- * @param TimerProcessID: The TimerProcessId associated with the timer when it has been created
- * @param TimerID: The TimerID of the expired timer
- * @param pTimerCallBack: The Callback associated with the timer when it has been created
- * @retval None
- */
- void HW_TS_RTC_Int_AppNot(uint32_t TimerProcessID, uint8_t TimerID, HW_TS_pTimerCb_t pTimerCallBack);
-
- /**
- * @brief Notify the application that the wakeupcounter has been updated
- * This API should be implemented by the user application
- * This API notifies the application that the counter has been updated. This is expected to be used along
- * with the HW_TS_RTC_ReadLeftTicksToCount () API. It could be that the counter has been updated since the
- * last call of HW_TS_RTC_ReadLeftTicksToCount () and before entering low power mode. This notification
- * provides a way to the application to solve that race condition to reevaluate the counter value before
- * entering low power mode
- *
- * @param None
- * @retval None
- */
- void HW_TS_RTC_CountUpdated_AppNot(void);
-
#ifdef __cplusplus
}
#endif
diff --git a/firmware/targets/f7/ble-glue/hw_timerserver.c b/firmware/targets/f7/ble-glue/hw_timerserver.c
deleted file mode 100644
index e0e4fcb5..00000000
--- a/firmware/targets/f7/ble-glue/hw_timerserver.c
+++ /dev/null
@@ -1,893 +0,0 @@
-/**
- ******************************************************************************
- * File Name : hw_timerserver.c
- * Description : Hardware timerserver source file for STM32WPAN Middleware.
- *
- ******************************************************************************
- * @attention
- *
- * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
- * All rights reserved.</center></h2>
- *
- * 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
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "app_common.h"
-#include "hw_conf.h"
-
-/* Private typedef -----------------------------------------------------------*/
-typedef enum
-{
- TimerID_Free,
- TimerID_Created,
- TimerID_Running
-}TimerIDStatus_t;
-
-typedef enum
-{
- SSR_Read_Requested,
- SSR_Read_Not_Requested
-}RequestReadSSR_t;
-
-typedef enum
-{
- WakeupTimerValue_Overpassed,
- WakeupTimerValue_LargeEnough
-}WakeupTimerLimitation_Status_t;
-
-typedef struct
-{
- HW_TS_pTimerCb_t pTimerCallBack;
- uint32_t CounterInit;
- uint32_t CountLeft;
- TimerIDStatus_t TimerIDStatus;
- HW_TS_Mode_t TimerMode;
- uint32_t TimerProcessID;
- uint8_t PreviousID;
- uint8_t NextID;
-}TimerContext_t;
-
-/* Private defines -----------------------------------------------------------*/
-#define SSR_FORBIDDEN_VALUE 0xFFFFFFFF
-#define TIMER_LIST_EMPTY 0xFFFF
-
-/* Private macros ------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-
-/**
- * START of Section TIMERSERVER_CONTEXT
- */
-
-PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile TimerContext_t aTimerContext[CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER];
-PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile uint8_t CurrentRunningTimerID;
-PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile uint8_t PreviousRunningTimerID;
-PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile uint32_t SSRValueOnLastSetup;
-PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile WakeupTimerLimitation_Status_t WakeupTimerLimitation;
-
-/**
- * END of Section TIMERSERVER_CONTEXT
- */
-
-static RTC_HandleTypeDef *phrtc; /**< RTC handle */
-static uint8_t WakeupTimerDivider;
-static uint8_t AsynchPrescalerUserConfig;
-static uint16_t SynchPrescalerUserConfig;
-static volatile uint16_t MaxWakeupTimerSetup;
-
-/* Global variables ----------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-static void RestartWakeupCounter(uint16_t Value);
-static uint16_t ReturnTimeElapsed(void);
-static void RescheduleTimerList(void);
-static void UnlinkTimer(uint8_t TimerID, RequestReadSSR_t RequestReadSSR);
-static void LinkTimerBefore(uint8_t TimerID, uint8_t RefTimerID);
-static void LinkTimerAfter(uint8_t TimerID, uint8_t RefTimerID);
-static uint16_t linkTimer(uint8_t TimerID);
-static uint32_t ReadRtcSsrValue(void);
-
-__weak void HW_TS_RTC_CountUpdated_AppNot(void);
-
-/* Functions Definition ------------------------------------------------------*/
-
-/**
- * @brief Read the RTC_SSR value
- * As described in the reference manual, the RTC_SSR shall be read twice to ensure
- * reliability of the value
- * @param None
- * @retval SSR value read
- */
-static uint32_t ReadRtcSsrValue(void)
-{
- uint32_t first_read;
- uint32_t second_read;
-
- first_read = (uint32_t)(READ_BIT(RTC->SSR, RTC_SSR_SS));
-
- second_read = (uint32_t)(READ_BIT(RTC->SSR, RTC_SSR_SS));
-
- while(first_read != second_read)
- {
- first_read = second_read;
-
- second_read = (uint32_t)(READ_BIT(RTC->SSR, RTC_SSR_SS));
- }
-
- return second_read;
-}
-
-/**
- * @brief Insert a Timer in the list after the Timer ID specified
- * @param TimerID: The ID of the Timer
- * @param RefTimerID: The ID of the Timer to be linked after
- * @retval None
- */
-static void LinkTimerAfter(uint8_t TimerID, uint8_t RefTimerID)
-{
- uint8_t next_id;
-
- next_id = aTimerContext[RefTimerID].NextID;
-
- if(next_id != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
- {
- aTimerContext[next_id].PreviousID = TimerID;
- }
- aTimerContext[TimerID].NextID = next_id;
- aTimerContext[TimerID].PreviousID = RefTimerID ;
- aTimerContext[RefTimerID].NextID = TimerID;
-
- return;
-}
-
-/**
- * @brief Insert a Timer in the list before the ID specified
- * @param TimerID: The ID of the Timer
- * @param RefTimerID: The ID of the Timer to be linked before
- * @retval None
- */
-static void LinkTimerBefore(uint8_t TimerID, uint8_t RefTimerID)
-{
- uint8_t previous_id;
-
- if(RefTimerID != CurrentRunningTimerID)
- {
- previous_id = aTimerContext[RefTimerID].PreviousID;
-
- aTimerContext[previous_id].NextID = TimerID;
- aTimerContext[TimerID].NextID = RefTimerID;
- aTimerContext[TimerID].PreviousID = previous_id ;
- aTimerContext[RefTimerID].PreviousID = TimerID;
- }
- else
- {
- aTimerContext[TimerID].NextID = RefTimerID;
- aTimerContext[RefTimerID].PreviousID = TimerID;
- }
-
- return;
-}
-
-/**
- * @brief Insert a Timer in the list
- * @param TimerID: The ID of the Timer
- * @retval None
- */
-static uint16_t linkTimer(uint8_t TimerID)
-{
- uint32_t time_left;
- uint16_t time_elapsed;
- uint8_t timer_id_lookup;
- uint8_t next_id;
-
- if(CurrentRunningTimerID == CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
- {
- /**
- * No timer in the list
- */
- PreviousRunningTimerID = CurrentRunningTimerID;
- CurrentRunningTimerID = TimerID;
- aTimerContext[TimerID].NextID = CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER;
-
- SSRValueOnLastSetup = SSR_FORBIDDEN_VALUE;
- time_elapsed = 0;
- }
- else
- {
- time_elapsed = ReturnTimeElapsed();
-
- /**
- * update count of the timer to be linked
- */
- aTimerContext[TimerID].CountLeft += time_elapsed;
- time_left = aTimerContext[TimerID].CountLeft;
-
- /**
- * Search for index where the new timer shall be linked
- */
- if(aTimerContext[CurrentRunningTimerID].CountLeft <= time_left)
- {
- /**
- * Search for the ID after the first one
- */
- timer_id_lookup = CurrentRunningTimerID;
- next_id = aTimerContext[timer_id_lookup].NextID;
- while((next_id != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) && (aTimerContext[next_id].CountLeft <= time_left))
- {
- timer_id_lookup = aTimerContext[timer_id_lookup].NextID;
- next_id = aTimerContext[timer_id_lookup].NextID;
- }
-
- /**
- * Link after the ID
- */
- LinkTimerAfter(TimerID, timer_id_lookup);
- }
- else
- {
- /**
- * Link before the first ID
- */
- LinkTimerBefore(TimerID, CurrentRunningTimerID);
- PreviousRunningTimerID = CurrentRunningTimerID;
- CurrentRunningTimerID = TimerID;
- }
- }
-
- return time_elapsed;
-}
-
-/**
- * @brief Remove a Timer from the list
- * @param TimerID: The ID of the Timer
- * @param RequestReadSSR: Request to read the SSR register or not
- * @retval None
- */
-static void UnlinkTimer(uint8_t TimerID, RequestReadSSR_t RequestReadSSR)
-{
- uint8_t previous_id;
- uint8_t next_id;
-
- if(TimerID == CurrentRunningTimerID)
- {
- PreviousRunningTimerID = CurrentRunningTimerID;
- CurrentRunningTimerID = aTimerContext[TimerID].NextID;
- }
- else
- {
- previous_id = aTimerContext[TimerID].PreviousID;
- next_id = aTimerContext[TimerID].NextID;
-
- aTimerContext[previous_id].NextID = aTimerContext[TimerID].NextID;
- if(next_id != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
- {
- aTimerContext[next_id].PreviousID = aTimerContext[TimerID].PreviousID;
- }
- }
-
- /**
- * Timer is out of the list
- */
- aTimerContext[TimerID].TimerIDStatus = TimerID_Created;
-
- if((CurrentRunningTimerID == CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) && (RequestReadSSR == SSR_Read_Requested))
- {
- SSRValueOnLastSetup = SSR_FORBIDDEN_VALUE;
- }
-
- return;
-}
-
-/**
- * @brief Return the number of ticks counted by the wakeuptimer since it has been started
- * @note The API is reading the SSR register to get how many ticks have been counted
- * since the time the timer has been started
- * @param None
- * @retval Time expired in Ticks
- */
-static uint16_t ReturnTimeElapsed(void)
-{
- uint32_t return_value;
- uint32_t wrap_counter;
-
- if(SSRValueOnLastSetup != SSR_FORBIDDEN_VALUE)
- {
- return_value = ReadRtcSsrValue(); /**< Read SSR register first */
-
- if (SSRValueOnLastSetup >= return_value)
- {
- return_value = SSRValueOnLastSetup - return_value;
- }
- else
- {
- wrap_counter = SynchPrescalerUserConfig - return_value;
- return_value = SSRValueOnLastSetup + wrap_counter;
- }
-
- /**
- * At this stage, ReturnValue holds the number of ticks counted by SSR
- * Need to translate in number of ticks counted by the Wakeuptimer
- */
- return_value = return_value*AsynchPrescalerUserConfig;
- return_value = return_value >> WakeupTimerDivider;
- }
- else
- {
- return_value = 0;
- }
-
- return (uint16_t)return_value;
-}
-
-/**
- * @brief Set the wakeup counter
- * @note The API is writing the counter value so that the value is decreased by one to cope with the fact
- * the interrupt is generated with 1 extra clock cycle (See RefManuel)
- * It assumes all condition are met to be allowed to write the wakeup counter
- * @param Value: Value to be written in the counter
- * @retval None
- */
-static void RestartWakeupCounter(uint16_t Value)
-{
- /**
- * The wakeuptimer has been disabled in the calling function to reduce the time to poll the WUTWF
- * FLAG when the new value will have to be written
- * __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc);
- */
-
- if(Value == 0)
- {
- SSRValueOnLastSetup = ReadRtcSsrValue();
-
- /**
- * Simulate that the Timer expired
- */
- HAL_NVIC_SetPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID);
- }
- else
- {
- if((Value > 1) ||(WakeupTimerDivider != 1))
- {
- Value -= 1;
- }
-
- while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == RESET);
-
- /**
- * make sure to clear the flags after checking the WUTWF.
- * It takes 2 RTCCLK between the time the WUTE bit is disabled and the
- * time the timer is disabled. The WUTWF bit somehow guarantee the system is stable
- * Otherwise, when the timer is periodic with 1 Tick, it may generate an extra interrupt in between
- * due to the autoreload feature
- */
- __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(phrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */
- __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */
- HAL_NVIC_ClearPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Clear pending bit in NVIC */
-
- MODIFY_REG(RTC->WUTR, RTC_WUTR_WUT, Value);
-
- /**
- * Update the value here after the WUTWF polling that may take some time
- */
- SSRValueOnLastSetup = ReadRtcSsrValue();
-
- __HAL_RTC_WAKEUPTIMER_ENABLE(phrtc); /**< Enable the Wakeup Timer */
-
- HW_TS_RTC_CountUpdated_AppNot();
- }
-
- return ;
-}
-
-/**
- * @brief Reschedule the list of timer
- * @note 1) Update the count left for each timer in the list
- * 2) Setup the wakeuptimer
- * @param None
- * @retval None
- */
-static void RescheduleTimerList(void)
-{
- uint8_t localTimerID;
- uint32_t timecountleft;
- uint16_t wakeup_timer_value;
- uint16_t time_elapsed;
-
- /**
- * The wakeuptimer is disabled now to reduce the time to poll the WUTWF
- * FLAG when the new value will have to be written
- */
- if((READ_BIT(RTC->CR, RTC_CR_WUTE) == (RTC_CR_WUTE)) == SET)
- {
- /**
- * Wait for the flag to be back to 0 when the wakeup timer is enabled
- */
- while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == SET);
- }
- __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc); /**< Disable the Wakeup Timer */
-
- localTimerID = CurrentRunningTimerID;
-
- /**
- * Calculate what will be the value to write in the wakeuptimer
- */
- timecountleft = aTimerContext[localTimerID].CountLeft;
-
- /**
- * Read how much has been counted
- */
- time_elapsed = ReturnTimeElapsed();
-
- if(timecountleft < time_elapsed )
- {
- /**
- * There is no tick left to count
- */
- wakeup_timer_value = 0;
- WakeupTimerLimitation = WakeupTimerValue_LargeEnough;
- }
- else
- {
- if(timecountleft > (time_elapsed + MaxWakeupTimerSetup))
- {
- /**
- * The number of tick left is greater than the Wakeuptimer maximum value
- */
- wakeup_timer_value = MaxWakeupTimerSetup;
-
- WakeupTimerLimitation = WakeupTimerValue_Overpassed;
- }
- else
- {
- wakeup_timer_value = timecountleft - time_elapsed;
- WakeupTimerLimitation = WakeupTimerValue_LargeEnough;
- }
-
- }
-
- /**
- * update ticks left to be counted for each timer
- */
- while(localTimerID != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
- {
- if (aTimerContext[localTimerID].CountLeft < time_elapsed)
- {
- aTimerContext[localTimerID].CountLeft = 0;
- }
- else
- {
- aTimerContext[localTimerID].CountLeft -= time_elapsed;
- }
- localTimerID = aTimerContext[localTimerID].NextID;
- }
-
- /**
- * Write next count
- */
- RestartWakeupCounter(wakeup_timer_value);
-
- return ;
-}
-
-/* Public functions ----------------------------------------------------------*/
-
-/**
- * For all public interface except that may need write access to the RTC, the RTC
- * shall be unlock at the beginning and locked at the output
- * In order to ease maintainability, the unlock is done at the top and the lock at then end
- * in case some new implementation is coming in the future
- */
-
-void HW_TS_RTC_Wakeup_Handler(void)
-{
- HW_TS_pTimerCb_t ptimer_callback;
- uint32_t timer_process_id;
- uint8_t local_current_running_timer_id;
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- uint32_t primask_bit;
-#endif
-
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
- __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
-#endif
-
-/* Disable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc );
-
- /**
- * Disable the Wakeup Timer
- * This may speed up a bit the processing to wait the timer to be disabled
- * The timer is still counting 2 RTCCLK
- */
- __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc);
-
- local_current_running_timer_id = CurrentRunningTimerID;
-
- if(aTimerContext[local_current_running_timer_id].TimerIDStatus == TimerID_Running)
- {
- ptimer_callback = aTimerContext[local_current_running_timer_id].pTimerCallBack;
- timer_process_id = aTimerContext[local_current_running_timer_id].TimerProcessID;
-
- /**
- * It should be good to check whether the TimeElapsed is greater or not than the tick left to be counted
- * However, due to the inaccuracy of the reading of the time elapsed, it may return there is 1 tick
- * to be left whereas the count is over
- * A more secure implementation has been done with a flag to state whereas the full count has been written
- * in the wakeuptimer or not
- */
- if(WakeupTimerLimitation != WakeupTimerValue_Overpassed)
- {
- if(aTimerContext[local_current_running_timer_id].TimerMode == hw_ts_Repeated)
- {
- UnlinkTimer(local_current_running_timer_id, SSR_Read_Not_Requested);
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
-#endif
- HW_TS_Start(local_current_running_timer_id, aTimerContext[local_current_running_timer_id].CounterInit);
-
- /* Disable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc );
- }
- else
- {
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
-#endif
- HW_TS_Stop(local_current_running_timer_id);
-
- /* Disable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc );
- }
-
- HW_TS_RTC_Int_AppNot(timer_process_id, local_current_running_timer_id, ptimer_callback);
- }
- else
- {
- RescheduleTimerList();
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
-#endif
- }
- }
- else
- {
- /**
- * We should never end up in this case
- * However, if due to any bug in the timer server this is the case, the mistake may not impact the user.
- * We could just clean the interrupt flag and get out from this unexpected interrupt
- */
- while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == RESET);
-
- /**
- * make sure to clear the flags after checking the WUTWF.
- * It takes 2 RTCCLK between the time the WUTE bit is disabled and the
- * time the timer is disabled. The WUTWF bit somehow guarantee the system is stable
- * Otherwise, when the timer is periodic with 1 Tick, it may generate an extra interrupt in between
- * due to the autoreload feature
- */
- __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(phrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */
- __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */
-
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
-#endif
- }
-
- /* Enable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_ENABLE( phrtc );
-
- return;
-}
-
-void HW_TS_Init(HW_TS_InitMode_t TimerInitMode, RTC_HandleTypeDef *hrtc)
-{
- uint8_t loop;
- uint32_t localmaxwakeuptimersetup;
-
- /**
- * Get RTC handler
- */
- phrtc = hrtc;
-
- /* Disable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc );
-
- SET_BIT(RTC->CR, RTC_CR_BYPSHAD);
-
- /**
- * Readout the user config
- */
- WakeupTimerDivider = (4 - ((uint32_t)(READ_BIT(RTC->CR, RTC_CR_WUCKSEL))));
-
- AsynchPrescalerUserConfig = (uint8_t)(READ_BIT(RTC->PRER, RTC_PRER_PREDIV_A) >> (uint32_t)POSITION_VAL(RTC_PRER_PREDIV_A)) + 1;
-
- SynchPrescalerUserConfig = (uint16_t)(READ_BIT(RTC->PRER, RTC_PRER_PREDIV_S)) + 1;
-
- /**
- * Margin is taken to avoid wrong calculation when the wrap around is there and some
- * application interrupts may have delayed the reading
- */
- localmaxwakeuptimersetup = ((((SynchPrescalerUserConfig - 1)*AsynchPrescalerUserConfig) - CFG_HW_TS_RTC_HANDLER_MAX_DELAY) >> WakeupTimerDivider);
-
- if(localmaxwakeuptimersetup >= 0xFFFF)
- {
- MaxWakeupTimerSetup = 0xFFFF;
- }
- else
- {
- MaxWakeupTimerSetup = (uint16_t)localmaxwakeuptimersetup;
- }
-
- /**
- * Configure EXTI module
- */
- LL_EXTI_EnableRisingTrig_0_31(RTC_EXTI_LINE_WAKEUPTIMER_EVENT);
- LL_EXTI_EnableIT_0_31(RTC_EXTI_LINE_WAKEUPTIMER_EVENT);
-
- if(TimerInitMode == hw_ts_InitMode_Full)
- {
- WakeupTimerLimitation = WakeupTimerValue_LargeEnough;
- SSRValueOnLastSetup = SSR_FORBIDDEN_VALUE;
-
- /**
- * Initialize the timer server
- */
- for(loop = 0; loop < CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER; loop++)
- {
- aTimerContext[loop].TimerIDStatus = TimerID_Free;
- }
-
- CurrentRunningTimerID = CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER; /**< Set ID to non valid value */
-
- __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc); /**< Disable the Wakeup Timer */
- __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(phrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */
- __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */
- HAL_NVIC_ClearPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Clear pending bit in NVIC */
- __HAL_RTC_WAKEUPTIMER_ENABLE_IT(phrtc, RTC_IT_WUT); /**< Enable interrupt in RTC module */
- }
- else
- {
- if(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTF) != RESET)
- {
- /**
- * Simulate that the Timer expired
- */
- HAL_NVIC_SetPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID);
- }
- }
-
- /* Enable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_ENABLE( phrtc );
-
- HAL_NVIC_SetPriority(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID, CFG_HW_TS_NVIC_RTC_WAKEUP_IT_PREEMPTPRIO, CFG_HW_TS_NVIC_RTC_WAKEUP_IT_SUBPRIO); /**< Set NVIC priority */
- HAL_NVIC_EnableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Enable NVIC */
-
- return;
-}
-
-HW_TS_ReturnStatus_t HW_TS_Create(uint32_t TimerProcessID, uint8_t *pTimerId, HW_TS_Mode_t TimerMode, HW_TS_pTimerCb_t pftimeout_handler)
-{
- HW_TS_ReturnStatus_t localreturnstatus;
- uint8_t loop = 0;
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- uint32_t primask_bit;
-#endif
-
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
- __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
-#endif
-
- while((loop < CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) && (aTimerContext[loop].TimerIDStatus != TimerID_Free))
- {
- loop++;
- }
-
- if(loop != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
- {
- aTimerContext[loop].TimerIDStatus = TimerID_Created;
-
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
-#endif
-
- aTimerContext[loop].TimerProcessID = TimerProcessID;
- aTimerContext[loop].TimerMode = TimerMode;
- aTimerContext[loop].pTimerCallBack = pftimeout_handler;
- *pTimerId = loop;
-
- localreturnstatus = hw_ts_Successful;
- }
- else
- {
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
-#endif
-
- localreturnstatus = hw_ts_Failed;
- }
-
- return(localreturnstatus);
-}
-
-void HW_TS_Delete(uint8_t timer_id)
-{
- HW_TS_Stop(timer_id);
-
- aTimerContext[timer_id].TimerIDStatus = TimerID_Free; /**< release ID */
-
- return;
-}
-
-void HW_TS_Stop(uint8_t timer_id)
-{
- uint8_t localcurrentrunningtimerid;
-
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- uint32_t primask_bit;
-#endif
-
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
- __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
-#endif
-
- HAL_NVIC_DisableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Disable NVIC */
-
- /* Disable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc );
-
- if(aTimerContext[timer_id].TimerIDStatus == TimerID_Running)
- {
- UnlinkTimer(timer_id, SSR_Read_Requested);
- localcurrentrunningtimerid = CurrentRunningTimerID;
-
- if(localcurrentrunningtimerid == CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
- {
- /**
- * List is empty
- */
-
- /**
- * Disable the timer
- */
- if((READ_BIT(RTC->CR, RTC_CR_WUTE) == (RTC_CR_WUTE)) == SET)
- {
- /**
- * Wait for the flag to be back to 0 when the wakeup timer is enabled
- */
- while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == SET);
- }
- __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc); /**< Disable the Wakeup Timer */
-
- while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == RESET);
-
- /**
- * make sure to clear the flags after checking the WUTWF.
- * It takes 2 RTCCLK between the time the WUTE bit is disabled and the
- * time the timer is disabled. The WUTWF bit somehow guarantee the system is stable
- * Otherwise, when the timer is periodic with 1 Tick, it may generate an extra interrupt in between
- * due to the autoreload feature
- */
- __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(phrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */
- __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */
- HAL_NVIC_ClearPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Clear pending bit in NVIC */
- }
- else if(PreviousRunningTimerID != localcurrentrunningtimerid)
- {
- RescheduleTimerList();
- }
- }
-
- /* Enable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_ENABLE( phrtc );
-
- HAL_NVIC_EnableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Enable NVIC */
-
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
-#endif
-
- return;
-}
-
-void HW_TS_Start(uint8_t timer_id, uint32_t timeout_ticks)
-{
- uint16_t time_elapsed;
- uint8_t localcurrentrunningtimerid;
-
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- uint32_t primask_bit;
-#endif
-
- if(aTimerContext[timer_id].TimerIDStatus == TimerID_Running)
- {
- HW_TS_Stop( timer_id );
- }
-
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
- __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
-#endif
-
- HAL_NVIC_DisableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Disable NVIC */
-
- /* Disable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc );
-
- aTimerContext[timer_id].TimerIDStatus = TimerID_Running;
-
- aTimerContext[timer_id].CountLeft = timeout_ticks;
- aTimerContext[timer_id].CounterInit = timeout_ticks;
-
- time_elapsed = linkTimer(timer_id);
-
- localcurrentrunningtimerid = CurrentRunningTimerID;
-
- if(PreviousRunningTimerID != localcurrentrunningtimerid)
- {
- RescheduleTimerList();
- }
- else
- {
- aTimerContext[timer_id].CountLeft -= time_elapsed;
- }
-
- /* Enable the write protection for RTC registers */
- __HAL_RTC_WRITEPROTECTION_ENABLE( phrtc );
-
- HAL_NVIC_EnableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Enable NVIC */
-
-#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
- __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
-#endif
-
- return;
-}
-
-uint16_t HW_TS_RTC_ReadLeftTicksToCount(void)
-{
- uint32_t primask_bit;
- uint16_t return_value, auro_reload_value, elapsed_time_value;
-
- primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
- __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
-
- if((READ_BIT(RTC->CR, RTC_CR_WUTE) == (RTC_CR_WUTE)) == SET)
- {
- auro_reload_value = (uint32_t)(READ_BIT(RTC->WUTR, RTC_WUTR_WUT));
-
- elapsed_time_value = ReturnTimeElapsed();
-
- if(auro_reload_value > elapsed_time_value)
- {
- return_value = auro_reload_value - elapsed_time_value;
- }
- else
- {
- return_value = 0;
- }
- }
- else
- {
- return_value = TIMER_LIST_EMPTY;
- }
-
- __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
-
- return (return_value);
-}
-
-__weak void HW_TS_RTC_Int_AppNot(uint32_t TimerProcessID, uint8_t TimerID, HW_TS_pTimerCb_t pTimerCallBack)
-{
- pTimerCallBack();
-
- return;
-}
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/firmware/targets/f7/furi-hal/furi-hal-bootloader.c b/firmware/targets/f7/furi-hal/furi-hal-bootloader.c
index e8ea913e..b5e7cb5c 100644
--- a/firmware/targets/f7/furi-hal/furi-hal-bootloader.c
+++ b/firmware/targets/f7/furi-hal/furi-hal-bootloader.c
@@ -23,11 +23,3 @@ void furi_hal_bootloader_set_mode(FuriHalBootloaderMode mode) {
LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR0, BOOT_REQUEST_DFU);
}
}
-
-void furi_hal_bootloader_set_flags(FuriHalBootloaderFlag flags) {
- LL_RTC_BAK_SetRegister(RTC, LL_RTC_BKP_DR2, flags);
-}
-
-FuriHalBootloaderFlag furi_hal_bootloader_get_flags() {
- return LL_RTC_BAK_GetRegister(RTC, LL_RTC_BKP_DR2);
-} \ No newline at end of file
diff --git a/firmware/targets/f7/furi-hal/furi-hal-clock.c b/firmware/targets/f7/furi-hal/furi-hal-clock.c
index 7a124049..ddbeaa0b 100644
--- a/firmware/targets/f7/furi-hal/furi-hal-clock.c
+++ b/firmware/targets/f7/furi-hal/furi-hal-clock.c
@@ -77,14 +77,6 @@ void furi_hal_clock_init() {
Error_Handler();
}
- if(LL_RCC_GetRTCClockSource() != LL_RCC_RTC_CLKSOURCE_LSE) {
- LL_RCC_ForceBackupDomainReset();
- LL_RCC_ReleaseBackupDomainReset();
- LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE);
- }
-
- LL_RCC_EnableRTC();
-
LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK2);
LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_PCLK1);
LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSOURCE_PLLSAI1);
@@ -118,7 +110,6 @@ void furi_hal_clock_init() {
LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_AES2);
// APB1
- LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB);
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPUART1);
diff --git a/firmware/targets/f7/furi-hal/furi-hal-interrupt.c b/firmware/targets/f7/furi-hal/furi-hal-interrupt.c
index 2685edab..4ff2bc7b 100644
--- a/firmware/targets/f7/furi-hal/furi-hal-interrupt.c
+++ b/firmware/targets/f7/furi-hal/furi-hal-interrupt.c
@@ -158,7 +158,6 @@ void DMA2_Channel8_IRQHandler(void) {
if (furi_hal_dma_channel_isr[1][7]) furi_hal_dma_channel_isr[1][7]();
}
-
void TAMP_STAMP_LSECSS_IRQHandler(void) {
if (LL_RCC_IsActiveFlag_LSECSS()) {
LL_RCC_ClearFlag_LSECSS();
@@ -174,7 +173,6 @@ void TAMP_STAMP_LSECSS_IRQHandler(void) {
void RCC_IRQHandler(void) {
}
-
void NMI_Handler(void) {
if (LL_RCC_IsActiveFlag_HSECSS()) {
LL_RCC_ClearFlag_HSECSS();
@@ -206,5 +204,4 @@ void UsageFault_Handler(void) {
}
void DebugMon_Handler(void) {
-
}
diff --git a/firmware/targets/f7/furi-hal/furi-hal-rtc.c b/firmware/targets/f7/furi-hal/furi-hal-rtc.c
new file mode 100644
index 00000000..13bb17cb
--- /dev/null
+++ b/firmware/targets/f7/furi-hal/furi-hal-rtc.c
@@ -0,0 +1,122 @@
+#include <furi-hal-rtc.h>
+#include <stm32wbxx_ll_rcc.h>
+#include <stm32wbxx_ll_rtc.h>
+
+#include <furi.h>
+
+#define TAG "FuriHalRtc"
+
+#define FURI_HAL_RTC_BOOT_FLAGS_REG LL_RTC_BKP_DR0
+#define FURI_HAL_RTC_BOOT_VERSION_REG LL_RTC_BKP_DR1
+#define FURI_HAL_RTC_SYSTEM_REG LL_RTC_BKP_DR2
+
+typedef struct {
+ uint8_t log_level:4;
+ uint8_t log_reserved:4;
+ uint8_t flags;
+ uint16_t reserved;
+} DeveloperReg;
+
+void furi_hal_rtc_init() {
+ if(LL_RCC_GetRTCClockSource() != LL_RCC_RTC_CLKSOURCE_LSE) {
+ LL_RCC_ForceBackupDomainReset();
+ LL_RCC_ReleaseBackupDomainReset();
+ LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE);
+ }
+
+ LL_RCC_EnableRTC();
+ LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB);
+
+ LL_RTC_InitTypeDef RTC_InitStruct = {0};
+ RTC_InitStruct.HourFormat = LL_RTC_HOURFORMAT_24HOUR;
+ RTC_InitStruct.AsynchPrescaler = 127;
+ RTC_InitStruct.SynchPrescaler = 255;
+ LL_RTC_Init(RTC, &RTC_InitStruct);
+
+ furi_log_set_level(furi_hal_rtc_get_log_level());
+
+ FURI_LOG_I(TAG, "Init OK");
+}
+
+void furi_hal_rtc_set_log_level(uint8_t level) {
+ uint32_t data = LL_RTC_BAK_GetRegister(RTC, FURI_HAL_RTC_SYSTEM_REG);
+ ((DeveloperReg*)&data)->log_level = level;
+ LL_RTC_BAK_SetRegister(RTC, FURI_HAL_RTC_SYSTEM_REG, data);
+ furi_log_set_level(level);
+}
+
+uint8_t furi_hal_rtc_get_log_level() {
+ uint32_t data = LL_RTC_BAK_GetRegister(RTC, FURI_HAL_RTC_SYSTEM_REG);
+ return ((DeveloperReg*)&data)->log_level;
+}
+
+void furi_hal_rtc_set_flag(FuriHalRtcFlag flag) {
+ uint32_t data = LL_RTC_BAK_GetRegister(RTC, FURI_HAL_RTC_SYSTEM_REG);
+ ((DeveloperReg*)&data)->flags |= flag;
+ LL_RTC_BAK_SetRegister(RTC, FURI_HAL_RTC_SYSTEM_REG, data);
+}
+
+void furi_hal_rtc_reset_flag(FuriHalRtcFlag flag) {
+ uint32_t data = LL_RTC_BAK_GetRegister(RTC, FURI_HAL_RTC_SYSTEM_REG);
+ ((DeveloperReg*)&data)->flags &= ~flag;
+ LL_RTC_BAK_SetRegister(RTC, FURI_HAL_RTC_SYSTEM_REG, data);
+}
+
+bool furi_hal_rtc_is_flag_set(FuriHalRtcFlag flag) {
+ uint32_t data = LL_RTC_BAK_GetRegister(RTC, FURI_HAL_RTC_SYSTEM_REG);
+ return ((DeveloperReg*)&data)->flags & flag;
+}
+
+void furi_hal_rtc_set_datetime(FuriHalRtcDateTime* datetime) {
+ furi_assert(datetime);
+
+ /* Disable write protection */
+ LL_RTC_DisableWriteProtection(RTC);
+
+ /* Enter Initialization mode and wait for INIT flag to be set */
+ LL_RTC_EnableInitMode(RTC);
+ while(!LL_RTC_IsActiveFlag_INIT(RTC)) {}
+
+ /* Set time */
+ LL_RTC_TIME_Config(RTC,
+ LL_RTC_TIME_FORMAT_AM_OR_24,
+ __LL_RTC_CONVERT_BIN2BCD(datetime->hour),
+ __LL_RTC_CONVERT_BIN2BCD(datetime->minute),
+ __LL_RTC_CONVERT_BIN2BCD(datetime->second)
+ );
+
+ /* Set date */
+ LL_RTC_DATE_Config(RTC,
+ datetime->weekday,
+ __LL_RTC_CONVERT_BIN2BCD(datetime->day),
+ __LL_RTC_CONVERT_BIN2BCD(datetime->month),
+ __LL_RTC_CONVERT_BIN2BCD(datetime->year - 2000)
+ );
+
+ /* Exit Initialization mode */
+ LL_RTC_DisableInitMode(RTC);
+
+ /* If RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */
+ if (!LL_RTC_IsShadowRegBypassEnabled(RTC)) {
+ LL_RTC_ClearFlag_RS(RTC);
+ while(!LL_RTC_IsActiveFlag_RS(RTC)) {};
+ }
+
+ /* Enable write protection */
+ LL_RTC_EnableWriteProtection(RTC);
+}
+
+void furi_hal_rtc_get_datetime(FuriHalRtcDateTime* datetime) {
+ furi_assert(datetime);
+
+ uint32_t time = LL_RTC_TIME_Get(RTC); // 0x00HHMMSS
+ uint32_t date = LL_RTC_DATE_Get(RTC); // 0xWWDDMMYY
+
+ datetime->second = __LL_RTC_CONVERT_BCD2BIN((time>>0) & 0xFF);
+ datetime->minute = __LL_RTC_CONVERT_BCD2BIN((time>>8) & 0xFF);
+ datetime->hour = __LL_RTC_CONVERT_BCD2BIN((time>>16) & 0xFF);
+ datetime->year = __LL_RTC_CONVERT_BCD2BIN((date >> 0) & 0xFF) + 2000;
+ datetime->month = __LL_RTC_CONVERT_BCD2BIN((date >> 8) & 0xFF);
+ datetime->day = __LL_RTC_CONVERT_BCD2BIN((date >> 16) & 0xFF);
+ datetime->weekday = __LL_RTC_CONVERT_BCD2BIN((date >> 24) & 0xFF);
+}
diff --git a/firmware/targets/f7/furi-hal/furi-hal.c b/firmware/targets/f7/furi-hal/furi-hal.c
index d213af95..3f41684f 100644
--- a/firmware/targets/f7/furi-hal/furi-hal.c
+++ b/firmware/targets/f7/furi-hal/furi-hal.c
@@ -1,7 +1,6 @@
#include <furi-hal.h>
#include <comp.h>
-#include <rtc.h>
#include <tim.h>
#include <gpio.h>
@@ -13,18 +12,14 @@
void furi_hal_init() {
furi_hal_clock_init();
+ furi_hal_rtc_init();
furi_hal_console_init();
furi_hal_interrupt_init();
furi_hal_delay_init();
- // FreeRTOS glue
- furi_hal_os_init();
-
MX_GPIO_Init();
FURI_LOG_I(TAG, "GPIO OK");
- MX_RTC_Init();
- FURI_LOG_I(TAG, "RTC OK");
furi_hal_bootloader_init();
furi_hal_version_init();
@@ -59,6 +54,9 @@ void furi_hal_init() {
furi_hal_bt_init();
furi_hal_compress_icon_init();
+ // FreeRTOS glue
+ furi_hal_os_init();
+
// FatFS driver initialization
MX_FATFS_Init();
FURI_LOG_I(TAG, "FATFS OK");
diff --git a/firmware/targets/f7/target.mk b/firmware/targets/f7/target.mk
index f54f3f25..e642e2aa 100644
--- a/firmware/targets/f7/target.mk
+++ b/firmware/targets/f7/target.mk
@@ -57,7 +57,6 @@ C_SOURCES += \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr_ex.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc.c \
- $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rtc.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rtc_ex.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_tim.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_tim_ex.c \
@@ -67,6 +66,7 @@ C_SOURCES += \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_i2c.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_lptim.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_rcc.c \
+ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_rtc.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_spi.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_tim.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usart.c \
diff --git a/firmware/targets/furi-hal-include/furi-hal-bootloader.h b/firmware/targets/furi-hal-include/furi-hal-bootloader.h
index a1ef2c26..8dd2901f 100644
--- a/firmware/targets/furi-hal-include/furi-hal-bootloader.h
+++ b/firmware/targets/furi-hal-include/furi-hal-bootloader.h
@@ -17,12 +17,6 @@ typedef enum {
FuriHalBootloaderModeDFU
} FuriHalBootloaderMode;
-/** Boot flags */
-typedef enum {
- FuriHalBootloaderFlagDefault=0,
- FuriHalBootloaderFlagFactoryReset=1,
-} FuriHalBootloaderFlag;
-
/** Initialize boot subsystem
*/
void furi_hal_bootloader_init();
@@ -33,18 +27,6 @@ void furi_hal_bootloader_init();
*/
void furi_hal_bootloader_set_mode(FuriHalBootloaderMode mode);
-/** Set bootloader flags
- *
- * @param[in] flags FuriHalBootloaderFlag
- */
-void furi_hal_bootloader_set_flags(FuriHalBootloaderFlag flags);
-
-/** Get boot flag
- *
- * @return FuriHalBootloaderFlag
- */
-FuriHalBootloaderFlag furi_hal_bootloader_get_flags();
-
#ifdef __cplusplus
}
#endif
diff --git a/firmware/targets/furi-hal-include/furi-hal-rtc.h b/firmware/targets/furi-hal-include/furi-hal-rtc.h
new file mode 100644
index 00000000..7c36aa09
--- /dev/null
+++ b/firmware/targets/furi-hal-include/furi-hal-rtc.h
@@ -0,0 +1,52 @@
+/**
+ * @file furi-hal-rtc.h
+ * Furi Hal RTC API
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <main.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ // Time
+ uint8_t hour; /**< Hour in 24H format: 0-23 */
+ uint8_t minute; /**< Minute: 0-59 */
+ uint8_t second; /**< Second: 0-59 */
+ // Date
+ uint8_t day; /**< Current day: 1-31 */
+ uint8_t month; /**< Current month: 1-12 */
+ uint16_t year; /**< Current year: 2000-2099 */
+ uint8_t weekday;/**< Current weekday: 1-7 */
+} FuriHalRtcDateTime;
+
+typedef enum {
+ FuriHalRtcFlagDebug = (1<<0),
+ FuriHalRtcFlagFactoryReset = (1<<1),
+} FuriHalRtcFlag;
+
+/** Initialize RTC subsystem */
+void furi_hal_rtc_init();
+
+void furi_hal_rtc_set_log_level(uint8_t level);
+
+uint8_t furi_hal_rtc_get_log_level();
+
+void furi_hal_rtc_set_flag(FuriHalRtcFlag flag);
+
+void furi_hal_rtc_reset_flag(FuriHalRtcFlag flag);
+
+bool furi_hal_rtc_is_flag_set(FuriHalRtcFlag flag);
+
+void furi_hal_rtc_set_datetime(FuriHalRtcDateTime* datetime);
+
+void furi_hal_rtc_get_datetime(FuriHalRtcDateTime* datetime);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/firmware/targets/furi-hal-include/furi-hal.h b/firmware/targets/furi-hal-include/furi-hal.h
index 4c223aab..f7613625 100644
--- a/firmware/targets/furi-hal-include/furi-hal.h
+++ b/firmware/targets/furi-hal-include/furi-hal.h
@@ -17,6 +17,7 @@ template <unsigned int N> struct STOP_EXTERNING_ME {};
#include "furi-hal-sd.h"
#include "furi-hal-i2c.h"
#include "furi-hal-resources.h"
+#include "furi-hal-rtc.h"
#include "furi-hal-gpio.h"
#include "furi-hal-light.h"
#include "furi-hal-delay.h"