[FL-3024] Locale settings (#2137)
* Locale settings * Time/date format fix * Locale: add docs, enums for HAL, cleanup. Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
This commit is contained in:
		
							parent
							
								
									2dea6969fe
								
							
						
					
					
						commit
						f10e82c64d
					
				
							
								
								
									
										11
									
								
								applications/debug/locale_test/application.fam
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								applications/debug/locale_test/application.fam
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| App( | ||||
|     appid="locale_test", | ||||
|     name="Locale Test", | ||||
|     apptype=FlipperAppType.DEBUG, | ||||
|     entry_point="locale_test_app", | ||||
|     cdefines=["APP_LOCALE"], | ||||
|     requires=["gui", "locale"], | ||||
|     stack_size=2 * 1024, | ||||
|     order=70, | ||||
|     fap_category="Debug", | ||||
| ) | ||||
							
								
								
									
										102
									
								
								applications/debug/locale_test/locale_test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								applications/debug/locale_test/locale_test.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,102 @@ | ||||
| #include <furi.h> | ||||
| #include <gui/gui.h> | ||||
| #include <gui/elements.h> | ||||
| #include <gui/view_dispatcher.h> | ||||
| #include <gui/modules/dialog_ex.h> | ||||
| #include <locale/locale.h> | ||||
| 
 | ||||
| typedef struct { | ||||
|     Gui* gui; | ||||
|     ViewDispatcher* view_dispatcher; | ||||
|     View* view; | ||||
| } LocaleTestApp; | ||||
| 
 | ||||
| static void locale_test_view_draw_callback(Canvas* canvas, void* _model) { | ||||
|     UNUSED(_model); | ||||
| 
 | ||||
|     // Prepare canvas
 | ||||
|     canvas_set_color(canvas, ColorBlack); | ||||
|     canvas_set_font(canvas, FontSecondary); | ||||
| 
 | ||||
|     FuriString* tmp_string = furi_string_alloc(); | ||||
| 
 | ||||
|     float temp = 25.3f; | ||||
|     LocaleMeasurementUnits units = locale_get_measurement_unit(); | ||||
|     if(units == LocaleMeasurementUnitsMetric) { | ||||
|         furi_string_printf(tmp_string, "Temp: %5.1fC", (double)temp); | ||||
|     } else { | ||||
|         temp = locale_celsius_to_fahrenheit(temp); | ||||
|         furi_string_printf(tmp_string, "Temp: %5.1fF", (double)temp); | ||||
|     } | ||||
|     canvas_draw_str(canvas, 0, 10, furi_string_get_cstr(tmp_string)); | ||||
| 
 | ||||
|     FuriHalRtcDateTime datetime; | ||||
|     furi_hal_rtc_get_datetime(&datetime); | ||||
| 
 | ||||
|     locale_format_time(tmp_string, &datetime, locale_get_time_format(), false); | ||||
|     canvas_draw_str(canvas, 0, 25, furi_string_get_cstr(tmp_string)); | ||||
| 
 | ||||
|     locale_format_date(tmp_string, &datetime, locale_get_date_format(), "/"); | ||||
|     canvas_draw_str(canvas, 0, 40, furi_string_get_cstr(tmp_string)); | ||||
| 
 | ||||
|     furi_string_free(tmp_string); | ||||
| } | ||||
| 
 | ||||
| static bool locale_test_view_input_callback(InputEvent* event, void* context) { | ||||
|     UNUSED(event); | ||||
|     UNUSED(context); | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| static uint32_t locale_test_exit(void* context) { | ||||
|     UNUSED(context); | ||||
|     return VIEW_NONE; | ||||
| } | ||||
| 
 | ||||
| static LocaleTestApp* locale_test_alloc() { | ||||
|     LocaleTestApp* app = malloc(sizeof(LocaleTestApp)); | ||||
| 
 | ||||
|     // Gui
 | ||||
|     app->gui = furi_record_open(RECORD_GUI); | ||||
| 
 | ||||
|     // View dispatcher
 | ||||
|     app->view_dispatcher = view_dispatcher_alloc(); | ||||
|     view_dispatcher_enable_queue(app->view_dispatcher); | ||||
|     view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); | ||||
| 
 | ||||
|     // Views
 | ||||
|     app->view = view_alloc(); | ||||
|     view_set_draw_callback(app->view, locale_test_view_draw_callback); | ||||
|     view_set_input_callback(app->view, locale_test_view_input_callback); | ||||
| 
 | ||||
|     view_set_previous_callback(app->view, locale_test_exit); | ||||
|     view_dispatcher_add_view(app->view_dispatcher, 0, app->view); | ||||
|     view_dispatcher_switch_to_view(app->view_dispatcher, 0); | ||||
| 
 | ||||
|     return app; | ||||
| } | ||||
| 
 | ||||
| static void locale_test_free(LocaleTestApp* app) { | ||||
|     furi_assert(app); | ||||
| 
 | ||||
|     // Free views
 | ||||
|     view_dispatcher_remove_view(app->view_dispatcher, 0); | ||||
| 
 | ||||
|     view_free(app->view); | ||||
|     view_dispatcher_free(app->view_dispatcher); | ||||
| 
 | ||||
|     // Close gui record
 | ||||
|     furi_record_close(RECORD_GUI); | ||||
|     app->gui = NULL; | ||||
| 
 | ||||
|     // Free rest
 | ||||
|     free(app); | ||||
| } | ||||
| 
 | ||||
| int32_t locale_test_app(void* p) { | ||||
|     UNUSED(p); | ||||
|     LocaleTestApp* app = locale_test_alloc(); | ||||
|     view_dispatcher_run(app->view_dispatcher); | ||||
|     locale_test_free(app); | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										9
									
								
								applications/services/locale/application.fam
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								applications/services/locale/application.fam
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| App( | ||||
|     appid="locale", | ||||
|     name="LocaleSrv", | ||||
|     apptype=FlipperAppType.STARTUP, | ||||
|     entry_point="locale_on_system_start", | ||||
|     cdefines=["SRV_LOCALE"], | ||||
|     order=90, | ||||
|     sdk_headers=["locale.h"], | ||||
| ) | ||||
							
								
								
									
										109
									
								
								applications/services/locale/locale.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								applications/services/locale/locale.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | ||||
| #include "locale.h" | ||||
| 
 | ||||
| #define TAG "LocaleSrv" | ||||
| 
 | ||||
| LocaleMeasurementUnits locale_get_measurement_unit(void) { | ||||
|     return (LocaleMeasurementUnits)furi_hal_rtc_get_locale_units(); | ||||
| } | ||||
| 
 | ||||
| void locale_set_measurement_unit(LocaleMeasurementUnits format) { | ||||
|     furi_hal_rtc_set_locale_units((FuriHalRtcLocaleUnits)format); | ||||
| } | ||||
| 
 | ||||
| LocaleTimeFormat locale_get_time_format(void) { | ||||
|     return (LocaleTimeFormat)furi_hal_rtc_get_locale_timeformat(); | ||||
| } | ||||
| 
 | ||||
| void locale_set_time_format(LocaleTimeFormat format) { | ||||
|     furi_hal_rtc_set_locale_timeformat((FuriHalRtcLocaleTimeFormat)format); | ||||
| } | ||||
| 
 | ||||
| LocaleDateFormat locale_get_date_format(void) { | ||||
|     return (LocaleDateFormat)furi_hal_rtc_get_locale_dateformat(); | ||||
| } | ||||
| 
 | ||||
| void locale_set_date_format(LocaleDateFormat format) { | ||||
|     furi_hal_rtc_set_locale_dateformat((FuriHalRtcLocaleDateFormat)format); | ||||
| } | ||||
| 
 | ||||
| float locale_fahrenheit_to_celsius(float temp_f) { | ||||
|     return (temp_f - 32.f) / 1.8f; | ||||
| } | ||||
| 
 | ||||
| float locale_celsius_to_fahrenheit(float temp_c) { | ||||
|     return (temp_c * 1.8f + 32.f); | ||||
| } | ||||
| 
 | ||||
| void locale_format_time( | ||||
|     FuriString* out_str, | ||||
|     const FuriHalRtcDateTime* datetime, | ||||
|     const LocaleTimeFormat format, | ||||
|     const bool show_seconds) { | ||||
|     furi_assert(out_str); | ||||
|     furi_assert(datetime); | ||||
| 
 | ||||
|     uint8_t hours = datetime->hour; | ||||
|     uint8_t am_pm = 0; | ||||
|     if(format == LocaleTimeFormat12h) { | ||||
|         if(hours > 12) { | ||||
|             hours -= 12; | ||||
|             am_pm = 2; | ||||
|         } else { | ||||
|             am_pm = 1; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if(show_seconds) { | ||||
|         furi_string_printf(out_str, "%02u:%02u:%02u", hours, datetime->minute, datetime->second); | ||||
|     } else { | ||||
|         furi_string_printf(out_str, "%02u:%02u", hours, datetime->minute); | ||||
|     } | ||||
| 
 | ||||
|     if(am_pm > 0) { | ||||
|         furi_string_cat_printf(out_str, " %s", (am_pm == 1) ? ("AM") : ("PM")); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void locale_format_date( | ||||
|     FuriString* out_str, | ||||
|     const FuriHalRtcDateTime* datetime, | ||||
|     const LocaleDateFormat format, | ||||
|     const char* separator) { | ||||
|     furi_assert(out_str); | ||||
|     furi_assert(datetime); | ||||
|     furi_assert(separator); | ||||
| 
 | ||||
|     if(format == LocaleDateFormatDMY) { | ||||
|         furi_string_printf( | ||||
|             out_str, | ||||
|             "%02u%s%02u%s%04u", | ||||
|             datetime->day, | ||||
|             separator, | ||||
|             datetime->month, | ||||
|             separator, | ||||
|             datetime->year); | ||||
|     } else if(format == LocaleDateFormatMDY) { | ||||
|         furi_string_printf( | ||||
|             out_str, | ||||
|             "%02u%s%02u%s%04u", | ||||
|             datetime->month, | ||||
|             separator, | ||||
|             datetime->day, | ||||
|             separator, | ||||
|             datetime->year); | ||||
|     } else { | ||||
|         furi_string_printf( | ||||
|             out_str, | ||||
|             "%04u%s%02u%s%02u", | ||||
|             datetime->year, | ||||
|             separator, | ||||
|             datetime->month, | ||||
|             separator, | ||||
|             datetime->day); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| int32_t locale_on_system_start(void* p) { | ||||
|     UNUSED(p); | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										107
									
								
								applications/services/locale/locale.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								applications/services/locale/locale.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,107 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include <stdbool.h> | ||||
| #include <furi.h> | ||||
| #include <furi_hal.h> | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
| 
 | ||||
| typedef enum { | ||||
|     LocaleMeasurementUnitsMetric = 0, /**< Metric measurement units */ | ||||
|     LocaleMeasurementUnitsImperial = 1, /**< Imperial measurement units */ | ||||
| } LocaleMeasurementUnits; | ||||
| 
 | ||||
| typedef enum { | ||||
|     LocaleTimeFormat24h = 0, /**< 24-hour format */ | ||||
|     LocaleTimeFormat12h = 1, /**< 12-hour format */ | ||||
| } LocaleTimeFormat; | ||||
| 
 | ||||
| typedef enum { | ||||
|     LocaleDateFormatDMY = 0, /**< Day/Month/Year */ | ||||
|     LocaleDateFormatMDY = 1, /**< Month/Day/Year */ | ||||
|     LocaleDateFormatYMD = 2, /**< Year/Month/Day */ | ||||
| } LocaleDateFormat; | ||||
| 
 | ||||
| /** Get Locale measurement units
 | ||||
|  * | ||||
|  * @return     The locale measurement units. | ||||
|  */ | ||||
| LocaleMeasurementUnits locale_get_measurement_unit(); | ||||
| 
 | ||||
| /** Set locale measurement units
 | ||||
|  * | ||||
|  * @param[in]  format  The locale measurements units | ||||
|  */ | ||||
| void locale_set_measurement_unit(LocaleMeasurementUnits format); | ||||
| 
 | ||||
| /** Convert Fahrenheit to Celsius
 | ||||
|  * | ||||
|  * @param[in]  temp_f  The Temperature in Fahrenheit | ||||
|  * | ||||
|  * @return     The Temperature in Celsius  | ||||
|  */ | ||||
| float locale_fahrenheit_to_celsius(float temp_f); | ||||
| 
 | ||||
| /** Convert Celsius to Fahrenheit
 | ||||
|  * | ||||
|  * @param[in]  temp_c  The Temperature in Celsius  | ||||
|  * | ||||
|  * @return     The Temperature in Fahrenheit | ||||
|  */ | ||||
| float locale_celsius_to_fahrenheit(float temp_c); | ||||
| 
 | ||||
| /** Get Locale time format
 | ||||
|  * | ||||
|  * @return     The locale time format. | ||||
|  */ | ||||
| LocaleTimeFormat locale_get_time_format(); | ||||
| 
 | ||||
| /** Set Locale Time Format
 | ||||
|  * | ||||
|  * @param[in]  format  The Locale Time Format | ||||
|  */ | ||||
| void locale_set_time_format(LocaleTimeFormat format); | ||||
| 
 | ||||
| /** Format time to furi string
 | ||||
|  * | ||||
|  * @param[out] out_str       The FuriString to store formatted time | ||||
|  * @param[in]  datetime      Pointer to the datetime | ||||
|  * @param[in]  format        The Locale Time Format | ||||
|  * @param[in]  show_seconds  The show seconds flag | ||||
|  */ | ||||
| void locale_format_time( | ||||
|     FuriString* out_str, | ||||
|     const FuriHalRtcDateTime* datetime, | ||||
|     const LocaleTimeFormat format, | ||||
|     const bool show_seconds); | ||||
| 
 | ||||
| /** Get Locale DateFormat
 | ||||
|  * | ||||
|  * @return     The Locale DateFormat. | ||||
|  */ | ||||
| LocaleDateFormat locale_get_date_format(); | ||||
| 
 | ||||
| /** Set Locale DateFormat
 | ||||
|  * | ||||
|  * @param[in]  format  The Locale DateFormat | ||||
|  */ | ||||
| void locale_set_date_format(LocaleDateFormat format); | ||||
| 
 | ||||
| /** Format date to furi string
 | ||||
|  * | ||||
|  * @param[out] out_str    The FuriString to store formatted date | ||||
|  * @param[in]  datetime   Pointer to the datetime | ||||
|  * @param[in]  format     The format | ||||
|  * @param[in]  separator  The separator | ||||
|  */ | ||||
| void locale_format_date( | ||||
|     FuriString* out_str, | ||||
|     const FuriHalRtcDateTime* datetime, | ||||
|     const LocaleDateFormat format, | ||||
|     const char* separator); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| @ -3,7 +3,7 @@ App( | ||||
|     name="System", | ||||
|     apptype=FlipperAppType.SETTINGS, | ||||
|     entry_point="system_settings_app", | ||||
|     requires=["gui"], | ||||
|     requires=["gui", "locale"], | ||||
|     stack_size=1 * 1024, | ||||
|     order=70, | ||||
| ) | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| #include "system_settings.h" | ||||
| #include <loader/loader.h> | ||||
| #include <lib/toolbox/value_index.h> | ||||
| #include <locale/locale.h> | ||||
| 
 | ||||
| const char* const log_level_text[] = { | ||||
|     "Default", | ||||
| @ -70,6 +71,59 @@ static void heap_trace_mode_changed(VariableItem* item) { | ||||
|     furi_hal_rtc_set_heap_track_mode(heap_trace_mode_value[index]); | ||||
| } | ||||
| 
 | ||||
| const char* const mesurement_units_text[] = { | ||||
|     "Metric", | ||||
|     "Imperial", | ||||
| }; | ||||
| 
 | ||||
| const uint32_t mesurement_units_value[] = { | ||||
|     LocaleMeasurementUnitsMetric, | ||||
|     LocaleMeasurementUnitsImperial, | ||||
| }; | ||||
| 
 | ||||
| static void mesurement_units_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, mesurement_units_text[index]); | ||||
|     locale_set_measurement_unit(mesurement_units_value[index]); | ||||
| } | ||||
| 
 | ||||
| const char* const time_format_text[] = { | ||||
|     "24h", | ||||
|     "12h", | ||||
| }; | ||||
| 
 | ||||
| const uint32_t time_format_value[] = { | ||||
|     LocaleTimeFormat24h, | ||||
|     LocaleTimeFormat12h, | ||||
| }; | ||||
| 
 | ||||
| static void time_format_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, time_format_text[index]); | ||||
|     locale_set_time_format(time_format_value[index]); | ||||
| } | ||||
| 
 | ||||
| const char* const date_format_text[] = { | ||||
|     "D/M/Y", | ||||
|     "M/D/Y", | ||||
|     "Y/M/D", | ||||
| }; | ||||
| 
 | ||||
| const uint32_t date_format_value[] = { | ||||
|     LocaleDateFormatDMY, | ||||
|     LocaleDateFormatMDY, | ||||
|     LocaleDateFormatYMD, | ||||
| }; | ||||
| 
 | ||||
| static void date_format_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, date_format_text[index]); | ||||
|     locale_set_date_format(date_format_value[index]); | ||||
| } | ||||
| 
 | ||||
| static uint32_t system_settings_exit(void* context) { | ||||
|     UNUSED(context); | ||||
|     return VIEW_NONE; | ||||
| @ -91,6 +145,31 @@ SystemSettings* system_settings_alloc() { | ||||
|     uint8_t value_index; | ||||
|     app->var_item_list = variable_item_list_alloc(); | ||||
| 
 | ||||
|     item = variable_item_list_add( | ||||
|         app->var_item_list, | ||||
|         "Units", | ||||
|         COUNT_OF(mesurement_units_text), | ||||
|         mesurement_units_changed, | ||||
|         app); | ||||
|     value_index = value_index_uint32( | ||||
|         locale_get_measurement_unit(), mesurement_units_value, COUNT_OF(mesurement_units_value)); | ||||
|     variable_item_set_current_value_index(item, value_index); | ||||
|     variable_item_set_current_value_text(item, mesurement_units_text[value_index]); | ||||
| 
 | ||||
|     item = variable_item_list_add( | ||||
|         app->var_item_list, "Time Format", COUNT_OF(time_format_text), time_format_changed, app); | ||||
|     value_index = value_index_uint32( | ||||
|         locale_get_time_format(), time_format_value, COUNT_OF(time_format_value)); | ||||
|     variable_item_set_current_value_index(item, value_index); | ||||
|     variable_item_set_current_value_text(item, time_format_text[value_index]); | ||||
| 
 | ||||
|     item = variable_item_list_add( | ||||
|         app->var_item_list, "Date Format", COUNT_OF(date_format_text), date_format_changed, app); | ||||
|     value_index = value_index_uint32( | ||||
|         locale_get_date_format(), date_format_value, COUNT_OF(date_format_value)); | ||||
|     variable_item_set_current_value_index(item, value_index); | ||||
|     variable_item_set_current_value_text(item, date_format_text[value_index]); | ||||
| 
 | ||||
|     item = variable_item_list_add( | ||||
|         app->var_item_list, "Log Level", COUNT_OF(log_level_text), log_level_changed, app); | ||||
|     value_index = value_index_uint32( | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| entry,status,name,type,params | ||||
| Version,+,11.0,, | ||||
| Version,+,11.1,, | ||||
| Header,+,applications/services/bt/bt_service/bt.h,, | ||||
| Header,+,applications/services/cli/cli.h,, | ||||
| Header,+,applications/services/cli/cli_vcp.h,, | ||||
| @ -29,6 +29,7 @@ Header,+,applications/services/gui/view_dispatcher.h,, | ||||
| Header,+,applications/services/gui/view_stack.h,, | ||||
| Header,+,applications/services/input/input.h,, | ||||
| Header,+,applications/services/loader/loader.h,, | ||||
| Header,+,applications/services/locale/locale.h,, | ||||
| Header,+,applications/services/notification/notification.h,, | ||||
| Header,+,applications/services/notification/notification_messages.h,, | ||||
| Header,+,applications/services/power/power_service/power.h,, | ||||
| @ -1265,6 +1266,9 @@ Function,+,furi_hal_rtc_get_boot_mode,FuriHalRtcBootMode, | ||||
| Function,+,furi_hal_rtc_get_datetime,void,FuriHalRtcDateTime* | ||||
| Function,+,furi_hal_rtc_get_fault_data,uint32_t, | ||||
| Function,+,furi_hal_rtc_get_heap_track_mode,FuriHalRtcHeapTrackMode, | ||||
| Function,+,furi_hal_rtc_get_locale_dateformat,FuriHalRtcLocaleDateFormat, | ||||
| Function,+,furi_hal_rtc_get_locale_timeformat,FuriHalRtcLocaleTimeFormat, | ||||
| Function,+,furi_hal_rtc_get_locale_units,FuriHalRtcLocaleUnits, | ||||
| Function,+,furi_hal_rtc_get_log_level,uint8_t, | ||||
| Function,+,furi_hal_rtc_get_pin_fails,uint32_t, | ||||
| Function,+,furi_hal_rtc_get_register,uint32_t,FuriHalRtcRegister | ||||
| @ -1278,6 +1282,9 @@ Function,+,furi_hal_rtc_set_datetime,void,FuriHalRtcDateTime* | ||||
| Function,+,furi_hal_rtc_set_fault_data,void,uint32_t | ||||
| Function,+,furi_hal_rtc_set_flag,void,FuriHalRtcFlag | ||||
| Function,+,furi_hal_rtc_set_heap_track_mode,void,FuriHalRtcHeapTrackMode | ||||
| Function,+,furi_hal_rtc_set_locale_dateformat,void,FuriHalRtcLocaleDateFormat | ||||
| Function,+,furi_hal_rtc_set_locale_timeformat,void,FuriHalRtcLocaleTimeFormat | ||||
| Function,+,furi_hal_rtc_set_locale_units,void,FuriHalRtcLocaleUnits | ||||
| Function,+,furi_hal_rtc_set_log_level,void,uint8_t | ||||
| Function,+,furi_hal_rtc_set_pin_fails,void,uint32_t | ||||
| Function,+,furi_hal_rtc_set_register,void,"FuriHalRtcRegister, uint32_t" | ||||
| @ -1736,6 +1743,16 @@ Function,+,loader_update_menu,void, | ||||
| Function,+,loading_alloc,Loading*, | ||||
| Function,+,loading_free,void,Loading* | ||||
| Function,+,loading_get_view,View*,Loading* | ||||
| Function,+,locale_celsius_to_fahrenheit,float,float | ||||
| Function,+,locale_fahrenheit_to_celsius,float,float | ||||
| Function,+,locale_format_date,void,"FuriString*, const FuriHalRtcDateTime*, const LocaleDateFormat, const char*" | ||||
| Function,+,locale_format_time,void,"FuriString*, const FuriHalRtcDateTime*, const LocaleTimeFormat, const _Bool" | ||||
| Function,+,locale_get_date_format,LocaleDateFormat, | ||||
| Function,+,locale_get_measurement_unit,LocaleMeasurementUnits, | ||||
| Function,+,locale_get_time_format,LocaleTimeFormat, | ||||
| Function,+,locale_set_date_format,void,LocaleDateFormat | ||||
| Function,+,locale_set_measurement_unit,void,LocaleMeasurementUnits | ||||
| Function,+,locale_set_time_format,void,LocaleTimeFormat | ||||
| Function,-,localtime,tm*,const time_t* | ||||
| Function,-,localtime_r,tm*,"const time_t*, tm*" | ||||
| Function,-,log,double,double | ||||
|  | ||||
| 
 | 
| @ -29,12 +29,15 @@ typedef struct { | ||||
|     uint8_t log_level : 4; | ||||
|     uint8_t log_reserved : 4; | ||||
|     uint8_t flags; | ||||
|     uint8_t boot_mode : 4; | ||||
|     uint8_t heap_track_mode : 2; | ||||
|     uint16_t reserved : 10; | ||||
| } DeveloperReg; | ||||
|     FuriHalRtcBootMode boot_mode : 4; | ||||
|     FuriHalRtcHeapTrackMode heap_track_mode : 2; | ||||
|     FuriHalRtcLocaleUnits locale_units : 1; | ||||
|     FuriHalRtcLocaleTimeFormat locale_timeformat : 1; | ||||
|     FuriHalRtcLocaleDateFormat locale_dateformat : 2; | ||||
|     uint8_t reserved : 6; | ||||
| } SystemReg; | ||||
| 
 | ||||
| _Static_assert(sizeof(DeveloperReg) == 4, "DeveloperReg size mismatch"); | ||||
| _Static_assert(sizeof(SystemReg) == 4, "SystemReg size mismatch"); | ||||
| 
 | ||||
| #define FURI_HAL_RTC_SECONDS_PER_MINUTE 60 | ||||
| #define FURI_HAL_RTC_SECONDS_PER_HOUR (FURI_HAL_RTC_SECONDS_PER_MINUTE * 60) | ||||
| @ -172,7 +175,7 @@ void furi_hal_rtc_set_register(FuriHalRtcRegister reg, uint32_t value) { | ||||
| 
 | ||||
| void furi_hal_rtc_set_log_level(uint8_t level) { | ||||
|     uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem); | ||||
|     DeveloperReg* data = (DeveloperReg*)&data_reg; | ||||
|     SystemReg* data = (SystemReg*)&data_reg; | ||||
|     data->log_level = level; | ||||
|     furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg); | ||||
|     furi_log_set_level(level); | ||||
| @ -180,13 +183,13 @@ void furi_hal_rtc_set_log_level(uint8_t level) { | ||||
| 
 | ||||
| uint8_t furi_hal_rtc_get_log_level() { | ||||
|     uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem); | ||||
|     DeveloperReg* data = (DeveloperReg*)&data_reg; | ||||
|     SystemReg* data = (SystemReg*)&data_reg; | ||||
|     return data->log_level; | ||||
| } | ||||
| 
 | ||||
| void furi_hal_rtc_set_flag(FuriHalRtcFlag flag) { | ||||
|     uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem); | ||||
|     DeveloperReg* data = (DeveloperReg*)&data_reg; | ||||
|     SystemReg* data = (SystemReg*)&data_reg; | ||||
|     data->flags |= flag; | ||||
|     furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg); | ||||
| 
 | ||||
| @ -197,7 +200,7 @@ void furi_hal_rtc_set_flag(FuriHalRtcFlag flag) { | ||||
| 
 | ||||
| void furi_hal_rtc_reset_flag(FuriHalRtcFlag flag) { | ||||
|     uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem); | ||||
|     DeveloperReg* data = (DeveloperReg*)&data_reg; | ||||
|     SystemReg* data = (SystemReg*)&data_reg; | ||||
|     data->flags &= ~flag; | ||||
|     furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg); | ||||
| 
 | ||||
| @ -208,34 +211,73 @@ void furi_hal_rtc_reset_flag(FuriHalRtcFlag flag) { | ||||
| 
 | ||||
| bool furi_hal_rtc_is_flag_set(FuriHalRtcFlag flag) { | ||||
|     uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem); | ||||
|     DeveloperReg* data = (DeveloperReg*)&data_reg; | ||||
|     SystemReg* data = (SystemReg*)&data_reg; | ||||
|     return data->flags & flag; | ||||
| } | ||||
| 
 | ||||
| void furi_hal_rtc_set_boot_mode(FuriHalRtcBootMode mode) { | ||||
|     uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem); | ||||
|     DeveloperReg* data = (DeveloperReg*)&data_reg; | ||||
|     SystemReg* data = (SystemReg*)&data_reg; | ||||
|     data->boot_mode = mode; | ||||
|     furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg); | ||||
| } | ||||
| 
 | ||||
| FuriHalRtcBootMode furi_hal_rtc_get_boot_mode() { | ||||
|     uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem); | ||||
|     DeveloperReg* data = (DeveloperReg*)&data_reg; | ||||
|     return (FuriHalRtcBootMode)data->boot_mode; | ||||
|     SystemReg* data = (SystemReg*)&data_reg; | ||||
|     return data->boot_mode; | ||||
| } | ||||
| 
 | ||||
| void furi_hal_rtc_set_heap_track_mode(FuriHalRtcHeapTrackMode mode) { | ||||
|     uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem); | ||||
|     DeveloperReg* data = (DeveloperReg*)&data_reg; | ||||
|     SystemReg* data = (SystemReg*)&data_reg; | ||||
|     data->heap_track_mode = mode; | ||||
|     furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg); | ||||
| } | ||||
| 
 | ||||
