diff --git a/applications/applications.c b/applications/applications.c index 82a0c833..76a13b86 100644 --- a/applications/applications.c +++ b/applications/applications.c @@ -65,6 +65,7 @@ extern int32_t bt_settings_app(void* p); extern int32_t desktop_settings_app(void* p); extern int32_t about_settings_app(void* p); extern int32_t power_settings_app(void* p); +extern int32_t system_settings_app(void* p); const FlipperApplication FLIPPER_SERVICES[] = { /* Services */ @@ -312,6 +313,10 @@ const FlipperApplication FLIPPER_SETTINGS_APPS[] = { {.app = passport_app, .name = "Passport", .stack_size = 1024, .icon = NULL}, #endif +#ifdef SRV_GUI + {.app = system_settings_app, .name = "System", .stack_size = 1024, .icon = NULL}, +#endif + #ifdef APP_ABOUT {.app = about_settings_app, .name = "About", .stack_size = 1024, .icon = NULL}, #endif diff --git a/applications/applications.mk b/applications/applications.mk index e98e4fb9..e067faef 100644 --- a/applications/applications.mk +++ b/applications/applications.mk @@ -316,9 +316,3 @@ SRV_STORAGE ?= 0 ifeq ($(SRV_STORAGE), 1) CFLAGS += -DSRV_STORAGE endif - - -LAB_TESTS ?= 0 -ifeq ($(LAB_TESTS), 1) -CFLAGS += -DLAB_TESTS -endif \ No newline at end of file diff --git a/applications/cli/cli_commands.c b/applications/cli/cli_commands.c index c3e51656..7f194220 100644 --- a/applications/cli/cli_commands.c +++ b/applications/cli/cli_commands.c @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include @@ -58,46 +57,40 @@ void cli_command_help(Cli* cli, string_t args, void* context) { } void cli_command_date(Cli* cli, string_t args, void* context) { - RTC_TimeTypeDef time; - RTC_DateTypeDef date; + FuriHalRtcDateTime datetime = {0}; if(string_size(args) > 0) { - uint16_t Hours, Minutes, Seconds, Month, Date, Year, WeekDay; + uint16_t hours, minutes, seconds, month, day, year, weekday; int ret = sscanf( string_get_cstr(args), "%hu:%hu:%hu %hu-%hu-%hu %hu", - &Hours, - &Minutes, - &Seconds, - &Month, - &Date, - &Year, - &WeekDay); + &hours, + &minutes, + &seconds, + &month, + &day, + &year, + &weekday); if(ret == 7) { - time.Hours = Hours; - time.Minutes = Minutes; - time.Seconds = Seconds; - time.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; - time.StoreOperation = RTC_STOREOPERATION_RESET; - date.WeekDay = WeekDay; - date.Month = Month; - date.Date = Date; - date.Year = Year - 2000; - HAL_RTC_SetTime(&hrtc, &time, RTC_FORMAT_BIN); - HAL_RTC_SetDate(&hrtc, &date, RTC_FORMAT_BIN); - + datetime.hour = hours; + datetime.minute = minutes; + datetime.second = seconds; + datetime.weekday = weekday; + datetime.month = month; + datetime.day = day; + datetime.year = year; + furi_hal_rtc_set_datetime(&datetime); // Verification - HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN); - HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN); + furi_hal_rtc_get_datetime(&datetime); printf( "New time is: %.2d:%.2d:%.2d %.2d-%.2d-%.2d %d", - time.Hours, - time.Minutes, - time.Seconds, - date.Month, - date.Date, - 2000 + date.Year, - date.WeekDay); + datetime.hour, + datetime.minute, + datetime.second, + datetime.month, + datetime.day, + datetime.year, + datetime.weekday); } else { printf( "Invalid time format, use `hh:mm:ss MM-DD-YYYY WD`. sscanf %d %s", @@ -106,19 +99,16 @@ void cli_command_date(Cli* cli, string_t args, void* context) { return; } } else { - // TODO add get_datetime to core, not use HAL here - // READ ORDER MATTERS! Time then date. - HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN); - HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN); + furi_hal_rtc_get_datetime(&datetime); printf( "%.2d:%.2d:%.2d %.2d-%.2d-%.2d %d", - time.Hours, - time.Minutes, - time.Seconds, - date.Month, - date.Date, - 2000 + date.Year, - date.WeekDay); + datetime.hour, + datetime.minute, + datetime.second, + datetime.month, + datetime.day, + datetime.year, + datetime.weekday); } } diff --git a/applications/dolphin/helpers/dolphin_state.c b/applications/dolphin/helpers/dolphin_state.c index 016d8a50..9efdecb8 100644 --- a/applications/dolphin/helpers/dolphin_state.c +++ b/applications/dolphin/helpers/dolphin_state.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -70,20 +71,18 @@ bool dolphin_state_load(DolphinState* dolphin_state) { } uint64_t dolphin_state_timestamp() { - RTC_TimeTypeDef time; - RTC_DateTypeDef date; + FuriHalRtcDateTime datetime; struct tm current; - HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN); - HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN); + furi_hal_rtc_get_datetime(&datetime); - current.tm_year = date.Year + 100; - current.tm_mday = date.Date; - current.tm_mon = date.Month - 1; + current.tm_year = datetime.year - 1900; + current.tm_mday = datetime.day; + current.tm_mon = datetime.month - 1; - current.tm_hour = time.Hours; - current.tm_min = time.Minutes; - current.tm_sec = time.Seconds; + current.tm_hour = datetime.hour; + current.tm_min = datetime.minute; + current.tm_sec = datetime.second; return mktime(¤t); } diff --git a/applications/dolphin/helpers/dolphin_state.h b/applications/dolphin/helpers/dolphin_state.h index 1196e256..8c9f3aa9 100644 --- a/applications/dolphin/helpers/dolphin_state.h +++ b/applications/dolphin/helpers/dolphin_state.h @@ -3,7 +3,6 @@ #include "dolphin_deed.h" #include #include -#include #include typedef struct DolphinState DolphinState; diff --git a/applications/nfc/nfc_i.h b/applications/nfc/nfc_i.h index 61a11ce8..2563ee01 100755 --- a/applications/nfc/nfc_i.h +++ b/applications/nfc/nfc_i.h @@ -6,6 +6,7 @@ #include "nfc_device.h" #include +#include #include #include diff --git a/applications/nfc/scenes/nfc_scene_start.c b/applications/nfc/scenes/nfc_scene_start.c old mode 100755 new mode 100644 index 18780dfe..b99580d2 --- a/applications/nfc/scenes/nfc_scene_start.c +++ b/applications/nfc/scenes/nfc_scene_start.c @@ -5,9 +5,7 @@ enum SubmenuIndex { SubmenuIndexRunScript, SubmenuIndexSaved, SubmenuIndexAddManualy, -#ifdef LAB_TESTS SubmenuIndexDebug, -#endif }; void nfc_scene_start_submenu_callback(void* context, uint32_t index) { @@ -32,9 +30,12 @@ void nfc_scene_start_on_enter(void* context) { submenu, "Saved cards", SubmenuIndexSaved, nfc_scene_start_submenu_callback, nfc); submenu_add_item( submenu, "Add manually", SubmenuIndexAddManualy, nfc_scene_start_submenu_callback, nfc); -#ifdef LAB_TESTS - submenu_add_item(submenu, "Debug", SubmenuIndexDebug, nfc_scene_start_submenu_callback, nfc); -#endif + + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { + submenu_add_item( + submenu, "Debug", SubmenuIndexDebug, nfc_scene_start_submenu_callback, nfc); + } + submenu_set_selected_item( submenu, scene_manager_get_scene_state(nfc->scene_manager, NfcSceneStart)); @@ -65,12 +66,10 @@ bool nfc_scene_start_on_event(void* context, SceneManagerEvent event) { nfc->scene_manager, NfcSceneStart, SubmenuIndexAddManualy); scene_manager_next_scene(nfc->scene_manager, NfcSceneSetType); consumed = true; -#ifdef LAB_TESTS } else if(event.event == SubmenuIndexDebug) { scene_manager_set_scene_state(nfc->scene_manager, NfcSceneStart, SubmenuIndexDebug); scene_manager_next_scene(nfc->scene_manager, NfcSceneEmulateApduSequence); consumed = true; -#endif } } return consumed; diff --git a/applications/rpc/rpc_system.c b/applications/rpc/rpc_system.c index 2ce23129..01cb3145 100644 --- a/applications/rpc/rpc_system.c +++ b/applications/rpc/rpc_system.c @@ -2,8 +2,7 @@ #include "rpc_i.h" #include "status.pb.h" -#include -#include +#include #include void rpc_system_system_ping_process(const PB_Main* msg_request, void* context) { @@ -104,7 +103,7 @@ void rpc_system_system_factory_reset_process(const PB_Main* request, void* conte furi_assert(request->which_content == PB_Main_system_factory_reset_request_tag); furi_assert(context); - furi_hal_bootloader_set_flags(FuriHalBootloaderFlagFactoryReset); + furi_hal_rtc_set_flag(FuriHalRtcFlagFactoryReset); power_reboot(PowerBootModeNormal); } diff --git a/applications/snake-game/snake-game.c b/applications/snake-game/snake-game.c index c1debed2..e3fde566 100644 --- a/applications/snake-game/snake-game.c +++ b/applications/snake-game/snake-game.c @@ -322,7 +322,7 @@ int32_t snake_game_app(void* p) { ValueMutex state_mutex; if(!init_mutex(&state_mutex, snake_state, sizeof(SnakeState))) { - furi_log_print(FURI_LOG_ERROR, "cannot create mutex\r\n"); + FURI_LOG_E("SnakeGame", "cannot create mutex\r\n"); free(snake_state); return 255; } diff --git a/applications/storage/storage-cli.c b/applications/storage/storage-cli.c index fc80864b..c66a965d 100644 --- a/applications/storage/storage-cli.c +++ b/applications/storage/storage-cli.c @@ -526,7 +526,7 @@ static void storage_cli_factory_reset(Cli* cli, string_t args, void* context) { char c = cli_getc(cli); if(c == 'y' || c == 'Y') { printf("Data will be wiped after reboot.\r\n"); - furi_hal_bootloader_set_flags(FuriHalBootloaderFlagFactoryReset); + furi_hal_rtc_set_flag(FuriHalRtcFlagFactoryReset); power_reboot(PowerBootModeNormal); } else { printf("Safe choice.\r\n"); diff --git a/applications/storage/storages/storage-int.c b/applications/storage/storages/storage-int.c index 69ffe15e..097934b6 100644 --- a/applications/storage/storages/storage-int.c +++ b/applications/storage/storages/storage-int.c @@ -69,7 +69,7 @@ static int storage_int_device_read( LFSData* lfs_data = c->context; size_t address = lfs_data->start_address + block * c->block_size + off; - FURI_LOG_D( + FURI_LOG_T( TAG, "Device read: block %d, off %d, buffer: %p, size %d, translated address: %p", block, @@ -92,7 +92,7 @@ static int storage_int_device_prog( LFSData* lfs_data = c->context; size_t address = lfs_data->start_address + block * c->block_size + off; - FURI_LOG_D( + FURI_LOG_T( TAG, "Device prog: block %d, off %d, buffer: %p, size %d, translated address: %p", block, @@ -163,15 +163,14 @@ static LFSData* storage_int_lfs_data_alloc() { static void storage_int_lfs_mount(LFSData* lfs_data, StorageData* storage) { int err; - FuriHalBootloaderFlag bootloader_flags = furi_hal_bootloader_get_flags(); lfs_t* lfs = &lfs_data->lfs; - if(bootloader_flags & FuriHalBootloaderFlagFactoryReset) { + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagFactoryReset)) { // Factory reset err = lfs_format(lfs, &lfs_data->config); if(err == 0) { FURI_LOG_I(TAG, "Factory reset: Format successful, trying to mount"); - furi_hal_bootloader_set_flags(bootloader_flags & ~FuriHalBootloaderFlagFactoryReset); + furi_hal_rtc_reset_flag(FuriHalRtcFlagFactoryReset); err = lfs_mount(lfs, &lfs_data->config); if(err == 0) { FURI_LOG_I(TAG, "Factory reset: Mounted"); @@ -687,4 +686,4 @@ void storage_int_init(StorageData* storage) { storage->fs_api.common.rename = storage_int_common_rename; storage->fs_api.common.remove = storage_int_common_remove; storage->fs_api.common.fs_info = storage_int_common_fs_info; -} \ No newline at end of file +} diff --git a/applications/storage_settings/scenes/storage_settings_scene_factory_reset.c b/applications/storage_settings/scenes/storage_settings_scene_factory_reset.c index 5409a33e..0318612f 100644 --- a/applications/storage_settings/scenes/storage_settings_scene_factory_reset.c +++ b/applications/storage_settings/scenes/storage_settings_scene_factory_reset.c @@ -63,7 +63,7 @@ bool storage_settings_scene_factory_reset_on_event(void* context, SceneManagerEv scene_manager_set_scene_state( app->scene_manager, StorageSettingsFactoryReset, counter); } else { - furi_hal_bootloader_set_flags(FuriHalBootloaderFlagFactoryReset); + furi_hal_rtc_set_flag(FuriHalRtcFlagFactoryReset); power_reboot(PowerBootModeNormal); } diff --git a/applications/subghz/scenes/subghz_scene_start.c b/applications/subghz/scenes/subghz_scene_start.c index afc9117e..640c42ca 100644 --- a/applications/subghz/scenes/subghz_scene_start.c +++ b/applications/subghz/scenes/subghz_scene_start.c @@ -3,9 +3,7 @@ enum SubmenuIndex { SubmenuIndexRead = 10, SubmenuIndexSaved, -#ifdef LAB_TESTS SubmenuIndexTest, -#endif SubmenuIndexAddManualy, SubmenuIndexFrequencyAnalyzer, SubmenuIndexReadRAW, @@ -43,10 +41,10 @@ void subghz_scene_start_on_enter(void* context) { SubmenuIndexFrequencyAnalyzer, subghz_scene_start_submenu_callback, subghz); -#ifdef LAB_TESTS - submenu_add_item( - subghz->submenu, "Test", SubmenuIndexTest, subghz_scene_start_submenu_callback, subghz); -#endif + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { + submenu_add_item( + subghz->submenu, "Test", SubmenuIndexTest, subghz_scene_start_submenu_callback, subghz); + } submenu_set_selected_item( subghz->submenu, scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneStart)); @@ -83,13 +81,11 @@ bool subghz_scene_start_on_event(void* context, SceneManagerEvent event) { subghz->scene_manager, SubGhzSceneStart, SubmenuIndexFrequencyAnalyzer); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneFrequencyAnalyzer); return true; -#ifdef LAB_TESTS } else if(event.event == SubmenuIndexTest) { scene_manager_set_scene_state( subghz->scene_manager, SubGhzSceneStart, SubmenuIndexTest); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTest); return true; -#endif } } return false; diff --git a/applications/system/system_settings.c b/applications/system/system_settings.c new file mode 100644 index 00000000..f820645e --- /dev/null +++ b/applications/system/system_settings.c @@ -0,0 +1,121 @@ +#include "system_settings.h" + +static uint8_t + uint32_value_index(const uint32_t value, const uint32_t values[], uint8_t values_count) { + int64_t last_value = INT64_MIN; + uint8_t index = 0; + for(uint8_t i = 0; i < values_count; i++) { + if((value >= last_value) && (value <= values[i])) { + index = i; + break; + } + last_value = values[i]; + } + return index; +} + +const char* const log_level_text[] = { + "Default", + "None", + "Error", + "Warning", + "Info", + "Debug", + "Trace", +}; + +const uint32_t log_level_value[] = { + FuriLogLevelDefault, + FuriLogLevelNone, + FuriLogLevelError, + FuriLogLevelWarn, + FuriLogLevelInfo, + FuriLogLevelDebug, + FuriLogLevelTrace, +}; + +static void log_level_changed(VariableItem* item) { + // SystemSettings* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, log_level_text[index]); + furi_hal_rtc_set_log_level(log_level_value[index]); +} + +const char* const debug_text[] = { + "Disable", + "Enable", +}; + +static void debug_changed(VariableItem* item) { + uint8_t index = variable_item_get_current_value_index(item); + variable_item_set_current_value_text(item, debug_text[index]); + if(index) { + furi_hal_rtc_set_flag(FuriHalRtcFlagDebug); + } else { + furi_hal_rtc_reset_flag(FuriHalRtcFlagDebug); + } +} + +static uint32_t system_settings_exit(void* context) { + return VIEW_NONE; +} + +SystemSettings* system_settings_alloc() { + SystemSettings* app = furi_alloc(sizeof(SystemSettings)); + + // Load settings + app->gui = furi_record_open("gui"); + + app->view_dispatcher = view_dispatcher_alloc(); + view_dispatcher_enable_queue(app->view_dispatcher); + view_dispatcher_set_event_callback_context(app->view_dispatcher, app); + + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + + VariableItem* item; + uint8_t value_index; + app->var_item_list = variable_item_list_alloc(); + + item = variable_item_list_add( + app->var_item_list, "Log Level", COUNT_OF(log_level_text), log_level_changed, app); + value_index = uint32_value_index( + furi_hal_rtc_get_log_level(), log_level_value, COUNT_OF(log_level_text)); + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, log_level_text[value_index]); + + item = variable_item_list_add( + app->var_item_list, "Debug", COUNT_OF(debug_text), debug_changed, app); + value_index = furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug) ? 1 : 0; + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, debug_text[value_index]); + + view_set_previous_callback( + variable_item_list_get_view(app->var_item_list), system_settings_exit); + view_dispatcher_add_view( + app->view_dispatcher, + SystemSettingsViewVarItemList, + variable_item_list_get_view(app->var_item_list)); + + view_dispatcher_switch_to_view(app->view_dispatcher, SystemSettingsViewVarItemList); + + return app; +} + +void system_settings_free(SystemSettings* app) { + furi_assert(app); + // Variable item list + view_dispatcher_remove_view(app->view_dispatcher, SystemSettingsViewVarItemList); + variable_item_list_free(app->var_item_list); + // View dispatcher + view_dispatcher_free(app->view_dispatcher); + // Records + furi_record_close("gui"); + free(app); +} + +int32_t system_settings_app(void* p) { + SystemSettings* app = system_settings_alloc(); + view_dispatcher_run(app->view_dispatcher); + system_settings_free(app); + return 0; +} diff --git a/applications/system/system_settings.h b/applications/system/system_settings.h new file mode 100755 index 00000000..e2475a1e --- /dev/null +++ b/applications/system/system_settings.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +#include +#include +#include + +typedef struct { + Gui* gui; + ViewDispatcher* view_dispatcher; + VariableItemList* var_item_list; +} SystemSettings; + +typedef enum { + SystemSettingsViewVarItemList, +} SystemSettingsView; diff --git a/core/furi/log.c b/core/furi/log.c index d30e1202..3cf68a18 100644 --- a/core/furi/log.c +++ b/core/furi/log.c @@ -3,6 +3,8 @@ #include #include +#define FURI_LOG_LEVEL_DEFAULT FuriLogLevelInfo + typedef struct { FuriLogLevel log_level; FuriLogPuts puts; @@ -14,15 +16,13 @@ static FuriLogParams furi_log; void furi_log_init() { // Set default logging parameters - furi_log.log_level = FURI_LOG_LEVEL; + furi_log.log_level = FURI_LOG_LEVEL_DEFAULT; furi_log.puts = furi_hal_console_puts; furi_log.timetamp = HAL_GetTick; furi_log.mutex = osMutexNew(NULL); } void furi_log_print(FuriLogLevel level, const char* format, ...) { - va_list args; - va_start(args, format); if(level <= furi_log.log_level && osMutexAcquire(furi_log.mutex, osWaitForever) == osOK) { string_t string; @@ -41,10 +41,12 @@ void furi_log_print(FuriLogLevel level, const char* format, ...) { osMutexRelease(furi_log.mutex); } - va_end(args); } void furi_log_set_level(FuriLogLevel level) { + if(level == FuriLogLevelDefault) { + level = FURI_LOG_LEVEL_DEFAULT; + } furi_log.log_level = level; } diff --git a/core/furi/log.h b/core/furi/log.h index 69c3dfde..3c86698b 100644 --- a/core/furi/log.h +++ b/core/furi/log.h @@ -8,11 +8,15 @@ extern "C" { #endif -#define FURI_LOG_LEVEL_DEFAULT 3 - -#ifndef FURI_LOG_LEVEL -#define FURI_LOG_LEVEL FURI_LOG_LEVEL_DEFAULT -#endif +typedef enum { + FuriLogLevelDefault = 0, + FuriLogLevelNone = 1, + FuriLogLevelError = 2, + FuriLogLevelWarn = 3, + FuriLogLevelInfo = 4, + FuriLogLevelDebug = 5, + FuriLogLevelTrace = 6, +} FuriLogLevel; #define FURI_LOG_CLR(clr) "\033[0;" clr "m" #define FURI_LOG_CLR_RESET "\033[0m" @@ -28,20 +32,11 @@ extern "C" { #define FURI_LOG_CLR_W FURI_LOG_CLR(FURI_LOG_CLR_BROWN) #define FURI_LOG_CLR_I FURI_LOG_CLR(FURI_LOG_CLR_GREEN) #define FURI_LOG_CLR_D FURI_LOG_CLR(FURI_LOG_CLR_BLUE) -#define FURI_LOG_CLR_V +#define FURI_LOG_CLR_T FURI_LOG_CLR(FURI_LOG_CLR_PURPLE) typedef void (*FuriLogPuts)(const char* data); typedef uint32_t (*FuriLogTimestamp)(void); -typedef enum { - FURI_LOG_NONE = 0, - FURI_LOG_ERROR = 1, - FURI_LOG_WARN = 2, - FURI_LOG_INFO = 3, - FURI_LOG_DEBUG = 4, - FURI_LOG_VERBOSE = 5, -} FuriLogLevel; - void furi_log_init(); void furi_log_print(FuriLogLevel level, const char* format, ...); void furi_log_set_level(FuriLogLevel level); @@ -54,11 +49,14 @@ void furi_log_set_timestamp(FuriLogTimestamp timestamp); #define FURI_LOG_SHOW(tag, format, log_level, log_letter, ...) \ furi_log_print(log_level, FURI_LOG_FORMAT(log_letter, tag, format), ##__VA_ARGS__) -#define FURI_LOG_E(tag, format, ...) FURI_LOG_SHOW(tag, format, FURI_LOG_ERROR, E, ##__VA_ARGS__) -#define FURI_LOG_W(tag, format, ...) FURI_LOG_SHOW(tag, format, FURI_LOG_WARN, W, ##__VA_ARGS__) -#define FURI_LOG_I(tag, format, ...) FURI_LOG_SHOW(tag, format, FURI_LOG_INFO, I, ##__VA_ARGS__) -#define FURI_LOG_D(tag, format, ...) FURI_LOG_SHOW(tag, format, FURI_LOG_DEBUG, D, ##__VA_ARGS__) -#define FURI_LOG_V(tag, format, ...) FURI_LOG_SHOW(tag, format, FURI_LOG_VERBOSE, V, ##__VA_ARGS__) +#define FURI_LOG_E(tag, format, ...) \ + FURI_LOG_SHOW(tag, format, FuriLogLevelError, E, ##__VA_ARGS__) +#define FURI_LOG_W(tag, format, ...) FURI_LOG_SHOW(tag, format, FuriLogLevelWarn, W, ##__VA_ARGS__) +#define FURI_LOG_I(tag, format, ...) FURI_LOG_SHOW(tag, format, FuriLogLevelInfo, I, ##__VA_ARGS__) +#define FURI_LOG_D(tag, format, ...) \ + FURI_LOG_SHOW(tag, format, FuriLogLevelDebug, D, ##__VA_ARGS__) +#define FURI_LOG_T(tag, format, ...) \ + FURI_LOG_SHOW(tag, format, FuriLogLevelTrace, T, ##__VA_ARGS__) #ifdef __cplusplus } 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 - * - *

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

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* 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 - * - *

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

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* 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 - * - *

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

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* 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 +#include +#include + +#include + +#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 #include -#include #include #include @@ -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 - * - *

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

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* 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 - * - *

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

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* 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 - * - *

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

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ - -/* 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 +#include +#include + +#include + +#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 #include -#include #include #include @@ -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 +#include +#include + +#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 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" diff --git a/lib/lfs_config.h b/lib/lfs_config.h index 7a883982..a545551c 100644 --- a/lib/lfs_config.h +++ b/lib/lfs_config.h @@ -8,9 +8,9 @@ #define LFS_TAG "Lfs" -#define LFS_TRACE(...) FURI_LOG_D(LFS_TAG, __VA_ARGS__); +#define LFS_TRACE(...) FURI_LOG_T(LFS_TAG, __VA_ARGS__); -#define LFS_DEBUG(...) FURI_LOG_I(LFS_TAG, __VA_ARGS__); +#define LFS_DEBUG(...) FURI_LOG_D(LFS_TAG, __VA_ARGS__); #define LFS_WARN(...) FURI_LOG_W(LFS_TAG, __VA_ARGS__);