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. | - 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. | - 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 | ## 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 | ## 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) | - Loading applications from SD (tested as PoC, work scheduled for Q2) | ||||||
| - More protocols (gathering feedback) | - More protocols (gathering feedback) | ||||||
| - User documentation (work in progress) | - User documentation (work in progress) | ||||||
|  | |||||||
| @ -131,7 +131,7 @@ const FlipperApplication FLIPPER_SERVICES[] = { | |||||||
| #endif | #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[] = { | const FlipperApplication FLIPPER_SYSTEM_APPS[] = { | ||||||
| #ifdef APP_UPDATER | #ifdef APP_UPDATER | ||||||
| @ -142,7 +142,7 @@ const FlipperApplication FLIPPER_SYSTEM_APPS[] = { | |||||||
| #endif | #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
 | // Main menu APP
 | ||||||
| const FlipperApplication FLIPPER_APPS[] = { | 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
 | // On system start hooks
 | ||||||
| const FlipperOnStartHook FLIPPER_ON_SYSTEM_START[] = { | const FlipperOnStartHook FLIPPER_ON_SYSTEM_START[] = { | ||||||
| @ -228,8 +228,7 @@ const FlipperOnStartHook FLIPPER_ON_SYSTEM_START[] = { | |||||||
| #endif | #endif | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const size_t FLIPPER_ON_SYSTEM_START_COUNT = | const size_t FLIPPER_ON_SYSTEM_START_COUNT = COUNT_OF(FLIPPER_ON_SYSTEM_START); | ||||||
|     sizeof(FLIPPER_ON_SYSTEM_START) / sizeof(FlipperOnStartHook); |  | ||||||
| 
 | 
 | ||||||
| // Plugin menu
 | // Plugin menu
 | ||||||
| const FlipperApplication FLIPPER_PLUGINS[] = { | const FlipperApplication FLIPPER_PLUGINS[] = { | ||||||
| @ -246,7 +245,7 @@ const FlipperApplication FLIPPER_PLUGINS[] = { | |||||||
| #endif | #endif | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const size_t FLIPPER_PLUGINS_COUNT = sizeof(FLIPPER_PLUGINS) / sizeof(FlipperApplication); | const size_t FLIPPER_PLUGINS_COUNT = COUNT_OF(FLIPPER_PLUGINS); | ||||||
| 
 | 
 | ||||||
| // Plugin menu
 | // Plugin menu
 | ||||||
| const FlipperApplication FLIPPER_DEBUG_APPS[] = { | const FlipperApplication FLIPPER_DEBUG_APPS[] = { | ||||||
| @ -307,7 +306,7 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { | |||||||
| #endif | #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 | #ifdef APP_ARCHIVE | ||||||
| const FlipperApplication FLIPPER_ARCHIVE = | const FlipperApplication FLIPPER_ARCHIVE = | ||||||
| @ -352,5 +351,4 @@ const FlipperApplication FLIPPER_SETTINGS_APPS[] = { | |||||||
| #endif | #endif | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const size_t FLIPPER_SETTINGS_APPS_COUNT = | const size_t FLIPPER_SETTINGS_APPS_COUNT = COUNT_OF(FLIPPER_SETTINGS_APPS); | ||||||
|     sizeof(FLIPPER_SETTINGS_APPS) / sizeof(FlipperApplication); |  | ||||||
|  | |||||||
| @ -34,13 +34,13 @@ bool desktop_scene_debug_on_event(void* context, SceneManagerEvent event) { | |||||||
|             break; |             break; | ||||||
| 
 | 
 | ||||||
|         case DesktopDebugEventDeed: |         case DesktopDebugEventDeed: | ||||||
|             dolphin_deed(dolphin, DolphinDeedIbuttonEmulate); |             dolphin_deed(dolphin, DolphinDeedTestRight); | ||||||
|             desktop_debug_get_dolphin_data(desktop->debug_view); |             desktop_debug_get_dolphin_data(desktop->debug_view); | ||||||
|             consumed = true; |             consumed = true; | ||||||
|             break; |             break; | ||||||
| 
 | 
 | ||||||
|         case DesktopDebugEventWrongDeed: |         case DesktopDebugEventWrongDeed: | ||||||
|             dolphin_deed(dolphin, DolphinDeedIbuttonRead); |             dolphin_deed(dolphin, DolphinDeedTestLeft); | ||||||
|             desktop_debug_get_dolphin_data(desktop->debug_view); |             desktop_debug_get_dolphin_data(desktop->debug_view); | ||||||
|             consumed = true; |             consumed = true; | ||||||
|             break; |             break; | ||||||
|  | |||||||
| @ -111,7 +111,10 @@ bool desktop_debug_input(InputEvent* event, void* context) { | |||||||
| 
 | 
 | ||||||
|     DesktopDebugView* debug_view = context; |     DesktopDebugView* debug_view = context; | ||||||
| 
 | 
 | ||||||
|     if(event->type != InputTypeShort) return false; |     if(event->type != InputTypeShort && event->type != InputTypeRepeat) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     DesktopViewStatsScreens current = 0; |     DesktopViewStatsScreens current = 0; | ||||||
|     with_view_model( |     with_view_model( | ||||||
|         debug_view->view, (DesktopDebugViewModel * model) { |         debug_view->view, (DesktopDebugViewModel * model) { | ||||||
| @ -125,11 +128,16 @@ bool desktop_debug_input(InputEvent* event, void* context) { | |||||||
|             return true; |             return true; | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|  |     size_t count = (event->type == InputTypeRepeat) ? 10 : 1; | ||||||
|     if(current == DesktopViewStatsMeta) { |     if(current == DesktopViewStatsMeta) { | ||||||
|         if(event->key == InputKeyLeft) { |         if(event->key == InputKeyLeft) { | ||||||
|  |             while(count-- > 0) { | ||||||
|                 debug_view->callback(DesktopDebugEventWrongDeed, debug_view->context); |                 debug_view->callback(DesktopDebugEventWrongDeed, debug_view->context); | ||||||
|  |             } | ||||||
|         } else if(event->key == InputKeyRight) { |         } else if(event->key == InputKeyRight) { | ||||||
|  |             while(count-- > 0) { | ||||||
|                 debug_view->callback(DesktopDebugEventDeed, debug_view->context); |                 debug_view->callback(DesktopDebugEventDeed, debug_view->context); | ||||||
|  |             } | ||||||
|         } else if(event->key == InputKeyOk) { |         } else if(event->key == InputKeyOk) { | ||||||
|             debug_view->callback(DesktopDebugEventSaveState, debug_view->context); |             debug_view->callback(DesktopDebugEventSaveState, debug_view->context); | ||||||
|         } else { |         } else { | ||||||
|  | |||||||
| @ -52,7 +52,10 @@ typedef enum { | |||||||
| 
 | 
 | ||||||
|     DolphinDeedU2fAuthorized, |     DolphinDeedU2fAuthorized, | ||||||
| 
 | 
 | ||||||
|     DolphinDeedMAX |     DolphinDeedMAX, | ||||||
|  | 
 | ||||||
|  |     DolphinDeedTestLeft, | ||||||
|  |     DolphinDeedTestRight, | ||||||
| } DolphinDeed; | } DolphinDeed; | ||||||
| 
 | 
 | ||||||
| typedef struct { | 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) { | 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); |     DolphinApp app = dolphin_deed_get_app(deed); | ||||||
|     int8_t weight_limit = |     int8_t weight_limit = | ||||||
|         dolphin_deed_get_app_limit(app) - dolphin_state->data.icounter_daily_limit[app]; |         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) { | 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_t application_name; | ||||||
|     string_init(application_name); |     string_init(application_name); | ||||||
| 
 | 
 | ||||||
| @ -292,7 +297,7 @@ static Loader* loader_alloc() { | |||||||
| 
 | 
 | ||||||
| #ifdef SRV_CLI | #ifdef SRV_CLI | ||||||
|     instance->cli = furi_record_open("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 | #else | ||||||
|     UNUSED(loader_cli); |     UNUSED(loader_cli); | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -418,11 +418,8 @@ static bool notification_save_settings(NotificationApp* app) { | |||||||
| static void input_event_callback(const void* value, void* context) { | static void input_event_callback(const void* value, void* context) { | ||||||
|     furi_assert(value); |     furi_assert(value); | ||||||
|     furi_assert(context); |     furi_assert(context); | ||||||
|     const InputEvent* event = value; |  | ||||||
|     NotificationApp* app = context; |     NotificationApp* app = context; | ||||||
|     if(event->type == InputTypePress) { |  | ||||||
|     notification_message(app, &sequence_display_on); |     notification_message(app, &sequence_display_on); | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // App alloc
 | // App alloc
 | ||||||
|  | |||||||
| @ -9,6 +9,7 @@ typedef struct Power Power; | |||||||
| typedef enum { | typedef enum { | ||||||
|     PowerBootModeNormal, |     PowerBootModeNormal, | ||||||
|     PowerBootModeDfu, |     PowerBootModeDfu, | ||||||
|  |     PowerBootModeUpdateStart, | ||||||
| } PowerBootMode; | } PowerBootMode; | ||||||
| 
 | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
|  | |||||||
| @ -17,6 +17,8 @@ void power_reboot(PowerBootMode mode) { | |||||||
|         furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); |         furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); | ||||||
|     } else if(mode == PowerBootModeDfu) { |     } else if(mode == PowerBootModeDfu) { | ||||||
|         furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeDfu); |         furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeDfu); | ||||||
|  |     } else if(mode == PowerBootModeUpdateStart) { | ||||||
|  |         furi_hal_rtc_set_boot_mode(FuriHalRtcBootModePreUpdate); | ||||||
|     } |     } | ||||||
|     furi_hal_power_reset(); |     furi_hal_power_reset(); | ||||||
| } | } | ||||||
|  | |||||||
| @ -61,6 +61,8 @@ static void rpc_system_system_reboot_process(const PB_Main* request, void* conte | |||||||
|         power_reboot(PowerBootModeNormal); |         power_reboot(PowerBootModeNormal); | ||||||
|     } else if(mode == PB_System_RebootRequest_RebootMode_DFU) { |     } else if(mode == PB_System_RebootRequest_RebootMode_DFU) { | ||||||
|         power_reboot(PowerBootModeDfu); |         power_reboot(PowerBootModeDfu); | ||||||
|  |     } else if(mode == PB_System_RebootRequest_RebootMode_UPDATE) { | ||||||
|  |         power_reboot(PowerBootModeUpdateStart); | ||||||
|     } else { |     } else { | ||||||
|         rpc_send_and_release_empty( |         rpc_send_and_release_empty( | ||||||
|             session, request->command_id, PB_CommandStatus_ERROR_INVALID_PARAMETERS); |             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); |     furi_assert(session); | ||||||
| 
 | 
 | ||||||
|     bool update_prepare_result = |     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; |         UpdatePrepareResultOK; | ||||||
| 
 | 
 | ||||||
|     PB_Main* response = malloc(sizeof(PB_Main)); |     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); |                 scene_manager_next_scene(subghz->scene_manager, SubGhzSceneNeedSaving); | ||||||
|             } else { |             } else { | ||||||
|                 //Restore default setting
 |                 //Restore default setting
 | ||||||
|                 subghz->txrx->frequency = subghz_setting_get_frequency( |                 subghz->txrx->frequency = subghz_setting_get_default_frequency(subghz->setting); | ||||||
|                     subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)); |  | ||||||
|                 subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; |                 subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; | ||||||
|                 if(!scene_manager_search_and_switch_to_previous_scene( |                 if(!scene_manager_search_and_switch_to_previous_scene( | ||||||
|                        subghz->scene_manager, SubGhzSceneSaved)) { |                        subghz->scene_manager, SubGhzSceneSaved)) { | ||||||
|  | |||||||
| @ -120,8 +120,7 @@ bool subghz_scene_receiver_on_event(void* context, SceneManagerEvent event) { | |||||||
|                 subghz_sleep(subghz); |                 subghz_sleep(subghz); | ||||||
|             }; |             }; | ||||||
|             subghz->txrx->hopper_state = SubGhzHopperStateOFF; |             subghz->txrx->hopper_state = SubGhzHopperStateOFF; | ||||||
|             subghz->txrx->frequency = subghz_setting_get_frequency( |             subghz->txrx->frequency = subghz_setting_get_default_frequency(subghz->setting); | ||||||
|                 subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)); |  | ||||||
|             subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; |             subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; | ||||||
|             subghz->txrx->idx_menu_chosen = 0; |             subghz->txrx->idx_menu_chosen = 0; | ||||||
|             subghz_receiver_set_rx_callback(subghz->txrx->receiver, NULL, subghz); |             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( |         sprintf( | ||||||
|             text_buf, |             text_buf, | ||||||
|             "%lu.%02lu", |             "%lu.%02lu", | ||||||
|             subghz_setting_get_frequency( |             subghz_setting_get_default_frequency(subghz->setting) / 1000000, | ||||||
|                 subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)) / |             (subghz_setting_get_default_frequency(subghz->setting) % 1000000) / 10000); | ||||||
|                 1000000, |  | ||||||
|             (subghz_setting_get_frequency( |  | ||||||
|                  subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)) % |  | ||||||
|              1000000) / |  | ||||||
|                 10000); |  | ||||||
|         variable_item_set_current_value_text( |         variable_item_set_current_value_text( | ||||||
|             (VariableItem*)scene_manager_get_scene_state( |             (VariableItem*)scene_manager_get_scene_state( | ||||||
|                 subghz->scene_manager, SubGhzSceneReceiverConfig), |                 subghz->scene_manager, SubGhzSceneReceiverConfig), | ||||||
|             text_buf); |             text_buf); | ||||||
|         subghz->txrx->frequency = subghz_setting_get_frequency( |         subghz->txrx->frequency = subghz_setting_get_default_frequency(subghz->setting); | ||||||
|             subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)); |  | ||||||
|         variable_item_set_current_value_index( |         variable_item_set_current_value_index( | ||||||
|             (VariableItem*)scene_manager_get_scene_state( |             (VariableItem*)scene_manager_get_scene_state( | ||||||
|                 subghz->scene_manager, SubGhzSceneReceiverConfig), |                 subghz->scene_manager, SubGhzSceneReceiverConfig), | ||||||
|  | |||||||
| @ -46,7 +46,7 @@ bool subghz_scene_set_type_submenu_gen_data_protocol( | |||||||
|         if(!subghz_protocol_decoder_base_serialize( |         if(!subghz_protocol_decoder_base_serialize( | ||||||
|                subghz->txrx->decoder_result, |                subghz->txrx->decoder_result, | ||||||
|                subghz->txrx->fff_data, |                subghz->txrx->fff_data, | ||||||
|                subghz_setting_get_frequency_default_index(subghz->setting), |                subghz_setting_get_default_frequency(subghz->setting), | ||||||
|                FuriHalSubGhzPresetOok650Async)) { |                FuriHalSubGhzPresetOok650Async)) { | ||||||
|             FURI_LOG_E(TAG, "Unable to serialize"); |             FURI_LOG_E(TAG, "Unable to serialize"); | ||||||
|             break; |             break; | ||||||
| @ -213,7 +213,7 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) { | |||||||
|                     0x2, |                     0x2, | ||||||
|                     0x0003, |                     0x0003, | ||||||
|                     "DoorHan", |                     "DoorHan", | ||||||
|                     subghz_setting_get_frequency_default_index(subghz->setting), |                     subghz_setting_get_default_frequency(subghz->setting), | ||||||
|                     FuriHalSubGhzPresetOok650Async); |                     FuriHalSubGhzPresetOok650Async); | ||||||
|                 generated_protocol = true; |                 generated_protocol = true; | ||||||
|             } else { |             } else { | ||||||
|  | |||||||
| @ -130,8 +130,7 @@ SubGhz* subghz_alloc() { | |||||||
| 
 | 
 | ||||||
|     //init Worker & Protocol & History
 |     //init Worker & Protocol & History
 | ||||||
|     subghz->txrx = malloc(sizeof(SubGhzTxRx)); |     subghz->txrx = malloc(sizeof(SubGhzTxRx)); | ||||||
|     subghz->txrx->frequency = subghz_setting_get_frequency( |     subghz->txrx->frequency = subghz_setting_get_default_frequency(subghz->setting); | ||||||
|         subghz->setting, subghz_setting_get_frequency_default_index(subghz->setting)); |  | ||||||
|     subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; |     subghz->txrx->preset = FuriHalSubGhzPresetOok650Async; | ||||||
|     subghz->txrx->txrx_state = SubGhzTxRxStateSleep; |     subghz->txrx->txrx_state = SubGhzTxRxStateSleep; | ||||||
|     subghz->txrx->hopper_state = SubGhzHopperStateOFF; |     subghz->txrx->hopper_state = SubGhzHopperStateOFF; | ||||||
|  | |||||||
| @ -246,7 +246,7 @@ bool subghz_key_load(SubGhz* subghz, const char* file_path) { | |||||||
|             break; |             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"); |             FURI_LOG_E(TAG, "Missing Frequency"); | ||||||
|             break; |             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; | static const uint32_t subghz_frequency_default_index_region_jp = 9; | ||||||
| 
 | 
 | ||||||
| LIST_DEF(frequencies_list, uint32_t) | LIST_DEF(FrequenciesList, uint32_t) | ||||||
| LIST_DEF(hopper_frequencies_list, uint32_t) |  | ||||||
| 
 | 
 | ||||||
| struct SubGhzSetting { | struct SubGhzSetting { | ||||||
|     frequencies_list_t frequencies; |     FrequenciesList_t frequencies; | ||||||
|     hopper_frequencies_list_t hopper_frequencies; |     FrequenciesList_t hopper_frequencies; | ||||||
|     size_t frequencies_count; |     size_t frequencies_count; | ||||||
|     size_t hopper_frequencies_count; |     size_t hopper_frequencies_count; | ||||||
|     uint32_t frequency_default_index; |     uint32_t frequency_default_index; | ||||||
| @ -165,15 +164,15 @@ struct SubGhzSetting { | |||||||
| 
 | 
 | ||||||
| SubGhzSetting* subghz_setting_alloc(void) { | SubGhzSetting* subghz_setting_alloc(void) { | ||||||
|     SubGhzSetting* instance = malloc(sizeof(SubGhzSetting)); |     SubGhzSetting* instance = malloc(sizeof(SubGhzSetting)); | ||||||
|     frequencies_list_init(instance->frequencies); |     FrequenciesList_init(instance->frequencies); | ||||||
|     hopper_frequencies_list_init(instance->hopper_frequencies); |     FrequenciesList_init(instance->hopper_frequencies); | ||||||
|     return instance; |     return instance; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void subghz_setting_free(SubGhzSetting* instance) { | void subghz_setting_free(SubGhzSetting* instance) { | ||||||
|     furi_assert(instance); |     furi_assert(instance); | ||||||
|     frequencies_list_clear(instance->frequencies); |     FrequenciesList_clear(instance->frequencies); | ||||||
|     hopper_frequencies_list_clear(instance->hopper_frequencies); |     FrequenciesList_clear(instance->hopper_frequencies); | ||||||
|     free(instance); |     free(instance); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -184,18 +183,18 @@ void subghz_setting_load_default( | |||||||
|     const uint32_t frequency_default_index) { |     const uint32_t frequency_default_index) { | ||||||
|     furi_assert(instance); |     furi_assert(instance); | ||||||
|     size_t i = 0; |     size_t i = 0; | ||||||
|     frequencies_list_clear(instance->frequencies); |     FrequenciesList_clear(instance->frequencies); | ||||||
|     hopper_frequencies_list_clear(instance->hopper_frequencies); |     FrequenciesList_clear(instance->hopper_frequencies); | ||||||
|     i = 0; |     i = 0; | ||||||
|     while(frequencies[i]) { |     while(frequencies[i]) { | ||||||
|         frequencies_list_push_back(instance->frequencies, frequencies[i]); |         FrequenciesList_push_back(instance->frequencies, frequencies[i]); | ||||||
|         i++; |         i++; | ||||||
|     } |     } | ||||||
|     instance->frequencies_count = i; |     instance->frequencies_count = i; | ||||||
| 
 | 
 | ||||||
|     i = 0; |     i = 0; | ||||||
|     while(hopper_frequencies[i]) { |     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++; |         i++; | ||||||
|     } |     } | ||||||
|     instance->hopper_frequencies_count = 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) { | void subghz_setting_load(SubGhzSetting* instance, const char* file_path) { | ||||||
|     furi_assert(instance); |     furi_assert(instance); | ||||||
| 
 | 
 | ||||||
|     frequencies_list_clear(instance->frequencies); |     FrequenciesList_clear(instance->frequencies); | ||||||
|     hopper_frequencies_list_clear(instance->hopper_frequencies); |     FrequenciesList_clear(instance->hopper_frequencies); | ||||||
| 
 | 
 | ||||||
|     Storage* storage = furi_record_open("storage"); |     Storage* storage = furi_record_open("storage"); | ||||||
|     FlipperFormat* fff_data_file = flipper_format_file_alloc(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)) { |                 fff_data_file, "Frequency", (uint32_t*)&temp_data32, 1)) { | ||||||
|                 if(furi_hal_subghz_is_frequency_valid(temp_data32)) { |                 if(furi_hal_subghz_is_frequency_valid(temp_data32)) { | ||||||
|                     FURI_LOG_I(TAG, "Frequency loaded %lu", 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++; |                     i++; | ||||||
|                 } else { |                 } else { | ||||||
|                     FURI_LOG_E(TAG, "Frequency not supported %lu", temp_data32); |                     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)) { |                 fff_data_file, "Hopper_frequency", (uint32_t*)&temp_data32, 1)) { | ||||||
|                 if(furi_hal_subghz_is_frequency_valid(temp_data32)) { |                 if(furi_hal_subghz_is_frequency_valid(temp_data32)) { | ||||||
|                     FURI_LOG_I(TAG, "Hopper frequency loaded %lu", 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++; |                     i++; | ||||||
|                 } else { |                 } else { | ||||||
|                     FURI_LOG_E(TAG, "Hopper frequency not supported %lu", temp_data32); |                     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); |         } while(false); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     string_clear(temp_str); | ||||||
|     flipper_format_free(fff_data_file); |     flipper_format_free(fff_data_file); | ||||||
|     furi_record_close("storage"); |     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) { | uint32_t subghz_setting_get_frequency(SubGhzSetting* instance, size_t idx) { | ||||||
|     furi_assert(instance); |     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) { | uint32_t subghz_setting_get_hopper_frequency(SubGhzSetting* instance, size_t idx) { | ||||||
|     furi_assert(instance); |     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) { | uint32_t subghz_setting_get_frequency_default_index(SubGhzSetting* instance) { | ||||||
|     furi_assert(instance); |     furi_assert(instance); | ||||||
|     return instance->frequency_default_index; |     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; | typedef struct SubGhzSetting SubGhzSetting; | ||||||
| 
 | 
 | ||||||
| SubGhzSetting* subghz_setting_alloc(void); | SubGhzSetting* subghz_setting_alloc(void); | ||||||
|  | 
 | ||||||
| void subghz_setting_free(SubGhzSetting* instance); | void subghz_setting_free(SubGhzSetting* instance); | ||||||
|  | 
 | ||||||
| void subghz_setting_load(SubGhzSetting* instance, const char* file_path); | void subghz_setting_load(SubGhzSetting* instance, const char* file_path); | ||||||
|  | 
 | ||||||
| size_t subghz_setting_get_frequency_count(SubGhzSetting* instance); | size_t subghz_setting_get_frequency_count(SubGhzSetting* instance); | ||||||
|  | 
 | ||||||
| size_t subghz_setting_get_hopper_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_frequency(SubGhzSetting* instance, size_t idx); | ||||||
|  | 
 | ||||||
| uint32_t subghz_setting_get_hopper_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_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 | #ifdef FURI_RAM_EXEC | ||||||
|     if(true) { |     if(true) { | ||||||
| #else | #else | ||||||
|     if(!arg) { |     FuriHalRtcBootMode boot_mode = furi_hal_rtc_get_boot_mode(); | ||||||
|  |     if(!arg && ((boot_mode == FuriHalRtcBootModePreUpdate) || | ||||||
|  |                 (boot_mode == FuriHalRtcBootModePostUpdate))) { | ||||||
| #endif | #endif | ||||||
|         updater->update_task = update_task_alloc(); |         updater->update_task = update_task_alloc(); | ||||||
|         update_task_set_progress_cb(updater->update_task, status_update_cb, updater->main_view); |         update_task_set_progress_cb(updater->update_task, status_update_cb, updater->main_view); | ||||||
|  | |||||||
| @ -12,7 +12,8 @@ | |||||||
| /* Enum definitions */ | /* Enum definitions */ | ||||||
| typedef enum _PB_System_RebootRequest_RebootMode {  | typedef enum _PB_System_RebootRequest_RebootMode {  | ||||||
|     PB_System_RebootRequest_RebootMode_OS = 0,  |     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; | } PB_System_RebootRequest_RebootMode; | ||||||
| 
 | 
 | ||||||
| /* Struct definitions */ | /* Struct definitions */ | ||||||
| @ -59,7 +60,7 @@ typedef struct _PB_System_ProtobufVersionRequest { | |||||||
| } PB_System_ProtobufVersionRequest; | } PB_System_ProtobufVersionRequest; | ||||||
| 
 | 
 | ||||||
| typedef struct _PB_System_UpdateRequest {  | typedef struct _PB_System_UpdateRequest {  | ||||||
|     char *update_folder;  |     char *update_manifest;  | ||||||
| } PB_System_UpdateRequest; | } PB_System_UpdateRequest; | ||||||
| 
 | 
 | ||||||
| typedef struct _PB_System_DateTime {  | typedef struct _PB_System_DateTime {  | ||||||
| @ -96,8 +97,8 @@ typedef struct _PB_System_SetDateTimeRequest { | |||||||
| 
 | 
 | ||||||
| /* Helper constants for enums */ | /* Helper constants for enums */ | ||||||
| #define _PB_System_RebootRequest_RebootMode_MIN PB_System_RebootRequest_RebootMode_OS | #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_MAX PB_System_RebootRequest_RebootMode_UPDATE | ||||||
| #define _PB_System_RebootRequest_RebootMode_ARRAYSIZE ((PB_System_RebootRequest_RebootMode)(PB_System_RebootRequest_RebootMode_DFU+1)) | #define _PB_System_RebootRequest_RebootMode_ARRAYSIZE ((PB_System_RebootRequest_RebootMode)(PB_System_RebootRequest_RebootMode_UPDATE+1)) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| @ -145,7 +146,7 @@ extern "C" { | |||||||
| #define PB_System_PingResponse_data_tag          1 | #define PB_System_PingResponse_data_tag          1 | ||||||
| #define PB_System_PowerInfoResponse_key_tag      1 | #define PB_System_PowerInfoResponse_key_tag      1 | ||||||
| #define PB_System_PowerInfoResponse_value_tag    2 | #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_hour_tag              1 | ||||||
| #define PB_System_DateTime_minute_tag            2 | #define PB_System_DateTime_minute_tag            2 | ||||||
| #define PB_System_DateTime_second_tag            3 | #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_ProtobufVersionResponse_DEFAULT NULL | ||||||
| 
 | 
 | ||||||
| #define PB_System_UpdateRequest_FIELDLIST(X, a) \ | #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_CALLBACK NULL | ||||||
| #define PB_System_UpdateRequest_DEFAULT NULL | #define PB_System_UpdateRequest_DEFAULT NULL | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1 +1 @@ | |||||||
| Subproject commit 0403ae1ba7a4501274da54b3aa6274f76fdd090c | Subproject commit 0ad90705b9434b6f8fb2c4b605069f0d56d8cc70 | ||||||
| @ -10,9 +10,8 @@ What does it do? | |||||||
| 
 | 
 | ||||||
| # Targets | # Targets | ||||||
| 
 | 
 | ||||||
| | Name      | Firmware      | Reset                   | DFU                     | | | Name      | Firmware Address  | Reset Combo           | DFU Combo             | | ||||||
| |           | Address       | Combo                   | Combo                   | | |-----------|-------------------|-----------------------|-----------------------| | ||||||
| --------------------------------------------------------------------------------- |  | ||||||
| | f7        | 0x08000000        | L+Back, release both  | L+Back, release Back  | | | 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. | Also there is a "hardware" ST bootloader combo available even on a bricked or empty device: L+Ok+Back, release Back, Left. | ||||||
| @ -35,6 +34,10 @@ Target independent code and headers in `target/include` folders. More details in | |||||||
| - `TARGET` - string - target to build. Default is `f7`. | - `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. | - `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  | # Flashing  | ||||||
| 
 | 
 | ||||||
| Using SWD (STLink): | Using SWD (STLink): | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Aleksandr Kutuzov
						Aleksandr Kutuzov