| FuriHalRtcHeapTrackMode furi_hal_rtc_get_heap_track_mode() { | ||||
|     uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem); | ||||
|     DeveloperReg* data = (DeveloperReg*)&data_reg; | ||||
|     return (FuriHalRtcHeapTrackMode)data->heap_track_mode; | ||||
|     SystemReg* data = (SystemReg*)&data_reg; | ||||
|     return data->heap_track_mode; | ||||
| } | ||||
| 
 | ||||
| void furi_hal_rtc_set_locale_units(FuriHalRtcLocaleUnits value) { | ||||
|     uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem); | ||||
|     SystemReg* data = (SystemReg*)&data_reg; | ||||
|     data->locale_units = value; | ||||
|     furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg); | ||||
| } | ||||
| 
 | ||||
| FuriHalRtcLocaleUnits furi_hal_rtc_get_locale_units() { | ||||
|     uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem); | ||||
|     SystemReg* data = (SystemReg*)&data_reg; | ||||
|     return data->locale_units; | ||||
| } | ||||
| 
 | ||||
| void furi_hal_rtc_set_locale_timeformat(FuriHalRtcLocaleTimeFormat value) { | ||||
|     uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem); | ||||
|     SystemReg* data = (SystemReg*)&data_reg; | ||||
|     data->locale_timeformat = value; | ||||
|     furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg); | ||||
| } | ||||
| 
 | ||||
