Merge remote-tracking branch 'origin/dev' into release-candidate
This commit is contained in:
		
						commit
						bc77681e65
					
				| @ -16,7 +16,7 @@ Flipper Zero's firmware consists of two components: | ||||
| - Core2 firmware set - proprietary components by ST: FUS + radio stack. FUS is flashed at factory and you should never update it. | ||||
| - Core1 Firmware - HAL + OS + Drivers + Applications. | ||||
| 
 | ||||
| All 3 of them must be flashed in order described. | ||||
| They both must be flashed in order described. | ||||
| 
 | ||||
| ## With STLink | ||||
| 
 | ||||
|  | ||||
| @ -35,7 +35,6 @@ Main goal for 1.0.0 is to provide first stable version for both Users and Develo | ||||
| 
 | ||||
| ## What we're planning to implement in 1.0.0 | ||||
| 
 | ||||
| - Updating firmware from SD (work in progress, almost done) | ||||
| - Loading applications from SD (tested as PoC, work scheduled for Q2) | ||||
| - More protocols (gathering feedback) | ||||
| - User documentation (work in progress) | ||||
|  | ||||
| @ -131,7 +131,7 @@ const FlipperApplication FLIPPER_SERVICES[] = { | ||||
| #endif | ||||
| }; | ||||
| 
 | ||||
| const size_t FLIPPER_SERVICES_COUNT = sizeof(FLIPPER_SERVICES) / sizeof(FlipperApplication); | ||||
| const size_t FLIPPER_SERVICES_COUNT = COUNT_OF(FLIPPER_SERVICES); | ||||
| 
 | ||||
