diff --git a/applications/accessor/accessor-app.cpp b/applications/accessor/accessor-app.cpp index b462ec793..7313474b9 100644 --- a/applications/accessor/accessor-app.cpp +++ b/applications/accessor/accessor-app.cpp @@ -109,16 +109,6 @@ void AccessorApp::notify_green_blink() { void AccessorApp::notify_success() { notification_message(notification, &sequence_success); - - hal_pwm_set(0.5, 1760 / 2, &htim2, TIM_CHANNEL_2); - delay(100); - hal_pwm_stop(&htim2, TIM_CHANNEL_2); - - delay(100); - - hal_pwm_set(0.5, 1760, &htim2, TIM_CHANNEL_2); - delay(100); - hal_pwm_stop(&htim2, TIM_CHANNEL_2); } /*************************** TEXT STORE *****************************/ diff --git a/applications/accessor/helpers/wiegand.cpp b/applications/accessor/helpers/wiegand.cpp index 9e92a15d7..777fa5613 100644 --- a/applications/accessor/helpers/wiegand.cpp +++ b/applications/accessor/helpers/wiegand.cpp @@ -11,6 +11,8 @@ volatile int WIEGAND::_bitCount = 0; int WIEGAND::_wiegandType = 0; constexpr uint32_t clocks_in_ms = 64 * 1000; +const GpioPin* pinD0 = &gpio_ext_pa4; +const GpioPin* pinD1 = &gpio_ext_pa7; WIEGAND::WIEGAND() { } @@ -53,9 +55,6 @@ void WIEGAND::begin() { _wiegandType = 0; _bitCount = 0; - const GpioPin* pinD0 = &gpio_ext_pa6; - const GpioPin* pinD1 = &gpio_ext_pa7; - hal_gpio_init_simple(pinD0, GpioModeInterruptFall); // Set D0 pin as input hal_gpio_init_simple(pinD1, GpioModeInterruptFall); // Set D1 pin as input @@ -64,11 +63,11 @@ void WIEGAND::begin() { } void WIEGAND::end() { - hal_gpio_remove_int_callback(&gpio_ext_pa6); - hal_gpio_remove_int_callback(&gpio_ext_pa7); + hal_gpio_remove_int_callback(pinD0); + hal_gpio_remove_int_callback(pinD1); - hal_gpio_init_simple(&gpio_ext_pa6, GpioModeAnalog); - hal_gpio_init_simple(&gpio_ext_pa7, GpioModeAnalog); + hal_gpio_init_simple(pinD0, GpioModeAnalog); + hal_gpio_init_simple(pinD1, GpioModeAnalog); } void WIEGAND::ReadD0() { diff --git a/applications/applications.c b/applications/applications.c index 36751e09b..cd7e9f4e1 100644 --- a/applications/applications.c +++ b/applications/applications.c @@ -32,6 +32,7 @@ extern int32_t scened_app(void* p); extern int32_t storage_test_app(void* p); extern int32_t subghz_app(void* p); extern int32_t vibro_test_app(void* p); +extern int32_t bt_debug_app(void* p); // Plugins extern int32_t music_player_app(void* p); @@ -48,6 +49,7 @@ extern void subghz_cli_init(); // Settings extern int32_t notification_settings_app(void* p); extern int32_t storage_settings_app(void* p); +extern int32_t bt_settings_app(void* p); const FlipperApplication FLIPPER_SERVICES[] = { /* Services */ @@ -236,6 +238,10 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { #ifdef APP_LF_RFID {.app = lfrfid_debug_app, .name = "LF-RFID Debug", .stack_size = 1024, .icon = &A_125khz_14}, #endif + +#ifdef SRV_BT + {.app = bt_debug_app, .name = "Bluetooth Debug", .stack_size = 1024, .icon = NULL}, +#endif }; const size_t FLIPPER_DEBUG_APPS_COUNT = sizeof(FLIPPER_DEBUG_APPS) / sizeof(FlipperApplication); @@ -254,6 +260,10 @@ const FlipperApplication FLIPPER_SETTINGS_APPS[] = { #ifdef SRV_STORAGE {.app = storage_settings_app, .name = "Storage", .stack_size = 2048, .icon = NULL}, #endif + +#ifdef SRV_BT + {.app = bt_settings_app, .name = "Bluetooth", .stack_size = 1024, .icon = NULL}, +#endif }; const size_t FLIPPER_SETTINGS_APPS_COUNT = diff --git a/applications/bt/bt.c b/applications/bt/bt.c deleted file mode 100644 index 41974f65a..000000000 --- a/applications/bt/bt.c +++ /dev/null @@ -1,266 +0,0 @@ -#include "bt_i.h" - -uint32_t bt_view_exit(void* context) { - (void)context; - return VIEW_NONE; -} - -void bt_update_statusbar(void* arg) { - furi_assert(arg); - Bt* bt = arg; - BtMessage m = {.type = BtMessageTypeUpdateStatusbar}; - furi_check(osMessageQueuePut(bt->message_queue, &m, 0, osWaitForever) == osOK); -} - -void bt_update_param(void* arg) { - furi_assert(arg); - Bt* bt = arg; - BtMessage m; - if(bt->state.type == BtStateHoppingTx || bt->state.type == BtStateCarrierRxRunning) { - m.type = BtMessageTypeStartTestCarrier; - } else if(bt->state.type == BtStatePacketRunning) { - m.type = BtMessageTypeStartTestPacketRx; - } - furi_check(osMessageQueuePut(bt->message_queue, &m, 0, osWaitForever) == osOK); -} - -Bt* bt_alloc() { - Bt* bt = furi_alloc(sizeof(Bt)); - - bt->message_queue = osMessageQueueNew(8, sizeof(BtMessage), NULL); - bt->update_status_timer = osTimerNew(bt_update_statusbar, osTimerPeriodic, bt, NULL); - osTimerStart(bt->update_status_timer, 4000); - bt->update_param_timer = osTimerNew(bt_update_param, osTimerPeriodic, bt, NULL); - bt->gui = furi_record_open("gui"); - bt->menu = furi_record_open("menu"); - - bt->state.type = BtStateReady; - bt->state.param.channel = BtChannel2402; - bt->state.param.power = BtPower0dB; - bt->state.param.datarate = BtDataRate1M; - - bt->statusbar_view_port = view_port_alloc(); - view_port_set_width(bt->statusbar_view_port, 5); - view_port_draw_callback_set(bt->statusbar_view_port, bt_draw_statusbar_callback, bt); - view_port_enabled_set(bt->statusbar_view_port, false); - gui_add_view_port(bt->gui, bt->statusbar_view_port, GuiLayerStatusBarLeft); - - bt->menu_icon = icon_animation_alloc(&A_Bluetooth_14); - bt->menu_item = menu_item_alloc_menu("Bluetooth", bt->menu_icon); - menu_item_subitem_add( - bt->menu_item, menu_item_alloc_function("Carrier test", NULL, bt_menu_test_carrier, bt)); - menu_item_subitem_add( - bt->menu_item, - menu_item_alloc_function("Test packet TX", NULL, bt_menu_test_packet_tx, bt)); - menu_item_subitem_add( - bt->menu_item, menu_item_alloc_function("Start app", NULL, bt_menu_start_app, bt)); - menu_item_subitem_add( - bt->menu_item, - menu_item_alloc_function("Test packet RX", NULL, bt_menu_test_packet_rx, bt)); - - // Carrier test - bt->view_test_carrier = view_alloc(); - view_set_context(bt->view_test_carrier, bt); - view_set_draw_callback(bt->view_test_carrier, bt_view_test_carrier_draw); - view_allocate_model( - bt->view_test_carrier, ViewModelTypeLocking, sizeof(BtViewTestCarrierModel)); - view_set_input_callback(bt->view_test_carrier, bt_view_test_carrier_input); - - // Packet TX test - bt->view_test_packet_tx = view_alloc(); - view_set_context(bt->view_test_packet_tx, bt); - view_set_draw_callback(bt->view_test_packet_tx, bt_view_test_packet_tx_draw); - view_allocate_model( - bt->view_test_packet_tx, ViewModelTypeLocking, sizeof(BtViewTestPacketTxModel)); - view_set_input_callback(bt->view_test_packet_tx, bt_view_test_packet_tx_input); - - // Packet RX test - bt->view_test_packet_rx = view_alloc(); - view_set_context(bt->view_test_packet_rx, bt); - view_set_draw_callback(bt->view_test_packet_rx, bt_view_test_packet_rx_draw); - view_allocate_model( - bt->view_test_packet_rx, ViewModelTypeLocking, sizeof(BtViewTestPacketRxModel)); - view_set_input_callback(bt->view_test_packet_rx, bt_view_test_packet_rx_input); - - // Start app - bt->view_start_app = view_alloc(); - view_set_context(bt->view_start_app, bt); - view_set_draw_callback(bt->view_start_app, bt_view_app_draw); - view_set_previous_callback(bt->view_start_app, bt_view_exit); - - // View dispatcher - bt->view_dispatcher = view_dispatcher_alloc(); - view_dispatcher_add_view(bt->view_dispatcher, BtViewTestCarrier, bt->view_test_carrier); - view_dispatcher_add_view(bt->view_dispatcher, BtViewTestPacketTx, bt->view_test_packet_tx); - view_dispatcher_add_view(bt->view_dispatcher, BtViewTestPacketRx, bt->view_test_packet_rx); - view_dispatcher_add_view(bt->view_dispatcher, BtViewStartApp, bt->view_start_app); - - Gui* gui = furi_record_open("gui"); - view_dispatcher_attach_to_gui(bt->view_dispatcher, gui, ViewDispatcherTypeFullscreen); - - with_value_mutex( - bt->menu, (Menu * menu) { menu_item_add(menu, bt->menu_item); }); - return bt; -} - -void bt_draw_statusbar_callback(Canvas* canvas, void* context) { - canvas_draw_icon(canvas, 0, 0, &I_Bluetooth_5x8); -} - -void bt_menu_test_carrier(void* context) { - furi_assert(context); - Bt* bt = context; - bt->state.type = BtStateCarrierTx; - BtMessage message = { - .type = BtMessageTypeStartTestCarrier, - .param.channel = bt->state.param.channel, - .param.power = bt->state.param.power}; - furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); -} - -void bt_menu_test_packet_tx(void* context) { - furi_assert(context); - Bt* bt = context; - bt->state.type = BtStatePacketSetup; - BtMessage message = { - .type = BtMessageTypeSetupTestPacketTx, - .param.channel = bt->state.param.channel, - .param.datarate = bt->state.param.datarate}; - furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); -} - -void bt_menu_test_packet_rx(void* context) { - furi_assert(context); - Bt* bt = context; - bt->state.type = BtStatePacketSetup; - BtMessage message = { - .type = BtMessageTypeSetupTestPacketRx, - .param.channel = bt->state.param.channel, - .param.datarate = bt->state.param.datarate}; - furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); -} - -void bt_menu_start_app(void* context) { - furi_assert(context); - Bt* bt = context; - bt->state.type = BtStateStartedApp; - BtMessage message = {.type = BtMessageTypeStartApp}; - furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); -} - -int32_t bt_srv() { - Bt* bt = bt_alloc(); - - furi_record_create("bt", bt); - - furi_hal_bt_init(); - BtMessage message; - while(1) { - furi_check(osMessageQueueGet(bt->message_queue, &message, NULL, osWaitForever) == osOK); - if(message.type == BtMessageTypeStartTestCarrier) { - // Start carrier test - furi_hal_bt_stop_tone_tx(); - if(bt->state.type == BtStateCarrierTx) { - furi_hal_bt_start_tone_tx(message.param.channel, message.param.power); - } else if(bt->state.type == BtStateHoppingTx) { - bt->state.param.channel = - bt_switch_channel(InputKeyRight, bt->state.param.channel); - furi_hal_bt_start_tone_tx(bt->state.param.channel, bt->state.param.power); - } else if(bt->state.type == BtStateCarrierRxStart) { - furi_hal_bt_start_packet_rx(bt->state.param.channel, bt->state.param.datarate); - bt->state.type = BtStateCarrierRxRunning; - } else if(bt->state.type == BtStateCarrierRxRunning) { - bt->state.param.rssi = furi_hal_bt_get_rssi(); - } - with_view_model( - bt->view_test_carrier, (BtViewTestCarrierModel * model) { - model->type = bt->state.type; - model->channel = bt->state.param.channel; - model->power = bt->state.param.power; - model->rssi = bt->state.param.rssi; - return true; - }); - view_dispatcher_switch_to_view(bt->view_dispatcher, BtViewTestCarrier); - } else if(message.type == BtMessageTypeStopTestCarrier) { - if(bt->state.type == BtStateCarrierRxRunning) { - furi_hal_bt_stop_packet_test(); - } else { - furi_hal_bt_stop_tone_tx(); - } - bt->state.type = BtStateReady; - } else if(message.type == BtMessageTypeSetupTestPacketTx) { - // Update packet test setup - furi_hal_bt_stop_packet_test(); - with_view_model( - bt->view_test_packet_tx, (BtViewTestPacketTxModel * model) { - model->type = bt->state.type; - model->channel = bt->state.param.channel; - model->datarate = bt->state.param.datarate; - return true; - }); - view_dispatcher_switch_to_view(bt->view_dispatcher, BtViewTestPacketTx); - } else if(message.type == BtMessageTypeStartTestPacketTx) { - // Start sending packets - if(bt->state.type == BtStatePacketStart) { - furi_hal_bt_start_packet_tx(message.param.channel, 1, message.param.datarate); - } else if(bt->state.type == BtStatePacketSetup) { - furi_hal_bt_stop_packet_test(); - bt->state.param.packets_sent = furi_hal_bt_get_transmitted_packets(); - } - with_view_model( - bt->view_test_packet_tx, (BtViewTestPacketTxModel * model) { - model->type = bt->state.type; - model->channel = bt->state.param.channel; - model->datarate = bt->state.param.datarate; - model->packets_sent = bt->state.param.packets_sent; - return true; - }); - view_dispatcher_switch_to_view(bt->view_dispatcher, BtViewTestPacketTx); - } else if(message.type == BtMessageTypeSetupTestPacketRx) { - // Update packet test setup - furi_hal_bt_stop_packet_test(); - with_view_model( - bt->view_test_packet_rx, (BtViewTestPacketRxModel * model) { - model->type = bt->state.type; - model->channel = bt->state.param.channel; - model->datarate = bt->state.param.datarate; - return true; - }); - view_dispatcher_switch_to_view(bt->view_dispatcher, BtViewTestPacketRx); - } else if(message.type == BtMessageTypeStartTestPacketRx) { - // Start test rx - if(bt->state.type == BtStatePacketStart) { - furi_hal_bt_start_packet_rx(message.param.channel, message.param.datarate); - bt->state.type = BtStatePacketRunning; - } else if(bt->state.type == BtStatePacketRunning) { - bt->state.param.rssi = furi_hal_bt_get_rssi(); - } else if(bt->state.type == BtStatePacketSetup) { - bt->state.param.packets_received = furi_hal_bt_stop_packet_test(); - } - with_view_model( - bt->view_test_packet_rx, (BtViewTestPacketRxModel * model) { - model->type = bt->state.type; - model->channel = bt->state.param.channel; - model->datarate = bt->state.param.datarate; - model->packets_received = bt->state.param.packets_received; - model->rssi = bt->state.param.rssi; - return true; - }); - view_dispatcher_switch_to_view(bt->view_dispatcher, BtViewTestPacketRx); - } else if(message.type == BtMessageTypeStopTestPacket) { - // Stop test packet tx - furi_hal_bt_stop_packet_test(); - bt->state.type = BtStateReady; - } else if(message.type == BtMessageTypeStartApp) { - // Start app - view_dispatcher_switch_to_view(bt->view_dispatcher, BtViewStartApp); - if(furi_hal_bt_start_app()) { - bt->state.type = BtStateStartedApp; - } - } else if(message.type == BtMessageTypeUpdateStatusbar) { - // Update statusbar - view_port_enabled_set(bt->statusbar_view_port, furi_hal_bt_is_alive()); - } - } - return 0; -} diff --git a/applications/bt/bt_debug_app/bt_debug_app.c b/applications/bt/bt_debug_app/bt_debug_app.c new file mode 100755 index 000000000..1511e84f1 --- /dev/null +++ b/applications/bt/bt_debug_app/bt_debug_app.c @@ -0,0 +1,94 @@ +#include "bt_debug_app.h" + +enum BtDebugSubmenuIndex { + BtDebugSubmenuIndexCarrierTest, + BtDebugSubmenuIndexPacketTest, +}; + +void bt_debug_submenu_callback(void* context, uint32_t index) { + furi_assert(context); + BtDebugApp* app = context; + if(index == BtDebugSubmenuIndexCarrierTest) { + view_dispatcher_switch_to_view(app->view_dispatcher, BtDebugAppViewCarrierTest); + } else if(index == BtDebugSubmenuIndexPacketTest) { + view_dispatcher_switch_to_view(app->view_dispatcher, BtDebugAppViewPacketTest); + } +} + +uint32_t bt_debug_exit(void* context) { + return VIEW_NONE; +} + +uint32_t bt_debug_start_view(void* context) { + return BtDebugAppViewSubmenu; +} + +BtDebugApp* bt_debug_app_alloc() { + BtDebugApp* app = furi_alloc(sizeof(BtDebugApp)); + // Gui + app->gui = furi_record_open("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->submenu = submenu_alloc(); + submenu_add_item( + app->submenu, + "Carrier test", + BtDebugSubmenuIndexCarrierTest, + bt_debug_submenu_callback, + app); + submenu_add_item( + app->submenu, "Packet test", BtDebugSubmenuIndexPacketTest, bt_debug_submenu_callback, app); + view_set_previous_callback(submenu_get_view(app->submenu), bt_debug_exit); + view_dispatcher_add_view( + app->view_dispatcher, BtDebugAppViewSubmenu, submenu_get_view(app->submenu)); + app->bt_carrier_test = bt_carrier_test_alloc(); + view_set_previous_callback( + bt_carrier_test_get_view(app->bt_carrier_test), bt_debug_start_view); + view_dispatcher_add_view( + app->view_dispatcher, + BtDebugAppViewCarrierTest, + bt_carrier_test_get_view(app->bt_carrier_test)); + app->bt_packet_test = bt_packet_test_alloc(); + view_set_previous_callback(bt_packet_test_get_view(app->bt_packet_test), bt_debug_start_view); + view_dispatcher_add_view( + app->view_dispatcher, + BtDebugAppViewPacketTest, + bt_packet_test_get_view(app->bt_packet_test)); + + // Switch to menu + view_dispatcher_switch_to_view(app->view_dispatcher, BtDebugAppViewSubmenu); + + return app; +} + +void bt_debug_app_free(BtDebugApp* app) { + furi_assert(app); + + // Free views + view_dispatcher_remove_view(app->view_dispatcher, BtDebugAppViewSubmenu); + submenu_free(app->submenu); + view_dispatcher_remove_view(app->view_dispatcher, BtDebugAppViewCarrierTest); + bt_carrier_test_free(app->bt_carrier_test); + view_dispatcher_remove_view(app->view_dispatcher, BtDebugAppViewPacketTest); + bt_packet_test_free(app->bt_packet_test); + view_dispatcher_free(app->view_dispatcher); + + // Close gui record + furi_record_close("gui"); + app->gui = NULL; + + // Free rest + free(app); +} + +int32_t bt_debug_app(void* p) { + BtDebugApp* app = bt_debug_app_alloc(); + view_dispatcher_run(app->view_dispatcher); + bt_debug_app_free(app); + return 0; +} diff --git a/applications/bt/bt_debug_app/bt_debug_app.h b/applications/bt/bt_debug_app/bt_debug_app.h new file mode 100644 index 000000000..ceb0e9346 --- /dev/null +++ b/applications/bt/bt_debug_app/bt_debug_app.h @@ -0,0 +1,26 @@ +#pragma once + +#include +#include +#include +#include + +#include +#include "views/bt_carrier_test.h" +#include "views/bt_packet_test.h" +#include "../bt_settings.h" + +typedef struct { + BtSettings settings; + Gui* gui; + ViewDispatcher* view_dispatcher; + Submenu* submenu; + BtCarrierTest* bt_carrier_test; + BtPacketTest* bt_packet_test; +} BtDebugApp; + +typedef enum { + BtDebugAppViewSubmenu, + BtDebugAppViewCarrierTest, + BtDebugAppViewPacketTest, +} BtDebugAppView; diff --git a/applications/bt/bt_debug_app/views/bt_carrier_test.c b/applications/bt/bt_debug_app/views/bt_carrier_test.c new file mode 100755 index 000000000..2343c861a --- /dev/null +++ b/applications/bt/bt_debug_app/views/bt_carrier_test.c @@ -0,0 +1,188 @@ +#include "bt_carrier_test.h" +#include "bt_test.h" +#include "bt_test_types.h" +#include "furi-hal-bt.h" + +struct BtCarrierTest { + BtTest* bt_test; + BtTestParam* bt_param_channel; + BtTestMode mode; + BtTestChannel channel; + BtTestPower power; + osTimerId_t timer; +}; + +static BtTestParamValue bt_param_mode[] = { + {.value = BtTestModeRx, .str = "Rx"}, + {.value = BtTestModeTx, .str = "Tx"}, + {.value = BtTestModeTxHopping, .str = "Hopping Tx"}, +}; + +static BtTestParamValue bt_param_channel[] = { + {.value = BtTestChannel2402, .str = "2402 MHz"}, + {.value = BtTestChannel2440, .str = "2440 MHz"}, + {.value = BtTestChannel2480, .str = "2480 MHz"}, +}; + +static BtTestParamValue bt_param_power[] = { + {.value = BtPower0dB, .str = "0 dB"}, + {.value = BtPower2dB, .str = "2 dB"}, + {.value = BtPower4dB, .str = "4 dB"}, + {.value = BtPower6dB, .str = "6 dB"}, +}; + +static void bt_carrier_test_start(BtCarrierTest* bt_carrier_test) { + furi_assert(bt_carrier_test); + if(bt_carrier_test->mode == BtTestModeRx) { + furi_hal_bt_start_packet_rx(bt_carrier_test->channel, 1); + osTimerStart(bt_carrier_test->timer, 1024 / 4); + } else if(bt_carrier_test->mode == BtTestModeTxHopping) { + furi_hal_bt_start_tone_tx(bt_carrier_test->channel, bt_carrier_test->power); + osTimerStart(bt_carrier_test->timer, 2048); + } else if(bt_carrier_test->mode == BtTestModeTx) { + furi_hal_bt_start_tone_tx(bt_carrier_test->channel, bt_carrier_test->power); + } +} + +static void bt_carrier_test_switch_channel(BtCarrierTest* bt_carrier_test) { + furi_assert(bt_carrier_test); + furi_hal_bt_stop_tone_tx(); + uint8_t channel_i = 0; + if(bt_carrier_test->channel == BtTestChannel2402) { + bt_carrier_test->channel = BtTestChannel2440; + channel_i = 1; + } else if(bt_carrier_test->channel == BtTestChannel2440) { + bt_carrier_test->channel = BtTestChannel2480; + channel_i = 2; + } else if(bt_carrier_test->channel == BtTestChannel2480) { + bt_carrier_test->channel = BtTestChannel2402; + channel_i = 0; + } + furi_hal_bt_start_tone_tx(bt_carrier_test->channel, bt_carrier_test->power); + bt_test_set_current_value_index(bt_carrier_test->bt_param_channel, channel_i); + bt_test_set_current_value_text( + bt_carrier_test->bt_param_channel, bt_param_channel[channel_i].str); +} + +static void bt_carrier_test_stop(BtCarrierTest* bt_carrier_test) { + furi_assert(bt_carrier_test); + if(bt_carrier_test->mode == BtTestModeTxHopping) { + furi_hal_bt_stop_tone_tx(); + osTimerStop(bt_carrier_test->timer); + } else if(bt_carrier_test->mode == BtTestModeTx) { + furi_hal_bt_stop_tone_tx(); + } else if(bt_carrier_test->mode == BtTestModeRx) { + furi_hal_bt_stop_packet_test(); + osTimerStop(bt_carrier_test->timer); + } +} + +static uint32_t bt_carrier_test_param_changed(BtTestParam* param, BtTestParamValue* param_val) { + furi_assert(param); + uint8_t index = bt_test_get_current_value_index(param); + bt_test_set_current_value_text(param, param_val[index].str); + return param_val[index].value; +} + +static void bt_carrier_test_mode_changed(BtTestParam* param) { + BtCarrierTest* bt_carrier_test = bt_test_get_context(param); + bt_carrier_test_stop(bt_carrier_test); + bt_carrier_test->mode = bt_carrier_test_param_changed(param, bt_param_mode); +} + +static void bt_carrier_test_channel_changed(BtTestParam* param) { + BtCarrierTest* bt_carrier_test = bt_test_get_context(param); + bt_carrier_test_stop(bt_carrier_test); + bt_carrier_test->channel = bt_carrier_test_param_changed(param, bt_param_channel); +} + +static void bt_carrier_test_param_channel(BtTestParam* param) { + BtCarrierTest* bt_carrier_test = bt_test_get_context(param); + bt_carrier_test_stop(bt_carrier_test); + bt_carrier_test->power = bt_carrier_test_param_changed(param, bt_param_power); +} + +static void bt_carrier_test_change_state_callback(BtTestState state, void* context) { + furi_assert(context); + BtCarrierTest* bt_carrier_test = context; + furi_hal_bt_stop_tone_tx(); + if(state == BtTestStateStarted) { + bt_carrier_test_start(bt_carrier_test); + } else if(state == BtTestStateStopped) { + bt_carrier_test_stop(bt_carrier_test); + } +} + +static void bt_carrier_test_exit_callback(void* context) { + furi_assert(context); + BtCarrierTest* bt_carrier_test = context; + bt_carrier_test_stop(bt_carrier_test); +} + +static void bt_test_carrier_timer_callback(void* context) { + furi_assert(context); + BtCarrierTest* bt_carrier_test = context; + if(bt_carrier_test->mode == BtTestModeRx) { + bt_test_set_rssi(bt_carrier_test->bt_test, furi_hal_bt_get_rssi()); + } else if(bt_carrier_test->mode == BtTestModeTxHopping) { + bt_carrier_test_switch_channel(bt_carrier_test); + } +} + +BtCarrierTest* bt_carrier_test_alloc() { + BtCarrierTest* bt_carrier_test = furi_alloc(sizeof(BtCarrierTest)); + bt_carrier_test->bt_test = bt_test_alloc(); + bt_test_set_context(bt_carrier_test->bt_test, bt_carrier_test); + bt_test_set_change_state_callback( + bt_carrier_test->bt_test, bt_carrier_test_change_state_callback); + bt_test_set_back_callback(bt_carrier_test->bt_test, bt_carrier_test_exit_callback); + + BtTestParam* param; + param = bt_test_param_add( + bt_carrier_test->bt_test, + "Mode", + SIZEOF_ARRAY(bt_param_mode), + bt_carrier_test_mode_changed, + bt_carrier_test); + bt_test_set_current_value_index(param, 0); + bt_test_set_current_value_text(param, bt_param_mode[0].str); + bt_carrier_test->mode = BtTestModeRx; + + param = bt_test_param_add( + bt_carrier_test->bt_test, + "Channel", + SIZEOF_ARRAY(bt_param_channel), + bt_carrier_test_channel_changed, + bt_carrier_test); + bt_test_set_current_value_index(param, 0); + bt_test_set_current_value_text(param, bt_param_channel[0].str); + bt_carrier_test->channel = BtTestChannel2402; + bt_carrier_test->bt_param_channel = param; + + param = bt_test_param_add( + bt_carrier_test->bt_test, + "Power", + SIZEOF_ARRAY(bt_param_power), + bt_carrier_test_param_channel, + bt_carrier_test); + bt_test_set_current_value_index(param, 0); + bt_test_set_current_value_text(param, bt_param_power[0].str); + bt_carrier_test->power = BtPower0dB; + + bt_carrier_test->timer = + osTimerNew(bt_test_carrier_timer_callback, osTimerPeriodic, bt_carrier_test, NULL); + + return bt_carrier_test; +} + +void bt_carrier_test_free(BtCarrierTest* bt_carrier_test) { + furi_assert(bt_carrier_test); + bt_test_free(bt_carrier_test->bt_test); + osTimerDelete(bt_carrier_test->timer); + free(bt_carrier_test); +} + +View* bt_carrier_test_get_view(BtCarrierTest* bt_carrier_test) { + furi_assert(bt_carrier_test); + return bt_test_get_view(bt_carrier_test->bt_test); +} diff --git a/applications/bt/bt_debug_app/views/bt_carrier_test.h b/applications/bt/bt_debug_app/views/bt_carrier_test.h new file mode 100644 index 000000000..51a400890 --- /dev/null +++ b/applications/bt/bt_debug_app/views/bt_carrier_test.h @@ -0,0 +1,10 @@ +#pragma once +#include + +typedef struct BtCarrierTest BtCarrierTest; + +BtCarrierTest* bt_carrier_test_alloc(); + +void bt_carrier_test_free(BtCarrierTest* bt_carrier_test); + +View* bt_carrier_test_get_view(BtCarrierTest* bt_carrier_test); diff --git a/applications/bt/bt_debug_app/views/bt_packet_test.c b/applications/bt/bt_debug_app/views/bt_packet_test.c new file mode 100644 index 000000000..192b88d10 --- /dev/null +++ b/applications/bt/bt_debug_app/views/bt_packet_test.c @@ -0,0 +1,155 @@ +#include "bt_packet_test.h" +#include "bt_test.h" +#include "bt_test_types.h" +#include "furi-hal-bt.h" + +struct BtPacketTest { + BtTest* bt_test; + BtTestMode mode; + BtTestChannel channel; + BtTestDataRate data_rate; + osTimerId_t timer; +}; + +static BtTestParamValue bt_param_mode[] = { + {.value = BtTestModeRx, .str = "Rx"}, + {.value = BtTestModeTx, .str = "Tx"}, +}; + +static BtTestParamValue bt_param_channel[] = { + {.value = BtTestChannel2402, .str = "2402 MHz"}, + {.value = BtTestChannel2440, .str = "2440 MHz"}, + {.value = BtTestChannel2480, .str = "2480 MHz"}, +}; + +static BtTestParamValue bt_param_data_rate[] = { + {.value = BtDataRate1M, .str = "1 Mbps"}, + {.value = BtDataRate2M, .str = "2 Mbps"}, +}; + +static void bt_packet_test_start(BtPacketTest* bt_packet_test) { + furi_assert(bt_packet_test); + if(bt_packet_test->mode == BtTestModeRx) { + furi_hal_bt_start_packet_rx(bt_packet_test->channel, bt_packet_test->data_rate); + osTimerStart(bt_packet_test->timer, 1024 / 4); + } else if(bt_packet_test->mode == BtTestModeTx) { + furi_hal_bt_start_packet_tx(bt_packet_test->channel, 1, bt_packet_test->data_rate); + } +} + +static void bt_packet_test_stop(BtPacketTest* bt_packet_test) { + furi_assert(bt_packet_test); + if(bt_packet_test->mode == BtTestModeTx) { + furi_hal_bt_stop_packet_test(); + bt_test_set_packets_tx(bt_packet_test->bt_test, furi_hal_bt_get_transmitted_packets()); + } else if(bt_packet_test->mode == BtTestModeRx) { + bt_test_set_packets_rx(bt_packet_test->bt_test, furi_hal_bt_stop_packet_test()); + osTimerStop(bt_packet_test->timer); + } +} + +static uint32_t bt_packet_test_param_changed(BtTestParam* param, BtTestParamValue* param_val) { + furi_assert(param); + uint8_t index = bt_test_get_current_value_index(param); + bt_test_set_current_value_text(param, param_val[index].str); + return param_val[index].value; +} + +static void bt_packet_test_mode_changed(BtTestParam* param) { + BtPacketTest* bt_packet_test = bt_test_get_context(param); + bt_packet_test_stop(bt_packet_test); + bt_packet_test->mode = bt_packet_test_param_changed(param, bt_param_mode); +} + +static void bt_packet_test_channel_changed(BtTestParam* param) { + BtPacketTest* bt_packet_test = bt_test_get_context(param); + bt_packet_test_stop(bt_packet_test); + bt_packet_test->channel = bt_packet_test_param_changed(param, bt_param_channel); +} + +static void bt_packet_test_param_channel(BtTestParam* param) { + BtPacketTest* bt_packet_test = bt_test_get_context(param); + bt_packet_test_stop(bt_packet_test); + bt_packet_test->data_rate = bt_packet_test_param_changed(param, bt_param_data_rate); +} + +static void bt_packet_test_change_state_callback(BtTestState state, void* context) { + furi_assert(context); + BtPacketTest* bt_packet_test = context; + if(state == BtTestStateStarted) { + bt_packet_test_start(bt_packet_test); + } else if(state == BtTestStateStopped) { + bt_packet_test_stop(bt_packet_test); + } +} + +static void bt_packet_test_exit_callback(void* context) { + furi_assert(context); + BtPacketTest* bt_packet_test = context; + bt_packet_test_stop(bt_packet_test); +} + +static void bt_test_packet_timer_callback(void* context) { + furi_assert(context); + BtPacketTest* bt_packet_test = context; + if(bt_packet_test->mode == BtTestModeRx) { + bt_test_set_rssi(bt_packet_test->bt_test, furi_hal_bt_get_rssi()); + } +} + +BtPacketTest* bt_packet_test_alloc() { + BtPacketTest* bt_packet_test = furi_alloc(sizeof(BtPacketTest)); + bt_packet_test->bt_test = bt_test_alloc(); + bt_test_set_context(bt_packet_test->bt_test, bt_packet_test); + bt_test_set_change_state_callback( + bt_packet_test->bt_test, bt_packet_test_change_state_callback); + bt_test_set_back_callback(bt_packet_test->bt_test, bt_packet_test_exit_callback); + + BtTestParam* param; + param = bt_test_param_add( + bt_packet_test->bt_test, + "Mode", + SIZEOF_ARRAY(bt_param_mode), + bt_packet_test_mode_changed, + bt_packet_test); + bt_test_set_current_value_index(param, 0); + bt_test_set_current_value_text(param, bt_param_mode[0].str); + bt_packet_test->mode = BtTestModeRx; + + param = bt_test_param_add( + bt_packet_test->bt_test, + "Channel", + SIZEOF_ARRAY(bt_param_channel), + bt_packet_test_channel_changed, + bt_packet_test); + bt_test_set_current_value_index(param, 0); + bt_test_set_current_value_text(param, bt_param_channel[0].str); + bt_packet_test->channel = BtTestChannel2402; + + param = bt_test_param_add( + bt_packet_test->bt_test, + "Data rate", + SIZEOF_ARRAY(bt_param_data_rate), + bt_packet_test_param_channel, + bt_packet_test); + bt_test_set_current_value_index(param, 0); + bt_test_set_current_value_text(param, bt_param_data_rate[0].str); + bt_packet_test->data_rate = BtDataRate1M; + + bt_packet_test->timer = + osTimerNew(bt_test_packet_timer_callback, osTimerPeriodic, bt_packet_test, NULL); + + return bt_packet_test; +} + +void bt_packet_test_free(BtPacketTest* bt_packet_test) { + furi_assert(bt_packet_test); + bt_test_free(bt_packet_test->bt_test); + osTimerDelete(bt_packet_test->timer); + free(bt_packet_test); +} + +View* bt_packet_test_get_view(BtPacketTest* bt_packet_test) { + furi_assert(bt_packet_test); + return bt_test_get_view(bt_packet_test->bt_test); +} diff --git a/applications/bt/bt_debug_app/views/bt_packet_test.h b/applications/bt/bt_debug_app/views/bt_packet_test.h new file mode 100644 index 000000000..8ea449b21 --- /dev/null +++ b/applications/bt/bt_debug_app/views/bt_packet_test.h @@ -0,0 +1,10 @@ +#pragma once +#include + +typedef struct BtPacketTest BtPacketTest; + +BtPacketTest* bt_packet_test_alloc(); + +void bt_packet_test_free(BtPacketTest* bt_packet_test); + +View* bt_packet_test_get_view(BtPacketTest* bt_packet_test); diff --git a/applications/bt/bt_debug_app/views/bt_test.c b/applications/bt/bt_debug_app/views/bt_test.c new file mode 100755 index 000000000..747ce6a40 --- /dev/null +++ b/applications/bt/bt_debug_app/views/bt_test.c @@ -0,0 +1,422 @@ +#include "bt_test.h" + +#include +#include +#include +#include +#include +#include + +struct BtTestParam { + const char* label; + uint8_t current_value_index; + string_t current_value_text; + uint8_t values_count; + BtTestParamChangeCallback change_callback; + void* context; +}; + +ARRAY_DEF(BtTestParamArray, BtTestParam, M_POD_OPLIST); + +struct BtTest { + View* view; + BtTestChangeStateCallback change_state_callback; + BtTestBackCallback back_callback; + void* context; +}; + +typedef struct { + BtTestState state; + BtTestParamArray_t params; + uint8_t position; + uint8_t window_position; + const char* message; + float rssi; + uint32_t packets_num_rx; + uint32_t packets_num_tx; +} BtTestModel; + +#define BT_TEST_START_MESSAGE "Ok - Start" +#define BT_TEST_STOP_MESSAGE "Ok - Stop" + +static void bt_test_process_up(BtTest* bt_test); +static void bt_test_process_down(BtTest* bt_test); +static void bt_test_process_left(BtTest* bt_test); +static void bt_test_process_right(BtTest* bt_test); +static void bt_test_process_ok(BtTest* bt_test); +static void bt_test_process_back(BtTest* bt_test); + +static void bt_test_draw_callback(Canvas* canvas, void* _model) { + BtTestModel* model = _model; + char info_str[32]; + + const uint8_t param_height = 16; + const uint8_t param_width = 123; + + canvas_clear(canvas); + + uint8_t position = 0; + BtTestParamArray_it_t it; + + canvas_set_font(canvas, FontSecondary); + for(BtTestParamArray_it(it, model->params); !BtTestParamArray_end_p(it); + BtTestParamArray_next(it)) { + uint8_t param_position = position - model->window_position; + uint8_t params_on_screen = 3; + uint8_t y_offset = 0; + + if(param_position < params_on_screen) { + const BtTestParam* param = BtTestParamArray_cref(it); + uint8_t param_y = y_offset + (param_position * param_height); + uint8_t param_text_y = param_y + param_height - 4; + + if(position == model->position) { + canvas_set_color(canvas, ColorBlack); + elements_slightly_rounded_box( + canvas, 0, param_y + 1, param_width, param_height - 2); + canvas_set_color(canvas, ColorWhite); + } else { + canvas_set_color(canvas, ColorBlack); + } + + canvas_draw_str(canvas, 6, param_text_y, param->label); + + if(param->current_value_index > 0) { + canvas_draw_str(canvas, 50, param_text_y, "<"); + } + + canvas_draw_str(canvas, 61, param_text_y, string_get_cstr(param->current_value_text)); + + if(param->current_value_index < (param->values_count - 1)) { + canvas_draw_str(canvas, 113, param_text_y, ">"); + } + } + + position++; + } + + elements_scrollbar(canvas, model->position, BtTestParamArray_size(model->params)); + canvas_draw_str(canvas, 6, 60, model->message); + if(model->state == BtTestStateStarted) { + if(model->rssi != 0.0f) { + snprintf(info_str, sizeof(info_str), "RSSI:%3.1f dB", model->rssi); + canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str); + } + } else if(model->state == BtTestStateStopped) { + if(model->packets_num_rx) { + snprintf(info_str, sizeof(info_str), "%ld pack rcv", model->packets_num_rx); + canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str); + } else if(model->packets_num_tx) { + snprintf(info_str, sizeof(info_str), "%ld pack sent", model->packets_num_tx); + canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str); + } + } +} + +static bool bt_test_input_callback(InputEvent* event, void* context) { + BtTest* bt_test = context; + furi_assert(bt_test); + bool consumed = false; + + if(event->type == InputTypeShort) { + switch(event->key) { + case InputKeyUp: + consumed = true; + bt_test_process_up(bt_test); + break; + case InputKeyDown: + consumed = true; + bt_test_process_down(bt_test); + break; + case InputKeyLeft: + consumed = true; + bt_test_process_left(bt_test); + break; + case InputKeyRight: + consumed = true; + bt_test_process_right(bt_test); + break; + case InputKeyOk: + consumed = true; + bt_test_process_ok(bt_test); + break; + case InputKeyBack: + consumed = false; + bt_test_process_back(bt_test); + break; + default: + break; + } + } + + return consumed; +} + +void bt_test_process_up(BtTest* bt_test) { + with_view_model( + bt_test->view, (BtTestModel * model) { + uint8_t params_on_screen = 3; + if(model->position > 0) { + model->position--; + if(((model->position - model->window_position) < 1) && + model->window_position > 0) { + model->window_position--; + } + } else { + model->position = BtTestParamArray_size(model->params) - 1; + if(model->position > (params_on_screen - 1)) { + model->window_position = model->position - (params_on_screen - 1); + } + } + return true; + }); +} + +void bt_test_process_down(BtTest* bt_test) { + with_view_model( + bt_test->view, (BtTestModel * model) { + uint8_t params_on_screen = 3; + if(model->position < (BtTestParamArray_size(model->params) - 1)) { + model->position++; + if((model->position - model->window_position) > (params_on_screen - 2) && + model->window_position < + (BtTestParamArray_size(model->params) - params_on_screen)) { + model->window_position++; + } + } else { + model->position = 0; + model->window_position = 0; + } + return true; + }); +} + +BtTestParam* bt_test_get_selected_param(BtTestModel* model) { + BtTestParam* param = NULL; + + BtTestParamArray_it_t it; + uint8_t position = 0; + for(BtTestParamArray_it(it, model->params); !BtTestParamArray_end_p(it); + BtTestParamArray_next(it)) { + if(position == model->position) { + break; + } + position++; + } + + param = BtTestParamArray_ref(it); + + furi_assert(param); + return param; +} + +void bt_test_process_left(BtTest* bt_test) { + BtTestParam* param; + with_view_model( + bt_test->view, (BtTestModel * model) { + param = bt_test_get_selected_param(model); + if(param->current_value_index > 0) { + param->current_value_index--; + if(param->change_callback) { + model->state = BtTestStateStopped; + model->message = BT_TEST_START_MESSAGE; + model->rssi = 0.0f; + model->packets_num_rx = 0; + model->packets_num_tx = 0; + } + } + return true; + }); + if(param->change_callback) { + param->change_callback(param); + } +} + +void bt_test_process_right(BtTest* bt_test) { + BtTestParam* param; + with_view_model( + bt_test->view, (BtTestModel * model) { + param = bt_test_get_selected_param(model); + if(param->current_value_index < (param->values_count - 1)) { + param->current_value_index++; + if(param->change_callback) { + model->state = BtTestStateStopped; + model->message = BT_TEST_START_MESSAGE; + model->rssi = 0.0f; + model->packets_num_rx = 0; + model->packets_num_tx = 0; + } + } + return true; + }); + if(param->change_callback) { + param->change_callback(param); + } +} + +void bt_test_process_ok(BtTest* bt_test) { + BtTestState state; + with_view_model( + bt_test->view, (BtTestModel * model) { + if(model->state == BtTestStateStarted) { + model->state = BtTestStateStopped; + model->message = BT_TEST_START_MESSAGE; + model->rssi = 0.0f; + model->packets_num_rx = 0; + model->packets_num_tx = 0; + } else if(model->state == BtTestStateStopped) { + model->state = BtTestStateStarted; + model->message = BT_TEST_STOP_MESSAGE; + } + state = model->state; + return true; + }); + if(bt_test->change_state_callback) { + bt_test->change_state_callback(state, bt_test->context); + } +} + +void bt_test_process_back(BtTest* bt_test) { + with_view_model( + bt_test->view, (BtTestModel * model) { + model->state = BtTestStateStopped; + model->rssi = 0.0f; + model->packets_num_rx = 0; + model->packets_num_tx = 0; + return false; + }); + if(bt_test->back_callback) { + bt_test->back_callback(bt_test->context); + } +} + +BtTest* bt_test_alloc() { + BtTest* bt_test = furi_alloc(sizeof(BtTest)); + bt_test->view = view_alloc(); + view_set_context(bt_test->view, bt_test); + view_allocate_model(bt_test->view, ViewModelTypeLocking, sizeof(BtTestModel)); + view_set_draw_callback(bt_test->view, bt_test_draw_callback); + view_set_input_callback(bt_test->view, bt_test_input_callback); + + with_view_model( + bt_test->view, (BtTestModel * model) { + model->state = BtTestStateStopped; + model->message = "Ok - Start"; + BtTestParamArray_init(model->params); + model->position = 0; + model->window_position = 0; + model->rssi = 0.0f; + model->packets_num_tx = 0; + model->packets_num_rx = 0; + return true; + }); + + return bt_test; +} + +void bt_test_free(BtTest* bt_test) { + furi_assert(bt_test); + + with_view_model( + bt_test->view, (BtTestModel * model) { + BtTestParamArray_it_t it; + for(BtTestParamArray_it(it, model->params); !BtTestParamArray_end_p(it); + BtTestParamArray_next(it)) { + string_clear(BtTestParamArray_ref(it)->current_value_text); + } + BtTestParamArray_clear(model->params); + return false; + }); + view_free(bt_test->view); + free(bt_test); +} + +View* bt_test_get_view(BtTest* bt_test) { + furi_assert(bt_test); + return bt_test->view; +} + +BtTestParam* bt_test_param_add( + BtTest* bt_test, + const char* label, + uint8_t values_count, + BtTestParamChangeCallback change_callback, + void* context) { + BtTestParam* param = NULL; + furi_assert(label); + furi_assert(bt_test); + + with_view_model( + bt_test->view, (BtTestModel * model) { + param = BtTestParamArray_push_new(model->params); + param->label = label; + param->values_count = values_count; + param->change_callback = change_callback; + param->context = context; + param->current_value_index = 0; + string_init(param->current_value_text); + return true; + }); + + return param; +} + +void bt_test_set_rssi(BtTest* bt_test, float rssi) { + furi_assert(bt_test); + with_view_model( + bt_test->view, (BtTestModel * model) { + model->rssi = rssi; + return true; + }); +} + +void bt_test_set_packets_tx(BtTest* bt_test, uint32_t packets_num) { + furi_assert(bt_test); + with_view_model( + bt_test->view, (BtTestModel * model) { + model->packets_num_tx = packets_num; + return true; + }); +} + +void bt_test_set_packets_rx(BtTest* bt_test, uint32_t packets_num) { + furi_assert(bt_test); + with_view_model( + bt_test->view, (BtTestModel * model) { + model->packets_num_rx = packets_num; + return true; + }); +} + +void bt_test_set_change_state_callback(BtTest* bt_test, BtTestChangeStateCallback callback) { + furi_assert(bt_test); + furi_assert(callback); + bt_test->change_state_callback = callback; +} + +void bt_test_set_back_callback(BtTest* bt_test, BtTestBackCallback callback) { + furi_assert(bt_test); + furi_assert(callback); + bt_test->back_callback = callback; +} + +void bt_test_set_context(BtTest* bt_test, void* context) { + furi_assert(bt_test); + bt_test->context = context; +} + +void bt_test_set_current_value_index(BtTestParam* param, uint8_t current_value_index) { + param->current_value_index = current_value_index; +} + +void bt_test_set_current_value_text(BtTestParam* param, const char* current_value_text) { + string_set_str(param->current_value_text, current_value_text); +} + +uint8_t bt_test_get_current_value_index(BtTestParam* param) { + return param->current_value_index; +} + +void* bt_test_get_context(BtTestParam* param) { + return param->context; +} diff --git a/applications/bt/bt_debug_app/views/bt_test.h b/applications/bt/bt_debug_app/views/bt_test.h new file mode 100755 index 000000000..2d738cbd0 --- /dev/null +++ b/applications/bt/bt_debug_app/views/bt_test.h @@ -0,0 +1,46 @@ +#pragma once +#include + +typedef enum { + BtTestStateStarted, + BtTestStateStopped, +} BtTestState; + +typedef struct BtTest BtTest; +typedef void (*BtTestChangeStateCallback)(BtTestState state, void* context); +typedef void (*BtTestBackCallback)(void* context); +typedef struct BtTestParam BtTestParam; +typedef void (*BtTestParamChangeCallback)(BtTestParam* param); + +BtTest* bt_test_alloc(); + +void bt_test_free(BtTest* bt_test); + +View* bt_test_get_view(BtTest* bt_test); + +BtTestParam* bt_test_param_add( + BtTest* bt_test, + const char* label, + uint8_t values_count, + BtTestParamChangeCallback change_callback, + void* context); + +void bt_test_set_change_state_callback(BtTest* bt_test, BtTestChangeStateCallback callback); + +void bt_test_set_back_callback(BtTest* bt_test, BtTestBackCallback callback); + +void bt_test_set_context(BtTest* bt_test, void* context); + +void bt_test_set_rssi(BtTest* bt_test, float rssi); + +void bt_test_set_packets_tx(BtTest* bt_test, uint32_t packets_num); + +void bt_test_set_packets_rx(BtTest* bt_test, uint32_t packets_num); + +void bt_test_set_current_value_index(BtTestParam* param, uint8_t current_value_index); + +void bt_test_set_current_value_text(BtTestParam* param, const char* current_value_text); + +uint8_t bt_test_get_current_value_index(BtTestParam* param); + +void* bt_test_get_context(BtTestParam* param); diff --git a/applications/bt/bt_debug_app/views/bt_test_types.h b/applications/bt/bt_debug_app/views/bt_test_types.h new file mode 100644 index 000000000..433bb5784 --- /dev/null +++ b/applications/bt/bt_debug_app/views/bt_test_types.h @@ -0,0 +1,30 @@ +#pragma once + +typedef enum { + BtTestModeRx, + BtTestModeTx, + BtTestModeTxHopping, +} BtTestMode; + +typedef enum { + BtTestChannel2402 = 0, + BtTestChannel2440 = 19, + BtTestChannel2480 = 39, +} BtTestChannel; + +typedef enum { + BtPower0dB = 0x19, + BtPower2dB = 0x1B, + BtPower4dB = 0x1D, + BtPower6dB = 0x1F, +} BtTestPower; + +typedef enum { + BtDataRate1M = 1, + BtDataRate2M = 2, +} BtTestDataRate; + +typedef struct { + uint32_t value; + const char* str; +} BtTestParamValue; diff --git a/applications/bt/bt_i.h b/applications/bt/bt_i.h deleted file mode 100644 index 6a5fe3830..000000000 --- a/applications/bt/bt_i.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include "bt.h" -#include "bt_views.h" -#include "bt_types.h" - -#include -#include - -#include - -#include -#include -#include -#include - -#include -#include - -struct Bt { - osMessageQueueId_t message_queue; - BtState state; - osTimerId_t update_status_timer; - osTimerId_t update_param_timer; - Gui* gui; - ValueMutex* menu; - // Status bar - ViewPort* statusbar_view_port; - // Menu - IconAnimation* menu_icon; - MenuItem* menu_item; - View* view_test_carrier; - View* view_test_packet_tx; - View* view_test_packet_rx; - View* view_start_app; - ViewDispatcher* view_dispatcher; -}; - -Bt* bt_alloc(); - -void bt_draw_statusbar_callback(Canvas* canvas, void* context); - -BtTestChannel bt_switch_channel(InputKey key, BtTestChannel inst_chan); - -void bt_draw_statusbar_callback(Canvas* canvas, void* context); - -void bt_menu_test_carrier(void* context); - -void bt_menu_test_packet_tx(void* context); - -void bt_menu_test_packet_rx(void* context); - -void bt_menu_start_app(void* context); diff --git a/applications/bt/bt_service/bt.c b/applications/bt/bt_service/bt.c new file mode 100644 index 000000000..76d4ae10c --- /dev/null +++ b/applications/bt/bt_service/bt.c @@ -0,0 +1,74 @@ +#include "bt_i.h" + +#define BT_SERVICE_TAG "BT" + +// static void bt_update_statusbar(void* arg) { +// furi_assert(arg); +// Bt* bt = arg; +// BtMessage m = {.type = BtMessageTypeUpdateStatusbar}; +// furi_check(osMessageQueuePut(bt->message_queue, &m, 0, osWaitForever) == osOK); +// } + +static void bt_draw_statusbar_callback(Canvas* canvas, void* context) { + canvas_draw_icon(canvas, 0, 0, &I_Bluetooth_5x8); +} + +static ViewPort* bt_statusbar_view_port_alloc() { + ViewPort* statusbar_view_port = view_port_alloc(); + view_port_set_width(statusbar_view_port, 5); + view_port_draw_callback_set(statusbar_view_port, bt_draw_statusbar_callback, NULL); + view_port_enabled_set(statusbar_view_port, false); + return statusbar_view_port; +} + +Bt* bt_alloc() { + Bt* bt = furi_alloc(sizeof(Bt)); + // Load settings + if(!bt_settings_load(&bt->bt_settings)) { + bt_settings_save(&bt->bt_settings); + } + // Alloc queue + bt->message_queue = osMessageQueueNew(8, sizeof(BtMessage), NULL); + + // doesn't make sense if we waiting for transition on service start + // bt->update_status_timer = osTimerNew(bt_update_statusbar, osTimerPeriodic, bt, NULL); + // osTimerStart(bt->update_status_timer, 4000); + + // Setup statusbar view port + bt->statusbar_view_port = bt_statusbar_view_port_alloc(); + // Gui + bt->gui = furi_record_open("gui"); + gui_add_view_port(bt->gui, bt->statusbar_view_port, GuiLayerStatusBarLeft); + + return bt; +} + +int32_t bt_srv() { + Bt* bt = bt_alloc(); + furi_record_create("bt", bt); + furi_hal_bt_init(); + + if(bt->bt_settings.enabled) { + if(!furi_hal_bt_wait_startup()) { + FURI_LOG_E(BT_SERVICE_TAG, "Core2 startup failed"); + } else { + view_port_enabled_set(bt->statusbar_view_port, true); + bool bt_app_started = furi_hal_bt_start_app(); + if(!bt_app_started) { + FURI_LOG_E(BT_SERVICE_TAG, "BT App start failed"); + } else { + FURI_LOG_I(BT_SERVICE_TAG, "BT App started"); + } + } + } + + BtMessage message; + while(1) { + furi_check(osMessageQueueGet(bt->message_queue, &message, NULL, osWaitForever) == osOK); + if(message.type == BtMessageTypeUpdateStatusbar) { + // Update statusbar + view_port_enabled_set(bt->statusbar_view_port, furi_hal_bt_is_alive()); + } + } + return 0; +} diff --git a/applications/bt/bt.h b/applications/bt/bt_service/bt.h similarity index 100% rename from applications/bt/bt.h rename to applications/bt/bt_service/bt.h diff --git a/applications/bt/bt_service/bt_i.h b/applications/bt/bt_service/bt_i.h new file mode 100644 index 000000000..b498e048c --- /dev/null +++ b/applications/bt/bt_service/bt_i.h @@ -0,0 +1,29 @@ +#pragma once + +#include "bt.h" + +#include +#include + +#include +#include +#include + +#include "../bt_settings.h" + +typedef enum { + BtMessageTypeUpdateStatusbar, +} BtMessageType; + +typedef struct { + BtMessageType type; + void* param; +} BtMessage; + +struct Bt { + BtSettings bt_settings; + osMessageQueueId_t message_queue; + osTimerId_t update_status_timer; + Gui* gui; + ViewPort* statusbar_view_port; +}; diff --git a/applications/bt/bt_settings.c b/applications/bt/bt_settings.c new file mode 100644 index 000000000..bd6399a96 --- /dev/null +++ b/applications/bt/bt_settings.c @@ -0,0 +1,50 @@ +#include "bt_settings.h" +#include +#include + +#define BT_SETTINGS_TAG "bt settings" +#define BT_SETTINGS_PATH "/int/bt.settings" + +bool bt_settings_load(BtSettings* bt_settings) { + furi_assert(bt_settings); + bool file_loaded = false; + BtSettings settings = {}; + + FURI_LOG_I(BT_SETTINGS_TAG, "Loading settings from \"%s\"", BT_SETTINGS_PATH); + FileWorker* file_worker = file_worker_alloc(true); + if(file_worker_open(file_worker, BT_SETTINGS_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) { + if(file_worker_read(file_worker, &settings, sizeof(settings))) { + file_loaded = true; + } + } + file_worker_free(file_worker); + + if(file_loaded) { + FURI_LOG_I(BT_SETTINGS_TAG, "Settings load success"); + if(settings.version != BT_SETTINGS_VERSION) { + FURI_LOG_E(BT_SETTINGS_TAG, "Settings version mismatch"); + } else { + osKernelLock(); + *bt_settings = settings; + osKernelUnlock(); + } + } else { + FURI_LOG_E(BT_SETTINGS_TAG, "Settings load failed"); + } + return file_loaded; +} + +bool bt_settings_save(BtSettings* bt_settings) { + furi_assert(bt_settings); + bool result = false; + + FileWorker* file_worker = file_worker_alloc(true); + if(file_worker_open(file_worker, BT_SETTINGS_PATH, FSAM_WRITE, FSOM_OPEN_ALWAYS)) { + if(file_worker_write(file_worker, bt_settings, sizeof(BtSettings))) { + FURI_LOG_I(BT_SETTINGS_TAG, "Settings saved to \"%s\"", BT_SETTINGS_PATH); + result = true; + } + } + file_worker_free(file_worker); + return result; +} diff --git a/applications/bt/bt_settings.h b/applications/bt/bt_settings.h new file mode 100644 index 000000000..d0a539ea3 --- /dev/null +++ b/applications/bt/bt_settings.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +#define BT_SETTINGS_VERSION (0) + +typedef struct { + uint8_t version; + bool enabled; +} BtSettings; + +bool bt_settings_load(BtSettings* bt_settings); + +bool bt_settings_save(BtSettings* bt_settings); diff --git a/applications/bt/bt_settings_app/bt_settings_app.c b/applications/bt/bt_settings_app/bt_settings_app.c new file mode 100755 index 000000000..6eaf37610 --- /dev/null +++ b/applications/bt/bt_settings_app/bt_settings_app.c @@ -0,0 +1,67 @@ +#include "bt_settings_app.h" + +static bool bt_settings_custom_event_callback(void* context, uint32_t event) { + furi_assert(context); + BtSettingsApp* app = context; + return scene_manager_handle_custom_event(app->scene_manager, event); +} + +static bool bt_settings_back_event_callback(void* context) { + furi_assert(context); + BtSettingsApp* app = context; + return scene_manager_handle_back_event(app->scene_manager); +} + +BtSettingsApp* bt_settings_app_alloc() { + BtSettingsApp* app = furi_alloc(sizeof(BtSettingsApp)); + + // Load settings + bt_settings_load(&app->settings); + app->gui = furi_record_open("gui"); + + app->view_dispatcher = view_dispatcher_alloc(); + app->scene_manager = scene_manager_alloc(&bt_settings_scene_handlers, app); + view_dispatcher_enable_queue(app->view_dispatcher); + view_dispatcher_set_event_callback_context(app->view_dispatcher, app); + + view_dispatcher_set_custom_event_callback( + app->view_dispatcher, bt_settings_custom_event_callback); + view_dispatcher_set_navigation_event_callback( + app->view_dispatcher, bt_settings_back_event_callback); + + view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen); + + app->submenu = submenu_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, BtSettingsAppViewSubmenu, submenu_get_view(app->submenu)); + app->dialog_ex = dialog_ex_alloc(); + view_dispatcher_add_view( + app->view_dispatcher, BtSettingsAppViewDialogEx, dialog_ex_get_view(app->dialog_ex)); + + scene_manager_next_scene(app->scene_manager, BtSettingsAppSceneStart); + return app; +} + +void bt_settings_app_free(BtSettingsApp* app) { + furi_assert(app); + // Submenu + view_dispatcher_remove_view(app->view_dispatcher, BtSettingsAppViewSubmenu); + submenu_free(app->submenu); + // Dialog + view_dispatcher_remove_view(app->view_dispatcher, BtSettingsAppViewDialogEx); + dialog_ex_free(app->dialog_ex); + // View dispatcher + view_dispatcher_free(app->view_dispatcher); + scene_manager_free(app->scene_manager); + // Records + furi_record_close("gui"); + free(app); +} + +extern int32_t bt_settings_app(void* p) { + BtSettingsApp* app = bt_settings_app_alloc(); + view_dispatcher_run(app->view_dispatcher); + bt_settings_save(&app->settings); + bt_settings_app_free(app); + return 0; +} diff --git a/applications/bt/bt_settings_app/bt_settings_app.h b/applications/bt/bt_settings_app/bt_settings_app.h new file mode 100644 index 000000000..cfbea1d0a --- /dev/null +++ b/applications/bt/bt_settings_app/bt_settings_app.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include +#include + +#include "../bt_settings.h" +#include "scenes/bt_settings_scene.h" + +typedef struct { + BtSettings settings; + Gui* gui; + SceneManager* scene_manager; + ViewDispatcher* view_dispatcher; + Submenu* submenu; + DialogEx* dialog_ex; +} BtSettingsApp; + +typedef enum { + BtSettingsAppViewSubmenu, + BtSettingsAppViewDialogEx, +} BtSettingsAppView; diff --git a/applications/bt/bt_settings_app/scenes/bt_settings_scene.c b/applications/bt/bt_settings_app/scenes/bt_settings_scene.c new file mode 100644 index 000000000..cc1b10724 --- /dev/null +++ b/applications/bt/bt_settings_app/scenes/bt_settings_scene.c @@ -0,0 +1,30 @@ +#include "bt_settings_scene.h" + +// Generate scene on_enter handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter, +void (*const bt_settings_on_enter_handlers[])(void*) = { +#include "bt_settings_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_event handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event, +bool (*const bt_settings_on_event_handlers[])(void* context, SceneManagerEvent event) = { +#include "bt_settings_scene_config.h" +}; +#undef ADD_SCENE + +// Generate scene on_exit handlers array +#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit, +void (*const bt_settings_on_exit_handlers[])(void* context) = { +#include "bt_settings_scene_config.h" +}; +#undef ADD_SCENE + +// Initialize scene handlers configuration structure +const SceneManagerHandlers bt_settings_scene_handlers = { + .on_enter_handlers = bt_settings_on_enter_handlers, + .on_event_handlers = bt_settings_on_event_handlers, + .on_exit_handlers = bt_settings_on_exit_handlers, + .scene_num = BtSettingsAppSceneNum, +}; diff --git a/applications/bt/bt_settings_app/scenes/bt_settings_scene.h b/applications/bt/bt_settings_app/scenes/bt_settings_scene.h new file mode 100644 index 000000000..efe1c2999 --- /dev/null +++ b/applications/bt/bt_settings_app/scenes/bt_settings_scene.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +// Generate scene id and total number +#define ADD_SCENE(prefix, name, id) BtSettingsAppScene##id, +typedef enum { +#include "bt_settings_scene_config.h" + BtSettingsAppSceneNum, +} BtSettingsAppScene; +#undef ADD_SCENE + +extern const SceneManagerHandlers bt_settings_scene_handlers; + +// Generate scene on_enter handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*); +#include "bt_settings_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_event handlers declaration +#define ADD_SCENE(prefix, name, id) \ + bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event); +#include "bt_settings_scene_config.h" +#undef ADD_SCENE + +// Generate scene on_exit handlers declaration +#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context); +#include "bt_settings_scene_config.h" +#undef ADD_SCENE diff --git a/applications/bt/bt_settings_app/scenes/bt_settings_scene_config.h b/applications/bt/bt_settings_app/scenes/bt_settings_scene_config.h new file mode 100644 index 000000000..e7d19b1a7 --- /dev/null +++ b/applications/bt/bt_settings_app/scenes/bt_settings_scene_config.h @@ -0,0 +1,2 @@ +ADD_SCENE(bt_settings, start, Start) +ADD_SCENE(bt_settings, disable_dialog, DisableDialog) diff --git a/applications/bt/bt_settings_app/scenes/bt_settings_scene_disable_dialog.c b/applications/bt/bt_settings_app/scenes/bt_settings_scene_disable_dialog.c new file mode 100755 index 000000000..ac2d5f44e --- /dev/null +++ b/applications/bt/bt_settings_app/scenes/bt_settings_scene_disable_dialog.c @@ -0,0 +1,44 @@ +#include "../bt_settings_app.h" +#include +#include + +static void bt_setting_disable_dialog_callback(DialogExResult result, void* context) { + BtSettingsApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, result); +} + +void bt_settings_scene_disable_dialog_on_enter(void* context) { + BtSettingsApp* app = context; + DialogEx* dialog_ex = app->dialog_ex; + dialog_ex_set_text( + dialog_ex, "Reboot device\nto disable Bluetooth", 64, 32, AlignCenter, AlignCenter); + dialog_ex_set_left_button_text(dialog_ex, "Back"); + dialog_ex_set_right_button_text(dialog_ex, "Reboot"); + dialog_ex_set_result_callback(dialog_ex, bt_setting_disable_dialog_callback); + dialog_ex_set_context(dialog_ex, app); + + view_dispatcher_switch_to_view(app->view_dispatcher, BtSettingsAppViewDialogEx); +} + +bool bt_settings_scene_disable_dialog_on_event(void* context, SceneManagerEvent event) { + BtSettingsApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == DialogExResultLeft) { + scene_manager_previous_scene(app->scene_manager); + consumed = true; + } else if(event.event == DialogExResultRight) { + app->settings.enabled = false; + bt_settings_save(&app->settings); + furi_hal_boot_set_mode(FuriHalBootModeNormal); + furi_hal_power_reset(); + } + } + return consumed; +} + +void bt_settings_scene_disable_dialog_on_exit(void* context) { + BtSettingsApp* app = context; + dialog_ex_clean(app->dialog_ex); +} diff --git a/applications/bt/bt_settings_app/scenes/bt_settings_scene_start.c b/applications/bt/bt_settings_app/scenes/bt_settings_scene_start.c new file mode 100755 index 000000000..faf1d3a1f --- /dev/null +++ b/applications/bt/bt_settings_app/scenes/bt_settings_scene_start.c @@ -0,0 +1,56 @@ +#include "../bt_settings_app.h" +#include "furi-hal-bt.h" + +enum BtSettingsAppStartSubmenuIndex { + BtSettingsAppStartSubmenuIndexEnable, +}; + +static void bt_settings_scene_start_submenu_callback(void* context, uint32_t index) { + BtSettingsApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +void bt_settings_scene_start_on_enter(void* context) { + BtSettingsApp* app = context; + Submenu* submenu = app->submenu; + + const char* submenu_label = app->settings.enabled ? "Disable" : "Enable"; + submenu_add_item( + submenu, + submenu_label, + BtSettingsAppStartSubmenuIndexEnable, + bt_settings_scene_start_submenu_callback, + app); + + view_dispatcher_switch_to_view(app->view_dispatcher, BtSettingsAppViewSubmenu); +} + +bool bt_settings_scene_start_on_event(void* context, SceneManagerEvent event) { + BtSettingsApp* app = context; + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == BtSettingsAppStartSubmenuIndexEnable) { + if(!app->settings.enabled) { + app->settings.enabled = true; + furi_hal_bt_start_app(); + submenu_clean(app->submenu); + submenu_add_item( + app->submenu, + "Disable", + BtSettingsAppStartSubmenuIndexEnable, + bt_settings_scene_start_submenu_callback, + app); + } else { + scene_manager_next_scene(app->scene_manager, BtSettingsAppSceneDisableDialog); + } + consumed = true; + } + } + return consumed; +} + +void bt_settings_scene_start_on_exit(void* context) { + BtSettingsApp* app = context; + submenu_clean(app->submenu); +} diff --git a/applications/bt/bt_types.h b/applications/bt/bt_types.h deleted file mode 100644 index 4cff41059..000000000 --- a/applications/bt/bt_types.h +++ /dev/null @@ -1,65 +0,0 @@ -#pragma once - -#include - -typedef enum { - BtMessageTypeStartTestCarrier, - BtMessageTypeHoppingTx, - BtMessageTypeStopTestCarrier, - BtMessageTypeSetupTestPacketTx, - BtMessageTypeSetupTestPacketRx, - BtMessageTypeStartTestPacketTx, - BtMessageTypeStartTestPacketRx, - BtMessageTypeStopTestPacket, - BtMessageTypeStartApp, - BtMessageTypeUpdateStatusbar, -} BtMessageType; - -typedef enum { - BtStateReady, - BtStateCarrierTx, - BtStateHoppingTx, - BtStateCarrierRxStart, - BtStateCarrierRxRunning, - BtStatePacketSetup, - BtStatePacketStart, - BtStatePacketRunning, - BtStateStartedApp, -} BtStateType; - -typedef enum { - BtChannel2402 = 0, - BtChannel2440 = 19, - BtChannel2480 = 39, -} BtTestChannel; - -typedef enum { - BtPower0dB = 0x19, - BtPower2dB = 0x1B, - BtPower4dB = 0x1D, - BtPower6dB = 0x1F, -} BtTestPower; - -typedef enum { - BtDataRate1M = 1, - BtDataRate2M = 2, -} BtTestDataRate; - -typedef struct { - BtTestChannel channel; - BtTestPower power; - BtTestDataRate datarate; - float rssi; - uint16_t packets_sent; - uint16_t packets_received; -} BtTestParam; - -typedef struct { - BtMessageType type; - BtTestParam param; -} BtMessage; - -typedef struct { - BtStateType type; - BtTestParam param; -} BtState; diff --git a/applications/bt/bt_views.c b/applications/bt/bt_views.c deleted file mode 100755 index fc55c1697..000000000 --- a/applications/bt/bt_views.c +++ /dev/null @@ -1,250 +0,0 @@ -#include "bt_views.h" - -void bt_view_test_carrier_draw(Canvas* canvas, void* model) { - BtViewTestCarrierModel* m = model; - canvas_clear(canvas); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 0, 12, "Performing Carrier test"); - if(m->type == BtStateCarrierTx) { - canvas_draw_str(canvas, 0, 24, "Manual Carrier TX"); - } else if(m->type == BtStateHoppingTx) { - canvas_draw_str(canvas, 0, 24, "Carrier TX Hopping mode"); - } else if(m->type == BtStateCarrierRxRunning) { - canvas_draw_str(canvas, 0, 24, "Manual Carrier RX"); - } - char buffer[32]; - snprintf(buffer, sizeof(buffer), "Channel:%d MHz", m->channel * 2 + 2402); - canvas_draw_str(canvas, 0, 36, buffer); - if(m->type == BtStateCarrierTx || m->type == BtStateHoppingTx) { - snprintf(buffer, sizeof(buffer), "Power:%d dB", m->power - BtPower0dB); - } else if(m->type == BtStateCarrierRxRunning) { - snprintf(buffer, sizeof(buffer), "RSSI: %3.1f dB", m->rssi); - } - canvas_draw_str(canvas, 0, 48, buffer); -} - -void bt_view_test_packet_rx_draw(Canvas* canvas, void* model) { - BtViewTestPacketRxModel* m = model; - canvas_clear(canvas); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 0, 12, "Performing packets RX test"); - if(m->type == BtStatePacketSetup) { - canvas_draw_str(canvas, 0, 24, "Setup parameters. Ok to start"); - } else { - canvas_draw_str(canvas, 0, 24, "Receiving packets ..."); - } - char buffer[32]; - snprintf(buffer, sizeof(buffer), "Channel:%d MHz", m->channel * 2 + 2402); - canvas_draw_str(canvas, 0, 36, buffer); - snprintf(buffer, sizeof(buffer), "Datarate:%d Mbps", m->datarate); - canvas_draw_str(canvas, 0, 48, buffer); - if(m->type == BtStatePacketSetup) { - snprintf(buffer, sizeof(buffer), "%d packets received", m->packets_received); - } else { - snprintf(buffer, sizeof(buffer), "RSSI: %3.1f dB", m->rssi); - } - canvas_draw_str(canvas, 0, 60, buffer); -} - -void bt_view_test_packet_tx_draw(Canvas* canvas, void* model) { - BtViewTestPacketTxModel* m = model; - canvas_clear(canvas); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 0, 12, "Packets send TX test"); - if(m->type == BtStatePacketSetup) { - canvas_draw_str(canvas, 0, 24, "Setup parameters. Ok to start"); - } else { - canvas_draw_str(canvas, 0, 24, "Sending packets ..."); - } - char buffer[32]; - snprintf(buffer, sizeof(buffer), "Channel:%d MHz", m->channel * 2 + 2402); - canvas_draw_str(canvas, 0, 36, buffer); - snprintf(buffer, sizeof(buffer), "Datarate:%d Mbps", m->datarate); - canvas_draw_str(canvas, 0, 48, buffer); - if(m->packets_sent && m->type == BtStatePacketSetup) { - snprintf(buffer, sizeof(buffer), "%d packets sent", m->packets_sent); - canvas_draw_str(canvas, 0, 60, buffer); - } -} - -void bt_view_app_draw(Canvas* canvas, void* model) { - canvas_clear(canvas); - canvas_set_font(canvas, FontSecondary); - canvas_draw_str(canvas, 0, 12, "Start BLE app"); -} - -BtTestChannel bt_switch_channel(InputKey key, BtTestChannel inst_chan) { - uint8_t pos = 0; - BtTestChannel arr[] = {BtChannel2402, BtChannel2440, BtChannel2480}; - for(pos = 0; pos < sizeof(arr); pos++) { - if(arr[pos] == inst_chan) { - break; - } - } - if(key == InputKeyRight) { - pos = (pos + 1) % sizeof(arr); - return arr[pos]; - } else if(key == InputKeyLeft) { - if(pos) { - return arr[pos - 1]; - } else { - return arr[sizeof(arr) - 1]; - } - } - return arr[0]; -} - -bool bt_view_test_carrier_input(InputEvent* event, void* context) { - furi_assert(event); - furi_assert(context); - Bt* bt = context; - if(event->type == InputTypeShort) { - if(event->key == InputKeyBack) { - if(osTimerIsRunning(bt->update_param_timer)) { - osTimerStop(bt->update_param_timer); - } - BtMessage m = {.type = BtMessageTypeStopTestCarrier}; - furi_check(osMessageQueuePut(bt->message_queue, &m, 0, osWaitForever) == osOK); - view_dispatcher_switch_to_view(bt->view_dispatcher, VIEW_NONE); - return true; - } else { - if(event->key == InputKeyRight || event->key == InputKeyLeft) { - bt->state.param.channel = bt_switch_channel(event->key, bt->state.param.channel); - } else if(event->key == InputKeyUp) { - if(bt->state.param.power < BtPower6dB) { - bt->state.param.power += 2; - } - } else if(event->key == InputKeyDown) { - if(bt->state.param.power > BtPower0dB) { - bt->state.param.power -= 2; - } - } else if(event->key == InputKeyOk) { - if(bt->state.type == BtStateCarrierTx) { - bt->state.type = BtStateHoppingTx; - osTimerStart(bt->update_param_timer, 2000); - } else if(bt->state.type == BtStateHoppingTx) { - osTimerStop(bt->update_param_timer); - bt->state.type = BtStateCarrierRxStart; - osTimerStart(bt->update_param_timer, 200); - } else { - osTimerStop(bt->update_param_timer); - bt->state.type = BtStateCarrierTx; - } - } - BtMessage m = { - .type = BtMessageTypeStartTestCarrier, - .param.channel = bt->state.param.channel, - .param.power = bt->state.param.power}; - furi_check(osMessageQueuePut(bt->message_queue, &m, 0, osWaitForever) == osOK); - return true; - } - } - return false; -} - -bool bt_view_test_packet_tx_input(InputEvent* event, void* context) { - furi_assert(event); - furi_assert(context); - Bt* bt = context; - if(event->type == InputTypeShort) { - if(event->key < InputKeyOk) { - // Process InputKeyUp, InputKeyDown, InputKeyLeft, InputKeyRight - if(event->key == InputKeyRight || event->key == InputKeyLeft) { - bt->state.param.channel = bt_switch_channel(event->key, bt->state.param.channel); - } else if(event->key == InputKeyUp) { - if(bt->state.param.datarate < BtDataRate2M) { - bt->state.param.datarate += 1; - } - } else if(event->key == InputKeyDown) { - if(bt->state.param.datarate > BtDataRate1M) { - bt->state.param.datarate -= 1; - } - } - bt->state.type = BtStatePacketSetup; - BtMessage m = { - .type = BtMessageTypeSetupTestPacketTx, - .param.channel = bt->state.param.channel, - .param.datarate = bt->state.param.datarate, - }; - furi_check(osMessageQueuePut(bt->message_queue, &m, 0, osWaitForever) == osOK); - return true; - } else if(event->key == InputKeyOk) { - if(bt->state.type == BtStatePacketSetup) { - bt->state.type = BtStatePacketStart; - } else if(bt->state.type == BtStatePacketStart) { - bt->state.type = BtStatePacketSetup; - } - BtMessage m = { - .type = BtMessageTypeStartTestPacketTx, - .param.channel = bt->state.param.channel, - .param.datarate = bt->state.param.datarate, - }; - furi_check(osMessageQueuePut(bt->message_queue, &m, 0, osWaitForever) == osOK); - return true; - } else if(event->key == InputKeyBack) { - BtMessage m = { - .type = BtMessageTypeStopTestPacket, - }; - furi_check(osMessageQueuePut(bt->message_queue, &m, 0, osWaitForever) == osOK); - view_dispatcher_switch_to_view(bt->view_dispatcher, VIEW_NONE); - return true; - } - } - return false; -} - -bool bt_view_test_packet_rx_input(InputEvent* event, void* context) { - furi_assert(event); - furi_assert(context); - Bt* bt = context; - if(event->type == InputTypeShort) { - if(event->key < InputKeyOk) { - // Process InputKeyUp, InputKeyDown, InputKeyLeft, InputKeyRight - if(event->key == InputKeyRight || event->key == InputKeyLeft) { - bt->state.param.channel = bt_switch_channel(event->key, bt->state.param.channel); - } else if(event->key == InputKeyUp) { - if(bt->state.param.datarate < BtDataRate2M) { - bt->state.param.datarate += 1; - } - } else if(event->key == InputKeyDown) { - if(bt->state.param.datarate > BtDataRate1M) { - bt->state.param.datarate -= 1; - } - } - bt->state.type = BtStatePacketSetup; - BtMessage m = { - .type = BtMessageTypeSetupTestPacketRx, - .param.channel = bt->state.param.channel, - .param.datarate = bt->state.param.datarate, - }; - furi_check(osMessageQueuePut(bt->message_queue, &m, 0, osWaitForever) == osOK); - return true; - } else if(event->key == InputKeyOk) { - if(bt->state.type == BtStatePacketSetup) { - bt->state.type = BtStatePacketStart; - osTimerStart(bt->update_param_timer, 200); - } else if(bt->state.type == BtStatePacketRunning) { - bt->state.type = BtStatePacketSetup; - osTimerStop(bt->update_param_timer); - } - BtMessage m = { - .type = BtMessageTypeStartTestPacketRx, - .param.channel = bt->state.param.channel, - .param.datarate = bt->state.param.datarate, - }; - furi_check(osMessageQueuePut(bt->message_queue, &m, 0, osWaitForever) == osOK); - return true; - } else if(event->key == InputKeyBack) { - if(osTimerIsRunning(bt->update_param_timer)) { - osTimerStop(bt->update_param_timer); - } - BtMessage m = { - .type = BtMessageTypeStopTestPacket, - }; - furi_check(osMessageQueuePut(bt->message_queue, &m, 0, osWaitForever) == osOK); - view_dispatcher_switch_to_view(bt->view_dispatcher, VIEW_NONE); - return true; - } - } - return false; -} diff --git a/applications/bt/bt_views.h b/applications/bt/bt_views.h deleted file mode 100644 index 9103f18f7..000000000 --- a/applications/bt/bt_views.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include "bt_i.h" -#include "bt_types.h" - -#include -#include -#include -#include -#include -#include - -typedef enum { - BtViewTestCarrier, - BtViewTestPacketTx, - BtViewTestPacketRx, - BtViewStartApp, -} BtView; - -typedef struct { - BtStateType type; - BtTestChannel channel; - BtTestPower power; - float rssi; -} BtViewTestCarrierModel; - -typedef struct { - BtStateType type; - BtTestChannel channel; - BtTestDataRate datarate; - uint16_t packets_sent; -} BtViewTestPacketTxModel; - -typedef struct { - BtStateType type; - BtTestChannel channel; - BtTestDataRate datarate; - float rssi; - uint16_t packets_received; -} BtViewTestPacketRxModel; - -void bt_view_test_carrier_draw(Canvas* canvas, void* model); - -bool bt_view_test_carrier_input(InputEvent* event, void* context); - -void bt_view_test_packet_tx_draw(Canvas* canvas, void* model); - -bool bt_view_test_packet_tx_input(InputEvent* event, void* context); - -void bt_view_test_packet_rx_draw(Canvas* canvas, void* model); - -bool bt_view_test_packet_rx_input(InputEvent* event, void* context); - -void bt_view_app_draw(Canvas* canvas, void* model); diff --git a/applications/gui/modules/dialog_ex.c b/applications/gui/modules/dialog_ex.c old mode 100644 new mode 100755 index 9a758983c..713750300 --- a/applications/gui/modules/dialog_ex.c +++ b/applications/gui/modules/dialog_ex.c @@ -243,3 +243,22 @@ void dialog_ex_set_right_button_text(DialogEx* dialog_ex, const char* text) { return true; }); } + +void dialog_ex_clean(DialogEx* dialog_ex) { + furi_assert(dialog_ex); + TextElement clean_text_el = { + .text = NULL, .x = 0, .y = 0, .horizontal = AlignLeft, .vertical = AlignLeft}; + IconElement clean_icon_el = {.icon = NULL, .x = 0, .y = 0}; + with_view_model( + dialog_ex->view, (DialogExModel * model) { + model->header = clean_text_el; + model->text = clean_text_el; + model->icon = clean_icon_el; + model->left_text = NULL; + model->center_text = NULL; + model->right_text = NULL; + return true; + }); + dialog_ex->context = NULL; + dialog_ex->callback = NULL; +} diff --git a/applications/gui/modules/dialog_ex.h b/applications/gui/modules/dialog_ex.h index b80fbcb06..7833128aa 100644 --- a/applications/gui/modules/dialog_ex.h +++ b/applications/gui/modules/dialog_ex.h @@ -5,50 +5,51 @@ extern "C" { #endif -/* Dialog anonymous structure */ +/** Dialog anonymous structure */ typedef struct DialogEx DialogEx; -/* DialogEx result */ +/** DialogEx result */ typedef enum { DialogExResultLeft, DialogExResultCenter, DialogExResultRight, } DialogExResult; -/* DialogEx result callback type +/** DialogEx result callback type * @warning comes from GUI thread */ typedef void (*DialogExResultCallback)(DialogExResult result, void* context); -/* Allocate and initialize dialog - * This dialog used to ask simple questions like Yes/ +/** Allocate and initialize dialog + * This dialog used to ask simple questions + * @return DialogEx instance */ DialogEx* dialog_ex_alloc(); -/* Deinitialize and free dialog +/** Deinitialize and free dialog * @param dialog - DialogEx instance */ void dialog_ex_free(DialogEx* dialog_ex); -/* Get dialog view +/** Get dialog view * @param dialog - DialogEx instance * @return View instance that can be used for embedding */ View* dialog_ex_get_view(DialogEx* dialog_ex); -/* Set dialog result callback +/** Set dialog result callback * @param dialog_ex - DialogEx instance * @param callback - result callback function */ void dialog_ex_set_result_callback(DialogEx* dialog_ex, DialogExResultCallback callback); -/* Set dialog context +/** Set dialog context * @param dialog_ex - DialogEx instance * @param context - context pointer, will be passed to result callback */ void dialog_ex_set_context(DialogEx* dialog_ex, void* context); -/* Set dialog header text +/** Set dialog header text * If text is null, dialog header will not be rendered * @param dialog - DialogEx instance * @param text - text to be shown, can be multiline @@ -63,7 +64,7 @@ void dialog_ex_set_header( Align horizontal, Align vertical); -/* Set dialog text +/** Set dialog text * If text is null, dialog text will not be rendered * @param dialog - DialogEx instance * @param text - text to be shown, can be multiline @@ -78,7 +79,7 @@ void dialog_ex_set_text( Align horizontal, Align vertical); -/* Set dialog icon +/** Set dialog icon * If x or y is negative, dialog icon will not be rendered * @param dialog - DialogEx instance * @param x, y - icon position @@ -86,27 +87,32 @@ void dialog_ex_set_text( */ void dialog_ex_set_icon(DialogEx* dialog_ex, uint8_t x, uint8_t y, const Icon* icon); -/* Set left button text +/** Set left button text * If text is null, left button will not be rendered and processed * @param dialog - DialogEx instance * @param text - text to be shown */ void dialog_ex_set_left_button_text(DialogEx* dialog_ex, const char* text); -/* Set center button text +/** Set center button text * If text is null, center button will not be rendered and processed * @param dialog - DialogEx instance * @param text - text to be shown */ void dialog_ex_set_center_button_text(DialogEx* dialog_ex, const char* text); -/* Set right button text +/** Set right button text * If text is null, right button will not be rendered and processed * @param dialog - DialogEx instance * @param text - text to be shown */ void dialog_ex_set_right_button_text(DialogEx* dialog_ex, const char* text); +/** Clean dialog + * @param dialog_ex DialogEx instance + */ +void dialog_ex_clean(DialogEx* dialog_ex); + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/applications/loader/loader.c b/applications/loader/loader.c index 50630ac6a..0ef11677e 100644 --- a/applications/loader/loader.c +++ b/applications/loader/loader.c @@ -238,7 +238,7 @@ static void loader_build_menu() { with_value_mutex( loader_instance->menu_vm, (Menu * menu) { MenuItem* menu_debug = - menu_item_alloc_menu("Debug tools", icon_animation_alloc(&A_Settings_14)); + menu_item_alloc_menu("Debug tools", icon_animation_alloc(&A_Debug_14)); for(size_t i = 0; i < FLIPPER_DEBUG_APPS_COUNT; i++) { // Add menu item diff --git a/assets/compiled/assets_icons.c b/assets/compiled/assets_icons.c index f95f04c14..60282caff 100644 --- a/assets/compiled/assets_icons.c +++ b/assets/compiled/assets_icons.c @@ -98,18 +98,6 @@ const uint8_t *_I_Flipper_young_80x60[] = {_I_Flipper_young_80x60_0}; const uint8_t _I_DolphinFirstStart3_57x48_0[] = {0x00,0x00,0x00,0x80,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x04,0x00,0x00,0xF8,0x03,0x01,0x00,0x00,0x08,0x00,0x00,0x04,0xBC,0x00,0x00,0x00,0x10,0x00,0x00,0x02,0xC0,0x00,0x00,0x00,0x20,0x00,0x00,0x02,0x00,0x01,0x00,0x00,0x20,0x00,0x00,0x02,0x00,0x02,0x00,0x38,0x40,0x00,0x00,0x02,0x00,0x04,0x00,0x3E,0x40,0x00,0x00,0xF4,0x03,0x08,0x80,0x07,0x80,0x00,0x00,0x5C,0x0D,0x10,0xE0,0x01,0x80,0x00,0x00,0xA8,0x3A,0x20,0xE0,0x00,0x00,0x01,0x00,0x58,0x55,0x00,0xC0,0x01,0x00,0x01,0x00,0xB0,0xAA,0x00,0x80,0x07,0x00,0x01,0x00,0x60,0x55,0x01,0x00,0x1E,0x00,0x01,0x0E,0xC0,0xAA,0x02,0xE0,0x5C,0x00,0x01,0x11,0x80,0x55,0x05,0x00,0xA9,0x00,0x01,0x21,0x00,0xAB,0x0A,0x00,0x56,0x07,0x01,0x41,0x00,0x56,0x15,0x00,0xEC,0x08,0x01,0x81,0x00,0xBF,0x2A,0x00,0x34,0x08,0x01,0x01,0xF1,0xC0,0x57,0x00,0x0C,0x08,0x01,0x02,0x0A,0x00,0xBE,0x00,0x04,0x08,0x01,0x02,0x06,0x00,0x78,0x83,0x02,0x04,0x01,0x02,0x0C,0x00,0xF0,0x7F,0x01,0x04,0x01,0x02,0xF4,0x01,0xFE,0x81,0x00,0x04,0x01,0x04,0x08,0xFF,0x6B,0x40,0x00,0x02,0x01,0x04,0x88,0x55,0x1D,0x40,0x00,0x02,0x01,0x04,0x50,0xAA,0x06,0x20,0x00,0x02,0x01,0x04,0x30,0xD4,0x01,0x20,0x00,0x01,0x01,0x04,0x10,0x68,0x00,0x10,0x00,0x01,0x01,0x04,0x18,0x18,0x00,0x10,0x00,0x01,0x01,0x08,0x18,0x06,0x80,0x10,0x00,0x01,0x01,0x08,0xE8,0x01,0x60,0x08,0x80,0x00,0x01,0x08,0x08,0x00,0x18,0x08,0x80,0x00,0x00,0x08,0x10,0x00,0x06,0x08,0x80,0x00,0x00,0x08,0x60,0xE0,0x01,0x08,0x80,0x00,0x00,0x08,0x80,0x1F,0x00,0x08,0x80,0x00,0x00,0x08,0x80,0x04,0x00,0x04,0x00,0x01,0x00,0x08,0x80,0x04,0x00,0x04,0x00,0x01,0x00,0x10,0x00,0x03,0x00,0x04,0x00,0x01,0x00,0x10,0x00,0x03,0x00,0x04,0x00,0x01,0x00,0x10,0x00,0x01,0x00,0x04,0x00,0x02,0x00,0x10,0x00,0x01,0x00,0x04,0x00,0x02,0x00,0x10,0x80,0x00,0x00,0x04,0x00,0x02,0x00,0x10,0x80,0x00,0x00,0x04,0x00,0x06,0x00,}; const uint8_t *_I_DolphinFirstStart3_57x48[] = {_I_DolphinFirstStart3_57x48_0}; -const uint8_t _I_Scanning_123x52_0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x07,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0x03,0x18,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x56,0x05,0x60,0x00,0x00,0x00,0x80,0x02,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x81,0x0A,0x80,0x00,0x00,0x00,0x80,0x02,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x80,0x00,0x15,0x00,0x01,0x00,0x00,0x40,0x02,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x40,0x00,0x38,0x00,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x00,0x00,0x82,0x00,0x00,0x20,0x00,0x74,0x00,0x04,0x00,0x00,0x40,0x82,0x01,0x00,0x00,0x00,0x41,0x00,0x00,0x20,0x00,0x68,0x00,0x04,0x00,0x00,0x20,0x82,0x02,0x06,0x00,0x00,0x21,0x00,0x00,0x10,0x00,0xD0,0xE0,0x0F,0x00,0x00,0x20,0x82,0x02,0x0A,0x0C,0x80,0x20,0x08,0x00,0x10,0x00,0xA0,0x1C,0x10,0x00,0x00,0x20,0x82,0x02,0x0A,0x14,0x80,0x10,0x04,0x00,0x08,0xE0,0xD3,0x03,0x10,0x00,0x00,0x10,0x82,0x02,0x0A,0x14,0x80,0x10,0x02,0x00,0x08,0x90,0xA7,0x40,0x24,0x00,0x00,0x10,0x82,0x02,0x0A,0x14,0x80,0x10,0x02,0x00,0x08,0xC8,0x7F,0x84,0x28,0x00,0x00,0x10,0x84,0x02,0x0A,0xFF,0x80,0x10,0x02,0x00,0x88,0x67,0x3E,0x88,0x28,0x00,0x00,0x10,0x84,0xFA,0xFF,0xFF,0x80,0x10,0x02,0x00,0x44,0x64,0x2E,0x88,0x28,0x00,0x00,0x10,0xFC,0xAF,0xFF,0x15,0x80,0x10,0x04,0x00,0x44,0xE4,0x2F,0x88,0x2A,0x00,0x00,0x18,0xD4,0xDF,0x1F,0x14,0x80,0x20,0x08,0x00,0x44,0xE4,0x2F,0x50,0xFF,0x00,0xFE,0x1F,0xEC,0x3F,0x0A,0x14,0x00,0x21,0x00,0x00,0x44,0xC4,0x2F,0xEA,0x00,0x01,0x01,0x1A,0xFC,0x02,0x0A,0x14,0x00,0x41,0x00,0x00,0x84,0x88,0x2F,0x1D,0x00,0x82,0x7D,0x1E,0x84,0x02,0x0A,0x18,0x00,0x82,0x00,0x00,0x86,0x1F,0xC6,0x06,0x00,0x84,0x7D,0x16,0x84,0x02,0x0A,0x00,0x00,0x02,0x00,0x00,0x46,0xF5,0xC3,0x01,0x00,0x44,0x01,0x22,0x84,0x02,0x0C,0x00,0x00,0x04,0x00,0x00,0x87,0x0A,0x7C,0x00,0x00,0x44,0x03,0x22,0x88,0x02,0x00,0x00,0x00,0x08,0x00,0x00,0x45,0x05,0x08,0x00,0x7E,0xA4,0x03,0x42,0x88,0x02,0x00,0x00,0x00,0x10,0x00,0x00,0x86,0x06,0x00,0xC0,0x81,0xA5,0x07,0x42,0x08,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x30,0x00,0xD2,0xFF,0x81,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x0C,0x00,0xD2,0x1F,0x80,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x80,0x00,0x03,0x00,0xD1,0x1F,0x00,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0xE1,0x00,0x80,0xE9,0x0F,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x1E,0x00,0xC0,0xE8,0x0F,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x70,0xEE,0x0F,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x3C,0xF9,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xAA,0x9F,0xF0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x40,0x55,0xFD,0x5F,0xF0,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0xEA,0xFF,0x3F,0xE0,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x40,0xD5,0xFF,0x1F,0xE0,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x80,0xAA,0xFF,0x0F,0xE0,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x55,0x55,0x03,0xF0,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0xAA,0xAA,0x00,0xB0,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x54,0x75,0x00,0x58,0x0D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0xA8,0x0F,0x00,0xA8,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x7C,0x00,0x00,0x5C,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0xAE,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0xD7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x80,0x7B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x00,0x00,0x00,0xC0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2A,0x00,0x00,0x00,0xF0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x55,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAA,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; -const uint8_t *_I_Scanning_123x52[] = {_I_Scanning_123x52_0}; - -const uint8_t _I_Quest_7x8_0[] = {0x1E,0x33,0x33,0x30,0x18,0x0C,0x00,0x0C,}; -const uint8_t *_I_Quest_7x8[] = {_I_Quest_7x8_0}; - -const uint8_t _I_Unlock_7x8_0[] = {0x1C,0x22,0x02,0x4F,0x67,0x73,0x79,0x3C,}; -const uint8_t *_I_Unlock_7x8[] = {_I_Unlock_7x8_0}; - -const uint8_t _I_Lock_7x8_0[] = {0x1C,0x22,0x22,0x7F,0x7F,0x77,0x7F,0x3E,}; -const uint8_t *_I_Lock_7x8[] = {_I_Lock_7x8_0}; - const uint8_t _I_PassportBottom_128x17_0[] = {0x2C,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8F,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x2C,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x9A,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x9A,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x95,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0xA8,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x9A,0xF2,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x8F,0xF9,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x0D,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x05,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x05,0xF2,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x05,0xFA,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x1F,0x09,0x79,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0xD5,0x80,0x55,0xD5,0x00,0xF3,0xCC,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x6A,0x00,0xAB,0x6A,0x00,0x06,0x86,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x00,0xFE,0x3F,0x00,0xFC,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; const uint8_t *_I_PassportBottom_128x17[] = {_I_PassportBottom_128x17_0}; @@ -220,6 +208,12 @@ const uint8_t _A_Bluetooth_14_4[] = {0x10,0x00,0x30,0x00,0x51,0x00,0x92,0x00,0x9 const uint8_t _A_Bluetooth_14_5[] = {0x10,0x00,0x30,0x00,0x51,0x00,0x92,0x00,0x94,0x04,0x58,0x08,0x30,0x09,0x30,0x09,0x58,0x08,0x94,0x04,0x92,0x00,0x51,0x00,0x30,0x00,0x10,0x00,}; const uint8_t *_A_Bluetooth_14[] = {_A_Bluetooth_14_0,_A_Bluetooth_14_1,_A_Bluetooth_14_2,_A_Bluetooth_14_3,_A_Bluetooth_14_4,_A_Bluetooth_14_5}; +const uint8_t _A_Debug_14_0[] = {0x20,0x01,0xC1,0x20,0x22,0x11,0x24,0x09,0xD9,0x26,0x16,0x1A,0xD8,0x06,0xD8,0x06,0xD6,0x1A,0x19,0x26,0xE4,0x09,0xC2,0x10,0x01,0x20,0x00,0x00,}; +const uint8_t _A_Debug_14_1[] = {0x20,0x01,0xC0,0x00,0x22,0x11,0x25,0x29,0xD8,0x06,0x16,0x1A,0xD9,0x26,0xD8,0x06,0xD4,0x0A,0x12,0x12,0xEA,0x15,0xC5,0x28,0x02,0x10,0x02,0x10,}; +const uint8_t _A_Debug_14_2[] = {0x20,0x01,0xC0,0x00,0x20,0x01,0x24,0x09,0xDA,0x16,0x11,0x22,0xDC,0x0E,0xDA,0x16,0xD9,0x26,0x14,0x0A,0xF2,0x13,0xD1,0x22,0x08,0x04,0x06,0x18,}; +const uint8_t _A_Debug_14_3[] = {0x22,0x11,0xC4,0x08,0x24,0x09,0x25,0x29,0xD9,0x26,0x12,0x12,0xDC,0x0E,0xD8,0x06,0xD8,0x06,0x14,0x0A,0xF4,0x0B,0xD2,0x12,0x19,0x26,0x06,0x18,}; +const uint8_t *_A_Debug_14[] = {_A_Debug_14_0,_A_Debug_14_1,_A_Debug_14_2,_A_Debug_14_3}; + const uint8_t _A_FileManager_14_0[] = {0xFC,0x07,0x04,0x04,0xF4,0x05,0x04,0x04,0xF7,0x05,0x05,0x04,0xF5,0x3F,0x15,0x20,0x0D,0x20,0x0D,0x10,0x05,0x10,0x05,0x08,0x03,0x08,0xFE,0x07,}; const uint8_t _A_FileManager_14_1[] = {0x00,0x00,0x00,0x00,0xFC,0x07,0x04,0x04,0xF7,0x05,0x05,0x04,0xF5,0x3F,0x15,0x20,0x0D,0x20,0x0D,0x10,0x05,0x10,0x05,0x08,0x03,0x08,0xFE,0x07,}; const uint8_t _A_FileManager_14_2[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x07,0x05,0x04,0xF5,0x3F,0x15,0x20,0x0D,0x20,0x0D,0x10,0x05,0x10,0x05,0x08,0x03,0x08,0xFE,0x07,}; @@ -423,6 +417,18 @@ const uint8_t *_I_Bluetooth_5x8[] = {_I_Bluetooth_5x8_0}; const uint8_t _I_Background_128x11_0[] = {0xFE,0x01,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x7D,0x06,0x00,0x00,0x00,0x00,0x00,0x18,0xFF,0xB7,0x55,0x31,0x00,0x00,0x00,0x00,0x81,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0x8F,0x00,0x00,0x00,0xE2,0xFF,0xFF,0xFF,0x7F,0x3D,0x01,0x00,0x00,0x00,0x00,0x00,0x40,0xB6,0xEA,0xFF,0x04,0x00,0x00,0x00,0x80,0x41,0xFE,0xFF,0xFF,0xAA,0xFE,0xFF,0x3F,0x01,0x00,0x00,0xF9,0xFF,0xFF,0xFF,0xAB,0x9F,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xF8,0xFF,0x7F,0x02,0x00,0x00,0x00,0x80,0x3E,0xFF,0xFF,0xFF,0xFF,0x55,0xFD,0x7F,0xFC,0xFF,0xFF,0x6C,0xFF,0xFF,0xFF,0xB5,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x80,0x01,0x00,0x00,0x00,0x80,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x01,0x00,0x00,0xFE,0xFF,0xFF,0xFF,0x7F,}; const uint8_t *_I_Background_128x11[] = {_I_Background_128x11_0}; +const uint8_t _I_Scanning_123x52_0[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x07,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0x03,0x18,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x56,0x05,0x60,0x00,0x00,0x00,0x80,0x02,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x81,0x0A,0x80,0x00,0x00,0x00,0x80,0x02,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x80,0x00,0x15,0x00,0x01,0x00,0x00,0x40,0x02,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x40,0x00,0x38,0x00,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x00,0x00,0x82,0x00,0x00,0x20,0x00,0x74,0x00,0x04,0x00,0x00,0x40,0x82,0x01,0x00,0x00,0x00,0x41,0x00,0x00,0x20,0x00,0x68,0x00,0x04,0x00,0x00,0x20,0x82,0x02,0x06,0x00,0x00,0x21,0x00,0x00,0x10,0x00,0xD0,0xE0,0x0F,0x00,0x00,0x20,0x82,0x02,0x0A,0x0C,0x80,0x20,0x08,0x00,0x10,0x00,0xA0,0x1C,0x10,0x00,0x00,0x20,0x82,0x02,0x0A,0x14,0x80,0x10,0x04,0x00,0x08,0xE0,0xD3,0x03,0x10,0x00,0x00,0x10,0x82,0x02,0x0A,0x14,0x80,0x10,0x02,0x00,0x08,0x90,0xA7,0x40,0x24,0x00,0x00,0x10,0x82,0x02,0x0A,0x14,0x80,0x10,0x02,0x00,0x08,0xC8,0x7F,0x84,0x28,0x00,0x00,0x10,0x84,0x02,0x0A,0xFF,0x80,0x10,0x02,0x00,0x88,0x67,0x3E,0x88,0x28,0x00,0x00,0x10,0x84,0xFA,0xFF,0xFF,0x80,0x10,0x02,0x00,0x44,0x64,0x2E,0x88,0x28,0x00,0x00,0x10,0xFC,0xAF,0xFF,0x15,0x80,0x10,0x04,0x00,0x44,0xE4,0x2F,0x88,0x2A,0x00,0x00,0x18,0xD4,0xDF,0x1F,0x14,0x80,0x20,0x08,0x00,0x44,0xE4,0x2F,0x50,0xFF,0x00,0xFE,0x1F,0xEC,0x3F,0x0A,0x14,0x00,0x21,0x00,0x00,0x44,0xC4,0x2F,0xEA,0x00,0x01,0x01,0x1A,0xFC,0x02,0x0A,0x14,0x00,0x41,0x00,0x00,0x84,0x88,0x2F,0x1D,0x00,0x82,0x7D,0x1E,0x84,0x02,0x0A,0x18,0x00,0x82,0x00,0x00,0x86,0x1F,0xC6,0x06,0x00,0x84,0x7D,0x16,0x84,0x02,0x0A,0x00,0x00,0x02,0x00,0x00,0x46,0xF5,0xC3,0x01,0x00,0x44,0x01,0x22,0x84,0x02,0x0C,0x00,0x00,0x04,0x00,0x00,0x87,0x0A,0x7C,0x00,0x00,0x44,0x03,0x22,0x88,0x02,0x00,0x00,0x00,0x08,0x00,0x00,0x45,0x05,0x08,0x00,0x7E,0xA4,0x03,0x42,0x88,0x02,0x00,0x00,0x00,0x10,0x00,0x00,0x86,0x06,0x00,0xC0,0x81,0xA5,0x07,0x42,0x08,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x30,0x00,0xD2,0xFF,0x81,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x0C,0x00,0xD2,0x1F,0x80,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x80,0x00,0x03,0x00,0xD1,0x1F,0x00,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0xE1,0x00,0x80,0xE9,0x0F,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x1E,0x00,0xC0,0xE8,0x0F,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x70,0xEE,0x0F,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x3C,0xF9,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xAA,0x9F,0xF0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x40,0x55,0xFD,0x5F,0xF0,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0xEA,0xFF,0x3F,0xE0,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x40,0xD5,0xFF,0x1F,0xE0,0x17,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x80,0xAA,0xFF,0x0F,0xE0,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x55,0x55,0x03,0xF0,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0xAA,0xAA,0x00,0xB0,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x54,0x75,0x00,0x58,0x0D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0xA8,0x0F,0x00,0xA8,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x7C,0x00,0x00,0x5C,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0xAE,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0xD7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x80,0x7B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x00,0x00,0x00,0xC0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2A,0x00,0x00,0x00,0xF0,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x55,0x00,0x00,0x00,0xFC,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAA,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}; +const uint8_t *_I_Scanning_123x52[] = {_I_Scanning_123x52_0}; + +const uint8_t _I_Quest_7x8_0[] = {0x1E,0x33,0x33,0x30,0x18,0x0C,0x00,0x0C,}; +const uint8_t *_I_Quest_7x8[] = {_I_Quest_7x8_0}; + +const uint8_t _I_Unlock_7x8_0[] = {0x1C,0x22,0x02,0x4F,0x67,0x73,0x79,0x3C,}; +const uint8_t *_I_Unlock_7x8[] = {_I_Unlock_7x8_0}; + +const uint8_t _I_Lock_7x8_0[] = {0x1C,0x22,0x22,0x7F,0x7F,0x77,0x7F,0x3E,}; +const uint8_t *_I_Lock_7x8[] = {_I_Lock_7x8_0}; + const uint8_t _I_DolphinMafia_115x62_0[] = {0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2F,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x15,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAF,0x0A,0x00,0x40,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x55,0x15,0x00,0x80,0xF0,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xAA,0x0A,0x00,0x80,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x55,0x15,0x00,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xAA,0x2A,0xE0,0xFF,0xFF,0xFF,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x55,0x55,0xFC,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xAA,0xAA,0xFF,0xFF,0xFF,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x55,0xD5,0xFF,0x7F,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xAA,0xFA,0xFF,0x2B,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x55,0xFD,0x7F,0x05,0xE8,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAB,0xFE,0xAF,0x00,0xF1,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x55,0xFF,0x15,0xE0,0x37,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEB,0xFF,0x0A,0xFC,0x7F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF6,0x7F,0x81,0xFF,0xEF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0xFA,0xAF,0xE0,0x3F,0xEE,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0xFE,0x57,0xF8,0x0F,0xCE,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0xFF,0x2B,0xFC,0x1F,0x07,0x00,0x30,0x00,0x00,0x00,0x00,0x80,0x02,0x00,0xC0,0xFF,0x15,0xFC,0xFF,0x07,0x00,0xC0,0x00,0x00,0x00,0x00,0x20,0x02,0x00,0xE0,0xBF,0x0A,0xFC,0xFF,0x03,0x00,0x00,0x01,0x00,0x00,0x00,0x18,0x01,0x00,0xF8,0x5F,0x05,0xF8,0xFF,0x03,0x00,0x00,0x02,0x00,0x00,0x60,0x86,0x00,0x00,0xFC,0xAF,0x02,0xFA,0xFF,0x01,0x00,0x00,0x02,0x00,0x30,0x1D,0x40,0x00,0x00,0xFF,0x57,0x01,0xF5,0x7F,0x00,0x00,0xC0,0x02,0x00,0x08,0x00,0x30,0x00,0x80,0xFF,0xAB,0x80,0xEA,0x1F,0x00,0x00,0xE0,0xFB,0x03,0x04,0x00,0x0E,0x00,0xC0,0xFF,0x57,0x00,0xF5,0x03,0x00,0x00,0xF8,0x02,0x00,0x04,0x60,0x01,0x00,0xE0,0xFF,0x2B,0x80,0x0A,0x04,0x00,0x00,0xC6,0xC2,0x0F,0x04,0x03,0x00,0x00,0xF0,0xFF,0x16,0x00,0x05,0x08,0x00,0x80,0x01,0x02,0x00,0xF0,0x00,0x00,0x00,0xF0,0x3F,0x0A,0x80,0x02,0x00,0x00,0x60,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0xE0,0x03,0x06,0x00,0x03,0x00,0x00,0x1C,0x00,0x01,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x82,0x00,0x00,0x03,0x80,0x00,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x82,0x00,0xE0,0x00,0x40,0x00,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x03,0x1E,0x00,0x30,0x00,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0xFC,0x01,0x00,0x0E,0x00,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0xC0,0x01,0x00,0x00,0x21,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0xE1,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0xF8,0x10,0x03,0x00,0x00,0x00,0x80,0x01,0x00,0x00,0x00,0xF0,0x04,0x00,0x00,0x04,0x10,0x04,0x00,0x00,0x00,0xE0,0x03,0x00,0x00,0x00,0x0F,0x04,0x00,0x00,0x04,0x10,0x08,0x00,0x00,0x00,0xB0,0x01,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x04,0x10,0x08,0x00,0x00,0x00,0xD8,0xFF,0xFF,0xFF,0x3F,0x00,0x28,0x00,0x00,0x08,0x10,0x08,0x00,0x00,0x00,0xEC,0x01,0x00,0x00,0xE0,0x1F,0x28,0x00,0x00,0x10,0x10,0x08,0x00,0x00,0x00,0xD6,0x02,0x00,0x00,0x00,0x30,0x50,0x00,0x00,0x10,0x10,0x04,0x00,0x00,0x00,0xEB,0x05,0x00,0x00,0x00,0x50,0x50,0x00,0x00,0x10,0x20,0x02,0x00,0x00,0x80,0xD4,0x0A,0x00,0x00,0x00,0x90,0x50,0x00,0x00,0x08,0xC0,0x01,0x00,0x00,0x40,0xEA,0x15,0x00,0x00,0x00,0x08,0x61,0x00,0x00,0x0C,0x00,0x01,0x00,0x00,0x20,0xF4,0xFF,0xFF,0x01,0x00,0x08,0x62,0x00,0x00,0x12,0x80,0x00,0x00,0x00,0x10,0xEA,0x15,0x00,0xFE,0x00,0x08,0xE4,0x01,0x00,0x21,0x80,0x00,0x00,0x00,0x10,0xF4,0x0A,0x00,0x00,0x0F,0x04,0xA8,0x06,0xC0,0xC0,0x40,0x00,0x00,0x00,0x08,0xE8,0x05,0x00,0x00,0x30,0x04,0x50,0x19,0x38,0x01,0x47,0x00,0x00,0x00,0x04,0xF4,0x02,0x00,0x00,0xC0,0x04,0xC0,0xE2,0x07,0x06,0x38,0x00,0x00,0x00,0x04,0xF8,0x05,0x00,0x00,0x00,0x03,0x40,0x01,0x00,0x18,0x20,0x00,0x00,0x00,0x02,0xF0,0x02,0x00,0x00,0x00,0x00,0x80,0x02,0x00,0x60,0x10,0x00,0x00,0x00,0x02,0xF8,0x01,0x00,0x00,0x00,0x00,0x80,0x05,0x00,0x80,0x11,0x00,0x00,0x00,0x01,0xF0,0x02,0x00,0x00,0x00,0x00,0x80,0x0A,0x00,0x00,0x0E,0x00,0x00,0x00,}; const uint8_t *_I_DolphinMafia_115x62[] = {_I_DolphinMafia_115x62_0}; @@ -472,10 +478,6 @@ const Icon I_DolphinFirstStart8_56x51 = {.width=56,.height=51,.frame_count=1,.fr const Icon I_DolphinFirstStart7_61x51 = {.width=61,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart7_61x51}; const Icon I_Flipper_young_80x60 = {.width=80,.height=60,.frame_count=1,.frame_rate=0,.frames=_I_Flipper_young_80x60}; const Icon I_DolphinFirstStart3_57x48 = {.width=57,.height=48,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart3_57x48}; -const Icon I_Scanning_123x52 = {.width=123,.height=52,.frame_count=1,.frame_rate=0,.frames=_I_Scanning_123x52}; -const Icon I_Quest_7x8 = {.width=7,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Quest_7x8}; -const Icon I_Unlock_7x8 = {.width=7,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Unlock_7x8}; -const Icon I_Lock_7x8 = {.width=7,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Lock_7x8}; const Icon I_PassportBottom_128x17 = {.width=128,.height=17,.frame_count=1,.frame_rate=0,.frames=_I_PassportBottom_128x17}; const Icon I_DoorLeft_8x56 = {.width=8,.height=56,.frame_count=1,.frame_rate=0,.frames=_I_DoorLeft_8x56}; const Icon I_DoorLocked_10x56 = {.width=10,.height=56,.frame_count=1,.frame_rate=0,.frames=_I_DoorLocked_10x56}; @@ -510,6 +512,7 @@ const Icon I_KeySaveSelected_24x11 = {.width=24,.height=11,.frame_count=1,.frame const Icon I_KeyBackspace_16x9 = {.width=16,.height=9,.frame_count=1,.frame_rate=0,.frames=_I_KeyBackspace_16x9}; const Icon A_125khz_14 = {.width=14,.height=14,.frame_count=4,.frame_rate=3,.frames=_A_125khz_14}; const Icon A_Bluetooth_14 = {.width=14,.height=14,.frame_count=6,.frame_rate=3,.frames=_A_Bluetooth_14}; +const Icon A_Debug_14 = {.width=14,.height=14,.frame_count=4,.frame_rate=3,.frames=_A_Debug_14}; const Icon A_FileManager_14 = {.width=14,.height=14,.frame_count=10,.frame_rate=3,.frames=_A_FileManager_14}; const Icon A_GPIO_14 = {.width=14,.height=14,.frame_count=8,.frame_rate=3,.frames=_A_GPIO_14}; const Icon A_Games_14 = {.width=14,.height=14,.frame_count=9,.frame_rate=3,.frames=_A_Games_14}; @@ -552,6 +555,10 @@ const Icon I_SDcardFail_11x8 = {.width=11,.height=8,.frame_count=1,.frame_rate=0 const Icon I_USBConnected_15x8 = {.width=15,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_USBConnected_15x8}; const Icon I_Bluetooth_5x8 = {.width=5,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Bluetooth_5x8}; const Icon I_Background_128x11 = {.width=128,.height=11,.frame_count=1,.frame_rate=0,.frames=_I_Background_128x11}; +const Icon I_Scanning_123x52 = {.width=123,.height=52,.frame_count=1,.frame_rate=0,.frames=_I_Scanning_123x52}; +const Icon I_Quest_7x8 = {.width=7,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Quest_7x8}; +const Icon I_Unlock_7x8 = {.width=7,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Unlock_7x8}; +const Icon I_Lock_7x8 = {.width=7,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Lock_7x8}; const Icon I_DolphinMafia_115x62 = {.width=115,.height=62,.frame_count=1,.frame_rate=0,.frames=_I_DolphinMafia_115x62}; const Icon I_DolphinExcited_64x63 = {.width=64,.height=63,.frame_count=1,.frame_rate=0,.frames=_I_DolphinExcited_64x63}; const Icon I_iButtonDolphinSuccess_109x60 = {.width=109,.height=60,.frame_count=1,.frame_rate=0,.frames=_I_iButtonDolphinSuccess_109x60}; diff --git a/assets/compiled/assets_icons.h b/assets/compiled/assets_icons.h index 689ce0d7e..312451f0e 100644 --- a/assets/compiled/assets_icons.h +++ b/assets/compiled/assets_icons.h @@ -29,10 +29,6 @@ extern const Icon I_DolphinFirstStart8_56x51; extern const Icon I_DolphinFirstStart7_61x51; extern const Icon I_Flipper_young_80x60; extern const Icon I_DolphinFirstStart3_57x48; -extern const Icon I_Scanning_123x52; -extern const Icon I_Quest_7x8; -extern const Icon I_Unlock_7x8; -extern const Icon I_Lock_7x8; extern const Icon I_PassportBottom_128x17; extern const Icon I_DoorLeft_8x56; extern const Icon I_DoorLocked_10x56; @@ -67,6 +63,7 @@ extern const Icon I_KeySaveSelected_24x11; extern const Icon I_KeyBackspace_16x9; extern const Icon A_125khz_14; extern const Icon A_Bluetooth_14; +extern const Icon A_Debug_14; extern const Icon A_FileManager_14; extern const Icon A_GPIO_14; extern const Icon A_Games_14; @@ -109,6 +106,10 @@ extern const Icon I_SDcardFail_11x8; extern const Icon I_USBConnected_15x8; extern const Icon I_Bluetooth_5x8; extern const Icon I_Background_128x11; +extern const Icon I_Scanning_123x52; +extern const Icon I_Quest_7x8; +extern const Icon I_Unlock_7x8; +extern const Icon I_Lock_7x8; extern const Icon I_DolphinMafia_115x62; extern const Icon I_DolphinExcited_64x63; extern const Icon I_iButtonDolphinSuccess_109x60; diff --git a/assets/icons/MainMenu/Debug_14/frame_01.png b/assets/icons/MainMenu/Debug_14/frame_01.png new file mode 100644 index 000000000..59b61fea8 Binary files /dev/null and b/assets/icons/MainMenu/Debug_14/frame_01.png differ diff --git a/assets/icons/MainMenu/Debug_14/frame_02.png b/assets/icons/MainMenu/Debug_14/frame_02.png new file mode 100644 index 000000000..93b4f950e Binary files /dev/null and b/assets/icons/MainMenu/Debug_14/frame_02.png differ diff --git a/assets/icons/MainMenu/Debug_14/frame_03.png b/assets/icons/MainMenu/Debug_14/frame_03.png new file mode 100644 index 000000000..cf55953c8 Binary files /dev/null and b/assets/icons/MainMenu/Debug_14/frame_03.png differ diff --git a/assets/icons/MainMenu/Debug_14/frame_04.png b/assets/icons/MainMenu/Debug_14/frame_04.png new file mode 100644 index 000000000..5f89c2e1b Binary files /dev/null and b/assets/icons/MainMenu/Debug_14/frame_04.png differ diff --git a/assets/icons/MainMenu/Debug_14/frame_rate b/assets/icons/MainMenu/Debug_14/frame_rate new file mode 100644 index 000000000..e440e5c84 --- /dev/null +++ b/assets/icons/MainMenu/Debug_14/frame_rate @@ -0,0 +1 @@ +3 \ No newline at end of file diff --git a/assets/icons/GubGHz/Scanning_123x52.png b/assets/icons/SubGhz/Scanning_123x52.png similarity index 100% rename from assets/icons/GubGHz/Scanning_123x52.png rename to assets/icons/SubGhz/Scanning_123x52.png diff --git a/assets/icons/GubGHz/lock_7x8.png b/assets/icons/SubGhz/lock_7x8.png similarity index 100% rename from assets/icons/GubGHz/lock_7x8.png rename to assets/icons/SubGhz/lock_7x8.png diff --git a/assets/icons/GubGHz/quest_7x8.png b/assets/icons/SubGhz/quest_7x8.png similarity index 100% rename from assets/icons/GubGHz/quest_7x8.png rename to assets/icons/SubGhz/quest_7x8.png diff --git a/assets/icons/GubGHz/unlock_7x8.png b/assets/icons/SubGhz/unlock_7x8.png similarity index 100% rename from assets/icons/GubGHz/unlock_7x8.png rename to assets/icons/SubGhz/unlock_7x8.png diff --git a/firmware/targets/f6/furi-hal/furi-hal-bt.c b/firmware/targets/f6/furi-hal/furi-hal-bt.c index ec14e85f2..f40f96010 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-bt.c +++ b/firmware/targets/f6/furi-hal/furi-hal-bt.c @@ -43,7 +43,7 @@ bool furi_hal_bt_is_alive() { return APPE_Status() == BleGlueStatusStarted; } -bool furi_hal_bt_wait_transition() { +bool furi_hal_bt_wait_startup() { uint8_t counter = 0; while (APPE_Status() == BleGlueStatusStartup) { osDelay(10); @@ -56,7 +56,7 @@ bool furi_hal_bt_wait_transition() { } bool furi_hal_bt_lock_flash() { - if (!furi_hal_bt_wait_transition()) { + if (!furi_hal_bt_wait_startup()) { return false; } if (APPE_Status() == BleGlueStatusUninitialized) { @@ -100,7 +100,7 @@ void furi_hal_bt_start_packet_rx(uint8_t channel, uint8_t datarate) { } uint16_t furi_hal_bt_stop_packet_test() { - uint16_t num_of_packets; + uint16_t num_of_packets = 0; hci_le_test_end(&num_of_packets); return num_of_packets; } diff --git a/firmware/targets/f6/furi-hal/furi-hal-gpio.c b/firmware/targets/f6/furi-hal/furi-hal-gpio.c index 65a8009bb..1de1657fd 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-gpio.c +++ b/firmware/targets/f6/furi-hal/furi-hal-gpio.c @@ -151,6 +151,7 @@ void hal_gpio_add_int_callback(const GpioPin* gpio, GpioExtiCallback cb, void* c __disable_irq(); uint8_t pin_num = hal_gpio_get_pin_num(gpio); + furi_assert(gpio_interrupt[pin_num].callback == NULL); gpio_interrupt[pin_num].callback = cb; gpio_interrupt[pin_num].context = ctx; gpio_interrupt[pin_num].ready = true; diff --git a/firmware/targets/furi-hal-include/furi-hal-bt.h b/firmware/targets/furi-hal-include/furi-hal-bt.h index d66233a11..801e3c48e 100644 --- a/firmware/targets/furi-hal-include/furi-hal-bt.h +++ b/firmware/targets/furi-hal-include/furi-hal-bt.h @@ -19,6 +19,9 @@ void furi_hal_bt_dump_state(string_t buffer); /** Get BT/BLE system component state */ bool furi_hal_bt_is_alive(); +/** Wait for Core2 startup */ +bool furi_hal_bt_wait_startup(); + /** * Lock shared access to flash controller * @return true if lock was successful, false if not