| FuriHalRtcLocaleTimeFormat furi_hal_rtc_get_locale_timeformat() { | ||||
|     uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem); | ||||
|     SystemReg* data = (SystemReg*)&data_reg; | ||||
|     return data->locale_timeformat; | ||||
| } | ||||
| 
 | ||||
| void furi_hal_rtc_set_locale_dateformat(FuriHalRtcLocaleDateFormat value) { | ||||
|     uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem); | ||||
|     SystemReg* data = (SystemReg*)&data_reg; | ||||
|     data->locale_dateformat = value; | ||||
|     furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg); | ||||
| } | ||||
| 
 | ||||
| FuriHalRtcLocaleDateFormat furi_hal_rtc_get_locale_dateformat() { | ||||
|     uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterSystem); | ||||
|     SystemReg* data = (SystemReg*)&data_reg; | ||||
|     return data->locale_dateformat; | ||||
| } | ||||
| 
 | ||||
| void furi_hal_rtc_set_datetime(FuriHalRtcDateTime* datetime) { | ||||
|  | ||||
| @ -59,53 +59,194 @@ typedef enum { | ||||
|     FuriHalRtcRegisterMAX, /**< Service value, do not use */ | ||||
| } FuriHalRtcRegister; | ||||
| 
 | ||||
| typedef enum { | ||||
|     FuriHalRtcLocaleUnitsMetric = 0, /**< Metric measurement units */ | ||||
|     FuriHalRtcLocaleUnitsImperial = 1, /**< Imperial measurement units */ | ||||
| } FuriHalRtcLocaleUnits; | ||||
| 
 | ||||
| typedef enum { | ||||
|     FuriHalRtcLocaleTimeFormat24h = 0, /**< 24-hour format */ | ||||
|     FuriHalRtcLocaleTimeFormat12h = 1, /**< 12-hour format */ | ||||
| } FuriHalRtcLocaleTimeFormat; | ||||
| 
 | ||||
| typedef enum { | ||||
|     FuriHalRtcLocaleDateFormatDMY = 0, /**< Day/Month/Year */ | ||||
|     FuriHalRtcLocaleDateFormatMDY = 1, /**< Month/Day/Year */ | ||||
|     FuriHalRtcLocaleDateFormatYMD = 2, /**< Year/Month/Day */ | ||||
| } FuriHalRtcLocaleDateFormat; | ||||
| 
 | ||||
| /** Early initialization */ | ||||
| void furi_hal_rtc_init_early(); | ||||
| 
 | ||||
| /** Early deinitialization */ | ||||
| /** Early de-initialization */ | ||||
| void furi_hal_rtc_deinit_early(); | ||||
| 
 | ||||
| /** Initialize RTC subsystem */ | ||||
| void furi_hal_rtc_init(); | ||||
| 
 | ||||
| /** Get RTC register content
 | ||||
|  * | ||||
|  * @param[in]  reg   The register identifier | ||||
|  * | ||||
|  * @return     content of the register | ||||
|  */ | ||||
| uint32_t furi_hal_rtc_get_register(FuriHalRtcRegister reg); | ||||
| 
 | ||||
| /** Set register content
 | ||||
|  * | ||||
|  * @param[in]  reg    The register identifier | ||||
|  * @param[in]  value  The value to store into register | ||||
|  */ | ||||
| void furi_hal_rtc_set_register(FuriHalRtcRegister reg, uint32_t value); | ||||
| 
 | ||||
| /** Set Log Level value
 | ||||
|  * | ||||
|  * @param[in]  level  The level to store | ||||
|  */ | ||||
| void furi_hal_rtc_set_log_level(uint8_t level); | ||||
| 
 | ||||
| /** Get Log Level value
 | ||||
|  * | ||||
|  * @return     The Log Level value | ||||
|  */ | ||||
| uint8_t furi_hal_rtc_get_log_level(); | ||||
| 
 | ||||
| /** Set RTC Flag
 | ||||
|  * | ||||
|  * @param[in]  flag  The flag to set | ||||
|  */ | ||||
| void furi_hal_rtc_set_flag(FuriHalRtcFlag flag); | ||||
| 
 | ||||
| /** Reset RTC Flag
 | ||||
|  * | ||||
|  * @param[in]  flag  The flag to reset | ||||
|  */ | ||||
| void furi_hal_rtc_reset_flag(FuriHalRtcFlag flag); | ||||
| 
 | ||||
| /** Check if RTC Flag is set
 | ||||
|  * | ||||
|  * @param[in]  flag  The flag to check | ||||
|  * | ||||
|  * @return     true if set | ||||
|  */ | ||||
| bool furi_hal_rtc_is_flag_set(FuriHalRtcFlag flag); | ||||
| 
 | ||||
| /** Set RTC boot mode
 | ||||
|  * | ||||
|  * @param[in]  mode  The mode to set | ||||
|  */ | ||||
| void furi_hal_rtc_set_boot_mode(FuriHalRtcBootMode mode); | ||||
| 
 | ||||
| /** Get RTC boot mode
 | ||||
|  * | ||||
|  * @return     The RTC boot mode. | ||||
|  */ | ||||
| FuriHalRtcBootMode furi_hal_rtc_get_boot_mode(); | ||||
| 
 | ||||
| /** Set Heap Track mode
 | ||||
|  * | ||||
|  * @param[in]  mode  The mode to set | ||||
|  */ | ||||
| void furi_hal_rtc_set_heap_track_mode(FuriHalRtcHeapTrackMode mode); | ||||
| 
 | ||||
| /** Get RTC Heap Track mode
 | ||||
|  * | ||||
|  * @return     The RTC heap track mode. | ||||
|  */ | ||||
| FuriHalRtcHeapTrackMode furi_hal_rtc_get_heap_track_mode(); | ||||
| 
 | ||||
| /** Set locale units
 | ||||
|  * | ||||
|  * @param[in]  mode  The RTC Locale Units | ||||
|  */ | ||||
| void furi_hal_rtc_set_locale_units(FuriHalRtcLocaleUnits value); | ||||
| 
 | ||||
| /** Get RTC Locale Units
 | ||||
|  * | ||||
|  * @return     The RTC Locale Units. | ||||
|  */ | ||||
| FuriHalRtcLocaleUnits furi_hal_rtc_get_locale_units(); | ||||
| 
 | ||||
| /** Set RTC Locale Time Format
 | ||||
|  * | ||||
|  * @param[in]  value  The RTC Locale Time Format | ||||
|  */ | ||||
| void furi_hal_rtc_set_locale_timeformat(FuriHalRtcLocaleTimeFormat value); | ||||
| 
 | ||||
| /** Get RTC Locale Time Format
 | ||||
|  * | ||||
|  * @return     The RTC Locale Time Format. | ||||
|  */ | ||||
| FuriHalRtcLocaleTimeFormat furi_hal_rtc_get_locale_timeformat(); | ||||
| 
 | ||||
| /** Set RTC Locale Date Format
 | ||||
|  * | ||||
|  * @param[in]  value  The RTC Locale Date Format | ||||
|  */ | ||||
| void furi_hal_rtc_set_locale_dateformat(FuriHalRtcLocaleDateFormat value); | ||||
| 
 | ||||
| /** Get RTC Locale Date Format
 | ||||
|  * | ||||
|  * @return     The RTC Locale Date Format | ||||
|  */ | ||||
| FuriHalRtcLocaleDateFormat furi_hal_rtc_get_locale_dateformat(); | ||||
| 
 | ||||
| /** Set RTC Date Time
 | ||||
|  * | ||||
|  * @param      datetime  The date time to set | ||||
|  */ | ||||
| void furi_hal_rtc_set_datetime(FuriHalRtcDateTime* datetime); | ||||
| 
 | ||||
| /** Get RTC Date Time
 | ||||
|  * | ||||
|  * @param      datetime  The datetime | ||||
|  */ | ||||
| void furi_hal_rtc_get_datetime(FuriHalRtcDateTime* datetime); | ||||
| 
 | ||||
| /** Validate Date Time
 | ||||
|  * | ||||
|  * @param      datetime  The datetime to validate | ||||
|  * | ||||
|  * @return     { description_of_the_return_value } | ||||
|  */ | ||||
| bool furi_hal_rtc_validate_datetime(FuriHalRtcDateTime* datetime); | ||||
| 
 | ||||
| /** Set RTC Fault Data
 | ||||
|  * | ||||
|  * @param[in]  value  The value | ||||
|  */ | ||||
| void furi_hal_rtc_set_fault_data(uint32_t value); | ||||
| 
 | ||||
| /** Get RTC Fault Data
 | ||||
|  * | ||||
|  * @return     RTC Fault Data value | ||||
|  */ | ||||
| uint32_t furi_hal_rtc_get_fault_data(); | ||||
| 
 | ||||
| /** Set Pin Fails count
 | ||||
|  * | ||||
|  * @param[in]  value  The Pin Fails count | ||||
|  */ | ||||
| void furi_hal_rtc_set_pin_fails(uint32_t value); | ||||
| 
 | ||||
| /** Get Pin Fails count
 | ||||
|  * | ||||
|  * @return     Pin Fails Count | ||||
|  */ | ||||
| uint32_t furi_hal_rtc_get_pin_fails(); | ||||
| 
 | ||||
| /** Get UNIX Timestamp
 | ||||
|  * | ||||
|  * @return     Unix Timestamp in seconds from UNIX epoch start | ||||
|  */ | ||||
| uint32_t furi_hal_rtc_get_timestamp(); | ||||
| 
 | ||||
| /** Convert DateTime to UNIX timestamp
 | ||||
|  * | ||||
|  * @param      datetime  The datetime | ||||
|  * | ||||
|  * @return     UNIX Timestamp in seconds from UNIX epoch start | ||||
|  */ | ||||
| uint32_t furi_hal_rtc_datetime_to_timestamp(FuriHalRtcDateTime* datetime); | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Nikolay Minaylov
						Nikolay Minaylov