| const FlipperApplication FLIPPER_SYSTEM_APPS[] = { | ||||
| #ifdef APP_UPDATER | ||||
| @ -142,7 +142,7 @@ const FlipperApplication FLIPPER_SYSTEM_APPS[] = { | ||||
| #endif | ||||
| }; | ||||
| 
 | ||||
| const size_t FLIPPER_SYSTEM_APPS_COUNT = sizeof(FLIPPER_SERVICES) / sizeof(FlipperApplication); | ||||
| const size_t FLIPPER_SYSTEM_APPS_COUNT = COUNT_OF(FLIPPER_SYSTEM_APPS); | ||||
| 
 | ||||
| // Main menu APP
 | ||||
| const FlipperApplication FLIPPER_APPS[] = { | ||||
| @ -181,7 +181,7 @@ const FlipperApplication FLIPPER_APPS[] = { | ||||
| 
 | ||||
| }; | ||||
| 
 | ||||
| const size_t FLIPPER_APPS_COUNT = sizeof(FLIPPER_APPS) / sizeof(FlipperApplication); | ||||
| const size_t FLIPPER_APPS_COUNT = COUNT_OF(FLIPPER_APPS); | ||||
| 
 | ||||
| // On system start hooks
 | ||||
| const FlipperOnStartHook FLIPPER_ON_SYSTEM_START[] = { | ||||
| @ -228,8 +228,7 @@ const FlipperOnStartHook FLIPPER_ON_SYSTEM_START[] = { | ||||
| #endif | ||||
| }; | ||||
| 
 | ||||
| const size_t FLIPPER_ON_SYSTEM_START_COUNT = | ||||
|     sizeof(FLIPPER_ON_SYSTEM_START) / sizeof(FlipperOnStartHook); | ||||
| const size_t FLIPPER_ON_SYSTEM_START_COUNT = COUNT_OF(FLIPPER_ON_SYSTEM_START); | ||||
| 
 | ||||
| // Plugin menu
 | ||||
| const FlipperApplication FLIPPER_PLUGINS[] = { | ||||
| @ -246,7 +245,7 @@ const FlipperApplication FLIPPER_PLUGINS[] = { | ||||
| #endif | ||||
| }; | ||||
| 
 | ||||
| const size_t FLIPPER_PLUGINS_COUNT = sizeof(FLIPPER_PLUGINS) / sizeof(FlipperApplication); | ||||
| const size_t FLIPPER_PLUGINS_COUNT = COUNT_OF(FLIPPER_PLUGINS); | ||||
| 
 | ||||
| // Plugin menu
 | ||||
| const FlipperApplication FLIPPER_DEBUG_APPS[] = { | ||||
| @ -307,7 +306,7 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { | ||||
| #endif | ||||
| }; | ||||
| 
 | ||||
| const size_t FLIPPER_DEBUG_APPS_COUNT = sizeof(FLIPPER_DEBUG_APPS) / sizeof(FlipperApplication); | ||||
| const size_t FLIPPER_DEBUG_APPS_COUNT = COUNT_OF(FLIPPER_DEBUG_APPS); | ||||
| 
 | ||||
| #ifdef APP_ARCHIVE | ||||
| const FlipperApplication FLIPPER_ARCHIVE = | ||||
| @ -352,5 +351,4 @@ const FlipperApplication FLIPPER_SETTINGS_APPS[] = { | ||||
| #endif | ||||
| }; | ||||
| 
 | ||||
| const size_t FLIPPER_SETTINGS_APPS_COUNT = | ||||
|     sizeof(FLIPPER_SETTINGS_APPS) / sizeof(FlipperApplication); | ||||
| const size_t FLIPPER_SETTINGS_APPS_COUNT = COUNT_OF(FLIPPER_SETTINGS_APPS); | ||||
|  | ||||
| @ -34,13 +34,13 @@ bool desktop_scene_debug_on_event(void* context, SceneManagerEvent event) { | ||||
|             break; | ||||
| 
 | ||||
|         case DesktopDebugEventDeed: | ||||
|             dolphin_deed(dolphin, DolphinDeedIbuttonEmulate); | ||||
|             dolphin_deed(dolphin, DolphinDeedTestRight); | ||||
|             desktop_debug_get_dolphin_data(desktop->debug_view); | ||||
|             consumed = true; | ||||
|             break; | ||||
| 
 | ||||
|         case DesktopDebugEventWrongDeed: | ||||
|             dolphin_deed(dolphin, DolphinDeedIbuttonRead); | ||||
|             dolphin_deed(dolphin, DolphinDeedTestLeft); | ||||
|             desktop_debug_get_dolphin_data(desktop->debug_view); | ||||
|             consumed = true; | ||||
|             break; | ||||
|  | ||||
| @ -111,7 +111,10 @@ bool desktop_debug_input(InputEvent* event, void* context) { | ||||
| 
 | ||||
|     DesktopDebugView* debug_view = context; | ||||
| 
 | ||||
|     if(event->type != InputTypeShort) return false; | ||||
|     if(event->type != InputTypeShort && event->type != InputTypeRepeat) { | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     DesktopViewStatsScreens current = 0; | ||||
|     with_view_model( | ||||
|         debug_view->view, (DesktopDebugViewModel * model) { | ||||
| @ -125,11 +128,16 @@ bool desktop_debug_input(InputEvent* event, void* context) { | ||||
|             return true; | ||||
|         }); | ||||
| 
 | ||||
|     size_t count = (event->type == InputTypeRepeat) ? 10 : 1; | ||||
|     if(current == DesktopViewStatsMeta) { | ||||
|         if(event->key == InputKeyLeft) { | ||||
|             debug_view->callback(DesktopDebugEventWrongDeed, debug_view->context); | ||||
|             while(count-- > 0) { | ||||
|                 debug_view->callback(DesktopDebugEventWrongDeed, debug_view->context); | ||||
|             } | ||||
|         } else if(event->key == InputKeyRight) { | ||||
|             debug_view->callback(DesktopDebugEventDeed, debug_view->context); | ||||
|             while(count-- > 0) { | ||||
|                 debug_view->callback(DesktopDebugEventDeed, debug_view->context); | ||||
|             } | ||||
|         } else if(event->key == InputKeyOk) { | ||||
|             debug_view->callback(DesktopDebugEventSaveState, debug_view->context); | ||||
|         } else { | ||||
|  | ||||
| @ -52,7 +52,10 @@ typedef enum { | ||||
| 
 | ||||
|     DolphinDeedU2fAuthorized, | ||||
| 
 | ||||
|     DolphinDeedMAX | ||||
|     DolphinDeedMAX, | ||||
| 
 | ||||
|     DolphinDeedTestLeft, | ||||
|     DolphinDeedTestRight, | ||||
| } DolphinDeed; | ||||
| 
 | ||||
| typedef struct { | ||||
|  | ||||
| @ -126,6 +126,23 @@ uint32_t dolphin_state_xp_to_levelup(uint32_t icounter) { | ||||
| } | ||||
| 
 | ||||
| void dolphin_state_on_deed(DolphinState* dolphin_state, DolphinDeed deed) { | ||||
|     // Special case for testing
 | ||||
|     if(deed > DolphinDeedMAX) { | ||||
|         if(deed == DolphinDeedTestLeft) { | ||||
|             dolphin_state->data.butthurt = | ||||
|                 CLAMP(dolphin_state->data.butthurt + 1, BUTTHURT_MAX, BUTTHURT_MIN); | ||||
|             if(dolphin_state->data.icounter > 0) dolphin_state->data.icounter--; | ||||
|             dolphin_state->data.timestamp = dolphin_state_timestamp(); | ||||
|             dolphin_state->dirty = true; | ||||
|         } else if(deed == DolphinDeedTestRight) { | ||||
|             dolphin_state->data.butthurt = BUTTHURT_MIN; | ||||
|             if(dolphin_state->data.icounter < UINT32_MAX) dolphin_state->data.icounter++; | ||||
|             dolphin_state->data.timestamp = dolphin_state_timestamp(); | ||||
|             dolphin_state->dirty = true; | ||||
|         } | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     DolphinApp app = dolphin_deed_get_app(deed); | ||||
|     int8_t weight_limit = | ||||
|         dolphin_deed_get_app_limit(app) - dolphin_state->data.icounter_daily_limit[app]; | ||||
|  | ||||
| @ -101,6 +101,11 @@ const FlipperApplication* loader_find_application_by_name(const char* name) { | ||||
| } | ||||
| 
 | ||||
| void loader_cli_open(Cli* cli, string_t args, Loader* instance) { | ||||
|     if(loader_is_locked(instance)) { | ||||
|         printf("Can't start, furi application is running"); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     string_t application_name; | ||||
|     string_init(application_name); | ||||
| 
 | ||||
| @ -292,7 +297,7 @@ static Loader* loader_alloc() { | ||||
| 
 | ||||
| #ifdef SRV_CLI | ||||
|     instance->cli = furi_record_open("cli"); | ||||
|     cli_add_command(instance->cli, "loader", CliCommandFlagDefault, loader_cli, instance); | ||||
|     cli_add_command(instance->cli, "loader", CliCommandFlagParallelSafe, loader_cli, instance); | ||||
| #else | ||||
|     UNUSED(loader_cli); | ||||
| #endif | ||||
|  | ||||
| @ -418,11 +418,8 @@ static bool notification_save_settings(NotificationApp* app) { | ||||
| static void input_event_callback(const void* value, void* context) { | ||||
|     furi_assert(value); | ||||
|     furi_assert(context); | ||||
|     const InputEvent* event = value; | ||||
|     NotificationApp* app = context; | ||||
|     if(event->type == InputTypePress) { | ||||
|         notification_message(app, &sequence_display_on); | ||||
|     } | ||||
|     notification_message(app, &sequence_display_on); | ||||
| } | ||||
| 
 | ||||
| // App alloc
 | ||||
|  | ||||
| @ -9,6 +9,7 @@ typedef struct Power Power; | ||||
| typedef enum { | ||||
|     PowerBootModeNormal, | ||||
|     PowerBootModeDfu, | ||||
|     PowerBootModeUpdateStart, | ||||
| } PowerBootMode; | ||||
| 
 | ||||
| typedef enum { | ||||
|  | ||||
| @ -17,6 +17,8 @@ void power_reboot(PowerBootMode mode) { | ||||
|         furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); | ||||
|     } else if(mode == PowerBootModeDfu) { | ||||
|         furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeDfu); | ||||
|     } else if(mode == PowerBootModeUpdateStart) { | ||||
|         furi_hal_rtc_set_boot_mode(FuriHalRtcBootModePreUpdate); | ||||
|     } | ||||
|     furi_hal_power_reset(); | ||||
| } | ||||
|  | ||||
| @ -61,6 +61,8 @@ static void rpc_system_system_reboot_process(const PB_Main* request, void* conte | ||||
|         power_reboot(PowerBootModeNormal); | ||||
|     } else if(mode == PB_System_RebootRequest_RebootMode_DFU) { | ||||
|         power_reboot(PowerBootModeDfu); | ||||
|     } else if(mode == PB_System_RebootRequest_RebootMode_UPDATE) { | ||||
|         power_reboot(PowerBootModeUpdateStart); | ||||
|     } else { | ||||
|         rpc_send_and_release_empty( | ||||
|             session, request->command_id, PB_CommandStatus_ERROR_INVALID_PARAMETERS); | ||||
| @ -274,7 +276,7 @@ static void rpc_system_system_update_request_process(const PB_Main* request, voi | ||||
|     furi_assert(session); | ||||
| 
 | ||||
|     bool update_prepare_result = | ||||
|         update_operation_prepare(request->content.system_update_request.update_folder) == | ||||
|         update_operation_prepare(request->content.system_update_request.update_manifest) == | ||||
|         UpdatePrepareResultOK; | ||||
| 
 | ||||
|     PB_Main* response = malloc(sizeof(PB_Main)); | ||||
|  | ||||
| @ -127,8 +127,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) { | ||||
|                 scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); | ||||
|             } else { | ||||
|                 //Restore default setting
 | ||||
|                 subghz->txrx->frequency = subghz_setting_get_frequency( | ||||
|                     subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)); | ||||
|                 subghz->txrx->frequency = subghz_setting_get_default_frequency(subghz->setting); | ||||
|                 subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; | ||||
|                 if(!scene_manager_search_and_switch_to_previous_scene( | ||||
|                        subghz->scene_manager, SubGhzSceneSaved)) { | ||||
|  | ||||
| @ -120,8 +120,7 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { | ||||
|                 subghz_sleep(subghz); | ||||
|             }; | ||||
|             subghz->txrx->hopper_state = SubGhzHopperStateOFF; | ||||
|             subghz->txrx->frequency = subghz_setting_get_frequency( | ||||
|                 subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)); | ||||
|             subghz->txrx->frequency = subghz_setting_get_default_frequency(subghz->setting); | ||||
|             subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; | ||||
|             subghz->txrx->idx_menu_chosen = 0; | ||||
|             subghz_receiver_set_rx_callback(subghz->txrx->receiver, NULL, subghz); | ||||
|  | ||||
| @ -111,19 +111,13 @@ static void subghz_scene_receiver_config_set_hopping_runing(VariableItem* item) | ||||
|         sprintf( | ||||
|             text_buf, | ||||
|             "%lu.%02lu", | ||||
|             subghz_setting_get_frequency( | ||||
|                 subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)) / | ||||
|                 1000000, | ||||
|             (subghz_setting_get_frequency( | ||||
|                  subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)) % | ||||
|              1000000) / | ||||
|                 10000); | ||||
|             subghz_setting_get_default_frequency(subghz->setting) / 1000000, | ||||
|             (subghz_setting_get_default_frequency(subghz->setting) % 1000000) / 10000); | ||||
|         variable_item_set_current_value_text( | ||||
|             (VariableItem*)scene_manager_get_scene_state( | ||||
|                 subghz->scene_manager, SubGhzSceneReceiverConfig), | ||||
|             text_buf); | ||||
|         subghz->txrx->frequency = subghz_setting_get_frequency( | ||||
|             subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)); | ||||
|         subghz->txrx->frequency = subghz_setting_get_default_frequency(subghz->setting); | ||||
|         variable_item_set_current_value_index( | ||||
|             (VariableItem*)scene_manager_get_scene_state( | ||||
|                 subghz->scene_manager, SubGhzSceneReceiverConfig), | ||||
|  | ||||
| @ -46,7 +46,7 @@ bool subghz_scene_set_type_submenu_gen_data_protocol( | ||||
|         if(!subghz_protocol_decoder_base_serialize( | ||||
|                subghz->txrx->decoder_result, | ||||
|                subghz->txrx->fff_data, | ||||
|                subghz_setting_get_frequency_default_index(subghz->setting), | ||||
|                subghz_setting_get_default_frequency(subghz->setting), | ||||
|                FuriHalSubGhzPresetOok650Async)) { | ||||
|             FURI_LOG_E(TAG, "Unable to serialize"); | ||||
|             break; | ||||
| @ -213,7 +213,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { | ||||
|                     0x2, | ||||
|                     0x0003, | ||||
|                     "DoorHan", | ||||
|                     subghz_setting_get_frequency_default_index(subghz->setting), | ||||
|                     subghz_setting_get_default_frequency(subghz->setting), | ||||
|                     FuriHalSubGhzPresetOok650Async); | ||||
|                 generated_protocol = true; | ||||
|             } else { | ||||
|  | ||||
| @ -130,8 +130,7 @@ SubGhz* subghz_alloc() { | ||||
| 
 | ||||
|     //init Worker & Protocol & History
 | ||||
|     subghz->txrx = malloc(sizeof(SubGhzTxRx)); | ||||
|     subghz->txrx->frequency = subghz_setting_get_frequency( | ||||
|         subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)); | ||||
|     subghz->txrx->frequency = subghz_setting_get_default_frequency(subghz->setting); | ||||
|     subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; | ||||
|     subghz->txrx->txrx_state = SubGhzTxRxStateSleep; | ||||
|     subghz->txrx->hopper_state = SubGhzHopperStateOFF; | ||||
|  | ||||
| @ -246,7 +246,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) { | ||||
|             break; | ||||
|         } | ||||
| 
 | ||||
|         if(!flipper_format_read_uint32(fff_data_file, "Frequency", (uint32_t*)&temp_data32, 1)) { | ||||
|         if(!flipper_format_read_uint32(fff_data_file, "Frequency", &temp_data32, 1)) { | ||||
|             FURI_LOG_E(TAG, "Missing Frequency"); | ||||
|             break; | ||||
|         } | ||||
|  | ||||
| @ -152,12 +152,11 @@ static const uint32_t subghz_hopper_frequencies_region_jp[] = { | ||||
| }; | ||||
| static const uint32_t subghz_frequency_default_index_region_jp = 9; | ||||
| 
 | ||||
| LIST_DEF(frequencies_list, uint32_t) | ||||
| LIST_DEF(hopper_frequencies_list, uint32_t) | ||||
| LIST_DEF(FrequenciesList, uint32_t) | ||||
| 
 | ||||
| struct SubGhzSetting { | ||||
|     frequencies_list_t frequencies; | ||||
|     hopper_frequencies_list_t hopper_frequencies; | ||||
|     FrequenciesList_t frequencies; | ||||
|     FrequenciesList_t hopper_frequencies; | ||||
|     size_t frequencies_count; | ||||
|     size_t hopper_frequencies_count; | ||||
|     uint32_t frequency_default_index; | ||||
| @ -165,15 +164,15 @@ struct SubGhzSetting { | ||||
| 
 | ||||
| SubGhzSetting* subghz_setting_alloc(void) { | ||||
|     SubGhzSetting* instance = malloc(sizeof(SubGhzSetting)); | ||||
|     frequencies_list_init(instance->frequencies); | ||||
|     hopper_frequencies_list_init(instance->hopper_frequencies); | ||||
|     FrequenciesList_init(instance->frequencies); | ||||
|     FrequenciesList_init(instance->hopper_frequencies); | ||||
|     return instance; | ||||
| } | ||||
| 
 | ||||
| void subghz_setting_free(SubGhzSetting* instance) { | ||||
|     furi_assert(instance); | ||||
|     frequencies_list_clear(instance->frequencies); | ||||
|     hopper_frequencies_list_clear(instance->hopper_frequencies); | ||||
|     FrequenciesList_clear(instance->frequencies); | ||||
|     FrequenciesList_clear(instance->hopper_frequencies); | ||||
|     free(instance); | ||||
| } | ||||
| 
 | ||||
| @ -184,18 +183,18 @@ void subghz_setting_load_default( | ||||
|     const uint32_t frequency_default_index) { | ||||
|     furi_assert(instance); | ||||
|     size_t i = 0; | ||||
|     frequencies_list_clear(instance->frequencies); | ||||
|     hopper_frequencies_list_clear(instance->hopper_frequencies); | ||||
|     FrequenciesList_clear(instance->frequencies); | ||||
|     FrequenciesList_clear(instance->hopper_frequencies); | ||||
|     i = 0; | ||||
|     while(frequencies[i]) { | ||||
|         frequencies_list_push_back(instance->frequencies, frequencies[i]); | ||||
|         FrequenciesList_push_back(instance->frequencies, frequencies[i]); | ||||
|         i++; | ||||
|     } | ||||
|     instance->frequencies_count = i; | ||||
| 
 | ||||
|     i = 0; | ||||
|     while(hopper_frequencies[i]) { | ||||
|         hopper_frequencies_list_push_back(instance->hopper_frequencies, hopper_frequencies[i]); | ||||
|         FrequenciesList_push_back(instance->hopper_frequencies, hopper_frequencies[i]); | ||||
|         i++; | ||||
|     } | ||||
|     instance->hopper_frequencies_count = i; | ||||
| @ -206,8 +205,8 @@ void subghz_setting_load_default( | ||||
| void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { | ||||
|     furi_assert(instance); | ||||
| 
 | ||||
|     frequencies_list_clear(instance->frequencies); | ||||
|     hopper_frequencies_list_clear(instance->hopper_frequencies); | ||||
|     FrequenciesList_clear(instance->frequencies); | ||||
|     FrequenciesList_clear(instance->hopper_frequencies); | ||||
| 
 | ||||
|     Storage* storage = furi_record_open("storage"); | ||||
|     FlipperFormat* fff_data_file = flipper_format_file_alloc(storage); | ||||
| @ -246,7 +245,7 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { | ||||
|                 fff_data_file, "Frequency", (uint32_t*)&temp_data32, 1)) { | ||||
|                 if(furi_hal_subghz_is_frequency_valid(temp_data32)) { | ||||
|                     FURI_LOG_I(TAG, "Frequency loaded %lu", temp_data32); | ||||
|                     frequencies_list_push_back(instance->frequencies, temp_data32); | ||||
|                     FrequenciesList_push_back(instance->frequencies, temp_data32); | ||||
|                     i++; | ||||
|                 } else { | ||||
|                     FURI_LOG_E(TAG, "Frequency not supported %lu", temp_data32); | ||||
| @ -263,7 +262,7 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { | ||||
|                 fff_data_file, "Hopper_frequency", (uint32_t*)&temp_data32, 1)) { | ||||
|                 if(furi_hal_subghz_is_frequency_valid(temp_data32)) { | ||||
|                     FURI_LOG_I(TAG, "Hopper frequency loaded %lu", temp_data32); | ||||
|                     hopper_frequencies_list_push_back(instance->hopper_frequencies, temp_data32); | ||||
|                     FrequenciesList_push_back(instance->hopper_frequencies, temp_data32); | ||||
|                     i++; | ||||
|                 } else { | ||||
|                     FURI_LOG_E(TAG, "Hopper frequency not supported %lu", temp_data32); | ||||
| @ -297,6 +296,8 @@ void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { | ||||
|             } | ||||
|         } while(false); | ||||
|     } | ||||
| 
 | ||||
|     string_clear(temp_str); | ||||
|     flipper_format_free(fff_data_file); | ||||
|     furi_record_close("storage"); | ||||
| 
 | ||||
| @ -347,15 +348,20 @@ size_t subghz_setting_get_hopper_frequency_count(SubGhzSetting* instance) { | ||||
| 
 | ||||
| uint32_t subghz_setting_get_frequency(SubGhzSetting* instance, size_t idx) { | ||||
|     furi_assert(instance); | ||||
|     return *frequencies_list_get(instance->frequencies, idx); | ||||
|     return *FrequenciesList_get(instance->frequencies, idx); | ||||
| } | ||||
| 
 | ||||
| uint32_t subghz_setting_get_hopper_frequency(SubGhzSetting* instance, size_t idx) { | ||||
|     furi_assert(instance); | ||||
|     return *hopper_frequencies_list_get(instance->hopper_frequencies, idx); | ||||
|     return *FrequenciesList_get(instance->hopper_frequencies, idx); | ||||
| } | ||||
| 
 | ||||
| uint32_t subghz_setting_get_frequency_default_index(SubGhzSetting* instance) { | ||||
|     furi_assert(instance); | ||||
|     return instance->frequency_default_index; | ||||
| } | ||||
| 
 | ||||
| uint32_t subghz_setting_get_default_frequency(SubGhzSetting* instance) { | ||||
|     furi_assert(instance); | ||||
|     return *FrequenciesList_get(instance->frequencies, instance->frequency_default_index); | ||||
| } | ||||
|  | ||||
| @ -8,10 +8,19 @@ | ||||
| typedef struct SubGhzSetting SubGhzSetting; | ||||
| 
 | ||||
| SubGhzSetting* subghz_setting_alloc(void); | ||||
| 
 | ||||
| void subghz_setting_free(SubGhzSetting* instance); | ||||
| 
 | ||||
| void subghz_setting_load(SubGhzSetting* instance, const char* file_path); | ||||
| 
 | ||||
| size_t subghz_setting_get_frequency_count(SubGhzSetting* instance); | ||||
| 
 | ||||
| size_t subghz_setting_get_hopper_frequency_count(SubGhzSetting* instance); | ||||
| 
 | ||||
| uint32_t subghz_setting_get_frequency(SubGhzSetting* instance, size_t idx); | ||||
| 
 | ||||
| uint32_t subghz_setting_get_hopper_frequency(SubGhzSetting* instance, size_t idx); | ||||
| 
 | ||||
| uint32_t subghz_setting_get_frequency_default_index(SubGhzSetting* instance); | ||||
| 
 | ||||
| uint32_t subghz_setting_get_default_frequency(SubGhzSetting* instance); | ||||
|  | ||||
| @ -80,7 +80,9 @@ Updater* updater_alloc(const char* arg) { | ||||
| #ifdef FURI_RAM_EXEC | ||||
|     if(true) { | ||||
| #else | ||||
|     if(!arg) { | ||||
|     FuriHalRtcBootMode boot_mode = furi_hal_rtc_get_boot_mode(); | ||||
|     if(!arg && ((boot_mode == FuriHalRtcBootModePreUpdate) || | ||||
|                 (boot_mode == FuriHalRtcBootModePostUpdate))) { | ||||
| #endif | ||||
|         updater->update_task = update_task_alloc(); | ||||
|         update_task_set_progress_cb(updater->update_task, status_update_cb, updater->main_view); | ||||
|  | ||||
| @ -12,7 +12,8 @@ | ||||
| /* Enum definitions */ | ||||
| typedef enum _PB_System_RebootRequest_RebootMode {  | ||||
|     PB_System_RebootRequest_RebootMode_OS = 0,  | ||||
|     PB_System_RebootRequest_RebootMode_DFU = 1  | ||||
|     PB_System_RebootRequest_RebootMode_DFU = 1,  | ||||
|     PB_System_RebootRequest_RebootMode_UPDATE = 2  | ||||
| } PB_System_RebootRequest_RebootMode; | ||||
| 
 | ||||
| /* Struct definitions */ | ||||
| @ -59,7 +60,7 @@ typedef struct _PB_System_ProtobufVersionRequest { | ||||
| } PB_System_ProtobufVersionRequest; | ||||
| 
 | ||||
| typedef struct _PB_System_UpdateRequest {  | ||||
|     char *update_folder;  | ||||
|     char *update_manifest;  | ||||
| } PB_System_UpdateRequest; | ||||
| 
 | ||||
| typedef struct _PB_System_DateTime {  | ||||
| @ -96,8 +97,8 @@ typedef struct _PB_System_SetDateTimeRequest { | ||||
| 
 | ||||
| /* Helper constants for enums */ | ||||
| #define _PB_System_RebootRequest_RebootMode_MIN PB_System_RebootRequest_RebootMode_OS | ||||
| #define _PB_System_RebootRequest_RebootMode_MAX PB_System_RebootRequest_RebootMode_DFU | ||||
| #define _PB_System_RebootRequest_RebootMode_ARRAYSIZE ((PB_System_RebootRequest_RebootMode)(PB_System_RebootRequest_RebootMode_DFU+1)) | ||||
| #define _PB_System_RebootRequest_RebootMode_MAX PB_System_RebootRequest_RebootMode_UPDATE | ||||
| #define _PB_System_RebootRequest_RebootMode_ARRAYSIZE ((PB_System_RebootRequest_RebootMode)(PB_System_RebootRequest_RebootMode_UPDATE+1)) | ||||
| 
 | ||||
| 
 | ||||
| #ifdef __cplusplus | ||||
| @ -145,7 +146,7 @@ extern "C" { | ||||
| #define PB_System_PingResponse_data_tag          1 | ||||
| #define PB_System_PowerInfoResponse_key_tag      1 | ||||
| #define PB_System_PowerInfoResponse_value_tag    2 | ||||
| #define PB_System_UpdateRequest_update_folder_tag 1 | ||||
| #define PB_System_UpdateRequest_update_manifest_tag 1 | ||||
| #define PB_System_DateTime_hour_tag              1 | ||||
| #define PB_System_DateTime_minute_tag            2 | ||||
| #define PB_System_DateTime_second_tag            3 | ||||
| @ -236,7 +237,7 @@ X(a, STATIC,   SINGULAR, UINT32,   minor,             2) | ||||
| #define PB_System_ProtobufVersionResponse_DEFAULT NULL | ||||
| 
 | ||||
| #define PB_System_UpdateRequest_FIELDLIST(X, a) \ | ||||
| X(a, POINTER,  SINGULAR, STRING,   update_folder,     1) | ||||
| X(a, POINTER,  SINGULAR, STRING,   update_manifest,   1) | ||||
| #define PB_System_UpdateRequest_CALLBACK NULL | ||||
| #define PB_System_UpdateRequest_DEFAULT NULL | ||||
| 
 | ||||
|  | ||||
| @ -1 +1 @@ | ||||
| Subproject commit 0403ae1ba7a4501274da54b3aa6274f76fdd090c | ||||
| Subproject commit 0ad90705b9434b6f8fb2c4b605069f0d56d8cc70 | ||||
| @ -10,10 +10,9 @@ What does it do? | ||||
| 
 | ||||
| # Targets | ||||
| 
 | ||||
| | Name      | Firmware      | Reset                   | DFU                     | | ||||
| |           | Address       | Combo                   | Combo                   | | ||||
| --------------------------------------------------------------------------------- | ||||
| | f7        | 0x08000000    | L+Back, release both    | L+Back, release Back    | | ||||
| | Name      | Firmware Address  | Reset Combo           | DFU Combo             | | ||||
| |-----------|-------------------|-----------------------|-----------------------| | ||||
| | f7        | 0x08000000        | L+Back, release both  | L+Back, release Back  | | ||||
| 
 | ||||
| Also there is a "hardware" ST bootloader combo available even on a bricked or empty device: L+Ok+Back, release Back, Left. | ||||
| Target independent code and headers in `target/include` folders. More details in `documentation/KeyCombo.md` | ||||
| @ -35,6 +34,10 @@ Target independent code and headers in `target/include` folders. More details in | ||||
| - `TARGET` - string - target to build. Default is `f7`. | ||||
| - `RAM_EXEC` - 0/1 - whether to build full firmware or RAM-based stage for firmware update. 0 is default, builds firmware. | ||||
| 
 | ||||
| # Building self-update package | ||||
| 
 | ||||
| `make DEBUG=0 COMPACT=1 updater_package` | ||||
| 
 | ||||
| # Flashing  | ||||
| 
 | ||||
| Using SWD (STLink): | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Aleksandr Kutuzov
						Aleksandr Kutuzov