From cf591ef7ebc024a0af74e26f4b645758e44ae4bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Sun, 28 Nov 2021 21:28:19 +0300 Subject: [PATCH 01/32] [FL-1911] FuriHal: i2c refactoring (#847) * Project: fix release build, replace asserts with checks. * FuriHal: i2c refactoring, new bus access model, flexible bus gpio configuration. * FuriHal: set i2c pins to high on detach. * FuriHal: more i2c bus events, put bus under reset when not used, move bus enable/disable routine to bus handler. * FuriHal: fix i2c deadlock in power api, add external i2c handle. --- applications/storage/storage-external-api.c | 4 +- applications/tests/rpc/rpc_test.c | 2 +- .../targets/f6/furi-hal/furi-hal-i2c-config.c | 149 +++++++++++++++ .../targets/f6/furi-hal/furi-hal-i2c-config.h | 31 ++++ .../targets/f6/furi-hal/furi-hal-i2c-types.h | 51 ++++++ bootloader/targets/f6/furi-hal/furi-hal-i2c.c | 87 +++++---- bootloader/targets/f6/furi-hal/furi-hal-i2c.h | 64 ++++++- .../targets/f6/furi-hal/furi-hal-light.c | 36 ++-- .../targets/f6/furi-hal/furi-hal-resources.c | 3 + .../targets/f6/furi-hal/furi-hal-resources.h | 15 +- .../targets/f7/furi-hal/furi-hal-i2c-config.c | 149 +++++++++++++++ .../targets/f7/furi-hal/furi-hal-i2c-config.h | 31 ++++ .../targets/f7/furi-hal/furi-hal-i2c-types.h | 51 ++++++ bootloader/targets/f7/furi-hal/furi-hal-i2c.c | 87 +++++---- bootloader/targets/f7/furi-hal/furi-hal-i2c.h | 64 ++++++- .../targets/f7/furi-hal/furi-hal-light.c | 36 ++-- .../targets/f7/furi-hal/furi-hal-resources.c | 3 + .../targets/f7/furi-hal/furi-hal-resources.h | 15 +- .../targets/f6/furi-hal/furi-hal-i2c-config.c | 133 ++++++++++++++ .../targets/f6/furi-hal/furi-hal-i2c-config.h | 31 ++++ .../targets/f6/furi-hal/furi-hal-i2c-types.h | 49 +++++ firmware/targets/f6/furi-hal/furi-hal-i2c.c | 107 +++++------ firmware/targets/f6/furi-hal/furi-hal-light.c | 57 +++--- firmware/targets/f6/furi-hal/furi-hal-power.c | 135 ++++++++++---- .../targets/f6/furi-hal/furi-hal-resources.c | 3 + .../targets/f6/furi-hal/furi-hal-resources.h | 21 +-- firmware/targets/f6/furi-hal/furi-hal-vcp.c | 2 +- .../targets/f7/furi-hal/furi-hal-i2c-config.c | 133 ++++++++++++++ .../targets/f7/furi-hal/furi-hal-i2c-config.h | 31 ++++ .../targets/f7/furi-hal/furi-hal-i2c-types.h | 49 +++++ firmware/targets/f7/furi-hal/furi-hal-i2c.c | 107 +++++------ firmware/targets/f7/furi-hal/furi-hal-light.c | 57 +++--- firmware/targets/f7/furi-hal/furi-hal-power.c | 135 ++++++++++---- .../targets/f7/furi-hal/furi-hal-resources.c | 3 + .../targets/f7/furi-hal/furi-hal-resources.h | 21 +-- firmware/targets/f7/furi-hal/furi-hal-spi.h | 108 ----------- firmware/targets/f7/furi-hal/furi-hal-vcp.c | 2 +- .../targets/furi-hal-include/furi-hal-i2c.h | 50 ++---- .../furi-hal-spi.h | 3 +- lib/drivers/bq25896.c | 87 ++++----- lib/drivers/bq25896.h | 27 +-- lib/drivers/bq27220.c | 169 +++++++++--------- lib/drivers/bq27220.h | 25 +-- lib/drivers/lp5562.c | 32 ++-- lib/drivers/lp5562.h | 11 +- 45 files changed, 1685 insertions(+), 781 deletions(-) create mode 100644 bootloader/targets/f6/furi-hal/furi-hal-i2c-config.c create mode 100644 bootloader/targets/f6/furi-hal/furi-hal-i2c-config.h create mode 100644 bootloader/targets/f6/furi-hal/furi-hal-i2c-types.h create mode 100644 bootloader/targets/f7/furi-hal/furi-hal-i2c-config.c create mode 100644 bootloader/targets/f7/furi-hal/furi-hal-i2c-config.h create mode 100644 bootloader/targets/f7/furi-hal/furi-hal-i2c-types.h create mode 100644 firmware/targets/f6/furi-hal/furi-hal-i2c-config.c create mode 100644 firmware/targets/f6/furi-hal/furi-hal-i2c-config.h create mode 100644 firmware/targets/f6/furi-hal/furi-hal-i2c-types.h create mode 100644 firmware/targets/f7/furi-hal/furi-hal-i2c-config.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-i2c-config.h create mode 100644 firmware/targets/f7/furi-hal/furi-hal-i2c-types.h delete mode 100644 firmware/targets/f7/furi-hal/furi-hal-spi.h rename firmware/targets/{f6/furi-hal => furi-hal-include}/furi-hal-spi.h (99%) diff --git a/applications/storage/storage-external-api.c b/applications/storage/storage-external-api.c index 6c61f707..05d1fc28 100644 --- a/applications/storage/storage-external-api.c +++ b/applications/storage/storage-external-api.c @@ -427,7 +427,7 @@ bool storage_simply_remove_recursive(Storage* storage, const char* path) { string_init_printf(fullname, "%s/%s", string_get_cstr(cur_dir), name); FS_Error error = storage_common_remove(storage, string_get_cstr(fullname)); - furi_assert(error == FSE_OK); + furi_check(error == FSE_OK); string_clear(fullname); } storage_dir_close(dir); @@ -438,7 +438,7 @@ bool storage_simply_remove_recursive(Storage* storage, const char* path) { } FS_Error error = storage_common_remove(storage, string_get_cstr(cur_dir)); - furi_assert(error == FSE_OK); + furi_check(error == FSE_OK); if(string_cmp(cur_dir, path)) { size_t last_char = string_search_rchar(cur_dir, '/'); diff --git a/applications/tests/rpc/rpc_test.c b/applications/tests/rpc/rpc_test.c index af99be4a..dbe1a324 100644 --- a/applications/tests/rpc/rpc_test.c +++ b/applications/tests/rpc/rpc_test.c @@ -115,7 +115,7 @@ static void clean_directory(Storage* fs_api, const char* clean_dir) { clean_directory(fs_api, fullname); } FS_Error error = storage_common_remove(fs_api, fullname); - furi_assert(error == FSE_OK); + furi_check(error == FSE_OK); free(fullname); } free(name); diff --git a/bootloader/targets/f6/furi-hal/furi-hal-i2c-config.c b/bootloader/targets/f6/furi-hal/furi-hal-i2c-config.c new file mode 100644 index 00000000..afaab237 --- /dev/null +++ b/bootloader/targets/f6/furi-hal/furi-hal-i2c-config.c @@ -0,0 +1,149 @@ +#include "furi-hal-i2c-config.h" +#include +#include + +#include +#include + +/** Timing register value is computed with the STM32CubeMX Tool, + * Standard Mode @100kHz with I2CCLK = 64 MHz, + * rise time = 0ns, fall time = 0ns + */ +#define FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100 0x10707DBC + +/** Timing register value is computed with the STM32CubeMX Tool, + * Fast Mode @400kHz with I2CCLK = 64 MHz, + * rise time = 0ns, fall time = 0ns + */ +#define FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_400 0x00602173 + +static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { + if(event == FuriHalI2cBusEventInit) { + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); + LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); + bus->current_handle = NULL; + } else if(event == FuriHalI2cBusEventDeinit) { + } else if(event == FuriHalI2cBusEventLock) { + } else if(event == FuriHalI2cBusEventUnlock) { + } else if(event == FuriHalI2cBusEventActivate) { + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1); + } else if(event == FuriHalI2cBusEventDeactivate) { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); + } +} + +FuriHalI2cBus furi_hal_i2c_bus_power = { + .i2c = I2C1, + .current_handle = NULL, + .callback = furi_hal_i2c_bus_power_event, +}; + +static void furi_hal_i2c_bus_external_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { + if(event == FuriHalI2cBusEventActivate) { + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C3); + LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3); + } else if(event == FuriHalI2cBusEventDeactivate) { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3); + } +} + +FuriHalI2cBus furi_hal_i2c_bus_external = { + .i2c = I2C3, + .current_handle = NULL, + .callback = furi_hal_i2c_bus_external_event, +}; + +void furi_hal_i2c_bus_handle_power_event( + FuriHalI2cBusHandle* handle, + FuriHalI2cBusHandleEvent event) { + if(event == FuriHalI2cBusHandleEventActivate) { + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + hal_gpio_init_ex( + &gpio_i2c_power_sda, + GpioModeAltFunctionOpenDrain, + GpioPullNo, + GpioSpeedLow, + GpioAltFn4I2C1); + hal_gpio_init_ex( + &gpio_i2c_power_scl, + GpioModeAltFunctionOpenDrain, + GpioPullNo, + GpioSpeedLow, + GpioAltFn4I2C1); + + LL_I2C_InitTypeDef I2C_InitStruct = {0}; + I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; + I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; + I2C_InitStruct.DigitalFilter = 0; + I2C_InitStruct.OwnAddress1 = 0; + I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; + I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; + if(furi_hal_version_get_hw_version() > 10) { + I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_400; + } else { + I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100; + } + LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct); + + LL_I2C_EnableAutoEndMode(handle->bus->i2c); + LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK); + LL_I2C_DisableOwnAddress2(handle->bus->i2c); + LL_I2C_DisableGeneralCall(handle->bus->i2c); + LL_I2C_EnableClockStretching(handle->bus->i2c); + LL_I2C_Enable(handle->bus->i2c); + } else if(event == FuriHalI2cBusHandleEventDeactivate) { + LL_I2C_Disable(handle->bus->i2c); + hal_gpio_write(&gpio_i2c_power_sda, 1); + hal_gpio_write(&gpio_i2c_power_scl, 1); + hal_gpio_init_ex( + &gpio_i2c_power_sda, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + hal_gpio_init_ex( + &gpio_i2c_power_scl, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + } +} + +FuriHalI2cBusHandle furi_hal_i2c_handle_power = { + .bus = &furi_hal_i2c_bus_power, + .callback = furi_hal_i2c_bus_handle_power_event, +}; + +void furi_hal_i2c_bus_handle_external_event( + FuriHalI2cBusHandle* handle, + FuriHalI2cBusHandleEvent event) { + if(event == FuriHalI2cBusHandleEventActivate) { + hal_gpio_init_ex( + &gpio_ext_pc0, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C3); + hal_gpio_init_ex( + &gpio_ext_pc1, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C3); + + LL_I2C_InitTypeDef I2C_InitStruct = {0}; + I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; + I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; + I2C_InitStruct.DigitalFilter = 0; + I2C_InitStruct.OwnAddress1 = 0; + I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; + I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; + I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100; + LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct); + + LL_I2C_EnableAutoEndMode(handle->bus->i2c); + LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK); + LL_I2C_DisableOwnAddress2(handle->bus->i2c); + LL_I2C_DisableGeneralCall(handle->bus->i2c); + LL_I2C_EnableClockStretching(handle->bus->i2c); + LL_I2C_Enable(handle->bus->i2c); + } else if(event == FuriHalI2cBusHandleEventDeactivate) { + LL_I2C_Disable(handle->bus->i2c); + hal_gpio_write(&gpio_ext_pc0, 1); + hal_gpio_write(&gpio_ext_pc1, 1); + hal_gpio_init_ex(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + hal_gpio_init_ex(&gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + } +} + +FuriHalI2cBusHandle furi_hal_i2c_handle_external = { + .bus = &furi_hal_i2c_bus_external, + .callback = furi_hal_i2c_bus_handle_external_event, +}; diff --git a/bootloader/targets/f6/furi-hal/furi-hal-i2c-config.h b/bootloader/targets/f6/furi-hal/furi-hal-i2c-config.h new file mode 100644 index 00000000..2094dca3 --- /dev/null +++ b/bootloader/targets/f6/furi-hal/furi-hal-i2c-config.h @@ -0,0 +1,31 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Internal(power) i2c bus, I2C1, under reset when not used */ +extern FuriHalI2cBus furi_hal_i2c_bus_power; + +/** External i2c bus, I2C3, under reset when not used */ +extern FuriHalI2cBus furi_hal_i2c_bus_external; + +/** Handle for internal(power) i2c bus + * Bus: furi_hal_i2c_bus_external + * Pins: PA9(SCL) / PA10(SDA), float on release + * Params: 400khz + */ +extern FuriHalI2cBusHandle furi_hal_i2c_handle_power; + +/** Handle for external i2c bus + * Bus: furi_hal_i2c_bus_external + * Pins: PC0(SCL) / PC1(SDA), float on release + * Params: 100khz + */ +extern FuriHalI2cBusHandle furi_hal_i2c_handle_external; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/bootloader/targets/f6/furi-hal/furi-hal-i2c-types.h b/bootloader/targets/f6/furi-hal/furi-hal-i2c-types.h new file mode 100644 index 00000000..0f2b735e --- /dev/null +++ b/bootloader/targets/f6/furi-hal/furi-hal-i2c-types.h @@ -0,0 +1,51 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct FuriHalI2cBus FuriHalI2cBus; +typedef struct FuriHalI2cBusHandle FuriHalI2cBusHandle; + +/** FuriHal i2c bus states */ +typedef enum { + FuriHalI2cBusEventInit, /**< Bus initialization event, called on system start */ + FuriHalI2cBusEventDeinit, /**< Bus deinitialization event, called on system stop */ + FuriHalI2cBusEventLock, /**< Bus lock event, called before activation */ + FuriHalI2cBusEventUnlock, /**< Bus unlock event, called after deactivation */ + FuriHalI2cBusEventActivate, /**< Bus activation event, called before handle activation */ + FuriHalI2cBusEventDeactivate, /**< Bus deactivation event, called after handle deactivation */ +} FuriHalI2cBusEvent; + +/** FuriHal i2c bus event callback */ +typedef void (*FuriHalI2cBusEventCallback)(FuriHalI2cBus* bus, FuriHalI2cBusEvent event); + +/** FuriHal i2c bus */ +struct FuriHalI2cBus { + I2C_TypeDef* i2c; + FuriHalI2cBusHandle* current_handle; + FuriHalI2cBusEventCallback callback; +}; + +/** FuriHal i2c handle states */ +typedef enum { + FuriHalI2cBusHandleEventActivate, /**< Handle activate: connect gpio and apply bus config */ + FuriHalI2cBusHandleEventDeactivate, /**< Handle deactivate: disconnect gpio and reset bus config */ +} FuriHalI2cBusHandleEvent; + +/** FuriHal i2c handle event callback */ +typedef void (*FuriHalI2cBusHandleEventCallback)( + FuriHalI2cBusHandle* handle, + FuriHalI2cBusHandleEvent event); + +/** FuriHal i2c handle */ +struct FuriHalI2cBusHandle { + FuriHalI2cBus* bus; + FuriHalI2cBusHandleEventCallback callback; +}; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/bootloader/targets/f6/furi-hal/furi-hal-i2c.c b/bootloader/targets/f6/furi-hal/furi-hal-i2c.c index c40a70af..f276ff75 100644 --- a/bootloader/targets/f6/furi-hal/furi-hal-i2c.c +++ b/bootloader/targets/f6/furi-hal/furi-hal-i2c.c @@ -1,66 +1,64 @@ #include +#include -#include #include -#include #include #include +#include + void furi_hal_i2c_init() { - LL_I2C_InitTypeDef I2C_InitStruct = {0}; - LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + furi_hal_i2c_bus_power.callback(&furi_hal_i2c_bus_power, FuriHalI2cBusEventInit); +} - LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); +void furi_hal_i2c_acquire(FuriHalI2cBusHandle* handle) { + handle->bus->callback(handle->bus, FuriHalI2cBusEventLock); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); - GPIO_InitStruct.Pin = POWER_I2C_SCL_Pin | POWER_I2C_SDA_Pin; - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; - GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; - GPIO_InitStruct.Alternate = LL_GPIO_AF_4; - LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + assert(handle->bus->current_handle == NULL); - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); + handle->bus->current_handle = handle; - I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; - I2C_InitStruct.Timing = POWER_I2C_TIMINGS; - I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; - I2C_InitStruct.DigitalFilter = 0; - I2C_InitStruct.OwnAddress1 = 0; - I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; - I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; - LL_I2C_Init(I2C1, &I2C_InitStruct); - LL_I2C_EnableAutoEndMode(I2C1); - LL_I2C_SetOwnAddress2(I2C1, 0, LL_I2C_OWNADDRESS2_NOMASK); - LL_I2C_DisableOwnAddress2(I2C1); - LL_I2C_DisableGeneralCall(I2C1); - LL_I2C_EnableClockStretching(I2C1); + handle->bus->callback(handle->bus, FuriHalI2cBusEventActivate); + + handle->callback(handle, FuriHalI2cBusHandleEventActivate); +} + +void furi_hal_i2c_release(FuriHalI2cBusHandle* handle) { + assert(handle->bus->current_handle == handle); + + handle->callback(handle, FuriHalI2cBusHandleEventDeactivate); + + handle->bus->callback(handle->bus, FuriHalI2cBusEventDeactivate); + + handle->bus->current_handle = NULL; + + handle->bus->callback(handle->bus, FuriHalI2cBusEventUnlock); } bool furi_hal_i2c_tx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, uint8_t address, const uint8_t* data, uint8_t size, uint32_t timeout) { + assert(handle->bus->current_handle == handle); uint32_t time_left = timeout; bool ret = true; - while(LL_I2C_IsActiveFlag_BUSY(instance)) + while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) ; LL_I2C_HandleTransfer( - instance, + handle->bus->i2c, address, LL_I2C_ADDRSLAVE_7BIT, size, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE); - while(!LL_I2C_IsActiveFlag_STOP(instance) || size > 0) { - if(LL_I2C_IsActiveFlag_TXIS(instance)) { - LL_I2C_TransmitData8(instance, (*data)); + while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c) || size > 0) { + if(LL_I2C_IsActiveFlag_TXIS(handle->bus->i2c)) { + LL_I2C_TransmitData8(handle->bus->i2c, (*data)); data++; size--; time_left = timeout; @@ -74,34 +72,35 @@ bool furi_hal_i2c_tx( } } - LL_I2C_ClearFlag_STOP(instance); + LL_I2C_ClearFlag_STOP(handle->bus->i2c); return ret; } bool furi_hal_i2c_rx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, uint8_t address, uint8_t* data, uint8_t size, uint32_t timeout) { + assert(handle->bus->current_handle == handle); uint32_t time_left = timeout; bool ret = true; - while(LL_I2C_IsActiveFlag_BUSY(instance)) + while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) ; LL_I2C_HandleTransfer( - instance, + handle->bus->i2c, address, LL_I2C_ADDRSLAVE_7BIT, size, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ); - while(!LL_I2C_IsActiveFlag_STOP(instance) || size > 0) { - if(LL_I2C_IsActiveFlag_RXNE(instance)) { - *data = LL_I2C_ReceiveData8(instance); + while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c) || size > 0) { + if(LL_I2C_IsActiveFlag_RXNE(handle->bus->i2c)) { + *data = LL_I2C_ReceiveData8(handle->bus->i2c); data++; size--; time_left = timeout; @@ -115,21 +114,21 @@ bool furi_hal_i2c_rx( } } - LL_I2C_ClearFlag_STOP(instance); + LL_I2C_ClearFlag_STOP(handle->bus->i2c); return ret; } bool furi_hal_i2c_trx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, uint8_t address, const uint8_t* tx_data, uint8_t tx_size, uint8_t* rx_data, uint8_t rx_size, uint32_t timeout) { - if(furi_hal_i2c_tx(instance, address, tx_data, tx_size, timeout) && - furi_hal_i2c_rx(instance, address, rx_data, rx_size, timeout)) { + if(furi_hal_i2c_tx(handle, address, tx_data, tx_size, timeout) && + furi_hal_i2c_rx(handle, address, rx_data, rx_size, timeout)) { return true; } else { return false; diff --git a/bootloader/targets/f6/furi-hal/furi-hal-i2c.h b/bootloader/targets/f6/furi-hal/furi-hal-i2c.h index 5db562e0..7ef1db44 100644 --- a/bootloader/targets/f6/furi-hal/furi-hal-i2c.h +++ b/bootloader/targets/f6/furi-hal/furi-hal-i2c.h @@ -1,31 +1,82 @@ +/** + * @file furi-hal-i2c.h + * I2C HAL API + */ + #pragma once #include #include -#include +#include #ifdef __cplusplus extern "C" { #endif +/** Init I2C + */ void furi_hal_i2c_init(); +/** Acquire i2c bus handle + * + * @return Instance of FuriHalI2cBus + */ +void furi_hal_i2c_acquire(FuriHalI2cBusHandle* handle); + +/** Release i2c bus handle + * + * @param bus instance of FuriHalI2cBus aquired in `furi_hal_i2c_acquire` + */ +void furi_hal_i2c_release(FuriHalI2cBusHandle* handle); + +/** Perform I2C tx transfer + * + * @param instance I2C_TypeDef instance + * @param address I2C slave address + * @param data pointer to data buffer + * @param size size of data buffer + * @param timeout timeout in ticks + * + * @return true on successful transfer, false otherwise + */ bool furi_hal_i2c_tx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, const uint8_t address, const uint8_t* data, const uint8_t size, uint32_t timeout); +/** Perform I2C rx transfer + * + * @param instance I2C_TypeDef instance + * @param address I2C slave address + * @param data pointer to data buffer + * @param size size of data buffer + * @param timeout timeout in ticks + * + * @return true on successful transfer, false otherwise + */ bool furi_hal_i2c_rx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, const uint8_t address, uint8_t* data, const uint8_t size, uint32_t timeout); +/** Perform I2C tx and rx transfers + * + * @param instance I2C_TypeDef instance + * @param address I2C slave address + * @param tx_data pointer to tx data buffer + * @param tx_size size of tx data buffer + * @param rx_data pointer to rx data buffer + * @param rx_size size of rx data buffer + * @param timeout timeout in ticks + * + * @return true on successful transfer, false otherwise + */ bool furi_hal_i2c_trx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, const uint8_t address, const uint8_t* tx_data, const uint8_t tx_size, @@ -33,11 +84,6 @@ bool furi_hal_i2c_trx( const uint8_t rx_size, uint32_t timeout); -#define with_furi_hal_i2c(type, pointer, function_body) \ - { \ - *pointer = ({ type __fn__ function_body __fn__; })(); \ - } - #ifdef __cplusplus } #endif diff --git a/bootloader/targets/f6/furi-hal/furi-hal-light.c b/bootloader/targets/f6/furi-hal/furi-hal-light.c index d5f54f6d..15a69f09 100644 --- a/bootloader/targets/f6/furi-hal/furi-hal-light.c +++ b/bootloader/targets/f6/furi-hal/furi-hal-light.c @@ -7,37 +7,43 @@ #define LED_CURRENT_WHITE 150 void furi_hal_light_init() { - lp5562_reset(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); - lp5562_set_channel_current(LP5562ChannelRed, LED_CURRENT_RED); - lp5562_set_channel_current(LP5562ChannelGreen, LED_CURRENT_GREEN); - lp5562_set_channel_current(LP5562ChannelBlue, LED_CURRENT_BLUE); - lp5562_set_channel_current(LP5562ChannelWhite, LED_CURRENT_WHITE); + lp5562_reset(&furi_hal_i2c_handle_power); - lp5562_set_channel_value(LP5562ChannelRed, 0x00); - lp5562_set_channel_value(LP5562ChannelGreen, 0x00); - lp5562_set_channel_value(LP5562ChannelBlue, 0x00); - lp5562_set_channel_value(LP5562ChannelWhite, 0x00); + lp5562_set_channel_current(&furi_hal_i2c_handle_power, LP5562ChannelRed, LED_CURRENT_RED); + lp5562_set_channel_current(&furi_hal_i2c_handle_power, LP5562ChannelGreen, LED_CURRENT_GREEN); + lp5562_set_channel_current(&furi_hal_i2c_handle_power, LP5562ChannelBlue, LED_CURRENT_BLUE); + lp5562_set_channel_current(&furi_hal_i2c_handle_power, LP5562ChannelWhite, LED_CURRENT_WHITE); - lp5562_enable(); - lp5562_configure(); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelRed, 0x00); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelGreen, 0x00); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelBlue, 0x00); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelWhite, 0x00); + + lp5562_enable(&furi_hal_i2c_handle_power); + lp5562_configure(&furi_hal_i2c_handle_power); + + furi_hal_i2c_release(&furi_hal_i2c_handle_power); } void furi_hal_light_set(Light light, uint8_t value) { + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); switch(light) { case LightRed: - lp5562_set_channel_value(LP5562ChannelRed, value); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelRed, value); break; case LightGreen: - lp5562_set_channel_value(LP5562ChannelGreen, value); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelGreen, value); break; case LightBlue: - lp5562_set_channel_value(LP5562ChannelBlue, value); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelBlue, value); break; case LightBacklight: - lp5562_set_channel_value(LP5562ChannelWhite, value); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelWhite, value); break; default: break; } + furi_hal_i2c_release(&furi_hal_i2c_handle_power); } \ No newline at end of file diff --git a/bootloader/targets/f6/furi-hal/furi-hal-resources.c b/bootloader/targets/f6/furi-hal/furi-hal-resources.c index 1260a485..3af9ba03 100644 --- a/bootloader/targets/f6/furi-hal/furi-hal-resources.c +++ b/bootloader/targets/f6/furi-hal/furi-hal-resources.c @@ -39,3 +39,6 @@ const GpioPin gpio_irda_tx = {.port = IR_TX_GPIO_Port, .pin = IR_TX_Pin}; const GpioPin gpio_usart_tx = {.port = USART1_TX_Port, .pin = USART1_TX_Pin}; const GpioPin gpio_usart_rx = {.port = USART1_RX_Port, .pin = USART1_RX_Pin}; + +const GpioPin gpio_i2c_power_sda = {.port = GPIOA, .pin = LL_GPIO_PIN_10}; +const GpioPin gpio_i2c_power_scl = {.port = GPIOA, .pin = LL_GPIO_PIN_9}; diff --git a/bootloader/targets/f6/furi-hal/furi-hal-resources.h b/bootloader/targets/f6/furi-hal/furi-hal-resources.h index 95bb4d0d..42b9b315 100644 --- a/bootloader/targets/f6/furi-hal/furi-hal-resources.h +++ b/bootloader/targets/f6/furi-hal/furi-hal-resources.h @@ -8,18 +8,6 @@ extern "C" { #endif -#define POWER_I2C_SCL_Pin LL_GPIO_PIN_9 -#define POWER_I2C_SCL_GPIO_Port GPIOA -#define POWER_I2C_SDA_Pin LL_GPIO_PIN_10 -#define POWER_I2C_SDA_GPIO_Port GPIOA - -#define POWER_I2C I2C1 -/* Timing register value is computed with the STM32CubeMX Tool, - * Fast Mode @100kHz with I2CCLK = 64 MHz, - * rise time = 0ns, fall time = 0ns - */ -#define POWER_I2C_TIMINGS 0x10707DBC - /* Input Keys */ typedef enum { InputKeyUp, @@ -77,6 +65,9 @@ extern const GpioPin gpio_irda_tx; extern const GpioPin gpio_usart_tx; extern const GpioPin gpio_usart_rx; +extern const GpioPin gpio_i2c_power_sda; +extern const GpioPin gpio_i2c_power_scl; + #ifdef __cplusplus } #endif diff --git a/bootloader/targets/f7/furi-hal/furi-hal-i2c-config.c b/bootloader/targets/f7/furi-hal/furi-hal-i2c-config.c new file mode 100644 index 00000000..afaab237 --- /dev/null +++ b/bootloader/targets/f7/furi-hal/furi-hal-i2c-config.c @@ -0,0 +1,149 @@ +#include "furi-hal-i2c-config.h" +#include +#include + +#include +#include + +/** Timing register value is computed with the STM32CubeMX Tool, + * Standard Mode @100kHz with I2CCLK = 64 MHz, + * rise time = 0ns, fall time = 0ns + */ +#define FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100 0x10707DBC + +/** Timing register value is computed with the STM32CubeMX Tool, + * Fast Mode @400kHz with I2CCLK = 64 MHz, + * rise time = 0ns, fall time = 0ns + */ +#define FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_400 0x00602173 + +static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { + if(event == FuriHalI2cBusEventInit) { + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); + LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); + bus->current_handle = NULL; + } else if(event == FuriHalI2cBusEventDeinit) { + } else if(event == FuriHalI2cBusEventLock) { + } else if(event == FuriHalI2cBusEventUnlock) { + } else if(event == FuriHalI2cBusEventActivate) { + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1); + } else if(event == FuriHalI2cBusEventDeactivate) { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); + } +} + +FuriHalI2cBus furi_hal_i2c_bus_power = { + .i2c = I2C1, + .current_handle = NULL, + .callback = furi_hal_i2c_bus_power_event, +}; + +static void furi_hal_i2c_bus_external_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { + if(event == FuriHalI2cBusEventActivate) { + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C3); + LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3); + } else if(event == FuriHalI2cBusEventDeactivate) { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3); + } +} + +FuriHalI2cBus furi_hal_i2c_bus_external = { + .i2c = I2C3, + .current_handle = NULL, + .callback = furi_hal_i2c_bus_external_event, +}; + +void furi_hal_i2c_bus_handle_power_event( + FuriHalI2cBusHandle* handle, + FuriHalI2cBusHandleEvent event) { + if(event == FuriHalI2cBusHandleEventActivate) { + LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + hal_gpio_init_ex( + &gpio_i2c_power_sda, + GpioModeAltFunctionOpenDrain, + GpioPullNo, + GpioSpeedLow, + GpioAltFn4I2C1); + hal_gpio_init_ex( + &gpio_i2c_power_scl, + GpioModeAltFunctionOpenDrain, + GpioPullNo, + GpioSpeedLow, + GpioAltFn4I2C1); + + LL_I2C_InitTypeDef I2C_InitStruct = {0}; + I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; + I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; + I2C_InitStruct.DigitalFilter = 0; + I2C_InitStruct.OwnAddress1 = 0; + I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; + I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; + if(furi_hal_version_get_hw_version() > 10) { + I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_400; + } else { + I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100; + } + LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct); + + LL_I2C_EnableAutoEndMode(handle->bus->i2c); + LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK); + LL_I2C_DisableOwnAddress2(handle->bus->i2c); + LL_I2C_DisableGeneralCall(handle->bus->i2c); + LL_I2C_EnableClockStretching(handle->bus->i2c); + LL_I2C_Enable(handle->bus->i2c); + } else if(event == FuriHalI2cBusHandleEventDeactivate) { + LL_I2C_Disable(handle->bus->i2c); + hal_gpio_write(&gpio_i2c_power_sda, 1); + hal_gpio_write(&gpio_i2c_power_scl, 1); + hal_gpio_init_ex( + &gpio_i2c_power_sda, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + hal_gpio_init_ex( + &gpio_i2c_power_scl, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + } +} + +FuriHalI2cBusHandle furi_hal_i2c_handle_power = { + .bus = &furi_hal_i2c_bus_power, + .callback = furi_hal_i2c_bus_handle_power_event, +}; + +void furi_hal_i2c_bus_handle_external_event( + FuriHalI2cBusHandle* handle, + FuriHalI2cBusHandleEvent event) { + if(event == FuriHalI2cBusHandleEventActivate) { + hal_gpio_init_ex( + &gpio_ext_pc0, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C3); + hal_gpio_init_ex( + &gpio_ext_pc1, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C3); + + LL_I2C_InitTypeDef I2C_InitStruct = {0}; + I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; + I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; + I2C_InitStruct.DigitalFilter = 0; + I2C_InitStruct.OwnAddress1 = 0; + I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; + I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; + I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100; + LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct); + + LL_I2C_EnableAutoEndMode(handle->bus->i2c); + LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK); + LL_I2C_DisableOwnAddress2(handle->bus->i2c); + LL_I2C_DisableGeneralCall(handle->bus->i2c); + LL_I2C_EnableClockStretching(handle->bus->i2c); + LL_I2C_Enable(handle->bus->i2c); + } else if(event == FuriHalI2cBusHandleEventDeactivate) { + LL_I2C_Disable(handle->bus->i2c); + hal_gpio_write(&gpio_ext_pc0, 1); + hal_gpio_write(&gpio_ext_pc1, 1); + hal_gpio_init_ex(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + hal_gpio_init_ex(&gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + } +} + +FuriHalI2cBusHandle furi_hal_i2c_handle_external = { + .bus = &furi_hal_i2c_bus_external, + .callback = furi_hal_i2c_bus_handle_external_event, +}; diff --git a/bootloader/targets/f7/furi-hal/furi-hal-i2c-config.h b/bootloader/targets/f7/furi-hal/furi-hal-i2c-config.h new file mode 100644 index 00000000..2094dca3 --- /dev/null +++ b/bootloader/targets/f7/furi-hal/furi-hal-i2c-config.h @@ -0,0 +1,31 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Internal(power) i2c bus, I2C1, under reset when not used */ +extern FuriHalI2cBus furi_hal_i2c_bus_power; + +/** External i2c bus, I2C3, under reset when not used */ +extern FuriHalI2cBus furi_hal_i2c_bus_external; + +/** Handle for internal(power) i2c bus + * Bus: furi_hal_i2c_bus_external + * Pins: PA9(SCL) / PA10(SDA), float on release + * Params: 400khz + */ +extern FuriHalI2cBusHandle furi_hal_i2c_handle_power; + +/** Handle for external i2c bus + * Bus: furi_hal_i2c_bus_external + * Pins: PC0(SCL) / PC1(SDA), float on release + * Params: 100khz + */ +extern FuriHalI2cBusHandle furi_hal_i2c_handle_external; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/bootloader/targets/f7/furi-hal/furi-hal-i2c-types.h b/bootloader/targets/f7/furi-hal/furi-hal-i2c-types.h new file mode 100644 index 00000000..0f2b735e --- /dev/null +++ b/bootloader/targets/f7/furi-hal/furi-hal-i2c-types.h @@ -0,0 +1,51 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct FuriHalI2cBus FuriHalI2cBus; +typedef struct FuriHalI2cBusHandle FuriHalI2cBusHandle; + +/** FuriHal i2c bus states */ +typedef enum { + FuriHalI2cBusEventInit, /**< Bus initialization event, called on system start */ + FuriHalI2cBusEventDeinit, /**< Bus deinitialization event, called on system stop */ + FuriHalI2cBusEventLock, /**< Bus lock event, called before activation */ + FuriHalI2cBusEventUnlock, /**< Bus unlock event, called after deactivation */ + FuriHalI2cBusEventActivate, /**< Bus activation event, called before handle activation */ + FuriHalI2cBusEventDeactivate, /**< Bus deactivation event, called after handle deactivation */ +} FuriHalI2cBusEvent; + +/** FuriHal i2c bus event callback */ +typedef void (*FuriHalI2cBusEventCallback)(FuriHalI2cBus* bus, FuriHalI2cBusEvent event); + +/** FuriHal i2c bus */ +struct FuriHalI2cBus { + I2C_TypeDef* i2c; + FuriHalI2cBusHandle* current_handle; + FuriHalI2cBusEventCallback callback; +}; + +/** FuriHal i2c handle states */ +typedef enum { + FuriHalI2cBusHandleEventActivate, /**< Handle activate: connect gpio and apply bus config */ + FuriHalI2cBusHandleEventDeactivate, /**< Handle deactivate: disconnect gpio and reset bus config */ +} FuriHalI2cBusHandleEvent; + +/** FuriHal i2c handle event callback */ +typedef void (*FuriHalI2cBusHandleEventCallback)( + FuriHalI2cBusHandle* handle, + FuriHalI2cBusHandleEvent event); + +/** FuriHal i2c handle */ +struct FuriHalI2cBusHandle { + FuriHalI2cBus* bus; + FuriHalI2cBusHandleEventCallback callback; +}; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/bootloader/targets/f7/furi-hal/furi-hal-i2c.c b/bootloader/targets/f7/furi-hal/furi-hal-i2c.c index c40a70af..f276ff75 100644 --- a/bootloader/targets/f7/furi-hal/furi-hal-i2c.c +++ b/bootloader/targets/f7/furi-hal/furi-hal-i2c.c @@ -1,66 +1,64 @@ #include +#include -#include #include -#include #include #include +#include + void furi_hal_i2c_init() { - LL_I2C_InitTypeDef I2C_InitStruct = {0}; - LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + furi_hal_i2c_bus_power.callback(&furi_hal_i2c_bus_power, FuriHalI2cBusEventInit); +} - LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); +void furi_hal_i2c_acquire(FuriHalI2cBusHandle* handle) { + handle->bus->callback(handle->bus, FuriHalI2cBusEventLock); - LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); - GPIO_InitStruct.Pin = POWER_I2C_SCL_Pin | POWER_I2C_SDA_Pin; - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; - GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; - GPIO_InitStruct.Alternate = LL_GPIO_AF_4; - LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + assert(handle->bus->current_handle == NULL); - LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); + handle->bus->current_handle = handle; - I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; - I2C_InitStruct.Timing = POWER_I2C_TIMINGS; - I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; - I2C_InitStruct.DigitalFilter = 0; - I2C_InitStruct.OwnAddress1 = 0; - I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; - I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; - LL_I2C_Init(I2C1, &I2C_InitStruct); - LL_I2C_EnableAutoEndMode(I2C1); - LL_I2C_SetOwnAddress2(I2C1, 0, LL_I2C_OWNADDRESS2_NOMASK); - LL_I2C_DisableOwnAddress2(I2C1); - LL_I2C_DisableGeneralCall(I2C1); - LL_I2C_EnableClockStretching(I2C1); + handle->bus->callback(handle->bus, FuriHalI2cBusEventActivate); + + handle->callback(handle, FuriHalI2cBusHandleEventActivate); +} + +void furi_hal_i2c_release(FuriHalI2cBusHandle* handle) { + assert(handle->bus->current_handle == handle); + + handle->callback(handle, FuriHalI2cBusHandleEventDeactivate); + + handle->bus->callback(handle->bus, FuriHalI2cBusEventDeactivate); + + handle->bus->current_handle = NULL; + + handle->bus->callback(handle->bus, FuriHalI2cBusEventUnlock); } bool furi_hal_i2c_tx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, uint8_t address, const uint8_t* data, uint8_t size, uint32_t timeout) { + assert(handle->bus->current_handle == handle); uint32_t time_left = timeout; bool ret = true; - while(LL_I2C_IsActiveFlag_BUSY(instance)) + while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) ; LL_I2C_HandleTransfer( - instance, + handle->bus->i2c, address, LL_I2C_ADDRSLAVE_7BIT, size, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE); - while(!LL_I2C_IsActiveFlag_STOP(instance) || size > 0) { - if(LL_I2C_IsActiveFlag_TXIS(instance)) { - LL_I2C_TransmitData8(instance, (*data)); + while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c) || size > 0) { + if(LL_I2C_IsActiveFlag_TXIS(handle->bus->i2c)) { + LL_I2C_TransmitData8(handle->bus->i2c, (*data)); data++; size--; time_left = timeout; @@ -74,34 +72,35 @@ bool furi_hal_i2c_tx( } } - LL_I2C_ClearFlag_STOP(instance); + LL_I2C_ClearFlag_STOP(handle->bus->i2c); return ret; } bool furi_hal_i2c_rx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, uint8_t address, uint8_t* data, uint8_t size, uint32_t timeout) { + assert(handle->bus->current_handle == handle); uint32_t time_left = timeout; bool ret = true; - while(LL_I2C_IsActiveFlag_BUSY(instance)) + while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) ; LL_I2C_HandleTransfer( - instance, + handle->bus->i2c, address, LL_I2C_ADDRSLAVE_7BIT, size, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ); - while(!LL_I2C_IsActiveFlag_STOP(instance) || size > 0) { - if(LL_I2C_IsActiveFlag_RXNE(instance)) { - *data = LL_I2C_ReceiveData8(instance); + while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c) || size > 0) { + if(LL_I2C_IsActiveFlag_RXNE(handle->bus->i2c)) { + *data = LL_I2C_ReceiveData8(handle->bus->i2c); data++; size--; time_left = timeout; @@ -115,21 +114,21 @@ bool furi_hal_i2c_rx( } } - LL_I2C_ClearFlag_STOP(instance); + LL_I2C_ClearFlag_STOP(handle->bus->i2c); return ret; } bool furi_hal_i2c_trx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, uint8_t address, const uint8_t* tx_data, uint8_t tx_size, uint8_t* rx_data, uint8_t rx_size, uint32_t timeout) { - if(furi_hal_i2c_tx(instance, address, tx_data, tx_size, timeout) && - furi_hal_i2c_rx(instance, address, rx_data, rx_size, timeout)) { + if(furi_hal_i2c_tx(handle, address, tx_data, tx_size, timeout) && + furi_hal_i2c_rx(handle, address, rx_data, rx_size, timeout)) { return true; } else { return false; diff --git a/bootloader/targets/f7/furi-hal/furi-hal-i2c.h b/bootloader/targets/f7/furi-hal/furi-hal-i2c.h index 5db562e0..7ef1db44 100644 --- a/bootloader/targets/f7/furi-hal/furi-hal-i2c.h +++ b/bootloader/targets/f7/furi-hal/furi-hal-i2c.h @@ -1,31 +1,82 @@ +/** + * @file furi-hal-i2c.h + * I2C HAL API + */ + #pragma once #include #include -#include +#include #ifdef __cplusplus extern "C" { #endif +/** Init I2C + */ void furi_hal_i2c_init(); +/** Acquire i2c bus handle + * + * @return Instance of FuriHalI2cBus + */ +void furi_hal_i2c_acquire(FuriHalI2cBusHandle* handle); + +/** Release i2c bus handle + * + * @param bus instance of FuriHalI2cBus aquired in `furi_hal_i2c_acquire` + */ +void furi_hal_i2c_release(FuriHalI2cBusHandle* handle); + +/** Perform I2C tx transfer + * + * @param instance I2C_TypeDef instance + * @param address I2C slave address + * @param data pointer to data buffer + * @param size size of data buffer + * @param timeout timeout in ticks + * + * @return true on successful transfer, false otherwise + */ bool furi_hal_i2c_tx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, const uint8_t address, const uint8_t* data, const uint8_t size, uint32_t timeout); +/** Perform I2C rx transfer + * + * @param instance I2C_TypeDef instance + * @param address I2C slave address + * @param data pointer to data buffer + * @param size size of data buffer + * @param timeout timeout in ticks + * + * @return true on successful transfer, false otherwise + */ bool furi_hal_i2c_rx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, const uint8_t address, uint8_t* data, const uint8_t size, uint32_t timeout); +/** Perform I2C tx and rx transfers + * + * @param instance I2C_TypeDef instance + * @param address I2C slave address + * @param tx_data pointer to tx data buffer + * @param tx_size size of tx data buffer + * @param rx_data pointer to rx data buffer + * @param rx_size size of rx data buffer + * @param timeout timeout in ticks + * + * @return true on successful transfer, false otherwise + */ bool furi_hal_i2c_trx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, const uint8_t address, const uint8_t* tx_data, const uint8_t tx_size, @@ -33,11 +84,6 @@ bool furi_hal_i2c_trx( const uint8_t rx_size, uint32_t timeout); -#define with_furi_hal_i2c(type, pointer, function_body) \ - { \ - *pointer = ({ type __fn__ function_body __fn__; })(); \ - } - #ifdef __cplusplus } #endif diff --git a/bootloader/targets/f7/furi-hal/furi-hal-light.c b/bootloader/targets/f7/furi-hal/furi-hal-light.c index d5f54f6d..15a69f09 100644 --- a/bootloader/targets/f7/furi-hal/furi-hal-light.c +++ b/bootloader/targets/f7/furi-hal/furi-hal-light.c @@ -7,37 +7,43 @@ #define LED_CURRENT_WHITE 150 void furi_hal_light_init() { - lp5562_reset(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); - lp5562_set_channel_current(LP5562ChannelRed, LED_CURRENT_RED); - lp5562_set_channel_current(LP5562ChannelGreen, LED_CURRENT_GREEN); - lp5562_set_channel_current(LP5562ChannelBlue, LED_CURRENT_BLUE); - lp5562_set_channel_current(LP5562ChannelWhite, LED_CURRENT_WHITE); + lp5562_reset(&furi_hal_i2c_handle_power); - lp5562_set_channel_value(LP5562ChannelRed, 0x00); - lp5562_set_channel_value(LP5562ChannelGreen, 0x00); - lp5562_set_channel_value(LP5562ChannelBlue, 0x00); - lp5562_set_channel_value(LP5562ChannelWhite, 0x00); + lp5562_set_channel_current(&furi_hal_i2c_handle_power, LP5562ChannelRed, LED_CURRENT_RED); + lp5562_set_channel_current(&furi_hal_i2c_handle_power, LP5562ChannelGreen, LED_CURRENT_GREEN); + lp5562_set_channel_current(&furi_hal_i2c_handle_power, LP5562ChannelBlue, LED_CURRENT_BLUE); + lp5562_set_channel_current(&furi_hal_i2c_handle_power, LP5562ChannelWhite, LED_CURRENT_WHITE); - lp5562_enable(); - lp5562_configure(); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelRed, 0x00); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelGreen, 0x00); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelBlue, 0x00); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelWhite, 0x00); + + lp5562_enable(&furi_hal_i2c_handle_power); + lp5562_configure(&furi_hal_i2c_handle_power); + + furi_hal_i2c_release(&furi_hal_i2c_handle_power); } void furi_hal_light_set(Light light, uint8_t value) { + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); switch(light) { case LightRed: - lp5562_set_channel_value(LP5562ChannelRed, value); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelRed, value); break; case LightGreen: - lp5562_set_channel_value(LP5562ChannelGreen, value); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelGreen, value); break; case LightBlue: - lp5562_set_channel_value(LP5562ChannelBlue, value); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelBlue, value); break; case LightBacklight: - lp5562_set_channel_value(LP5562ChannelWhite, value); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelWhite, value); break; default: break; } + furi_hal_i2c_release(&furi_hal_i2c_handle_power); } \ No newline at end of file diff --git a/bootloader/targets/f7/furi-hal/furi-hal-resources.c b/bootloader/targets/f7/furi-hal/furi-hal-resources.c index 1260a485..3af9ba03 100644 --- a/bootloader/targets/f7/furi-hal/furi-hal-resources.c +++ b/bootloader/targets/f7/furi-hal/furi-hal-resources.c @@ -39,3 +39,6 @@ const GpioPin gpio_irda_tx = {.port = IR_TX_GPIO_Port, .pin = IR_TX_Pin}; const GpioPin gpio_usart_tx = {.port = USART1_TX_Port, .pin = USART1_TX_Pin}; const GpioPin gpio_usart_rx = {.port = USART1_RX_Port, .pin = USART1_RX_Pin}; + +const GpioPin gpio_i2c_power_sda = {.port = GPIOA, .pin = LL_GPIO_PIN_10}; +const GpioPin gpio_i2c_power_scl = {.port = GPIOA, .pin = LL_GPIO_PIN_9}; diff --git a/bootloader/targets/f7/furi-hal/furi-hal-resources.h b/bootloader/targets/f7/furi-hal/furi-hal-resources.h index 95bb4d0d..42b9b315 100644 --- a/bootloader/targets/f7/furi-hal/furi-hal-resources.h +++ b/bootloader/targets/f7/furi-hal/furi-hal-resources.h @@ -8,18 +8,6 @@ extern "C" { #endif -#define POWER_I2C_SCL_Pin LL_GPIO_PIN_9 -#define POWER_I2C_SCL_GPIO_Port GPIOA -#define POWER_I2C_SDA_Pin LL_GPIO_PIN_10 -#define POWER_I2C_SDA_GPIO_Port GPIOA - -#define POWER_I2C I2C1 -/* Timing register value is computed with the STM32CubeMX Tool, - * Fast Mode @100kHz with I2CCLK = 64 MHz, - * rise time = 0ns, fall time = 0ns - */ -#define POWER_I2C_TIMINGS 0x10707DBC - /* Input Keys */ typedef enum { InputKeyUp, @@ -77,6 +65,9 @@ extern const GpioPin gpio_irda_tx; extern const GpioPin gpio_usart_tx; extern const GpioPin gpio_usart_rx; +extern const GpioPin gpio_i2c_power_sda; +extern const GpioPin gpio_i2c_power_scl; + #ifdef __cplusplus } #endif diff --git a/firmware/targets/f6/furi-hal/furi-hal-i2c-config.c b/firmware/targets/f6/furi-hal/furi-hal-i2c-config.c new file mode 100644 index 00000000..273d46b1 --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-i2c-config.c @@ -0,0 +1,133 @@ +#include "furi-hal-i2c-config.h" +#include +#include + +/** Timing register value is computed with the STM32CubeMX Tool, + * Standard Mode @100kHz with I2CCLK = 64 MHz, + * rise time = 0ns, fall time = 0ns + */ +#define FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100 0x10707DBC + +/** Timing register value is computed with the STM32CubeMX Tool, + * Fast Mode @400kHz with I2CCLK = 64 MHz, + * rise time = 0ns, fall time = 0ns + */ +#define FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_400 0x00602173 + +osMutexId_t furi_hal_i2c_bus_power_mutex = NULL; + +static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { + if (event == FuriHalI2cBusEventInit) { + furi_hal_i2c_bus_power_mutex = osMutexNew(NULL); + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); + LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); + bus->current_handle = NULL; + } else if (event == FuriHalI2cBusEventDeinit) { + osMutexDelete(furi_hal_i2c_bus_power_mutex); + } else if (event == FuriHalI2cBusEventLock) { + furi_check(osMutexAcquire(furi_hal_i2c_bus_power_mutex, osWaitForever) == osOK); + } else if (event == FuriHalI2cBusEventUnlock) { + furi_check(osMutexRelease(furi_hal_i2c_bus_power_mutex) == osOK); + } else if (event == FuriHalI2cBusEventActivate) { + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1); + } else if (event == FuriHalI2cBusEventDeactivate) { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); + } +} + +FuriHalI2cBus furi_hal_i2c_bus_power = { + .i2c=I2C1, + .callback=furi_hal_i2c_bus_power_event, +}; + +osMutexId_t furi_hal_i2c_bus_external_mutex = NULL; + +static void furi_hal_i2c_bus_external_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { + if (event == FuriHalI2cBusEventActivate) { + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C3); + LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3); + } else if (event == FuriHalI2cBusEventDeactivate) { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3); + } +} + +FuriHalI2cBus furi_hal_i2c_bus_external = { + .i2c=I2C3, + .callback=furi_hal_i2c_bus_external_event, +}; + +void furi_hal_i2c_bus_handle_power_event(FuriHalI2cBusHandle* handle, FuriHalI2cBusHandleEvent event) { + if (event == FuriHalI2cBusHandleEventActivate) { + hal_gpio_init_ex(&gpio_i2c_power_sda, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C1); + hal_gpio_init_ex(&gpio_i2c_power_scl, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C1); + + LL_I2C_InitTypeDef I2C_InitStruct = {0}; + I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; + I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; + I2C_InitStruct.DigitalFilter = 0; + I2C_InitStruct.OwnAddress1 = 0; + I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; + I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; + if (furi_hal_version_get_hw_version() > 10) { + I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_400; + } else { + I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100; + } + LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct); + + LL_I2C_EnableAutoEndMode(handle->bus->i2c); + LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK); + LL_I2C_DisableOwnAddress2(handle->bus->i2c); + LL_I2C_DisableGeneralCall(handle->bus->i2c); + LL_I2C_EnableClockStretching(handle->bus->i2c); + LL_I2C_Enable(handle->bus->i2c); + } else if (event == FuriHalI2cBusHandleEventDeactivate) { + LL_I2C_Disable(handle->bus->i2c); + hal_gpio_write(&gpio_i2c_power_sda, 1); + hal_gpio_write(&gpio_i2c_power_scl, 1); + hal_gpio_init_ex(&gpio_i2c_power_sda, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + hal_gpio_init_ex(&gpio_i2c_power_scl, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + } +} + +FuriHalI2cBusHandle furi_hal_i2c_handle_power = { + .bus = &furi_hal_i2c_bus_power, + .callback = furi_hal_i2c_bus_handle_power_event, +}; + +void furi_hal_i2c_bus_handle_external_event(FuriHalI2cBusHandle* handle, FuriHalI2cBusHandleEvent event) { + if (event == FuriHalI2cBusHandleEventActivate) { + hal_gpio_init_ex(&gpio_ext_pc0, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C3); + hal_gpio_init_ex(&gpio_ext_pc1, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C3); + + LL_I2C_InitTypeDef I2C_InitStruct = {0}; + I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; + I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; + I2C_InitStruct.DigitalFilter = 0; + I2C_InitStruct.OwnAddress1 = 0; + I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; + I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; + I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100; + LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct); + + LL_I2C_EnableAutoEndMode(handle->bus->i2c); + LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK); + LL_I2C_DisableOwnAddress2(handle->bus->i2c); + LL_I2C_DisableGeneralCall(handle->bus->i2c); + LL_I2C_EnableClockStretching(handle->bus->i2c); + LL_I2C_Enable(handle->bus->i2c); + } else if (event == FuriHalI2cBusHandleEventDeactivate) { + LL_I2C_Disable(handle->bus->i2c); + hal_gpio_write(&gpio_ext_pc0, 1); + hal_gpio_write(&gpio_ext_pc1, 1); + hal_gpio_init_ex(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + hal_gpio_init_ex(&gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + } +} + +FuriHalI2cBusHandle furi_hal_i2c_handle_external = { + .bus = &furi_hal_i2c_bus_external, + .callback = furi_hal_i2c_bus_handle_external_event, +}; diff --git a/firmware/targets/f6/furi-hal/furi-hal-i2c-config.h b/firmware/targets/f6/furi-hal/furi-hal-i2c-config.h new file mode 100644 index 00000000..2094dca3 --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-i2c-config.h @@ -0,0 +1,31 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Internal(power) i2c bus, I2C1, under reset when not used */ +extern FuriHalI2cBus furi_hal_i2c_bus_power; + +/** External i2c bus, I2C3, under reset when not used */ +extern FuriHalI2cBus furi_hal_i2c_bus_external; + +/** Handle for internal(power) i2c bus + * Bus: furi_hal_i2c_bus_external + * Pins: PA9(SCL) / PA10(SDA), float on release + * Params: 400khz + */ +extern FuriHalI2cBusHandle furi_hal_i2c_handle_power; + +/** Handle for external i2c bus + * Bus: furi_hal_i2c_bus_external + * Pins: PC0(SCL) / PC1(SDA), float on release + * Params: 100khz + */ +extern FuriHalI2cBusHandle furi_hal_i2c_handle_external; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/firmware/targets/f6/furi-hal/furi-hal-i2c-types.h b/firmware/targets/f6/furi-hal/furi-hal-i2c-types.h new file mode 100644 index 00000000..4f7aab91 --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-i2c-types.h @@ -0,0 +1,49 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct FuriHalI2cBus FuriHalI2cBus; +typedef struct FuriHalI2cBusHandle FuriHalI2cBusHandle; + +/** FuriHal i2c bus states */ +typedef enum { + FuriHalI2cBusEventInit, /**< Bus initialization event, called on system start */ + FuriHalI2cBusEventDeinit, /**< Bus deinitialization event, called on system stop */ + FuriHalI2cBusEventLock, /**< Bus lock event, called before activation */ + FuriHalI2cBusEventUnlock, /**< Bus unlock event, called after deactivation */ + FuriHalI2cBusEventActivate, /**< Bus activation event, called before handle activation */ + FuriHalI2cBusEventDeactivate, /**< Bus deactivation event, called after handle deactivation */ +} FuriHalI2cBusEvent; + +/** FuriHal i2c bus event callback */ +typedef void (*FuriHalI2cBusEventCallback)(FuriHalI2cBus* bus, FuriHalI2cBusEvent event); + +/** FuriHal i2c bus */ +struct FuriHalI2cBus { + I2C_TypeDef* i2c; + FuriHalI2cBusHandle* current_handle; + FuriHalI2cBusEventCallback callback; +}; + +/** FuriHal i2c handle states */ +typedef enum { + FuriHalI2cBusHandleEventActivate, /**< Handle activate: connect gpio and apply bus config */ + FuriHalI2cBusHandleEventDeactivate, /**< Handle deactivate: disconnect gpio and reset bus config */ +} FuriHalI2cBusHandleEvent; + +/** FuriHal i2c handle event callback */ +typedef void (*FuriHalI2cBusHandleEventCallback)(FuriHalI2cBusHandle* handle, FuriHalI2cBusHandleEvent event); + +/** FuriHal i2c handle */ +struct FuriHalI2cBusHandle { + FuriHalI2cBus* bus; + FuriHalI2cBusHandleEventCallback callback; +}; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/firmware/targets/f6/furi-hal/furi-hal-i2c.c b/firmware/targets/f6/furi-hal/furi-hal-i2c.c index b1ec4711..2fd5c5e3 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-i2c.c +++ b/firmware/targets/f6/furi-hal/furi-hal-i2c.c @@ -8,68 +8,62 @@ #define TAG "FuriHalI2C" -osMutexId_t furi_hal_i2c_mutex = NULL; - void furi_hal_i2c_init() { - furi_hal_i2c_mutex = osMutexNew(NULL); - furi_check(furi_hal_i2c_mutex); - - LL_I2C_InitTypeDef I2C_InitStruct = {0}; - LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; - - LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); - - GPIO_InitStruct.Pin = POWER_I2C_SCL_Pin | POWER_I2C_SDA_Pin; - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; - GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; - GPIO_InitStruct.Alternate = LL_GPIO_AF_4; - LL_GPIO_Init(GPIOA, &GPIO_InitStruct); - - I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; - I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; - I2C_InitStruct.DigitalFilter = 0; - I2C_InitStruct.OwnAddress1 = 0; - I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; - I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; - if (furi_hal_version_get_hw_version() > 10) { - I2C_InitStruct.Timing = POWER_I2C_TIMINGS_400; - } else { - I2C_InitStruct.Timing = POWER_I2C_TIMINGS_100; - } - LL_I2C_Init(POWER_I2C, &I2C_InitStruct); - LL_I2C_EnableAutoEndMode(POWER_I2C); - LL_I2C_SetOwnAddress2(POWER_I2C, 0, LL_I2C_OWNADDRESS2_NOMASK); - LL_I2C_DisableOwnAddress2(POWER_I2C); - LL_I2C_DisableGeneralCall(POWER_I2C); - LL_I2C_EnableClockStretching(POWER_I2C); + furi_hal_i2c_bus_power.callback(&furi_hal_i2c_bus_power, FuriHalI2cBusEventInit); + furi_hal_i2c_bus_external.callback(&furi_hal_i2c_bus_external, FuriHalI2cBusEventInit); FURI_LOG_I(TAG, "Init OK"); } +void furi_hal_i2c_acquire(FuriHalI2cBusHandle* handle) { + // Lock bus access + handle->bus->callback(handle->bus, FuriHalI2cBusEventLock); + // Ensuree that no active handle set + furi_check(handle->bus->current_handle == NULL); + // Set current handle + handle->bus->current_handle = handle; + // Activate bus + handle->bus->callback(handle->bus, FuriHalI2cBusEventActivate); + // Activate handle + handle->callback(handle, FuriHalI2cBusHandleEventActivate); +} + +void furi_hal_i2c_release(FuriHalI2cBusHandle* handle) { + // Ensure that current handle is our handle + furi_check(handle->bus->current_handle == handle); + // Deactivate handle + handle->callback(handle, FuriHalI2cBusHandleEventDeactivate); + // Deactivate bus + handle->bus->callback(handle->bus, FuriHalI2cBusEventDeactivate); + // Reset current handle + handle->bus->current_handle = NULL; + // Unlock bus + handle->bus->callback(handle->bus, FuriHalI2cBusEventUnlock); +} + bool furi_hal_i2c_tx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, uint8_t address, const uint8_t* data, uint8_t size, uint32_t timeout) { + furi_check(handle->bus->current_handle == handle); uint32_t time_left = timeout; bool ret = true; - while(LL_I2C_IsActiveFlag_BUSY(instance)) + while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) ; LL_I2C_HandleTransfer( - instance, + handle->bus->i2c, address, LL_I2C_ADDRSLAVE_7BIT, size, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE); - while(!LL_I2C_IsActiveFlag_STOP(instance) || size > 0) { - if(LL_I2C_IsActiveFlag_TXIS(instance)) { - LL_I2C_TransmitData8(instance, (*data)); + while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c) || size > 0) { + if(LL_I2C_IsActiveFlag_TXIS(handle->bus->i2c)) { + LL_I2C_TransmitData8(handle->bus->i2c, (*data)); data++; size--; time_left = timeout; @@ -83,34 +77,35 @@ bool furi_hal_i2c_tx( } } - LL_I2C_ClearFlag_STOP(instance); + LL_I2C_ClearFlag_STOP(handle->bus->i2c); return ret; } bool furi_hal_i2c_rx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, uint8_t address, uint8_t* data, uint8_t size, uint32_t timeout) { + furi_check(handle->bus->current_handle == handle); uint32_t time_left = timeout; bool ret = true; - while(LL_I2C_IsActiveFlag_BUSY(instance)) + while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) ; LL_I2C_HandleTransfer( - instance, + handle->bus->i2c, address, LL_I2C_ADDRSLAVE_7BIT, size, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ); - while(!LL_I2C_IsActiveFlag_STOP(instance) || size > 0) { - if(LL_I2C_IsActiveFlag_RXNE(instance)) { - *data = LL_I2C_ReceiveData8(instance); + while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c) || size > 0) { + if(LL_I2C_IsActiveFlag_RXNE(handle->bus->i2c)) { + *data = LL_I2C_ReceiveData8(handle->bus->i2c); data++; size--; time_left = timeout; @@ -124,31 +119,23 @@ bool furi_hal_i2c_rx( } } - LL_I2C_ClearFlag_STOP(instance); + LL_I2C_ClearFlag_STOP(handle->bus->i2c); return ret; } bool furi_hal_i2c_trx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, uint8_t address, const uint8_t* tx_data, uint8_t tx_size, uint8_t* rx_data, uint8_t rx_size, uint32_t timeout) { - if(furi_hal_i2c_tx(instance, address, tx_data, tx_size, timeout) && - furi_hal_i2c_rx(instance, address, rx_data, rx_size, timeout)) { + if(furi_hal_i2c_tx(handle, address, tx_data, tx_size, timeout) && + furi_hal_i2c_rx(handle, address, rx_data, rx_size, timeout)) { return true; } else { return false; } } - -void furi_hal_i2c_lock() { - furi_check(osMutexAcquire(furi_hal_i2c_mutex, osWaitForever) == osOK); -} - -void furi_hal_i2c_unlock() { - furi_check(osMutexRelease(furi_hal_i2c_mutex) == osOK); -} diff --git a/firmware/targets/f6/furi-hal/furi-hal-light.c b/firmware/targets/f6/furi-hal/furi-hal-light.c index ecf0d4f2..15a69f09 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-light.c +++ b/firmware/targets/f6/furi-hal/furi-hal-light.c @@ -1,46 +1,49 @@ #include #include -#define TAG "FuriHalLight" - -#define LED_CURRENT_RED 50 -#define LED_CURRENT_GREEN 50 -#define LED_CURRENT_BLUE 50 -#define LED_CURRENT_WHITE 150 +#define LED_CURRENT_RED 50 +#define LED_CURRENT_GREEN 50 +#define LED_CURRENT_BLUE 50 +#define LED_CURRENT_WHITE 150 void furi_hal_light_init() { - lp5562_reset(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); - lp5562_set_channel_current(LP5562ChannelRed, LED_CURRENT_RED); - lp5562_set_channel_current(LP5562ChannelGreen, LED_CURRENT_GREEN); - lp5562_set_channel_current(LP5562ChannelBlue, LED_CURRENT_BLUE); - lp5562_set_channel_current(LP5562ChannelWhite, LED_CURRENT_WHITE); + lp5562_reset(&furi_hal_i2c_handle_power); - lp5562_set_channel_value(LP5562ChannelRed, 0x00); - lp5562_set_channel_value(LP5562ChannelGreen, 0x00); - lp5562_set_channel_value(LP5562ChannelBlue, 0x00); - lp5562_set_channel_value(LP5562ChannelWhite, 0x00); + lp5562_set_channel_current(&furi_hal_i2c_handle_power, LP5562ChannelRed, LED_CURRENT_RED); + lp5562_set_channel_current(&furi_hal_i2c_handle_power, LP5562ChannelGreen, LED_CURRENT_GREEN); + lp5562_set_channel_current(&furi_hal_i2c_handle_power, LP5562ChannelBlue, LED_CURRENT_BLUE); + lp5562_set_channel_current(&furi_hal_i2c_handle_power, LP5562ChannelWhite, LED_CURRENT_WHITE); - lp5562_enable(); - lp5562_configure(); - FURI_LOG_I(TAG, "Init OK"); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelRed, 0x00); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelGreen, 0x00); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelBlue, 0x00); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelWhite, 0x00); + + lp5562_enable(&furi_hal_i2c_handle_power); + lp5562_configure(&furi_hal_i2c_handle_power); + + furi_hal_i2c_release(&furi_hal_i2c_handle_power); } void furi_hal_light_set(Light light, uint8_t value) { + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); switch(light) { - case LightRed: - lp5562_set_channel_value(LP5562ChannelRed, value); + case LightRed: + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelRed, value); break; - case LightGreen: - lp5562_set_channel_value(LP5562ChannelGreen, value); + case LightGreen: + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelGreen, value); break; - case LightBlue: - lp5562_set_channel_value(LP5562ChannelBlue, value); + case LightBlue: + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelBlue, value); break; - case LightBacklight: - lp5562_set_channel_value(LP5562ChannelWhite, value); + case LightBacklight: + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelWhite, value); break; - default: + default: break; } + furi_hal_i2c_release(&furi_hal_i2c_handle_power); } \ No newline at end of file diff --git a/firmware/targets/f6/furi-hal/furi-hal-power.c b/firmware/targets/f6/furi-hal/furi-hal-power.c index 870cbda6..ad333b5d 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-power.c +++ b/firmware/targets/f6/furi-hal/furi-hal-power.c @@ -74,8 +74,12 @@ void HAL_RCC_CSSCallback(void) { void furi_hal_power_init() { LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1); LL_PWR_SMPS_SetMode(LL_PWR_SMPS_STEP_DOWN); - bq27220_init(&cedv); - bq25896_init(); + + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + bq27220_init(&furi_hal_i2c_handle_power, &cedv); + bq25896_init(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + FURI_LOG_I(TAG, "Init OK"); } @@ -161,19 +165,30 @@ void furi_hal_power_sleep() { uint8_t furi_hal_power_get_pct() { - return bq27220_get_state_of_charge(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + uint8_t ret = bq27220_get_state_of_charge(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + return ret; } uint8_t furi_hal_power_get_bat_health_pct() { - return bq27220_get_state_of_health(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + uint8_t ret = bq27220_get_state_of_health(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + return ret; } bool furi_hal_power_is_charging() { - return bq25896_is_charging(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + bool ret = bq25896_is_charging(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + return ret; } void furi_hal_power_off() { - bq25896_poweroff(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + bq25896_poweroff(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); } void furi_hal_power_reset() { @@ -181,66 +196,102 @@ void furi_hal_power_reset() { } void furi_hal_power_enable_otg() { - bq25896_enable_otg(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + bq25896_enable_otg(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); } void furi_hal_power_disable_otg() { - bq25896_disable_otg(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + bq25896_disable_otg(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); } bool furi_hal_power_is_otg_enabled() { - return bq25896_is_otg_enabled(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + bool ret = bq25896_is_otg_enabled(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + return ret; } uint32_t furi_hal_power_get_battery_remaining_capacity() { - return bq27220_get_remaining_capacity(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + uint32_t ret = bq27220_get_remaining_capacity(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + return ret; } uint32_t furi_hal_power_get_battery_full_capacity() { - return bq27220_get_full_charge_capacity(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + uint32_t ret = bq27220_get_full_charge_capacity(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + return ret; } float furi_hal_power_get_battery_voltage(FuriHalPowerIC ic) { + float ret = 0.0f; + + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); if (ic == FuriHalPowerICCharger) { - return (float)bq25896_get_vbat_voltage() / 1000.0f; + ret = (float)bq25896_get_vbat_voltage(&furi_hal_i2c_handle_power) / 1000.0f; } else if (ic == FuriHalPowerICFuelGauge) { - return (float)bq27220_get_voltage() / 1000.0f; - } else { - return 0.0f; + ret = (float)bq27220_get_voltage(&furi_hal_i2c_handle_power) / 1000.0f; } + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + + return ret; } float furi_hal_power_get_battery_current(FuriHalPowerIC ic) { + float ret = 0.0f; + + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); if (ic == FuriHalPowerICCharger) { - return (float)bq25896_get_vbat_current() / 1000.0f; + ret = (float)bq25896_get_vbat_current(&furi_hal_i2c_handle_power) / 1000.0f; } else if (ic == FuriHalPowerICFuelGauge) { - return (float)bq27220_get_current() / 1000.0f; - } else { - return 0.0f; + ret = (float)bq27220_get_current(&furi_hal_i2c_handle_power) / 1000.0f; + } + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + + return ret; +} + +static float furi_hal_power_get_battery_temperature_internal(FuriHalPowerIC ic) { + float ret = 0.0f; + + if (ic == FuriHalPowerICCharger) { + // Linear approximation, +/- 5 C + ret = (71.0f - (float)bq25896_get_ntc_mpct(&furi_hal_i2c_handle_power)/1000) / 0.6f; + } else if (ic == FuriHalPowerICFuelGauge) { + ret = ((float)bq27220_get_temperature(&furi_hal_i2c_handle_power) - 2731.0f) / 10.0f; } + + return ret; } float furi_hal_power_get_battery_temperature(FuriHalPowerIC ic) { - if (ic == FuriHalPowerICCharger) { - // Linear approximation, +/- 5 C - return (71.0f - (float)bq25896_get_ntc_mpct()/1000) / 0.6f; - } else if (ic == FuriHalPowerICFuelGauge) { - return ((float)bq27220_get_temperature() - 2731.0f) / 10.0f; - } else { - return 0.0f; - } - + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + float ret = furi_hal_power_get_battery_temperature_internal(ic); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + + return ret; } float furi_hal_power_get_usb_voltage(){ - return (float)bq25896_get_vbus_voltage() / 1000.0f; + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + float ret = (float)bq25896_get_vbus_voltage(&furi_hal_i2c_handle_power) / 1000.0f; + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + return ret; } void furi_hal_power_dump_state() { BatteryStatus battery_status; OperationStatus operation_status; - if (bq27220_get_battery_status(&battery_status) == BQ27220_ERROR - || bq27220_get_operation_status(&operation_status) == BQ27220_ERROR) { + + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + + if (bq27220_get_battery_status(&furi_hal_i2c_handle_power, &battery_status) == BQ27220_ERROR + || bq27220_get_operation_status(&furi_hal_i2c_handle_power, &operation_status) == BQ27220_ERROR) { printf("Failed to get bq27220 status. Communication error.\r\n"); } else { printf( @@ -266,21 +317,23 @@ void furi_hal_power_dump_state() { // Voltage and current info printf( "bq27220: Full capacity: %dmAh, Design capacity: %dmAh, Remaining capacity: %dmAh, State of Charge: %d%%, State of health: %d%%\r\n", - bq27220_get_full_charge_capacity(), bq27220_get_design_capacity(), bq27220_get_remaining_capacity(), - bq27220_get_state_of_charge(), bq27220_get_state_of_health() + bq27220_get_full_charge_capacity(&furi_hal_i2c_handle_power), bq27220_get_design_capacity(&furi_hal_i2c_handle_power), bq27220_get_remaining_capacity(&furi_hal_i2c_handle_power), + bq27220_get_state_of_charge(&furi_hal_i2c_handle_power), bq27220_get_state_of_health(&furi_hal_i2c_handle_power) ); printf( "bq27220: Voltage: %dmV, Current: %dmA, Temperature: %dC\r\n", - bq27220_get_voltage(), bq27220_get_current(), (int)furi_hal_power_get_battery_temperature(FuriHalPowerICFuelGauge) + bq27220_get_voltage(&furi_hal_i2c_handle_power), bq27220_get_current(&furi_hal_i2c_handle_power), (int)furi_hal_power_get_battery_temperature_internal(FuriHalPowerICFuelGauge) ); } printf( "bq25896: VBUS: %d, VSYS: %d, VBAT: %d, Current: %d, NTC: %ldm%%\r\n", - bq25896_get_vbus_voltage(), bq25896_get_vsys_voltage(), - bq25896_get_vbat_voltage(), bq25896_get_vbat_current(), - bq25896_get_ntc_mpct() + bq25896_get_vbus_voltage(&furi_hal_i2c_handle_power), bq25896_get_vsys_voltage(&furi_hal_i2c_handle_power), + bq25896_get_vbat_voltage(&furi_hal_i2c_handle_power), bq25896_get_vbat_current(&furi_hal_i2c_handle_power), + bq25896_get_ntc_mpct(&furi_hal_i2c_handle_power) ); + + furi_hal_i2c_release(&furi_hal_i2c_handle_power); } void furi_hal_power_enable_external_3_3v(){ @@ -298,7 +351,9 @@ void furi_hal_power_suppress_charge_enter() { xTaskResumeAll(); if (disable_charging) { - bq25896_disable_charging(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + bq25896_disable_charging(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); } } @@ -309,6 +364,8 @@ void furi_hal_power_suppress_charge_exit() { xTaskResumeAll(); if (enable_charging) { - bq25896_enable_charging(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + bq25896_enable_charging(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); } } \ No newline at end of file diff --git a/firmware/targets/f6/furi-hal/furi-hal-resources.c b/firmware/targets/f6/furi-hal/furi-hal-resources.c index 6d7f8a0b..21f6f3fa 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-resources.c +++ b/firmware/targets/f6/furi-hal/furi-hal-resources.c @@ -54,3 +54,6 @@ const GpioPin gpio_irda_tx = {.port = IR_TX_GPIO_Port, .pin = IR_TX_Pin}; const GpioPin gpio_usart_tx = {.port = USART1_TX_Port, .pin = USART1_TX_Pin}; const GpioPin gpio_usart_rx = {.port = USART1_RX_Port, .pin = USART1_RX_Pin}; + +const GpioPin gpio_i2c_power_sda = {.port = GPIOA, .pin = LL_GPIO_PIN_10}; +const GpioPin gpio_i2c_power_scl = {.port = GPIOA, .pin = LL_GPIO_PIN_9}; diff --git a/firmware/targets/f6/furi-hal/furi-hal-resources.h b/firmware/targets/f6/furi-hal/furi-hal-resources.h index bec183ef..feec0451 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-resources.h +++ b/firmware/targets/f6/furi-hal/furi-hal-resources.h @@ -10,24 +10,6 @@ extern "C" { #endif -#define POWER_I2C_SCL_Pin LL_GPIO_PIN_9 -#define POWER_I2C_SCL_GPIO_Port GPIOA -#define POWER_I2C_SDA_Pin LL_GPIO_PIN_10 -#define POWER_I2C_SDA_GPIO_Port GPIOA - -#define POWER_I2C I2C1 -/** Timing register value is computed with the STM32CubeMX Tool, - * Standard Mode @100kHz with I2CCLK = 64 MHz, - * rise time = 0ns, fall time = 0ns - */ -#define POWER_I2C_TIMINGS_100 0x10707DBC - -/** Timing register value is computed with the STM32CubeMX Tool, - * Fast Mode @400kHz with I2CCLK = 64 MHz, - * rise time = 0ns, fall time = 0ns - */ -#define POWER_I2C_TIMINGS_400 0x00602173 - /* Input Related Constants */ #define INPUT_DEBOUNCE_TICKS 20 @@ -98,6 +80,9 @@ extern const GpioPin gpio_irda_tx; extern const GpioPin gpio_usart_tx; extern const GpioPin gpio_usart_rx; +extern const GpioPin gpio_i2c_power_sda; +extern const GpioPin gpio_i2c_power_scl; + #ifdef __cplusplus } diff --git a/firmware/targets/f6/furi-hal/furi-hal-vcp.c b/firmware/targets/f6/furi-hal/furi-hal-vcp.c index ce3cda49..05033817 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-vcp.c +++ b/firmware/targets/f6/furi-hal/furi-hal-vcp.c @@ -280,7 +280,7 @@ static void vcp_on_cdc_control_line(void* context, uint8_t state) { static void vcp_on_cdc_rx(void* context) { uint32_t ret = osThreadFlagsSet(furi_thread_get_thread_id(vcp->thread), VcpEvtRx); - furi_assert((ret & osFlagsError) == 0); + furi_check((ret & osFlagsError) == 0); } static void vcp_on_cdc_tx_complete(void* context) { diff --git a/firmware/targets/f7/furi-hal/furi-hal-i2c-config.c b/firmware/targets/f7/furi-hal/furi-hal-i2c-config.c new file mode 100644 index 00000000..273d46b1 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-i2c-config.c @@ -0,0 +1,133 @@ +#include "furi-hal-i2c-config.h" +#include +#include + +/** Timing register value is computed with the STM32CubeMX Tool, + * Standard Mode @100kHz with I2CCLK = 64 MHz, + * rise time = 0ns, fall time = 0ns + */ +#define FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100 0x10707DBC + +/** Timing register value is computed with the STM32CubeMX Tool, + * Fast Mode @400kHz with I2CCLK = 64 MHz, + * rise time = 0ns, fall time = 0ns + */ +#define FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_400 0x00602173 + +osMutexId_t furi_hal_i2c_bus_power_mutex = NULL; + +static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { + if (event == FuriHalI2cBusEventInit) { + furi_hal_i2c_bus_power_mutex = osMutexNew(NULL); + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); + LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); + bus->current_handle = NULL; + } else if (event == FuriHalI2cBusEventDeinit) { + osMutexDelete(furi_hal_i2c_bus_power_mutex); + } else if (event == FuriHalI2cBusEventLock) { + furi_check(osMutexAcquire(furi_hal_i2c_bus_power_mutex, osWaitForever) == osOK); + } else if (event == FuriHalI2cBusEventUnlock) { + furi_check(osMutexRelease(furi_hal_i2c_bus_power_mutex) == osOK); + } else if (event == FuriHalI2cBusEventActivate) { + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1); + } else if (event == FuriHalI2cBusEventDeactivate) { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); + } +} + +FuriHalI2cBus furi_hal_i2c_bus_power = { + .i2c=I2C1, + .callback=furi_hal_i2c_bus_power_event, +}; + +osMutexId_t furi_hal_i2c_bus_external_mutex = NULL; + +static void furi_hal_i2c_bus_external_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { + if (event == FuriHalI2cBusEventActivate) { + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C3); + LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1); + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3); + } else if (event == FuriHalI2cBusEventDeactivate) { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3); + } +} + +FuriHalI2cBus furi_hal_i2c_bus_external = { + .i2c=I2C3, + .callback=furi_hal_i2c_bus_external_event, +}; + +void furi_hal_i2c_bus_handle_power_event(FuriHalI2cBusHandle* handle, FuriHalI2cBusHandleEvent event) { + if (event == FuriHalI2cBusHandleEventActivate) { + hal_gpio_init_ex(&gpio_i2c_power_sda, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C1); + hal_gpio_init_ex(&gpio_i2c_power_scl, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C1); + + LL_I2C_InitTypeDef I2C_InitStruct = {0}; + I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; + I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; + I2C_InitStruct.DigitalFilter = 0; + I2C_InitStruct.OwnAddress1 = 0; + I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; + I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; + if (furi_hal_version_get_hw_version() > 10) { + I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_400; + } else { + I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100; + } + LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct); + + LL_I2C_EnableAutoEndMode(handle->bus->i2c); + LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK); + LL_I2C_DisableOwnAddress2(handle->bus->i2c); + LL_I2C_DisableGeneralCall(handle->bus->i2c); + LL_I2C_EnableClockStretching(handle->bus->i2c); + LL_I2C_Enable(handle->bus->i2c); + } else if (event == FuriHalI2cBusHandleEventDeactivate) { + LL_I2C_Disable(handle->bus->i2c); + hal_gpio_write(&gpio_i2c_power_sda, 1); + hal_gpio_write(&gpio_i2c_power_scl, 1); + hal_gpio_init_ex(&gpio_i2c_power_sda, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + hal_gpio_init_ex(&gpio_i2c_power_scl, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + } +} + +FuriHalI2cBusHandle furi_hal_i2c_handle_power = { + .bus = &furi_hal_i2c_bus_power, + .callback = furi_hal_i2c_bus_handle_power_event, +}; + +void furi_hal_i2c_bus_handle_external_event(FuriHalI2cBusHandle* handle, FuriHalI2cBusHandleEvent event) { + if (event == FuriHalI2cBusHandleEventActivate) { + hal_gpio_init_ex(&gpio_ext_pc0, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C3); + hal_gpio_init_ex(&gpio_ext_pc1, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C3); + + LL_I2C_InitTypeDef I2C_InitStruct = {0}; + I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; + I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; + I2C_InitStruct.DigitalFilter = 0; + I2C_InitStruct.OwnAddress1 = 0; + I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; + I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; + I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100; + LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct); + + LL_I2C_EnableAutoEndMode(handle->bus->i2c); + LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK); + LL_I2C_DisableOwnAddress2(handle->bus->i2c); + LL_I2C_DisableGeneralCall(handle->bus->i2c); + LL_I2C_EnableClockStretching(handle->bus->i2c); + LL_I2C_Enable(handle->bus->i2c); + } else if (event == FuriHalI2cBusHandleEventDeactivate) { + LL_I2C_Disable(handle->bus->i2c); + hal_gpio_write(&gpio_ext_pc0, 1); + hal_gpio_write(&gpio_ext_pc1, 1); + hal_gpio_init_ex(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + hal_gpio_init_ex(&gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + } +} + +FuriHalI2cBusHandle furi_hal_i2c_handle_external = { + .bus = &furi_hal_i2c_bus_external, + .callback = furi_hal_i2c_bus_handle_external_event, +}; diff --git a/firmware/targets/f7/furi-hal/furi-hal-i2c-config.h b/firmware/targets/f7/furi-hal/furi-hal-i2c-config.h new file mode 100644 index 00000000..2094dca3 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-i2c-config.h @@ -0,0 +1,31 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Internal(power) i2c bus, I2C1, under reset when not used */ +extern FuriHalI2cBus furi_hal_i2c_bus_power; + +/** External i2c bus, I2C3, under reset when not used */ +extern FuriHalI2cBus furi_hal_i2c_bus_external; + +/** Handle for internal(power) i2c bus + * Bus: furi_hal_i2c_bus_external + * Pins: PA9(SCL) / PA10(SDA), float on release + * Params: 400khz + */ +extern FuriHalI2cBusHandle furi_hal_i2c_handle_power; + +/** Handle for external i2c bus + * Bus: furi_hal_i2c_bus_external + * Pins: PC0(SCL) / PC1(SDA), float on release + * Params: 100khz + */ +extern FuriHalI2cBusHandle furi_hal_i2c_handle_external; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/firmware/targets/f7/furi-hal/furi-hal-i2c-types.h b/firmware/targets/f7/furi-hal/furi-hal-i2c-types.h new file mode 100644 index 00000000..4f7aab91 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-i2c-types.h @@ -0,0 +1,49 @@ +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct FuriHalI2cBus FuriHalI2cBus; +typedef struct FuriHalI2cBusHandle FuriHalI2cBusHandle; + +/** FuriHal i2c bus states */ +typedef enum { + FuriHalI2cBusEventInit, /**< Bus initialization event, called on system start */ + FuriHalI2cBusEventDeinit, /**< Bus deinitialization event, called on system stop */ + FuriHalI2cBusEventLock, /**< Bus lock event, called before activation */ + FuriHalI2cBusEventUnlock, /**< Bus unlock event, called after deactivation */ + FuriHalI2cBusEventActivate, /**< Bus activation event, called before handle activation */ + FuriHalI2cBusEventDeactivate, /**< Bus deactivation event, called after handle deactivation */ +} FuriHalI2cBusEvent; + +/** FuriHal i2c bus event callback */ +typedef void (*FuriHalI2cBusEventCallback)(FuriHalI2cBus* bus, FuriHalI2cBusEvent event); + +/** FuriHal i2c bus */ +struct FuriHalI2cBus { + I2C_TypeDef* i2c; + FuriHalI2cBusHandle* current_handle; + FuriHalI2cBusEventCallback callback; +}; + +/** FuriHal i2c handle states */ +typedef enum { + FuriHalI2cBusHandleEventActivate, /**< Handle activate: connect gpio and apply bus config */ + FuriHalI2cBusHandleEventDeactivate, /**< Handle deactivate: disconnect gpio and reset bus config */ +} FuriHalI2cBusHandleEvent; + +/** FuriHal i2c handle event callback */ +typedef void (*FuriHalI2cBusHandleEventCallback)(FuriHalI2cBusHandle* handle, FuriHalI2cBusHandleEvent event); + +/** FuriHal i2c handle */ +struct FuriHalI2cBusHandle { + FuriHalI2cBus* bus; + FuriHalI2cBusHandleEventCallback callback; +}; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/firmware/targets/f7/furi-hal/furi-hal-i2c.c b/firmware/targets/f7/furi-hal/furi-hal-i2c.c index b1ec4711..2fd5c5e3 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-i2c.c +++ b/firmware/targets/f7/furi-hal/furi-hal-i2c.c @@ -8,68 +8,62 @@ #define TAG "FuriHalI2C" -osMutexId_t furi_hal_i2c_mutex = NULL; - void furi_hal_i2c_init() { - furi_hal_i2c_mutex = osMutexNew(NULL); - furi_check(furi_hal_i2c_mutex); - - LL_I2C_InitTypeDef I2C_InitStruct = {0}; - LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; - - LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); - - GPIO_InitStruct.Pin = POWER_I2C_SCL_Pin | POWER_I2C_SDA_Pin; - GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; - GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN; - GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; - GPIO_InitStruct.Alternate = LL_GPIO_AF_4; - LL_GPIO_Init(GPIOA, &GPIO_InitStruct); - - I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C; - I2C_InitStruct.AnalogFilter = LL_I2C_ANALOGFILTER_ENABLE; - I2C_InitStruct.DigitalFilter = 0; - I2C_InitStruct.OwnAddress1 = 0; - I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK; - I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; - if (furi_hal_version_get_hw_version() > 10) { - I2C_InitStruct.Timing = POWER_I2C_TIMINGS_400; - } else { - I2C_InitStruct.Timing = POWER_I2C_TIMINGS_100; - } - LL_I2C_Init(POWER_I2C, &I2C_InitStruct); - LL_I2C_EnableAutoEndMode(POWER_I2C); - LL_I2C_SetOwnAddress2(POWER_I2C, 0, LL_I2C_OWNADDRESS2_NOMASK); - LL_I2C_DisableOwnAddress2(POWER_I2C); - LL_I2C_DisableGeneralCall(POWER_I2C); - LL_I2C_EnableClockStretching(POWER_I2C); + furi_hal_i2c_bus_power.callback(&furi_hal_i2c_bus_power, FuriHalI2cBusEventInit); + furi_hal_i2c_bus_external.callback(&furi_hal_i2c_bus_external, FuriHalI2cBusEventInit); FURI_LOG_I(TAG, "Init OK"); } +void furi_hal_i2c_acquire(FuriHalI2cBusHandle* handle) { + // Lock bus access + handle->bus->callback(handle->bus, FuriHalI2cBusEventLock); + // Ensuree that no active handle set + furi_check(handle->bus->current_handle == NULL); + // Set current handle + handle->bus->current_handle = handle; + // Activate bus + handle->bus->callback(handle->bus, FuriHalI2cBusEventActivate); + // Activate handle + handle->callback(handle, FuriHalI2cBusHandleEventActivate); +} + +void furi_hal_i2c_release(FuriHalI2cBusHandle* handle) { + // Ensure that current handle is our handle + furi_check(handle->bus->current_handle == handle); + // Deactivate handle + handle->callback(handle, FuriHalI2cBusHandleEventDeactivate); + // Deactivate bus + handle->bus->callback(handle->bus, FuriHalI2cBusEventDeactivate); + // Reset current handle + handle->bus->current_handle = NULL; + // Unlock bus + handle->bus->callback(handle->bus, FuriHalI2cBusEventUnlock); +} + bool furi_hal_i2c_tx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, uint8_t address, const uint8_t* data, uint8_t size, uint32_t timeout) { + furi_check(handle->bus->current_handle == handle); uint32_t time_left = timeout; bool ret = true; - while(LL_I2C_IsActiveFlag_BUSY(instance)) + while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) ; LL_I2C_HandleTransfer( - instance, + handle->bus->i2c, address, LL_I2C_ADDRSLAVE_7BIT, size, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE); - while(!LL_I2C_IsActiveFlag_STOP(instance) || size > 0) { - if(LL_I2C_IsActiveFlag_TXIS(instance)) { - LL_I2C_TransmitData8(instance, (*data)); + while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c) || size > 0) { + if(LL_I2C_IsActiveFlag_TXIS(handle->bus->i2c)) { + LL_I2C_TransmitData8(handle->bus->i2c, (*data)); data++; size--; time_left = timeout; @@ -83,34 +77,35 @@ bool furi_hal_i2c_tx( } } - LL_I2C_ClearFlag_STOP(instance); + LL_I2C_ClearFlag_STOP(handle->bus->i2c); return ret; } bool furi_hal_i2c_rx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, uint8_t address, uint8_t* data, uint8_t size, uint32_t timeout) { + furi_check(handle->bus->current_handle == handle); uint32_t time_left = timeout; bool ret = true; - while(LL_I2C_IsActiveFlag_BUSY(instance)) + while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) ; LL_I2C_HandleTransfer( - instance, + handle->bus->i2c, address, LL_I2C_ADDRSLAVE_7BIT, size, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ); - while(!LL_I2C_IsActiveFlag_STOP(instance) || size > 0) { - if(LL_I2C_IsActiveFlag_RXNE(instance)) { - *data = LL_I2C_ReceiveData8(instance); + while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c) || size > 0) { + if(LL_I2C_IsActiveFlag_RXNE(handle->bus->i2c)) { + *data = LL_I2C_ReceiveData8(handle->bus->i2c); data++; size--; time_left = timeout; @@ -124,31 +119,23 @@ bool furi_hal_i2c_rx( } } - LL_I2C_ClearFlag_STOP(instance); + LL_I2C_ClearFlag_STOP(handle->bus->i2c); return ret; } bool furi_hal_i2c_trx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, uint8_t address, const uint8_t* tx_data, uint8_t tx_size, uint8_t* rx_data, uint8_t rx_size, uint32_t timeout) { - if(furi_hal_i2c_tx(instance, address, tx_data, tx_size, timeout) && - furi_hal_i2c_rx(instance, address, rx_data, rx_size, timeout)) { + if(furi_hal_i2c_tx(handle, address, tx_data, tx_size, timeout) && + furi_hal_i2c_rx(handle, address, rx_data, rx_size, timeout)) { return true; } else { return false; } } - -void furi_hal_i2c_lock() { - furi_check(osMutexAcquire(furi_hal_i2c_mutex, osWaitForever) == osOK); -} - -void furi_hal_i2c_unlock() { - furi_check(osMutexRelease(furi_hal_i2c_mutex) == osOK); -} diff --git a/firmware/targets/f7/furi-hal/furi-hal-light.c b/firmware/targets/f7/furi-hal/furi-hal-light.c index ecf0d4f2..15a69f09 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-light.c +++ b/firmware/targets/f7/furi-hal/furi-hal-light.c @@ -1,46 +1,49 @@ #include #include -#define TAG "FuriHalLight" - -#define LED_CURRENT_RED 50 -#define LED_CURRENT_GREEN 50 -#define LED_CURRENT_BLUE 50 -#define LED_CURRENT_WHITE 150 +#define LED_CURRENT_RED 50 +#define LED_CURRENT_GREEN 50 +#define LED_CURRENT_BLUE 50 +#define LED_CURRENT_WHITE 150 void furi_hal_light_init() { - lp5562_reset(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); - lp5562_set_channel_current(LP5562ChannelRed, LED_CURRENT_RED); - lp5562_set_channel_current(LP5562ChannelGreen, LED_CURRENT_GREEN); - lp5562_set_channel_current(LP5562ChannelBlue, LED_CURRENT_BLUE); - lp5562_set_channel_current(LP5562ChannelWhite, LED_CURRENT_WHITE); + lp5562_reset(&furi_hal_i2c_handle_power); - lp5562_set_channel_value(LP5562ChannelRed, 0x00); - lp5562_set_channel_value(LP5562ChannelGreen, 0x00); - lp5562_set_channel_value(LP5562ChannelBlue, 0x00); - lp5562_set_channel_value(LP5562ChannelWhite, 0x00); + lp5562_set_channel_current(&furi_hal_i2c_handle_power, LP5562ChannelRed, LED_CURRENT_RED); + lp5562_set_channel_current(&furi_hal_i2c_handle_power, LP5562ChannelGreen, LED_CURRENT_GREEN); + lp5562_set_channel_current(&furi_hal_i2c_handle_power, LP5562ChannelBlue, LED_CURRENT_BLUE); + lp5562_set_channel_current(&furi_hal_i2c_handle_power, LP5562ChannelWhite, LED_CURRENT_WHITE); - lp5562_enable(); - lp5562_configure(); - FURI_LOG_I(TAG, "Init OK"); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelRed, 0x00); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelGreen, 0x00); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelBlue, 0x00); + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelWhite, 0x00); + + lp5562_enable(&furi_hal_i2c_handle_power); + lp5562_configure(&furi_hal_i2c_handle_power); + + furi_hal_i2c_release(&furi_hal_i2c_handle_power); } void furi_hal_light_set(Light light, uint8_t value) { + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); switch(light) { - case LightRed: - lp5562_set_channel_value(LP5562ChannelRed, value); + case LightRed: + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelRed, value); break; - case LightGreen: - lp5562_set_channel_value(LP5562ChannelGreen, value); + case LightGreen: + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelGreen, value); break; - case LightBlue: - lp5562_set_channel_value(LP5562ChannelBlue, value); + case LightBlue: + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelBlue, value); break; - case LightBacklight: - lp5562_set_channel_value(LP5562ChannelWhite, value); + case LightBacklight: + lp5562_set_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelWhite, value); break; - default: + default: break; } + furi_hal_i2c_release(&furi_hal_i2c_handle_power); } \ No newline at end of file diff --git a/firmware/targets/f7/furi-hal/furi-hal-power.c b/firmware/targets/f7/furi-hal/furi-hal-power.c index 870cbda6..ad333b5d 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-power.c +++ b/firmware/targets/f7/furi-hal/furi-hal-power.c @@ -74,8 +74,12 @@ void HAL_RCC_CSSCallback(void) { void furi_hal_power_init() { LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1); LL_PWR_SMPS_SetMode(LL_PWR_SMPS_STEP_DOWN); - bq27220_init(&cedv); - bq25896_init(); + + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + bq27220_init(&furi_hal_i2c_handle_power, &cedv); + bq25896_init(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + FURI_LOG_I(TAG, "Init OK"); } @@ -161,19 +165,30 @@ void furi_hal_power_sleep() { uint8_t furi_hal_power_get_pct() { - return bq27220_get_state_of_charge(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + uint8_t ret = bq27220_get_state_of_charge(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + return ret; } uint8_t furi_hal_power_get_bat_health_pct() { - return bq27220_get_state_of_health(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + uint8_t ret = bq27220_get_state_of_health(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + return ret; } bool furi_hal_power_is_charging() { - return bq25896_is_charging(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + bool ret = bq25896_is_charging(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + return ret; } void furi_hal_power_off() { - bq25896_poweroff(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + bq25896_poweroff(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); } void furi_hal_power_reset() { @@ -181,66 +196,102 @@ void furi_hal_power_reset() { } void furi_hal_power_enable_otg() { - bq25896_enable_otg(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + bq25896_enable_otg(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); } void furi_hal_power_disable_otg() { - bq25896_disable_otg(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + bq25896_disable_otg(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); } bool furi_hal_power_is_otg_enabled() { - return bq25896_is_otg_enabled(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + bool ret = bq25896_is_otg_enabled(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + return ret; } uint32_t furi_hal_power_get_battery_remaining_capacity() { - return bq27220_get_remaining_capacity(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + uint32_t ret = bq27220_get_remaining_capacity(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + return ret; } uint32_t furi_hal_power_get_battery_full_capacity() { - return bq27220_get_full_charge_capacity(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + uint32_t ret = bq27220_get_full_charge_capacity(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + return ret; } float furi_hal_power_get_battery_voltage(FuriHalPowerIC ic) { + float ret = 0.0f; + + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); if (ic == FuriHalPowerICCharger) { - return (float)bq25896_get_vbat_voltage() / 1000.0f; + ret = (float)bq25896_get_vbat_voltage(&furi_hal_i2c_handle_power) / 1000.0f; } else if (ic == FuriHalPowerICFuelGauge) { - return (float)bq27220_get_voltage() / 1000.0f; - } else { - return 0.0f; + ret = (float)bq27220_get_voltage(&furi_hal_i2c_handle_power) / 1000.0f; } + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + + return ret; } float furi_hal_power_get_battery_current(FuriHalPowerIC ic) { + float ret = 0.0f; + + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); if (ic == FuriHalPowerICCharger) { - return (float)bq25896_get_vbat_current() / 1000.0f; + ret = (float)bq25896_get_vbat_current(&furi_hal_i2c_handle_power) / 1000.0f; } else if (ic == FuriHalPowerICFuelGauge) { - return (float)bq27220_get_current() / 1000.0f; - } else { - return 0.0f; + ret = (float)bq27220_get_current(&furi_hal_i2c_handle_power) / 1000.0f; + } + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + + return ret; +} + +static float furi_hal_power_get_battery_temperature_internal(FuriHalPowerIC ic) { + float ret = 0.0f; + + if (ic == FuriHalPowerICCharger) { + // Linear approximation, +/- 5 C + ret = (71.0f - (float)bq25896_get_ntc_mpct(&furi_hal_i2c_handle_power)/1000) / 0.6f; + } else if (ic == FuriHalPowerICFuelGauge) { + ret = ((float)bq27220_get_temperature(&furi_hal_i2c_handle_power) - 2731.0f) / 10.0f; } + + return ret; } float furi_hal_power_get_battery_temperature(FuriHalPowerIC ic) { - if (ic == FuriHalPowerICCharger) { - // Linear approximation, +/- 5 C - return (71.0f - (float)bq25896_get_ntc_mpct()/1000) / 0.6f; - } else if (ic == FuriHalPowerICFuelGauge) { - return ((float)bq27220_get_temperature() - 2731.0f) / 10.0f; - } else { - return 0.0f; - } - + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + float ret = furi_hal_power_get_battery_temperature_internal(ic); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + + return ret; } float furi_hal_power_get_usb_voltage(){ - return (float)bq25896_get_vbus_voltage() / 1000.0f; + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + float ret = (float)bq25896_get_vbus_voltage(&furi_hal_i2c_handle_power) / 1000.0f; + furi_hal_i2c_release(&furi_hal_i2c_handle_power); + return ret; } void furi_hal_power_dump_state() { BatteryStatus battery_status; OperationStatus operation_status; - if (bq27220_get_battery_status(&battery_status) == BQ27220_ERROR - || bq27220_get_operation_status(&operation_status) == BQ27220_ERROR) { + + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + + if (bq27220_get_battery_status(&furi_hal_i2c_handle_power, &battery_status) == BQ27220_ERROR + || bq27220_get_operation_status(&furi_hal_i2c_handle_power, &operation_status) == BQ27220_ERROR) { printf("Failed to get bq27220 status. Communication error.\r\n"); } else { printf( @@ -266,21 +317,23 @@ void furi_hal_power_dump_state() { // Voltage and current info printf( "bq27220: Full capacity: %dmAh, Design capacity: %dmAh, Remaining capacity: %dmAh, State of Charge: %d%%, State of health: %d%%\r\n", - bq27220_get_full_charge_capacity(), bq27220_get_design_capacity(), bq27220_get_remaining_capacity(), - bq27220_get_state_of_charge(), bq27220_get_state_of_health() + bq27220_get_full_charge_capacity(&furi_hal_i2c_handle_power), bq27220_get_design_capacity(&furi_hal_i2c_handle_power), bq27220_get_remaining_capacity(&furi_hal_i2c_handle_power), + bq27220_get_state_of_charge(&furi_hal_i2c_handle_power), bq27220_get_state_of_health(&furi_hal_i2c_handle_power) ); printf( "bq27220: Voltage: %dmV, Current: %dmA, Temperature: %dC\r\n", - bq27220_get_voltage(), bq27220_get_current(), (int)furi_hal_power_get_battery_temperature(FuriHalPowerICFuelGauge) + bq27220_get_voltage(&furi_hal_i2c_handle_power), bq27220_get_current(&furi_hal_i2c_handle_power), (int)furi_hal_power_get_battery_temperature_internal(FuriHalPowerICFuelGauge) ); } printf( "bq25896: VBUS: %d, VSYS: %d, VBAT: %d, Current: %d, NTC: %ldm%%\r\n", - bq25896_get_vbus_voltage(), bq25896_get_vsys_voltage(), - bq25896_get_vbat_voltage(), bq25896_get_vbat_current(), - bq25896_get_ntc_mpct() + bq25896_get_vbus_voltage(&furi_hal_i2c_handle_power), bq25896_get_vsys_voltage(&furi_hal_i2c_handle_power), + bq25896_get_vbat_voltage(&furi_hal_i2c_handle_power), bq25896_get_vbat_current(&furi_hal_i2c_handle_power), + bq25896_get_ntc_mpct(&furi_hal_i2c_handle_power) ); + + furi_hal_i2c_release(&furi_hal_i2c_handle_power); } void furi_hal_power_enable_external_3_3v(){ @@ -298,7 +351,9 @@ void furi_hal_power_suppress_charge_enter() { xTaskResumeAll(); if (disable_charging) { - bq25896_disable_charging(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + bq25896_disable_charging(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); } } @@ -309,6 +364,8 @@ void furi_hal_power_suppress_charge_exit() { xTaskResumeAll(); if (enable_charging) { - bq25896_enable_charging(); + furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); + bq25896_enable_charging(&furi_hal_i2c_handle_power); + furi_hal_i2c_release(&furi_hal_i2c_handle_power); } } \ No newline at end of file diff --git a/firmware/targets/f7/furi-hal/furi-hal-resources.c b/firmware/targets/f7/furi-hal/furi-hal-resources.c index 52ea3cf7..3f7fe36c 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-resources.c +++ b/firmware/targets/f7/furi-hal/furi-hal-resources.c @@ -55,3 +55,6 @@ const GpioPin gpio_irda_tx = {.port = IR_TX_GPIO_Port, .pin = IR_TX_Pin}; const GpioPin gpio_usart_tx = {.port = USART1_TX_Port, .pin = USART1_TX_Pin}; const GpioPin gpio_usart_rx = {.port = USART1_RX_Port, .pin = USART1_RX_Pin}; + +const GpioPin gpio_i2c_power_sda = {.port = GPIOA, .pin = LL_GPIO_PIN_10}; +const GpioPin gpio_i2c_power_scl = {.port = GPIOA, .pin = LL_GPIO_PIN_9}; diff --git a/firmware/targets/f7/furi-hal/furi-hal-resources.h b/firmware/targets/f7/furi-hal/furi-hal-resources.h index 09af7532..aed61372 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-resources.h +++ b/firmware/targets/f7/furi-hal/furi-hal-resources.h @@ -10,24 +10,6 @@ extern "C" { #endif -#define POWER_I2C_SCL_Pin LL_GPIO_PIN_9 -#define POWER_I2C_SCL_GPIO_Port GPIOA -#define POWER_I2C_SDA_Pin LL_GPIO_PIN_10 -#define POWER_I2C_SDA_GPIO_Port GPIOA - -#define POWER_I2C I2C1 -/** Timing register value is computed with the STM32CubeMX Tool, - * Standard Mode @100kHz with I2CCLK = 64 MHz, - * rise time = 0ns, fall time = 0ns - */ -#define POWER_I2C_TIMINGS_100 0x10707DBC - -/** Timing register value is computed with the STM32CubeMX Tool, - * Fast Mode @400kHz with I2CCLK = 64 MHz, - * rise time = 0ns, fall time = 0ns - */ -#define POWER_I2C_TIMINGS_400 0x00602173 - /* Input Related Constants */ #define INPUT_DEBOUNCE_TICKS 20 @@ -99,6 +81,9 @@ extern const GpioPin gpio_irda_tx; extern const GpioPin gpio_usart_tx; extern const GpioPin gpio_usart_rx; +extern const GpioPin gpio_i2c_power_sda; +extern const GpioPin gpio_i2c_power_scl; + #ifdef __cplusplus } diff --git a/firmware/targets/f7/furi-hal/furi-hal-spi.h b/firmware/targets/f7/furi-hal/furi-hal-spi.h deleted file mode 100644 index 638e713a..00000000 --- a/firmware/targets/f7/furi-hal/furi-hal-spi.h +++ /dev/null @@ -1,108 +0,0 @@ -#pragma once -#include "main.h" -#include "furi-hal-spi-config.h" -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Init SPI API - */ -void furi_hal_spi_init(); - -/* Bus Level API */ - -/** Lock SPI bus - * Takes bus mutex, if used - */ -void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus); - -/** Unlock SPI bus - * Releases BUS mutex, if used - */ -void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus); - -/** - * Configure SPI bus - * @param bus - spi bus handler - * @param config - spi configuration structure - */ -void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config); - -/** SPI Receive - * @param bus - spi bus handler - * @param buffer - receive buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); - -/** SPI Transmit - * @param bus - spi bus handler - * @param buffer - transmit buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); - -/** SPI Transmit and Receive - * @param bus - spi bus handlere - * @param tx_buffer - device handle - * @param rx_buffer - device handle - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_bus_trx(const FuriHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout); - -/* Device Level API */ - -/** Reconfigure SPI bus for device - * @param device - device description - */ -void furi_hal_spi_device_configure(const FuriHalSpiDevice* device); - -/** Get Device handle - * And lock access to the corresponding SPI BUS - * @param device_id - device identifier - * @return device handle - */ -const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id); - -/** Return Device handle - * And unlock access to the corresponding SPI BUS - * @param device - device handle - */ -void furi_hal_spi_device_return(const FuriHalSpiDevice* device); - -/** SPI Recieve - * @param device - device handle - * @param buffer - receive buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_device_rx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout); - -/** SPI Transmit - * @param device - device handle - * @param buffer - transmit buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_device_tx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout); - -/** SPI Transmit and Receive - * @param device - device handle - * @param tx_buffer - device handle - * @param rx_buffer - device handle - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_device_trx(const FuriHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout); - - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/firmware/targets/f7/furi-hal/furi-hal-vcp.c b/firmware/targets/f7/furi-hal/furi-hal-vcp.c index ce3cda49..05033817 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-vcp.c +++ b/firmware/targets/f7/furi-hal/furi-hal-vcp.c @@ -280,7 +280,7 @@ static void vcp_on_cdc_control_line(void* context, uint8_t state) { static void vcp_on_cdc_rx(void* context) { uint32_t ret = osThreadFlagsSet(furi_thread_get_thread_id(vcp->thread), VcpEvtRx); - furi_assert((ret & osFlagsError) == 0); + furi_check((ret & osFlagsError) == 0); } static void vcp_on_cdc_tx_complete(void* context) { diff --git a/firmware/targets/furi-hal-include/furi-hal-i2c.h b/firmware/targets/furi-hal-include/furi-hal-i2c.h index db61aea8..7ef1db44 100644 --- a/firmware/targets/furi-hal-include/furi-hal-i2c.h +++ b/firmware/targets/furi-hal-include/furi-hal-i2c.h @@ -7,7 +7,7 @@ #include #include -#include +#include #ifdef __cplusplus extern "C" { @@ -17,18 +17,30 @@ extern "C" { */ void furi_hal_i2c_init(); +/** Acquire i2c bus handle + * + * @return Instance of FuriHalI2cBus + */ +void furi_hal_i2c_acquire(FuriHalI2cBusHandle* handle); + +/** Release i2c bus handle + * + * @param bus instance of FuriHalI2cBus aquired in `furi_hal_i2c_acquire` + */ +void furi_hal_i2c_release(FuriHalI2cBusHandle* handle); + /** Perform I2C tx transfer * * @param instance I2C_TypeDef instance * @param address I2C slave address * @param data pointer to data buffer * @param size size of data buffer - * @param timeout timeout in CPU ticks + * @param timeout timeout in ticks * * @return true on successful transfer, false otherwise */ bool furi_hal_i2c_tx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, const uint8_t address, const uint8_t* data, const uint8_t size, @@ -40,12 +52,12 @@ bool furi_hal_i2c_tx( * @param address I2C slave address * @param data pointer to data buffer * @param size size of data buffer - * @param timeout timeout in CPU ticks + * @param timeout timeout in ticks * * @return true on successful transfer, false otherwise */ bool furi_hal_i2c_rx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, const uint8_t address, uint8_t* data, const uint8_t size, @@ -59,12 +71,12 @@ bool furi_hal_i2c_rx( * @param tx_size size of tx data buffer * @param rx_data pointer to rx data buffer * @param rx_size size of rx data buffer - * @param timeout timeout in CPU ticks + * @param timeout timeout in ticks * * @return true on successful transfer, false otherwise */ bool furi_hal_i2c_trx( - I2C_TypeDef* instance, + FuriHalI2cBusHandle* handle, const uint8_t address, const uint8_t* tx_data, const uint8_t tx_size, @@ -72,30 +84,6 @@ bool furi_hal_i2c_trx( const uint8_t rx_size, uint32_t timeout); -/** Acquire I2C mutex - */ -void furi_hal_i2c_lock(); - -/** Release I2C mutex - */ -void furi_hal_i2c_unlock(); - -/** With clause for I2C peripheral - * - * @param type type of function_body - * @param pointer pointer to return of function_body - * @param function_body a (){} lambda declaration, executed with I2C mutex - * acquired - * - * @return Nothing - */ -#define with_furi_hal_i2c(type, pointer, function_body) \ - { \ - furi_hal_i2c_lock(); \ - *pointer = ({ type __fn__ function_body __fn__; })(); \ - furi_hal_i2c_unlock(); \ - } - #ifdef __cplusplus } #endif diff --git a/firmware/targets/f6/furi-hal/furi-hal-spi.h b/firmware/targets/furi-hal-include/furi-hal-spi.h similarity index 99% rename from firmware/targets/f6/furi-hal/furi-hal-spi.h rename to firmware/targets/furi-hal-include/furi-hal-spi.h index 638e713a..e42dcdc4 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-spi.h +++ b/firmware/targets/furi-hal-include/furi-hal-spi.h @@ -25,8 +25,7 @@ void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus); */ void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus); -/** - * Configure SPI bus +/** Configure SPI bus * @param bus - spi bus handler * @param config - spi configuration structure */ diff --git a/lib/drivers/bq25896.c b/lib/drivers/bq25896.c index 9062653b..3f923b97 100644 --- a/lib/drivers/bq25896.c +++ b/lib/drivers/bq25896.c @@ -1,7 +1,6 @@ #include "bq25896.h" #include "bq25896_reg.h" -#include #include uint8_t bit_reverse(uint8_t b) { @@ -11,29 +10,17 @@ uint8_t bit_reverse(uint8_t b) { return b; } -bool bq25896_read(uint8_t address, uint8_t* data, size_t size) { - bool ret; - with_furi_hal_i2c( - bool, &ret, () { - return furi_hal_i2c_trx( - POWER_I2C, BQ25896_ADDRESS, &address, 1, data, size, BQ25896_I2C_TIMEOUT); - }); - return ret; +bool bq25896_read(FuriHalI2cBusHandle* handle, uint8_t address, uint8_t* data, size_t size) { + return furi_hal_i2c_trx(handle, BQ25896_ADDRESS, &address, 1, data, size, BQ25896_I2C_TIMEOUT); } -bool bq25896_read_reg(uint8_t address, uint8_t* data) { - bq25896_read(address, data, 1); - return true; +bool bq25896_read_reg(FuriHalI2cBusHandle* handle, uint8_t address, uint8_t* data) { + return bq25896_read(handle, address, data, 1); } -bool bq25896_write_reg(uint8_t address, uint8_t* data) { +bool bq25896_write_reg(FuriHalI2cBusHandle* handle, uint8_t address, uint8_t* data) { uint8_t buffer[2] = {address, *data}; - bool ret; - with_furi_hal_i2c( - bool, &ret, () { - return furi_hal_i2c_tx(POWER_I2C, BQ25896_ADDRESS, buffer, 2, BQ25896_I2C_TIMEOUT); - }); - return ret; + return furi_hal_i2c_tx(handle, BQ25896_ADDRESS, buffer, 2, BQ25896_I2C_TIMEOUT); } typedef struct { @@ -62,62 +49,62 @@ typedef struct { static bq25896_regs_t bq25896_regs; -void bq25896_init() { +void bq25896_init(FuriHalI2cBusHandle* handle) { bq25896_regs.r14.REG_RST = 1; - bq25896_write_reg(0x14, (uint8_t*)&bq25896_regs.r14); + bq25896_write_reg(handle, 0x14, (uint8_t*)&bq25896_regs.r14); // Readout all registers - bq25896_read(0x00, (uint8_t*)&bq25896_regs, sizeof(bq25896_regs)); + bq25896_read(handle, 0x00, (uint8_t*)&bq25896_regs, sizeof(bq25896_regs)); // Poll ADC forever bq25896_regs.r02.CONV_START = 1; bq25896_regs.r02.CONV_RATE = 1; - bq25896_write_reg(0x02, (uint8_t*)&bq25896_regs.r02); + bq25896_write_reg(handle, 0x02, (uint8_t*)&bq25896_regs.r02); bq25896_regs.r07.WATCHDOG = WatchdogDisable; - bq25896_write_reg(0x07, (uint8_t*)&bq25896_regs.r07); + bq25896_write_reg(handle, 0x07, (uint8_t*)&bq25896_regs.r07); - bq25896_read(0x00, (uint8_t*)&bq25896_regs, sizeof(bq25896_regs)); + bq25896_read(handle, 0x00, (uint8_t*)&bq25896_regs, sizeof(bq25896_regs)); } -void bq25896_poweroff() { +void bq25896_poweroff(FuriHalI2cBusHandle* handle) { bq25896_regs.r09.BATFET_DIS = 1; - bq25896_write_reg(0x09, (uint8_t*)&bq25896_regs.r09); + bq25896_write_reg(handle, 0x09, (uint8_t*)&bq25896_regs.r09); } -bool bq25896_is_charging() { - bq25896_read(0x00, (uint8_t*)&bq25896_regs, sizeof(bq25896_regs)); - bq25896_read_reg(0x0B, (uint8_t*)&bq25896_regs.r0B); +bool bq25896_is_charging(FuriHalI2cBusHandle* handle) { + bq25896_read(handle, 0x00, (uint8_t*)&bq25896_regs, sizeof(bq25896_regs)); + bq25896_read_reg(handle, 0x0B, (uint8_t*)&bq25896_regs.r0B); return bq25896_regs.r0B.CHRG_STAT != ChrgStatNo; } -void bq25896_enable_charging() { +void bq25896_enable_charging(FuriHalI2cBusHandle* handle) { bq25896_regs.r03.CHG_CONFIG = 1; - bq25896_write_reg(0x03, (uint8_t*)&bq25896_regs.r03); + bq25896_write_reg(handle, 0x03, (uint8_t*)&bq25896_regs.r03); } -void bq25896_disable_charging() { +void bq25896_disable_charging(FuriHalI2cBusHandle* handle) { bq25896_regs.r03.CHG_CONFIG = 0; - bq25896_write_reg(0x03, (uint8_t*)&bq25896_regs.r03); + bq25896_write_reg(handle, 0x03, (uint8_t*)&bq25896_regs.r03); } -void bq25896_enable_otg() { +void bq25896_enable_otg(FuriHalI2cBusHandle* handle) { bq25896_regs.r03.OTG_CONFIG = 1; - bq25896_write_reg(0x03, (uint8_t*)&bq25896_regs.r03); + bq25896_write_reg(handle, 0x03, (uint8_t*)&bq25896_regs.r03); } -void bq25896_disable_otg() { +void bq25896_disable_otg(FuriHalI2cBusHandle* handle) { bq25896_regs.r03.OTG_CONFIG = 0; - bq25896_write_reg(0x03, (uint8_t*)&bq25896_regs.r03); + bq25896_write_reg(handle, 0x03, (uint8_t*)&bq25896_regs.r03); } -bool bq25896_is_otg_enabled() { - bq25896_read_reg(0x03, (uint8_t*)&bq25896_regs.r03); +bool bq25896_is_otg_enabled(FuriHalI2cBusHandle* handle) { + bq25896_read_reg(handle, 0x03, (uint8_t*)&bq25896_regs.r03); return bq25896_regs.r03.OTG_CONFIG; } -uint16_t bq25896_get_vbus_voltage() { - bq25896_read_reg(0x11, (uint8_t*)&bq25896_regs.r11); +uint16_t bq25896_get_vbus_voltage(FuriHalI2cBusHandle* handle) { + bq25896_read_reg(handle, 0x11, (uint8_t*)&bq25896_regs.r11); if(bq25896_regs.r11.VBUS_GD) { return (uint16_t)bq25896_regs.r11.VBUSV * 100 + 2600; } else { @@ -125,22 +112,22 @@ uint16_t bq25896_get_vbus_voltage() { } } -uint16_t bq25896_get_vsys_voltage() { - bq25896_read_reg(0x0F, (uint8_t*)&bq25896_regs.r0F); +uint16_t bq25896_get_vsys_voltage(FuriHalI2cBusHandle* handle) { + bq25896_read_reg(handle, 0x0F, (uint8_t*)&bq25896_regs.r0F); return (uint16_t)bq25896_regs.r0F.SYSV * 20 + 2304; } -uint16_t bq25896_get_vbat_voltage() { - bq25896_read_reg(0x0E, (uint8_t*)&bq25896_regs.r0E); +uint16_t bq25896_get_vbat_voltage(FuriHalI2cBusHandle* handle) { + bq25896_read_reg(handle, 0x0E, (uint8_t*)&bq25896_regs.r0E); return (uint16_t)bq25896_regs.r0E.BATV * 20 + 2304; } -uint16_t bq25896_get_vbat_current() { - bq25896_read_reg(0x12, (uint8_t*)&bq25896_regs.r12); +uint16_t bq25896_get_vbat_current(FuriHalI2cBusHandle* handle) { + bq25896_read_reg(handle, 0x12, (uint8_t*)&bq25896_regs.r12); return (uint16_t)bq25896_regs.r12.ICHGR * 50; } -uint32_t bq25896_get_ntc_mpct() { - bq25896_read_reg(0x10, (uint8_t*)&bq25896_regs.r10); +uint32_t bq25896_get_ntc_mpct(FuriHalI2cBusHandle* handle) { + bq25896_read_reg(handle, 0x10, (uint8_t*)&bq25896_regs.r10); return (uint32_t)bq25896_regs.r10.TSPCT * 465 + 21000; } diff --git a/lib/drivers/bq25896.h b/lib/drivers/bq25896.h index 03bf7ba2..c6c9a30b 100644 --- a/lib/drivers/bq25896.h +++ b/lib/drivers/bq25896.h @@ -2,42 +2,43 @@ #include #include +#include /** Initialize Driver */ -void bq25896_init(); +void bq25896_init(FuriHalI2cBusHandle* handle); /** Send device into shipping mode */ -void bq25896_poweroff(); +void bq25896_poweroff(FuriHalI2cBusHandle* handle); /** Is currently charging */ -bool bq25896_is_charging(); +bool bq25896_is_charging(FuriHalI2cBusHandle* handle); /** Enable charging */ -void bq25896_enable_charging(); +void bq25896_enable_charging(FuriHalI2cBusHandle* handle); /** Disable charging */ -void bq25896_disable_charging(); +void bq25896_disable_charging(FuriHalI2cBusHandle* handle); /** Enable otg */ -void bq25896_enable_otg(); +void bq25896_enable_otg(FuriHalI2cBusHandle* handle); /** Disable otg */ -void bq25896_disable_otg(); +void bq25896_disable_otg(FuriHalI2cBusHandle* handle); /** Is otg enabled */ -bool bq25896_is_otg_enabled(); +bool bq25896_is_otg_enabled(FuriHalI2cBusHandle* handle); /** Get VBUS Voltage in mV */ -uint16_t bq25896_get_vbus_voltage(); +uint16_t bq25896_get_vbus_voltage(FuriHalI2cBusHandle* handle); /** Get VSYS Voltage in mV */ -uint16_t bq25896_get_vsys_voltage(); +uint16_t bq25896_get_vsys_voltage(FuriHalI2cBusHandle* handle); /** Get VBAT Voltage in mV */ -uint16_t bq25896_get_vbat_voltage(); +uint16_t bq25896_get_vbat_voltage(FuriHalI2cBusHandle* handle); /** Get VBAT current in mA */ -uint16_t bq25896_get_vbat_current(); +uint16_t bq25896_get_vbat_current(FuriHalI2cBusHandle* handle); /** Get NTC voltage in mpct of REGN */ -uint32_t bq25896_get_ntc_mpct(); +uint32_t bq25896_get_ntc_mpct(FuriHalI2cBusHandle* handle); diff --git a/lib/drivers/bq27220.c b/lib/drivers/bq27220.c index 578e3849..8689db4a 100644 --- a/lib/drivers/bq27220.c +++ b/lib/drivers/bq27220.c @@ -1,37 +1,32 @@ #include "bq27220.h" #include "bq27220_reg.h" -#include #include +#include #include #define TAG "Gauge" -uint16_t bq27220_read_word(uint8_t address) { +uint16_t bq27220_read_word(FuriHalI2cBusHandle* handle, uint8_t address) { uint8_t buffer[2] = {address}; - uint16_t ret; - with_furi_hal_i2c( - uint16_t, &ret, () { - if(furi_hal_i2c_trx( - POWER_I2C, BQ27220_ADDRESS, buffer, 1, buffer, 2, BQ27220_I2C_TIMEOUT)) { - return *(uint16_t*)buffer; - } else { - return 0; - } - }); + uint16_t ret = 0; + + if(furi_hal_i2c_trx(handle, BQ27220_ADDRESS, buffer, 1, buffer, 2, BQ27220_I2C_TIMEOUT)) { + ret = *(uint16_t*)buffer; + } + return ret; } -bool bq27220_control(uint16_t control) { - bool ret; - with_furi_hal_i2c( - bool, &ret, () { - uint8_t buffer[3]; - buffer[0] = CommandControl; - buffer[1] = control & 0xFF; - buffer[2] = (control >> 8) & 0xFF; - return furi_hal_i2c_tx(POWER_I2C, BQ27220_ADDRESS, buffer, 3, BQ27220_I2C_TIMEOUT); - }); +bool bq27220_control(FuriHalI2cBusHandle* handle, uint16_t control) { + bool ret = false; + uint8_t buffer[3]; + + buffer[0] = CommandControl; + buffer[1] = control & 0xFF; + buffer[2] = (control >> 8) & 0xFF; + ret = furi_hal_i2c_tx(handle, BQ27220_ADDRESS, buffer, 3, BQ27220_I2C_TIMEOUT); + return ret; } @@ -43,75 +38,73 @@ uint8_t bq27220_get_checksum(uint8_t* data, uint16_t len) { return 0xFF - ret; } -bool bq27220_set_parameter_u16(uint16_t address, uint16_t value) { +bool bq27220_set_parameter_u16(FuriHalI2cBusHandle* handle, uint16_t address, uint16_t value) { bool ret; uint8_t buffer[5]; - with_furi_hal_i2c( - bool, &ret, () { - buffer[0] = CommandSelectSubclass; - buffer[1] = address & 0xFF; - buffer[2] = (address >> 8) & 0xFF; - buffer[3] = (value >> 8) & 0xFF; - buffer[4] = value & 0xFF; - return furi_hal_i2c_tx(POWER_I2C, BQ27220_ADDRESS, buffer, 5, BQ27220_I2C_TIMEOUT); - }); + + buffer[0] = CommandSelectSubclass; + buffer[1] = address & 0xFF; + buffer[2] = (address >> 8) & 0xFF; + buffer[3] = (value >> 8) & 0xFF; + buffer[4] = value & 0xFF; + ret = furi_hal_i2c_tx(handle, BQ27220_ADDRESS, buffer, 5, BQ27220_I2C_TIMEOUT); + delay_us(10000); + uint8_t checksum = bq27220_get_checksum(&buffer[1], 4); - with_furi_hal_i2c( - bool, &ret, () { - buffer[0] = CommandMACDataSum; - buffer[1] = checksum; - buffer[2] = 6; - return furi_hal_i2c_tx(POWER_I2C, BQ27220_ADDRESS, buffer, 3, BQ27220_I2C_TIMEOUT); - }); + buffer[0] = CommandMACDataSum; + buffer[1] = checksum; + buffer[2] = 6; + ret = furi_hal_i2c_tx(handle, BQ27220_ADDRESS, buffer, 3, BQ27220_I2C_TIMEOUT); + delay_us(10000); return ret; } -bool bq27220_init(const ParamCEDV* cedv) { +bool bq27220_init(FuriHalI2cBusHandle* handle, const ParamCEDV* cedv) { uint32_t timeout = 100; - uint16_t design_cap = bq27220_get_design_capacity(); + uint16_t design_cap = bq27220_get_design_capacity(handle); if(cedv->design_cap == design_cap) { FURI_LOG_I(TAG, "Skip battery profile update"); return true; } FURI_LOG_I(TAG, "Start updating battery profile"); OperationStatus status = {}; - if(!bq27220_control(Control_ENTER_CFG_UPDATE)) { + if(!bq27220_control(handle, Control_ENTER_CFG_UPDATE)) { FURI_LOG_E(TAG, "Can't configure update"); return false; }; while((status.CFGUPDATE != 1) && (timeout-- > 0)) { - bq27220_get_operation_status(&status); + bq27220_get_operation_status(handle, &status); } - bq27220_set_parameter_u16(AddressGaugingConfig, cedv->cedv_conf.gauge_conf_raw); - bq27220_set_parameter_u16(AddressFullChargeCapacity, cedv->full_charge_cap); - bq27220_set_parameter_u16(AddressDesignCapacity, cedv->design_cap); - bq27220_set_parameter_u16(AddressEMF, cedv->EMF); - bq27220_set_parameter_u16(AddressC0, cedv->C0); - bq27220_set_parameter_u16(AddressR0, cedv->R0); - bq27220_set_parameter_u16(AddressT0, cedv->T0); - bq27220_set_parameter_u16(AddressR1, cedv->R1); - bq27220_set_parameter_u16(AddressTC, (cedv->TC) << 8 | cedv->C1); - bq27220_set_parameter_u16(AddressStartDOD0, cedv->DOD0); - bq27220_set_parameter_u16(AddressStartDOD10, cedv->DOD10); - bq27220_set_parameter_u16(AddressStartDOD20, cedv->DOD20); - bq27220_set_parameter_u16(AddressStartDOD30, cedv->DOD30); - bq27220_set_parameter_u16(AddressStartDOD40, cedv->DOD40); - bq27220_set_parameter_u16(AddressStartDOD50, cedv->DOD40); - bq27220_set_parameter_u16(AddressStartDOD60, cedv->DOD60); - bq27220_set_parameter_u16(AddressStartDOD70, cedv->DOD70); - bq27220_set_parameter_u16(AddressStartDOD80, cedv->DOD80); - bq27220_set_parameter_u16(AddressStartDOD90, cedv->DOD90); - bq27220_set_parameter_u16(AddressStartDOD100, cedv->DOD100); - bq27220_set_parameter_u16(AddressEDV0, cedv->EDV0); - bq27220_set_parameter_u16(AddressEDV1, cedv->EDV1); - bq27220_set_parameter_u16(AddressEDV2, cedv->EDV2); + bq27220_set_parameter_u16(handle, AddressGaugingConfig, cedv->cedv_conf.gauge_conf_raw); + bq27220_set_parameter_u16(handle, AddressFullChargeCapacity, cedv->full_charge_cap); + bq27220_set_parameter_u16(handle, AddressDesignCapacity, cedv->design_cap); + bq27220_set_parameter_u16(handle, AddressEMF, cedv->EMF); + bq27220_set_parameter_u16(handle, AddressC0, cedv->C0); + bq27220_set_parameter_u16(handle, AddressR0, cedv->R0); + bq27220_set_parameter_u16(handle, AddressT0, cedv->T0); + bq27220_set_parameter_u16(handle, AddressR1, cedv->R1); + bq27220_set_parameter_u16(handle, AddressTC, (cedv->TC) << 8 | cedv->C1); + bq27220_set_parameter_u16(handle, AddressStartDOD0, cedv->DOD0); + bq27220_set_parameter_u16(handle, AddressStartDOD10, cedv->DOD10); + bq27220_set_parameter_u16(handle, AddressStartDOD20, cedv->DOD20); + bq27220_set_parameter_u16(handle, AddressStartDOD30, cedv->DOD30); + bq27220_set_parameter_u16(handle, AddressStartDOD40, cedv->DOD40); + bq27220_set_parameter_u16(handle, AddressStartDOD50, cedv->DOD40); + bq27220_set_parameter_u16(handle, AddressStartDOD60, cedv->DOD60); + bq27220_set_parameter_u16(handle, AddressStartDOD70, cedv->DOD70); + bq27220_set_parameter_u16(handle, AddressStartDOD80, cedv->DOD80); + bq27220_set_parameter_u16(handle, AddressStartDOD90, cedv->DOD90); + bq27220_set_parameter_u16(handle, AddressStartDOD100, cedv->DOD100); + bq27220_set_parameter_u16(handle, AddressEDV0, cedv->EDV0); + bq27220_set_parameter_u16(handle, AddressEDV1, cedv->EDV1); + bq27220_set_parameter_u16(handle, AddressEDV2, cedv->EDV2); - bq27220_control(Control_EXIT_CFG_UPDATE); + bq27220_control(handle, Control_EXIT_CFG_UPDATE); delay_us(10000); - design_cap = bq27220_get_design_capacity(); + design_cap = bq27220_get_design_capacity(handle); if(cedv->design_cap == design_cap) { FURI_LOG_I(TAG, "Battery profile update success"); return true; @@ -121,16 +114,16 @@ bool bq27220_init(const ParamCEDV* cedv) { } } -uint16_t bq27220_get_voltage() { - return bq27220_read_word(CommandVoltage); +uint16_t bq27220_get_voltage(FuriHalI2cBusHandle* handle) { + return bq27220_read_word(handle, CommandVoltage); } -int16_t bq27220_get_current() { - return bq27220_read_word(CommandCurrent); +int16_t bq27220_get_current(FuriHalI2cBusHandle* handle) { + return bq27220_read_word(handle, CommandCurrent); } -uint8_t bq27220_get_battery_status(BatteryStatus* battery_status) { - uint16_t data = bq27220_read_word(CommandBatteryStatus); +uint8_t bq27220_get_battery_status(FuriHalI2cBusHandle* handle, BatteryStatus* battery_status) { + uint16_t data = bq27220_read_word(handle, CommandBatteryStatus); if(data == BQ27220_ERROR) { return BQ27220_ERROR; } else { @@ -139,8 +132,8 @@ uint8_t bq27220_get_battery_status(BatteryStatus* battery_status) { } } -uint8_t bq27220_get_operation_status(OperationStatus* operation_status) { - uint16_t data = bq27220_read_word(CommandOperationStatus); +uint8_t bq27220_get_operation_status(FuriHalI2cBusHandle* handle, OperationStatus* operation_status) { + uint16_t data = bq27220_read_word(handle, CommandOperationStatus); if(data == BQ27220_ERROR) { return BQ27220_ERROR; } else { @@ -149,26 +142,26 @@ uint8_t bq27220_get_operation_status(OperationStatus* operation_status) { } } -uint16_t bq27220_get_temperature() { - return bq27220_read_word(CommandTemperature); +uint16_t bq27220_get_temperature(FuriHalI2cBusHandle* handle) { + return bq27220_read_word(handle, CommandTemperature); } -uint16_t bq27220_get_full_charge_capacity() { - return bq27220_read_word(CommandFullChargeCapacity); +uint16_t bq27220_get_full_charge_capacity(FuriHalI2cBusHandle* handle) { + return bq27220_read_word(handle, CommandFullChargeCapacity); } -uint16_t bq27220_get_design_capacity() { - return bq27220_read_word(CommandDesignCapacity); +uint16_t bq27220_get_design_capacity(FuriHalI2cBusHandle* handle) { + return bq27220_read_word(handle, CommandDesignCapacity); } -uint16_t bq27220_get_remaining_capacity() { - return bq27220_read_word(CommandRemainingCapacity); +uint16_t bq27220_get_remaining_capacity(FuriHalI2cBusHandle* handle) { + return bq27220_read_word(handle, CommandRemainingCapacity); } -uint16_t bq27220_get_state_of_charge() { - return bq27220_read_word(CommandStateOfCharge); +uint16_t bq27220_get_state_of_charge(FuriHalI2cBusHandle* handle) { + return bq27220_read_word(handle, CommandStateOfCharge); } -uint16_t bq27220_get_state_of_health() { - return bq27220_read_word(CommandStateOfHealth); +uint16_t bq27220_get_state_of_health(FuriHalI2cBusHandle* handle) { + return bq27220_read_word(handle, CommandStateOfHealth); } diff --git a/lib/drivers/bq27220.h b/lib/drivers/bq27220.h index 312d46fd..4c97c48e 100644 --- a/lib/drivers/bq27220.h +++ b/lib/drivers/bq27220.h @@ -2,6 +2,7 @@ #include #include +#include #define BQ27220_ERROR 0x0 #define BQ27220_SUCCESS 0x1 @@ -95,36 +96,36 @@ typedef struct { /** Initialize Driver * @return true on success, false otherwise */ -bool bq27220_init(const ParamCEDV* cedv); +bool bq27220_init(FuriHalI2cBusHandle* handle, const ParamCEDV* cedv); /** Get battery voltage in mV or error */ -uint16_t bq27220_get_voltage(); +uint16_t bq27220_get_voltage(FuriHalI2cBusHandle* handle); /** Get current in mA or error*/ -int16_t bq27220_get_current(); +int16_t bq27220_get_current(FuriHalI2cBusHandle* handle); /** Get battery status */ -uint8_t bq27220_get_battery_status(BatteryStatus* battery_status); +uint8_t bq27220_get_battery_status(FuriHalI2cBusHandle* handle, BatteryStatus* battery_status); /** Get operation status */ -uint8_t bq27220_get_operation_status(OperationStatus* operation_status); +uint8_t bq27220_get_operation_status(FuriHalI2cBusHandle* handle, OperationStatus* operation_status); /** Get temperature in units of 0.1°K */ -uint16_t bq27220_get_temperature(); +uint16_t bq27220_get_temperature(FuriHalI2cBusHandle* handle); /** Get compensated full charge capacity in in mAh */ -uint16_t bq27220_get_full_charge_capacity(); +uint16_t bq27220_get_full_charge_capacity(FuriHalI2cBusHandle* handle); /** Get design capacity in mAh */ -uint16_t bq27220_get_design_capacity(); +uint16_t bq27220_get_design_capacity(FuriHalI2cBusHandle* handle); /** Get remaining capacity in in mAh */ -uint16_t bq27220_get_remaining_capacity(); +uint16_t bq27220_get_remaining_capacity(FuriHalI2cBusHandle* handle); /** Get predicted remaining battery capacity in percents */ -uint16_t bq27220_get_state_of_charge(); +uint16_t bq27220_get_state_of_charge(FuriHalI2cBusHandle* handle); /** Get ratio of full charge capacity over design capacity in percents */ -uint16_t bq27220_get_state_of_health(); +uint16_t bq27220_get_state_of_health(FuriHalI2cBusHandle* handle); -void bq27220_change_design_capacity(uint16_t capacity); +void bq27220_change_design_capacity(FuriHalI2cBusHandle* handle, uint16_t capacity); diff --git a/lib/drivers/lp5562.c b/lib/drivers/lp5562.c index 954fa65e..8535f3ac 100644 --- a/lib/drivers/lp5562.c +++ b/lib/drivers/lp5562.c @@ -1,27 +1,21 @@ #include "lp5562.h" #include "lp5562_reg.h" -#include #include -bool lp5562_write_reg(uint8_t address, uint8_t* data) { +static bool lp5562_write_reg(FuriHalI2cBusHandle* handle, uint8_t address, uint8_t* data) { uint8_t buffer[2] = {address, *data}; - bool ret; - with_furi_hal_i2c( - bool, &ret, () { - return furi_hal_i2c_tx(POWER_I2C, LP5562_ADDRESS, buffer, 2, LP5562_I2C_TIMEOUT); - }); - return ret; + return furi_hal_i2c_tx(handle, LP5562_ADDRESS, buffer, 2, LP5562_I2C_TIMEOUT); } -void lp5562_reset() { +void lp5562_reset(FuriHalI2cBusHandle* handle) { Reg0D_Reset reg = {.value = 0xFF}; - lp5562_write_reg(0x0D, (uint8_t*)®); + lp5562_write_reg(handle, 0x0D, (uint8_t*)®); } -void lp5562_configure() { +void lp5562_configure(FuriHalI2cBusHandle* handle) { Reg08_Config config = {.INT_CLK_EN = true, .PS_EN = true, .PWM_HF = true}; - lp5562_write_reg(0x08, (uint8_t*)&config); + lp5562_write_reg(handle, 0x08, (uint8_t*)&config); Reg70_LedMap map = { .red = EngSelectI2C, @@ -29,15 +23,15 @@ void lp5562_configure() { .blue = EngSelectI2C, .white = EngSelectI2C, }; - lp5562_write_reg(0x70, (uint8_t*)&map); + lp5562_write_reg(handle, 0x70, (uint8_t*)&map); } -void lp5562_enable() { +void lp5562_enable(FuriHalI2cBusHandle* handle) { Reg00_Enable reg = {.CHIP_EN = true, .LOG_EN = true}; - lp5562_write_reg(0x00, (uint8_t*)®); + lp5562_write_reg(handle, 0x00, (uint8_t*)®); } -void lp5562_set_channel_current(LP5562Channel channel, uint8_t value) { +void lp5562_set_channel_current(FuriHalI2cBusHandle* handle, LP5562Channel channel, uint8_t value) { uint8_t reg_no; if(channel == LP5562ChannelRed) { reg_no = 0x07; @@ -50,10 +44,10 @@ void lp5562_set_channel_current(LP5562Channel channel, uint8_t value) { } else { return; } - lp5562_write_reg(reg_no, &value); + lp5562_write_reg(handle, reg_no, &value); } -void lp5562_set_channel_value(LP5562Channel channel, uint8_t value) { +void lp5562_set_channel_value(FuriHalI2cBusHandle* handle, LP5562Channel channel, uint8_t value) { uint8_t reg_no; if(channel == LP5562ChannelRed) { reg_no = 0x04; @@ -66,5 +60,5 @@ void lp5562_set_channel_value(LP5562Channel channel, uint8_t value) { } else { return; } - lp5562_write_reg(reg_no, &value); + lp5562_write_reg(handle, reg_no, &value); } diff --git a/lib/drivers/lp5562.h b/lib/drivers/lp5562.h index b58e2ee0..7af6ae6f 100644 --- a/lib/drivers/lp5562.h +++ b/lib/drivers/lp5562.h @@ -2,6 +2,7 @@ #include #include +#include /** Channel types */ typedef enum { @@ -12,16 +13,16 @@ typedef enum { } LP5562Channel; /** Initialize Driver */ -void lp5562_reset(); +void lp5562_reset(FuriHalI2cBusHandle* handle); /** Configure Driver */ -void lp5562_configure(); +void lp5562_configure(FuriHalI2cBusHandle* handle); /** Enable Driver */ -void lp5562_enable(); +void lp5562_enable(FuriHalI2cBusHandle* handle); /** Set channel current */ -void lp5562_set_channel_current(LP5562Channel channel, uint8_t value); +void lp5562_set_channel_current(FuriHalI2cBusHandle* handle, LP5562Channel channel, uint8_t value); /** Set channel current */ -void lp5562_set_channel_value(LP5562Channel channel, uint8_t value); +void lp5562_set_channel_value(FuriHalI2cBusHandle* handle, LP5562Channel channel, uint8_t value); From d86125c7f7b73330d75316f5996de94cee373bfd Mon Sep 17 00:00:00 2001 From: Albert Kharisov Date: Mon, 29 Nov 2021 16:51:15 +0400 Subject: [PATCH 02/32] Fix butthurt and battery (#850) * Fix butthurt and battery --- applications/dolphin/dolphin.c | 1 - applications/dolphin/helpers/dolphin_state.c | 30 ++++++++++++++------ applications/power/power_service/power.c | 3 +- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/applications/dolphin/dolphin.c b/applications/dolphin/dolphin.c index f6871c04..9f9fe508 100644 --- a/applications/dolphin/dolphin.c +++ b/applications/dolphin/dolphin.c @@ -88,7 +88,6 @@ static void dolphin_check_butthurt(DolphinState* state) { float diff_time = difftime(state->data.timestamp, dolphin_state_timestamp()); if((fabs(diff_time)) > DOLPHIN_TIMEGATE) { - FURI_LOG_I("DolphinState", "Increasing butthurt"); dolphin_state_butthurted(state); } } diff --git a/applications/dolphin/helpers/dolphin_state.c b/applications/dolphin/helpers/dolphin_state.c index 13b8ca95..2878edf5 100644 --- a/applications/dolphin/helpers/dolphin_state.c +++ b/applications/dolphin/helpers/dolphin_state.c @@ -12,6 +12,8 @@ #define DOLPHIN_LVL_THRESHOLD 20.0f #define LEVEL2_THRESHOLD 20 #define LEVEL3_THRESHOLD 100 +#define BUTTHURT_MAX 14 +#define BUTTHURT_MIN 0 DolphinState* dolphin_state_alloc() { return furi_alloc(sizeof(DolphinState)); @@ -44,20 +46,27 @@ bool dolphin_state_save(DolphinState* dolphin_state) { } bool dolphin_state_load(DolphinState* dolphin_state) { - bool loaded = saved_struct_load( + bool success = saved_struct_load( DOLPHIN_STATE_PATH, &dolphin_state->data, sizeof(DolphinStoreData), DOLPHIN_STATE_HEADER_MAGIC, DOLPHIN_STATE_HEADER_VERSION); - if(!loaded) { + if(success) { + if((dolphin_state->data.butthurt > BUTTHURT_MAX) || + (dolphin_state->data.butthurt < BUTTHURT_MIN)) { + success = false; + } + } + + if(!success) { FURI_LOG_W(TAG, "Reset dolphin-state"); memset(dolphin_state, 0, sizeof(*dolphin_state)); dolphin_state->dirty = true; } - return loaded; + return success; } uint64_t dolphin_state_timestamp() { @@ -124,8 +133,10 @@ bool dolphin_state_on_deed(DolphinState* dolphin_state, DolphinDeed deed) { dolphin_state->data.icounter += MIN(xp_to_levelup, deed_weight->icounter); } - uint32_t new_butthurt = - CLAMP(((int32_t)dolphin_state->data.butthurt) + deed_weight->butthurt, 14, 0); + uint32_t new_butthurt = CLAMP( + ((int32_t)dolphin_state->data.butthurt) + deed_weight->butthurt, + BUTTHURT_MAX, + BUTTHURT_MIN); if(!!dolphin_state->data.butthurt != !!new_butthurt) { mood_changed = true; @@ -138,9 +149,12 @@ bool dolphin_state_on_deed(DolphinState* dolphin_state, DolphinDeed deed) { } void dolphin_state_butthurted(DolphinState* dolphin_state) { - dolphin_state->data.butthurt++; - dolphin_state->data.timestamp = dolphin_state_timestamp(); - dolphin_state->dirty = true; + if(dolphin_state->data.butthurt < BUTTHURT_MAX) { + dolphin_state->data.butthurt++; + FURI_LOG_I("DolphinState", "Increasing butthurt"); + dolphin_state->data.timestamp = dolphin_state_timestamp(); + dolphin_state->dirty = true; + } } void dolphin_state_increase_level(DolphinState* dolphin_state) { diff --git a/applications/power/power_service/power.c b/applications/power/power_service/power.c index e23e4a5f..a1bdc854 100644 --- a/applications/power/power_service/power.c +++ b/applications/power/power_service/power.c @@ -7,7 +7,7 @@ #include #define POWER_OFF_TIMEOUT 90 -#define POWER_BATTERY_WELL_LEVEL 99 +#define POWER_BATTERY_WELL_LEVEL 70 bool power_is_battery_well(PowerInfo* info) { return info->health > POWER_BATTERY_WELL_LEVEL; @@ -172,6 +172,7 @@ static void power_check_battery_level_change(Power* power) { int32_t power_srv(void* p) { (void)p; Power* power = power_alloc(); + power_update_info(power); furi_record_create("power", power); while(1) { From 9d27ef8901a07ed607d2d6e8cf680453be203601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Tue, 30 Nov 2021 15:09:43 +0300 Subject: [PATCH 03/32] [FL-2060] FuriHal: SPI refactoring, flexible bus reconfiguration on fly, same design as i2c. (#853) * FuriHal: SPI refactoring, flexible bus reconfigration on fly, same desiag as i2c. * Lib: update CC1101 driver documentation * FuriHal: update spi symbol names to match naming convention. --- .../targets/f6/furi-hal/furi-hal-spi-config.c | 258 +++++++++++++++--- .../targets/f6/furi-hal/furi-hal-spi-config.h | 90 +++--- .../targets/f6/furi-hal/furi-hal-spi-types.h | 64 +++++ bootloader/targets/f6/furi-hal/furi-hal-spi.c | 245 ++++++----------- bootloader/targets/f6/furi-hal/furi-hal-spi.h | 129 --------- .../targets/f7/furi-hal/furi-hal-spi-config.c | 258 +++++++++++++++--- .../targets/f7/furi-hal/furi-hal-spi-config.h | 90 +++--- .../targets/f7/furi-hal/furi-hal-spi-types.h | 64 +++++ bootloader/targets/f7/furi-hal/furi-hal-spi.c | 245 ++++++----------- bootloader/targets/f7/furi-hal/furi-hal-spi.h | 129 --------- .../targets/furi-hal-include/furi-hal-spi.h | 102 +++++++ firmware/targets/f6/fatfs/spi_sd_hal.c | 12 +- firmware/targets/f6/fatfs/stm32_adafruit_sd.c | 35 ++- firmware/targets/f6/fatfs/user_diskio.c | 26 +- firmware/targets/f6/furi-hal/furi-hal-sd.c | 4 +- .../targets/f6/furi-hal/furi-hal-spi-config.c | 209 ++++++++++++-- .../targets/f6/furi-hal/furi-hal-spi-config.h | 92 +++---- .../targets/f6/furi-hal/furi-hal-spi-types.h | 62 +++++ firmware/targets/f6/furi-hal/furi-hal-spi.c | 198 +++++--------- .../targets/f6/furi-hal/furi-hal-subghz.c | 132 ++++----- firmware/targets/f7/fatfs/spi_sd_hal.c | 12 +- firmware/targets/f7/fatfs/stm32_adafruit_sd.c | 35 ++- firmware/targets/f7/fatfs/user_diskio.c | 26 +- firmware/targets/f7/furi-hal/furi-hal-sd.c | 4 +- .../targets/f7/furi-hal/furi-hal-spi-config.c | 209 ++++++++++++-- .../targets/f7/furi-hal/furi-hal-spi-config.h | 92 +++---- .../targets/f7/furi-hal/furi-hal-spi-types.h | 62 +++++ firmware/targets/f7/furi-hal/furi-hal-spi.c | 198 +++++--------- .../targets/f7/furi-hal/furi-hal-subghz.c | 132 ++++----- .../targets/furi-hal-include/furi-hal-sd.h | 4 + .../targets/furi-hal-include/furi-hal-spi.h | 142 +++++----- firmware/targets/furi-hal-include/furi-hal.h | 1 + lib/ST25RFAL002/platform.c | 18 +- lib/drivers/cc1101.c | 116 ++++---- lib/drivers/cc1101.h | 160 ++++++----- lib/u8g2/u8g2_glue.c | 14 +- 36 files changed, 2057 insertions(+), 1612 deletions(-) create mode 100644 bootloader/targets/f6/furi-hal/furi-hal-spi-types.h delete mode 100644 bootloader/targets/f6/furi-hal/furi-hal-spi.h create mode 100644 bootloader/targets/f7/furi-hal/furi-hal-spi-types.h delete mode 100644 bootloader/targets/f7/furi-hal/furi-hal-spi.h create mode 100644 bootloader/targets/furi-hal-include/furi-hal-spi.h create mode 100644 firmware/targets/f6/furi-hal/furi-hal-spi-types.h create mode 100644 firmware/targets/f7/furi-hal/furi-hal-spi-types.h diff --git a/bootloader/targets/f6/furi-hal/furi-hal-spi-config.c b/bootloader/targets/f6/furi-hal/furi-hal-spi-config.c index 00b06a4f..1d2d0186 100644 --- a/bootloader/targets/f6/furi-hal/furi-hal-spi-config.c +++ b/bootloader/targets/f6/furi-hal/furi-hal-spi-config.c @@ -1,10 +1,9 @@ #include #include -#define SPI_R SPI1 -#define SPI_D SPI2 +/* SPI Presets */ -const LL_SPI_InitTypeDef furi_hal_spi_config_nfc = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_2edge_low_8m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -17,7 +16,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_nfc = { .CRCPoly = 7, }; -const LL_SPI_InitTypeDef furi_hal_spi_config_subghz = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_8m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -30,7 +29,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_subghz = { .CRCPoly = 7, }; -const LL_SPI_InitTypeDef furi_hal_spi_config_display = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_4m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -43,10 +42,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_display = { .CRCPoly = 7, }; -/** - * SD Card in fast mode (after init) - */ -const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_16m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -59,10 +55,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast = { .CRCPoly = 7, }; -/** - * SD Card in slow mode (before init) - */ -const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_2m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -75,40 +68,223 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow = { .CRCPoly = 7, }; -const FuriHalSpiBus spi_r = { - .spi = SPI_R, +/* SPI Buses */ + +static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { + if(event == FuriHalSpiBusEventInit) { + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); + bus->current_handle = NULL; + } else if(event == FuriHalSpiBusEventDeinit) { + } else if(event == FuriHalSpiBusEventLock) { + } else if(event == FuriHalSpiBusEventUnlock) { + } else if(event == FuriHalSpiBusEventActivate) { + LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1); + } else if(event == FuriHalSpiBusEventDeactivate) { + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); + } +} + +FuriHalSpiBus furi_hal_spi_bus_r = { + .spi = SPI1, + .callback = furi_hal_spi_bus_r_event_callback, +}; + +static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { + if(event == FuriHalSpiBusEventInit) { + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); + bus->current_handle = NULL; + } else if(event == FuriHalSpiBusEventDeinit) { + } else if(event == FuriHalSpiBusEventLock) { + } else if(event == FuriHalSpiBusEventUnlock) { + } else if(event == FuriHalSpiBusEventActivate) { + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2); + } else if(event == FuriHalSpiBusEventDeactivate) { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); + } +} + +FuriHalSpiBus furi_hal_spi_bus_d = { + .spi = SPI2, + .callback = furi_hal_spi_bus_d_event_callback, +}; + +/* SPI Bus Handles */ + +inline static void furi_hal_spi_bus_r_handle_event_callback( + FuriHalSpiBusHandle* handle, + FuriHalSpiBusHandleEvent event, + const LL_SPI_InitTypeDef* preset) { + if(event == FuriHalSpiBusHandleEventInit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + } else if(event == FuriHalSpiBusHandleEventDeinit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + } else if(event == FuriHalSpiBusHandleEventActivate) { + LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset); + LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); + LL_SPI_Enable(handle->bus->spi); + + hal_gpio_init_ex( + handle->miso, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn5SPI1); + hal_gpio_init_ex( + handle->mosi, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn5SPI1); + hal_gpio_init_ex( + handle->sck, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn5SPI1); + + hal_gpio_write(handle->cs, false); + } else if(event == FuriHalSpiBusHandleEventDeactivate) { + hal_gpio_write(handle->cs, true); + + hal_gpio_init(handle->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + hal_gpio_init(handle->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + hal_gpio_init(handle->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + + LL_SPI_Disable(handle->bus->spi); + } +} + +static void furi_hal_spi_bus_handle_subghz_event_callback( + FuriHalSpiBusHandle* handle, + FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_8m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_subghz = { + .bus = &furi_hal_spi_bus_r, + .callback = furi_hal_spi_bus_handle_subghz_event_callback, .miso = &gpio_spi_r_miso, .mosi = &gpio_spi_r_mosi, - .clk = &gpio_spi_r_sck, + .sck = &gpio_spi_r_sck, + .cs = &gpio_subghz_cs, }; -const FuriHalSpiBus spi_d = { - .spi = SPI_D, +static void furi_hal_spi_bus_handle_nfc_event_callback( + FuriHalSpiBusHandle* handle, + FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_2edge_low_8m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_nfc = { + .bus = &furi_hal_spi_bus_r, + .callback = furi_hal_spi_bus_handle_nfc_event_callback, + .miso = &gpio_spi_r_miso, + .mosi = &gpio_spi_r_mosi, + .sck = &gpio_spi_r_sck, + .cs = &gpio_nfc_cs, +}; + +static void furi_hal_spi_bus_handle_external_event_callback( + FuriHalSpiBusHandle* handle, + FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_2m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_external = { + .bus = &furi_hal_spi_bus_r, + .callback = furi_hal_spi_bus_handle_external_event_callback, + .miso = &gpio_ext_pa6, + .mosi = &gpio_ext_pa7, + .sck = &gpio_ext_pb3, + .cs = &gpio_ext_pa4, +}; + +inline static void furi_hal_spi_bus_d_handle_event_callback( + FuriHalSpiBusHandle* handle, + FuriHalSpiBusHandleEvent event, + const LL_SPI_InitTypeDef* preset) { + if(event == FuriHalSpiBusHandleEventInit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh); + + hal_gpio_init_ex( + handle->miso, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn5SPI2); + hal_gpio_init_ex( + handle->mosi, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn5SPI2); + hal_gpio_init_ex( + handle->sck, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn5SPI2); + + } else if(event == FuriHalSpiBusHandleEventDeinit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullUp, GpioSpeedLow); + } else if(event == FuriHalSpiBusHandleEventActivate) { + LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset); + LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); + LL_SPI_Enable(handle->bus->spi); + hal_gpio_write(handle->cs, false); + } else if(event == FuriHalSpiBusHandleEventDeactivate) { + hal_gpio_write(handle->cs, true); + LL_SPI_Disable(handle->bus->spi); + } +} + +static void furi_hal_spi_bus_handle_display_event_callback( + FuriHalSpiBusHandle* handle, + FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_4m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_display = { + .bus = &furi_hal_spi_bus_d, + .callback = furi_hal_spi_bus_handle_display_event_callback, .miso = &gpio_spi_d_miso, .mosi = &gpio_spi_d_mosi, - .clk = &gpio_spi_d_sck, + .sck = &gpio_spi_d_sck, + .cs = &gpio_display_cs, }; -const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax] = { - { - .bus = &spi_r, - .config = &furi_hal_spi_config_subghz, - .chip_select = &gpio_subghz_cs, - }, - { - .bus = &spi_d, - .config = &furi_hal_spi_config_display, - .chip_select = &gpio_display_cs, - }, - { - .bus = &spi_d, - .config = &furi_hal_spi_config_sd_fast, - .chip_select = &gpio_sdcard_cs, - }, - { - .bus = &spi_d, - .config = &furi_hal_spi_config_sd_slow, - .chip_select = &gpio_sdcard_cs, - }, - {.bus = &spi_r, .config = &furi_hal_spi_config_nfc, .chip_select = &gpio_nfc_cs}, +static void furi_hal_spi_bus_handle_sd_fast_event_callback( + FuriHalSpiBusHandle* handle, + FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_16m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast = { + .bus = &furi_hal_spi_bus_d, + .callback = furi_hal_spi_bus_handle_sd_fast_event_callback, + .miso = &gpio_spi_d_miso, + .mosi = &gpio_spi_d_mosi, + .sck = &gpio_spi_d_sck, + .cs = &gpio_sdcard_cs, +}; + +static void furi_hal_spi_bus_handle_sd_slow_event_callback( + FuriHalSpiBusHandle* handle, + FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_2m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_slow = { + .bus = &furi_hal_spi_bus_d, + .callback = furi_hal_spi_bus_handle_sd_slow_event_callback, + .miso = &gpio_spi_d_miso, + .mosi = &gpio_spi_d_mosi, + .sck = &gpio_spi_d_sck, + .cs = &gpio_sdcard_cs, }; diff --git a/bootloader/targets/f6/furi-hal/furi-hal-spi-config.h b/bootloader/targets/f6/furi-hal/furi-hal-spi-config.h index dea1cd65..d483e625 100644 --- a/bootloader/targets/f6/furi-hal/furi-hal-spi-config.h +++ b/bootloader/targets/f6/furi-hal/furi-hal-spi-config.h @@ -1,60 +1,60 @@ #pragma once -#include -#include +#include #ifdef __cplusplus extern "C" { #endif -extern const LL_SPI_InitTypeDef furi_hal_spi_config_nfc; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_subghz; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_display; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow; +/** Preset for ST25R916 */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_2edge_low_8m; -/** FURI HAL SPI BUS handler - * Structure content may change at some point +/** Preset for CC1101 */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_8m; + +/** Preset for ST7567 (Display) */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_4m; + +/** Preset for SdCard in fast mode */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_16m; + +/** Preset for SdCard in slow mode */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_2m; + +/** Furi Hal Spi Bus R (Radio: CC1101, Nfc, External)*/ +extern FuriHalSpiBus furi_hal_spi_bus_r; + +/** Furi Hal Spi Bus D (Display, SdCard) */ +extern FuriHalSpiBus furi_hal_spi_bus_d; + +/** CC1101 on `furi_hal_spi_bus_r` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_subghz; + +/** ST25R3916 on `furi_hal_spi_bus_r` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_nfc; + +/** External on `furi_hal_spi_bus_r` + * Preset: `furi_hal_spi_preset_1edge_low_2m` + * + * miso: pa6 + * mosi: pa7 + * sck: pb3 + * cs: pa4 (software controlled) + * + * @warning not initialized by default, call `furi_hal_spi_bus_handle_init` to initialize + * Bus pins are floating on inactive state, CS high after initialization + * */ -typedef struct { - const SPI_TypeDef* spi; - const GpioPin* miso; - const GpioPin* mosi; - const GpioPin* clk; -} FuriHalSpiBus; +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_external; -/** FURI HAL SPI Device handler - * Structure content may change at some point - */ -typedef struct { - const FuriHalSpiBus* bus; - const LL_SPI_InitTypeDef* config; - const GpioPin* chip_select; -} FuriHalSpiDevice; +/** ST7567(Display) on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_display; -/** FURI HAL SPI Standard Device IDs */ -typedef enum { - FuriHalSpiDeviceIdSubGhz, /** SubGhz: CC1101, non-standard SPI usage */ - FuriHalSpiDeviceIdDisplay, /** Display: ERC12864, only have MOSI */ - FuriHalSpiDeviceIdSdCardFast, /** SDCARD: fast mode, after initialization */ - FuriHalSpiDeviceIdSdCardSlow, /** SDCARD: slow mode, before initialization */ - FuriHalSpiDeviceIdNfc, /** NFC: ST25R3916, pretty standard, but RFAL makes it complex */ +/** SdCard in fast mode on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast; - FuriHalSpiDeviceIdMax, /** Service Value, do not use */ -} FuriHalSpiDeviceId; - -/** Furi Hal Spi Bus R - * CC1101, Nfc - */ -extern const FuriHalSpiBus spi_r; - -/** Furi Hal Spi Bus D - * Display, SdCard - */ -extern const FuriHalSpiBus spi_d; - -/** Furi Hal Spi devices */ -extern const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax]; +/** SdCard in slow mode on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_slow; #ifdef __cplusplus } diff --git a/bootloader/targets/f6/furi-hal/furi-hal-spi-types.h b/bootloader/targets/f6/furi-hal/furi-hal-spi-types.h new file mode 100644 index 00000000..7bff3d26 --- /dev/null +++ b/bootloader/targets/f6/furi-hal/furi-hal-spi-types.h @@ -0,0 +1,64 @@ +#pragma once + +#include +#include + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct FuriHalSpiBus FuriHalSpiBus; +typedef struct FuriHalSpiBusHandle FuriHalSpiBusHandle; + +/** FuriHal spi bus states */ +typedef enum { + FuriHalSpiBusEventInit, /**< Bus initialization event, called on system start */ + FuriHalSpiBusEventDeinit, /**< Bus deinitialization event, called on system stop */ + FuriHalSpiBusEventLock, /**< Bus lock event, called before activation */ + FuriHalSpiBusEventUnlock, /**< Bus unlock event, called after deactivation */ + FuriHalSpiBusEventActivate, /**< Bus activation event, called before handle activation */ + FuriHalSpiBusEventDeactivate, /**< Bus deactivation event, called after handle deactivation */ +} FuriHalSpiBusEvent; + +/** FuriHal spi bus event callback */ +typedef void (*FuriHalSpiBusEventCallback)(FuriHalSpiBus* bus, FuriHalSpiBusEvent event); + +/** FuriHal spi bus */ +struct FuriHalSpiBus { + SPI_TypeDef* spi; + FuriHalSpiBusEventCallback callback; + FuriHalSpiBusHandle* current_handle; +}; + +/** FuriHal spi handle states */ +typedef enum { + FuriHalSpiBusHandleEventInit, /**< Handle init, called on system start, initialize gpio for idle state */ + FuriHalSpiBusHandleEventDeinit, /**< Handle deinit, called on system stop, deinitialize gpio for default state */ + FuriHalSpiBusHandleEventActivate, /**< Handle activate: connect gpio and apply bus config */ + FuriHalSpiBusHandleEventDeactivate, /**< Handle deactivate: disconnect gpio and reset bus config */ +} FuriHalSpiBusHandleEvent; + +/** FuriHal spi handle event callback */ +typedef void (*FuriHalSpiBusHandleEventCallback)( + FuriHalSpiBusHandle* handle, + FuriHalSpiBusHandleEvent event); + +/** FuriHal spi handle */ +struct FuriHalSpiBusHandle { + FuriHalSpiBus* bus; + FuriHalSpiBusHandleEventCallback callback; + const GpioPin* miso; + const GpioPin* mosi; + const GpioPin* sck; + const GpioPin* cs; +}; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/bootloader/targets/f6/furi-hal/furi-hal-spi.c b/bootloader/targets/f6/furi-hal/furi-hal-spi.c index e36e9230..e3f894b6 100644 --- a/bootloader/targets/f6/furi-hal/furi-hal-spi.c +++ b/bootloader/targets/f6/furi-hal/furi-hal-spi.c @@ -2,239 +2,150 @@ #include "furi-hal-resources.h" #include +#include #include #include #include #include -extern void Enable_SPI(SPI_TypeDef* spi); - void furi_hal_spi_init() { - for(size_t i = 0; i < FuriHalSpiDeviceIdMax; ++i) { - hal_gpio_write(furi_hal_spi_devices[i].chip_select, true); - hal_gpio_init( - furi_hal_spi_devices[i].chip_select, - GpioModeOutputPushPull, - GpioPullNo, - GpioSpeedVeryHigh); - } + furi_hal_spi_bus_init(&furi_hal_spi_bus_r); + furi_hal_spi_bus_init(&furi_hal_spi_bus_d); - hal_gpio_init_ex( - &gpio_spi_r_miso, - GpioModeAltFunctionPushPull, - GpioPullNo, - GpioSpeedVeryHigh, - GpioAltFn5SPI1); - hal_gpio_init_ex( - &gpio_spi_r_mosi, - GpioModeAltFunctionPushPull, - GpioPullNo, - GpioSpeedVeryHigh, - GpioAltFn5SPI1); - hal_gpio_init_ex( - &gpio_spi_r_sck, - GpioModeAltFunctionPushPull, - GpioPullNo, - GpioSpeedVeryHigh, - GpioAltFn5SPI1); - - hal_gpio_init_ex( - &gpio_spi_d_miso, - GpioModeAltFunctionPushPull, - GpioPullUp, - GpioSpeedVeryHigh, - GpioAltFn5SPI2); - hal_gpio_init_ex( - &gpio_spi_d_mosi, - GpioModeAltFunctionPushPull, - GpioPullUp, - GpioSpeedVeryHigh, - GpioAltFn5SPI2); - hal_gpio_init_ex( - &gpio_spi_d_sck, - GpioModeAltFunctionPushPull, - GpioPullUp, - GpioSpeedVeryHigh, - GpioAltFn5SPI2); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_nfc); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_display); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_slow); } -void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus) { +void furi_hal_spi_bus_init(FuriHalSpiBus* bus) { assert(bus); + bus->callback(bus, FuriHalSpiBusEventInit); } -void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus) { +void furi_hal_spi_bus_deinit(FuriHalSpiBus* bus) { assert(bus); + bus->callback(bus, FuriHalSpiBusEventDeinit); } -void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config) { - assert(bus); - LL_SPI_DeInit((SPI_TypeDef*)bus->spi); - LL_SPI_Init((SPI_TypeDef*)bus->spi, (LL_SPI_InitTypeDef*)config); - LL_SPI_SetRxFIFOThreshold((SPI_TypeDef*)bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); - LL_SPI_Enable((SPI_TypeDef*)bus->spi); +void furi_hal_spi_bus_handle_init(FuriHalSpiBusHandle* handle) { + assert(handle); + handle->callback(handle, FuriHalSpiBusHandleEventInit); } -void furi_hal_spi_bus_end_txrx(const FuriHalSpiBus* bus, uint32_t timeout) { - while(LL_SPI_GetTxFIFOLevel((SPI_TypeDef*)bus->spi) != LL_SPI_TX_FIFO_EMPTY) +void furi_hal_spi_bus_handle_deinit(FuriHalSpiBusHandle* handle) { + assert(handle); + handle->callback(handle, FuriHalSpiBusHandleEventDeinit); +} + +void furi_hal_spi_acquire(FuriHalSpiBusHandle* handle) { + assert(handle); + + handle->bus->callback(handle->bus, FuriHalSpiBusEventLock); + handle->bus->callback(handle->bus, FuriHalSpiBusEventActivate); + + assert(handle->bus->current_handle == NULL); + + handle->bus->current_handle = handle; + handle->callback(handle, FuriHalSpiBusHandleEventActivate); +} + +void furi_hal_spi_release(FuriHalSpiBusHandle* handle) { + assert(handle); + assert(handle->bus->current_handle == handle); + + // Handle event and unset handle + handle->callback(handle, FuriHalSpiBusHandleEventDeactivate); + handle->bus->current_handle = NULL; + + // Bus events + handle->bus->callback(handle->bus, FuriHalSpiBusEventDeactivate); + handle->bus->callback(handle->bus, FuriHalSpiBusEventUnlock); +} + +static void furi_hal_spi_bus_end_txrx(FuriHalSpiBusHandle* handle, uint32_t timeout) { + while(LL_SPI_GetTxFIFOLevel(handle->bus->spi) != LL_SPI_TX_FIFO_EMPTY) ; - while(LL_SPI_IsActiveFlag_BSY((SPI_TypeDef*)bus->spi)) + while(LL_SPI_IsActiveFlag_BSY(handle->bus->spi)) ; - while(LL_SPI_GetRxFIFOLevel((SPI_TypeDef*)bus->spi) != LL_SPI_RX_FIFO_EMPTY) { - LL_SPI_ReceiveData8((SPI_TypeDef*)bus->spi); + while(LL_SPI_GetRxFIFOLevel(handle->bus->spi) != LL_SPI_RX_FIFO_EMPTY) { + LL_SPI_ReceiveData8(handle->bus->spi); } } -bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { - assert(bus); +bool furi_hal_spi_bus_rx( + FuriHalSpiBusHandle* handle, + uint8_t* buffer, + size_t size, + uint32_t timeout) { + assert(handle); + assert(handle->bus->current_handle == handle); assert(buffer); assert(size > 0); - return furi_hal_spi_bus_trx(bus, buffer, buffer, size, timeout); + return furi_hal_spi_bus_trx(handle, buffer, buffer, size, timeout); } -bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { - assert(bus); +bool furi_hal_spi_bus_tx( + FuriHalSpiBusHandle* handle, + uint8_t* buffer, + size_t size, + uint32_t timeout) { + assert(handle); + assert(handle->bus->current_handle == handle); assert(buffer); assert(size > 0); bool ret = true; while(size > 0) { - if(LL_SPI_IsActiveFlag_TXE((SPI_TypeDef*)bus->spi)) { - LL_SPI_TransmitData8((SPI_TypeDef*)bus->spi, *buffer); + if(LL_SPI_IsActiveFlag_TXE(handle->bus->spi)) { + LL_SPI_TransmitData8(handle->bus->spi, *buffer); buffer++; size--; } } - furi_hal_spi_bus_end_txrx(bus, timeout); - LL_SPI_ClearFlag_OVR((SPI_TypeDef*)bus->spi); + furi_hal_spi_bus_end_txrx(handle, timeout); + LL_SPI_ClearFlag_OVR(handle->bus->spi); return ret; } bool furi_hal_spi_bus_trx( - const FuriHalSpiBus* bus, + FuriHalSpiBusHandle* handle, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { - assert(bus); + assert(handle); + assert(handle->bus->current_handle == handle); assert(tx_buffer); assert(rx_buffer); assert(size > 0); + bool ret = true; size_t tx_size = size; bool tx_allowed = true; while(size > 0) { - if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE((SPI_TypeDef*)bus->spi) && tx_allowed) { - LL_SPI_TransmitData8((SPI_TypeDef*)bus->spi, *tx_buffer); + if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE(handle->bus->spi) && tx_allowed) { + LL_SPI_TransmitData8(handle->bus->spi, *tx_buffer); tx_buffer++; tx_size--; tx_allowed = false; } - if(LL_SPI_IsActiveFlag_RXNE((SPI_TypeDef*)bus->spi)) { - *rx_buffer = LL_SPI_ReceiveData8((SPI_TypeDef*)bus->spi); + if(LL_SPI_IsActiveFlag_RXNE(handle->bus->spi)) { + *rx_buffer = LL_SPI_ReceiveData8(handle->bus->spi); rx_buffer++; size--; tx_allowed = true; } } - furi_hal_spi_bus_end_txrx(bus, timeout); - - return ret; -} - -void furi_hal_spi_device_configure(const FuriHalSpiDevice* device) { - assert(device); - assert(device->config); - - furi_hal_spi_bus_configure(device->bus, device->config); -} - -const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id) { - assert(device_id < FuriHalSpiDeviceIdMax); - - const FuriHalSpiDevice* device = &furi_hal_spi_devices[device_id]; - assert(device); - - furi_hal_spi_bus_lock(device->bus); - furi_hal_spi_device_configure(device); - - return device; -} - -void furi_hal_spi_device_return(const FuriHalSpiDevice* device) { - furi_hal_spi_bus_unlock(device->bus); -} - -bool furi_hal_spi_device_rx( - const FuriHalSpiDevice* device, - uint8_t* buffer, - size_t size, - uint32_t timeout) { - assert(device); - assert(buffer); - assert(size > 0); - - if(device->chip_select) { - hal_gpio_write(device->chip_select, false); - } - - bool ret = furi_hal_spi_bus_rx(device->bus, buffer, size, timeout); - - if(device->chip_select) { - hal_gpio_write(device->chip_select, true); - } - - return ret; -} - -bool furi_hal_spi_device_tx( - const FuriHalSpiDevice* device, - uint8_t* buffer, - size_t size, - uint32_t timeout) { - assert(device); - assert(buffer); - assert(size > 0); - - if(device->chip_select) { - hal_gpio_write(device->chip_select, false); - } - - bool ret = furi_hal_spi_bus_tx(device->bus, buffer, size, timeout); - - if(device->chip_select) { - hal_gpio_write(device->chip_select, true); - } - - return ret; -} - -bool furi_hal_spi_device_trx( - const FuriHalSpiDevice* device, - uint8_t* tx_buffer, - uint8_t* rx_buffer, - size_t size, - uint32_t timeout) { - assert(device); - assert(tx_buffer); - assert(rx_buffer); - assert(size > 0); - - if(device->chip_select) { - hal_gpio_write(device->chip_select, false); - } - - bool ret = furi_hal_spi_bus_trx(device->bus, tx_buffer, rx_buffer, size, timeout); - - if(device->chip_select) { - hal_gpio_write(device->chip_select, true); - } + furi_hal_spi_bus_end_txrx(handle, timeout); return ret; } diff --git a/bootloader/targets/f6/furi-hal/furi-hal-spi.h b/bootloader/targets/f6/furi-hal/furi-hal-spi.h deleted file mode 100644 index 8027eb5d..00000000 --- a/bootloader/targets/f6/furi-hal/furi-hal-spi.h +++ /dev/null @@ -1,129 +0,0 @@ -#pragma once - -#include "main.h" - -#include "furi-hal-spi-config.h" -#include - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Init SPI API - */ -void furi_hal_spi_init(); - -/* Bus Level API */ - -/** Lock SPI bus - * Takes bus mutex, if used - */ -void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus); - -/** Unlock SPI bus - * Releases BUS mutex, if used - */ -void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus); - -/** - * Configure SPI bus - * @param bus - spi bus handler - * @param config - spi configuration structure - */ -void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config); - -/** SPI Receive - * @param bus - spi bus handler - * @param buffer - receive buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); - -/** SPI Transmit - * @param bus - spi bus handler - * @param buffer - transmit buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); - -/** SPI Transmit and Receive - * @param bus - spi bus handlere - * @param tx_buffer - device handle - * @param rx_buffer - device handle - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_bus_trx( - const FuriHalSpiBus* bus, - uint8_t* tx_buffer, - uint8_t* rx_buffer, - size_t size, - uint32_t timeout); - -/* Device Level API */ - -/** Reconfigure SPI bus for device - * @param device - device description - */ -void furi_hal_spi_device_configure(const FuriHalSpiDevice* device); - -/** Get Device handle - * And lock access to the corresponding SPI BUS - * @param device_id - device identifier - * @return device handle - */ -const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id); - -/** Return Device handle - * And unlock access to the corresponding SPI BUS - * @param device - device handle - */ -void furi_hal_spi_device_return(const FuriHalSpiDevice* device); - -/** SPI Recieve - * @param device - device handle - * @param buffer - receive buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_device_rx( - const FuriHalSpiDevice* device, - uint8_t* buffer, - size_t size, - uint32_t timeout); - -/** SPI Transmit - * @param device - device handle - * @param buffer - transmit buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_device_tx( - const FuriHalSpiDevice* device, - uint8_t* buffer, - size_t size, - uint32_t timeout); - -/** SPI Transmit and Receive - * @param device - device handle - * @param tx_buffer - device handle - * @param rx_buffer - device handle - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_device_trx( - const FuriHalSpiDevice* device, - uint8_t* tx_buffer, - uint8_t* rx_buffer, - size_t size, - uint32_t timeout); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/bootloader/targets/f7/furi-hal/furi-hal-spi-config.c b/bootloader/targets/f7/furi-hal/furi-hal-spi-config.c index 00b06a4f..1d2d0186 100644 --- a/bootloader/targets/f7/furi-hal/furi-hal-spi-config.c +++ b/bootloader/targets/f7/furi-hal/furi-hal-spi-config.c @@ -1,10 +1,9 @@ #include #include -#define SPI_R SPI1 -#define SPI_D SPI2 +/* SPI Presets */ -const LL_SPI_InitTypeDef furi_hal_spi_config_nfc = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_2edge_low_8m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -17,7 +16,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_nfc = { .CRCPoly = 7, }; -const LL_SPI_InitTypeDef furi_hal_spi_config_subghz = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_8m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -30,7 +29,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_subghz = { .CRCPoly = 7, }; -const LL_SPI_InitTypeDef furi_hal_spi_config_display = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_4m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -43,10 +42,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_display = { .CRCPoly = 7, }; -/** - * SD Card in fast mode (after init) - */ -const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_16m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -59,10 +55,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast = { .CRCPoly = 7, }; -/** - * SD Card in slow mode (before init) - */ -const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_2m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -75,40 +68,223 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow = { .CRCPoly = 7, }; -const FuriHalSpiBus spi_r = { - .spi = SPI_R, +/* SPI Buses */ + +static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { + if(event == FuriHalSpiBusEventInit) { + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); + bus->current_handle = NULL; + } else if(event == FuriHalSpiBusEventDeinit) { + } else if(event == FuriHalSpiBusEventLock) { + } else if(event == FuriHalSpiBusEventUnlock) { + } else if(event == FuriHalSpiBusEventActivate) { + LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1); + } else if(event == FuriHalSpiBusEventDeactivate) { + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); + } +} + +FuriHalSpiBus furi_hal_spi_bus_r = { + .spi = SPI1, + .callback = furi_hal_spi_bus_r_event_callback, +}; + +static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { + if(event == FuriHalSpiBusEventInit) { + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); + bus->current_handle = NULL; + } else if(event == FuriHalSpiBusEventDeinit) { + } else if(event == FuriHalSpiBusEventLock) { + } else if(event == FuriHalSpiBusEventUnlock) { + } else if(event == FuriHalSpiBusEventActivate) { + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2); + } else if(event == FuriHalSpiBusEventDeactivate) { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); + } +} + +FuriHalSpiBus furi_hal_spi_bus_d = { + .spi = SPI2, + .callback = furi_hal_spi_bus_d_event_callback, +}; + +/* SPI Bus Handles */ + +inline static void furi_hal_spi_bus_r_handle_event_callback( + FuriHalSpiBusHandle* handle, + FuriHalSpiBusHandleEvent event, + const LL_SPI_InitTypeDef* preset) { + if(event == FuriHalSpiBusHandleEventInit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + } else if(event == FuriHalSpiBusHandleEventDeinit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + } else if(event == FuriHalSpiBusHandleEventActivate) { + LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset); + LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); + LL_SPI_Enable(handle->bus->spi); + + hal_gpio_init_ex( + handle->miso, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn5SPI1); + hal_gpio_init_ex( + handle->mosi, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn5SPI1); + hal_gpio_init_ex( + handle->sck, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn5SPI1); + + hal_gpio_write(handle->cs, false); + } else if(event == FuriHalSpiBusHandleEventDeactivate) { + hal_gpio_write(handle->cs, true); + + hal_gpio_init(handle->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + hal_gpio_init(handle->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + hal_gpio_init(handle->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + + LL_SPI_Disable(handle->bus->spi); + } +} + +static void furi_hal_spi_bus_handle_subghz_event_callback( + FuriHalSpiBusHandle* handle, + FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_8m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_subghz = { + .bus = &furi_hal_spi_bus_r, + .callback = furi_hal_spi_bus_handle_subghz_event_callback, .miso = &gpio_spi_r_miso, .mosi = &gpio_spi_r_mosi, - .clk = &gpio_spi_r_sck, + .sck = &gpio_spi_r_sck, + .cs = &gpio_subghz_cs, }; -const FuriHalSpiBus spi_d = { - .spi = SPI_D, +static void furi_hal_spi_bus_handle_nfc_event_callback( + FuriHalSpiBusHandle* handle, + FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_2edge_low_8m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_nfc = { + .bus = &furi_hal_spi_bus_r, + .callback = furi_hal_spi_bus_handle_nfc_event_callback, + .miso = &gpio_spi_r_miso, + .mosi = &gpio_spi_r_mosi, + .sck = &gpio_spi_r_sck, + .cs = &gpio_nfc_cs, +}; + +static void furi_hal_spi_bus_handle_external_event_callback( + FuriHalSpiBusHandle* handle, + FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_2m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_external = { + .bus = &furi_hal_spi_bus_r, + .callback = furi_hal_spi_bus_handle_external_event_callback, + .miso = &gpio_ext_pa6, + .mosi = &gpio_ext_pa7, + .sck = &gpio_ext_pb3, + .cs = &gpio_ext_pa4, +}; + +inline static void furi_hal_spi_bus_d_handle_event_callback( + FuriHalSpiBusHandle* handle, + FuriHalSpiBusHandleEvent event, + const LL_SPI_InitTypeDef* preset) { + if(event == FuriHalSpiBusHandleEventInit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh); + + hal_gpio_init_ex( + handle->miso, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn5SPI2); + hal_gpio_init_ex( + handle->mosi, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn5SPI2); + hal_gpio_init_ex( + handle->sck, + GpioModeAltFunctionPushPull, + GpioPullNo, + GpioSpeedVeryHigh, + GpioAltFn5SPI2); + + } else if(event == FuriHalSpiBusHandleEventDeinit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullUp, GpioSpeedLow); + } else if(event == FuriHalSpiBusHandleEventActivate) { + LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset); + LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); + LL_SPI_Enable(handle->bus->spi); + hal_gpio_write(handle->cs, false); + } else if(event == FuriHalSpiBusHandleEventDeactivate) { + hal_gpio_write(handle->cs, true); + LL_SPI_Disable(handle->bus->spi); + } +} + +static void furi_hal_spi_bus_handle_display_event_callback( + FuriHalSpiBusHandle* handle, + FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_4m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_display = { + .bus = &furi_hal_spi_bus_d, + .callback = furi_hal_spi_bus_handle_display_event_callback, .miso = &gpio_spi_d_miso, .mosi = &gpio_spi_d_mosi, - .clk = &gpio_spi_d_sck, + .sck = &gpio_spi_d_sck, + .cs = &gpio_display_cs, }; -const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax] = { - { - .bus = &spi_r, - .config = &furi_hal_spi_config_subghz, - .chip_select = &gpio_subghz_cs, - }, - { - .bus = &spi_d, - .config = &furi_hal_spi_config_display, - .chip_select = &gpio_display_cs, - }, - { - .bus = &spi_d, - .config = &furi_hal_spi_config_sd_fast, - .chip_select = &gpio_sdcard_cs, - }, - { - .bus = &spi_d, - .config = &furi_hal_spi_config_sd_slow, - .chip_select = &gpio_sdcard_cs, - }, - {.bus = &spi_r, .config = &furi_hal_spi_config_nfc, .chip_select = &gpio_nfc_cs}, +static void furi_hal_spi_bus_handle_sd_fast_event_callback( + FuriHalSpiBusHandle* handle, + FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_16m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast = { + .bus = &furi_hal_spi_bus_d, + .callback = furi_hal_spi_bus_handle_sd_fast_event_callback, + .miso = &gpio_spi_d_miso, + .mosi = &gpio_spi_d_mosi, + .sck = &gpio_spi_d_sck, + .cs = &gpio_sdcard_cs, +}; + +static void furi_hal_spi_bus_handle_sd_slow_event_callback( + FuriHalSpiBusHandle* handle, + FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_2m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_slow = { + .bus = &furi_hal_spi_bus_d, + .callback = furi_hal_spi_bus_handle_sd_slow_event_callback, + .miso = &gpio_spi_d_miso, + .mosi = &gpio_spi_d_mosi, + .sck = &gpio_spi_d_sck, + .cs = &gpio_sdcard_cs, }; diff --git a/bootloader/targets/f7/furi-hal/furi-hal-spi-config.h b/bootloader/targets/f7/furi-hal/furi-hal-spi-config.h index dea1cd65..d483e625 100644 --- a/bootloader/targets/f7/furi-hal/furi-hal-spi-config.h +++ b/bootloader/targets/f7/furi-hal/furi-hal-spi-config.h @@ -1,60 +1,60 @@ #pragma once -#include -#include +#include #ifdef __cplusplus extern "C" { #endif -extern const LL_SPI_InitTypeDef furi_hal_spi_config_nfc; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_subghz; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_display; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow; +/** Preset for ST25R916 */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_2edge_low_8m; -/** FURI HAL SPI BUS handler - * Structure content may change at some point +/** Preset for CC1101 */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_8m; + +/** Preset for ST7567 (Display) */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_4m; + +/** Preset for SdCard in fast mode */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_16m; + +/** Preset for SdCard in slow mode */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_2m; + +/** Furi Hal Spi Bus R (Radio: CC1101, Nfc, External)*/ +extern FuriHalSpiBus furi_hal_spi_bus_r; + +/** Furi Hal Spi Bus D (Display, SdCard) */ +extern FuriHalSpiBus furi_hal_spi_bus_d; + +/** CC1101 on `furi_hal_spi_bus_r` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_subghz; + +/** ST25R3916 on `furi_hal_spi_bus_r` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_nfc; + +/** External on `furi_hal_spi_bus_r` + * Preset: `furi_hal_spi_preset_1edge_low_2m` + * + * miso: pa6 + * mosi: pa7 + * sck: pb3 + * cs: pa4 (software controlled) + * + * @warning not initialized by default, call `furi_hal_spi_bus_handle_init` to initialize + * Bus pins are floating on inactive state, CS high after initialization + * */ -typedef struct { - const SPI_TypeDef* spi; - const GpioPin* miso; - const GpioPin* mosi; - const GpioPin* clk; -} FuriHalSpiBus; +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_external; -/** FURI HAL SPI Device handler - * Structure content may change at some point - */ -typedef struct { - const FuriHalSpiBus* bus; - const LL_SPI_InitTypeDef* config; - const GpioPin* chip_select; -} FuriHalSpiDevice; +/** ST7567(Display) on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_display; -/** FURI HAL SPI Standard Device IDs */ -typedef enum { - FuriHalSpiDeviceIdSubGhz, /** SubGhz: CC1101, non-standard SPI usage */ - FuriHalSpiDeviceIdDisplay, /** Display: ERC12864, only have MOSI */ - FuriHalSpiDeviceIdSdCardFast, /** SDCARD: fast mode, after initialization */ - FuriHalSpiDeviceIdSdCardSlow, /** SDCARD: slow mode, before initialization */ - FuriHalSpiDeviceIdNfc, /** NFC: ST25R3916, pretty standard, but RFAL makes it complex */ +/** SdCard in fast mode on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast; - FuriHalSpiDeviceIdMax, /** Service Value, do not use */ -} FuriHalSpiDeviceId; - -/** Furi Hal Spi Bus R - * CC1101, Nfc - */ -extern const FuriHalSpiBus spi_r; - -/** Furi Hal Spi Bus D - * Display, SdCard - */ -extern const FuriHalSpiBus spi_d; - -/** Furi Hal Spi devices */ -extern const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax]; +/** SdCard in slow mode on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_slow; #ifdef __cplusplus } diff --git a/bootloader/targets/f7/furi-hal/furi-hal-spi-types.h b/bootloader/targets/f7/furi-hal/furi-hal-spi-types.h new file mode 100644 index 00000000..7bff3d26 --- /dev/null +++ b/bootloader/targets/f7/furi-hal/furi-hal-spi-types.h @@ -0,0 +1,64 @@ +#pragma once + +#include +#include + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct FuriHalSpiBus FuriHalSpiBus; +typedef struct FuriHalSpiBusHandle FuriHalSpiBusHandle; + +/** FuriHal spi bus states */ +typedef enum { + FuriHalSpiBusEventInit, /**< Bus initialization event, called on system start */ + FuriHalSpiBusEventDeinit, /**< Bus deinitialization event, called on system stop */ + FuriHalSpiBusEventLock, /**< Bus lock event, called before activation */ + FuriHalSpiBusEventUnlock, /**< Bus unlock event, called after deactivation */ + FuriHalSpiBusEventActivate, /**< Bus activation event, called before handle activation */ + FuriHalSpiBusEventDeactivate, /**< Bus deactivation event, called after handle deactivation */ +} FuriHalSpiBusEvent; + +/** FuriHal spi bus event callback */ +typedef void (*FuriHalSpiBusEventCallback)(FuriHalSpiBus* bus, FuriHalSpiBusEvent event); + +/** FuriHal spi bus */ +struct FuriHalSpiBus { + SPI_TypeDef* spi; + FuriHalSpiBusEventCallback callback; + FuriHalSpiBusHandle* current_handle; +}; + +/** FuriHal spi handle states */ +typedef enum { + FuriHalSpiBusHandleEventInit, /**< Handle init, called on system start, initialize gpio for idle state */ + FuriHalSpiBusHandleEventDeinit, /**< Handle deinit, called on system stop, deinitialize gpio for default state */ + FuriHalSpiBusHandleEventActivate, /**< Handle activate: connect gpio and apply bus config */ + FuriHalSpiBusHandleEventDeactivate, /**< Handle deactivate: disconnect gpio and reset bus config */ +} FuriHalSpiBusHandleEvent; + +/** FuriHal spi handle event callback */ +typedef void (*FuriHalSpiBusHandleEventCallback)( + FuriHalSpiBusHandle* handle, + FuriHalSpiBusHandleEvent event); + +/** FuriHal spi handle */ +struct FuriHalSpiBusHandle { + FuriHalSpiBus* bus; + FuriHalSpiBusHandleEventCallback callback; + const GpioPin* miso; + const GpioPin* mosi; + const GpioPin* sck; + const GpioPin* cs; +}; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/bootloader/targets/f7/furi-hal/furi-hal-spi.c b/bootloader/targets/f7/furi-hal/furi-hal-spi.c index e36e9230..e3f894b6 100644 --- a/bootloader/targets/f7/furi-hal/furi-hal-spi.c +++ b/bootloader/targets/f7/furi-hal/furi-hal-spi.c @@ -2,239 +2,150 @@ #include "furi-hal-resources.h" #include +#include #include #include #include #include -extern void Enable_SPI(SPI_TypeDef* spi); - void furi_hal_spi_init() { - for(size_t i = 0; i < FuriHalSpiDeviceIdMax; ++i) { - hal_gpio_write(furi_hal_spi_devices[i].chip_select, true); - hal_gpio_init( - furi_hal_spi_devices[i].chip_select, - GpioModeOutputPushPull, - GpioPullNo, - GpioSpeedVeryHigh); - } + furi_hal_spi_bus_init(&furi_hal_spi_bus_r); + furi_hal_spi_bus_init(&furi_hal_spi_bus_d); - hal_gpio_init_ex( - &gpio_spi_r_miso, - GpioModeAltFunctionPushPull, - GpioPullNo, - GpioSpeedVeryHigh, - GpioAltFn5SPI1); - hal_gpio_init_ex( - &gpio_spi_r_mosi, - GpioModeAltFunctionPushPull, - GpioPullNo, - GpioSpeedVeryHigh, - GpioAltFn5SPI1); - hal_gpio_init_ex( - &gpio_spi_r_sck, - GpioModeAltFunctionPushPull, - GpioPullNo, - GpioSpeedVeryHigh, - GpioAltFn5SPI1); - - hal_gpio_init_ex( - &gpio_spi_d_miso, - GpioModeAltFunctionPushPull, - GpioPullUp, - GpioSpeedVeryHigh, - GpioAltFn5SPI2); - hal_gpio_init_ex( - &gpio_spi_d_mosi, - GpioModeAltFunctionPushPull, - GpioPullUp, - GpioSpeedVeryHigh, - GpioAltFn5SPI2); - hal_gpio_init_ex( - &gpio_spi_d_sck, - GpioModeAltFunctionPushPull, - GpioPullUp, - GpioSpeedVeryHigh, - GpioAltFn5SPI2); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_nfc); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_display); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_slow); } -void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus) { +void furi_hal_spi_bus_init(FuriHalSpiBus* bus) { assert(bus); + bus->callback(bus, FuriHalSpiBusEventInit); } -void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus) { +void furi_hal_spi_bus_deinit(FuriHalSpiBus* bus) { assert(bus); + bus->callback(bus, FuriHalSpiBusEventDeinit); } -void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config) { - assert(bus); - LL_SPI_DeInit((SPI_TypeDef*)bus->spi); - LL_SPI_Init((SPI_TypeDef*)bus->spi, (LL_SPI_InitTypeDef*)config); - LL_SPI_SetRxFIFOThreshold((SPI_TypeDef*)bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); - LL_SPI_Enable((SPI_TypeDef*)bus->spi); +void furi_hal_spi_bus_handle_init(FuriHalSpiBusHandle* handle) { + assert(handle); + handle->callback(handle, FuriHalSpiBusHandleEventInit); } -void furi_hal_spi_bus_end_txrx(const FuriHalSpiBus* bus, uint32_t timeout) { - while(LL_SPI_GetTxFIFOLevel((SPI_TypeDef*)bus->spi) != LL_SPI_TX_FIFO_EMPTY) +void furi_hal_spi_bus_handle_deinit(FuriHalSpiBusHandle* handle) { + assert(handle); + handle->callback(handle, FuriHalSpiBusHandleEventDeinit); +} + +void furi_hal_spi_acquire(FuriHalSpiBusHandle* handle) { + assert(handle); + + handle->bus->callback(handle->bus, FuriHalSpiBusEventLock); + handle->bus->callback(handle->bus, FuriHalSpiBusEventActivate); + + assert(handle->bus->current_handle == NULL); + + handle->bus->current_handle = handle; + handle->callback(handle, FuriHalSpiBusHandleEventActivate); +} + +void furi_hal_spi_release(FuriHalSpiBusHandle* handle) { + assert(handle); + assert(handle->bus->current_handle == handle); + + // Handle event and unset handle + handle->callback(handle, FuriHalSpiBusHandleEventDeactivate); + handle->bus->current_handle = NULL; + + // Bus events + handle->bus->callback(handle->bus, FuriHalSpiBusEventDeactivate); + handle->bus->callback(handle->bus, FuriHalSpiBusEventUnlock); +} + +static void furi_hal_spi_bus_end_txrx(FuriHalSpiBusHandle* handle, uint32_t timeout) { + while(LL_SPI_GetTxFIFOLevel(handle->bus->spi) != LL_SPI_TX_FIFO_EMPTY) ; - while(LL_SPI_IsActiveFlag_BSY((SPI_TypeDef*)bus->spi)) + while(LL_SPI_IsActiveFlag_BSY(handle->bus->spi)) ; - while(LL_SPI_GetRxFIFOLevel((SPI_TypeDef*)bus->spi) != LL_SPI_RX_FIFO_EMPTY) { - LL_SPI_ReceiveData8((SPI_TypeDef*)bus->spi); + while(LL_SPI_GetRxFIFOLevel(handle->bus->spi) != LL_SPI_RX_FIFO_EMPTY) { + LL_SPI_ReceiveData8(handle->bus->spi); } } -bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { - assert(bus); +bool furi_hal_spi_bus_rx( + FuriHalSpiBusHandle* handle, + uint8_t* buffer, + size_t size, + uint32_t timeout) { + assert(handle); + assert(handle->bus->current_handle == handle); assert(buffer); assert(size > 0); - return furi_hal_spi_bus_trx(bus, buffer, buffer, size, timeout); + return furi_hal_spi_bus_trx(handle, buffer, buffer, size, timeout); } -bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { - assert(bus); +bool furi_hal_spi_bus_tx( + FuriHalSpiBusHandle* handle, + uint8_t* buffer, + size_t size, + uint32_t timeout) { + assert(handle); + assert(handle->bus->current_handle == handle); assert(buffer); assert(size > 0); bool ret = true; while(size > 0) { - if(LL_SPI_IsActiveFlag_TXE((SPI_TypeDef*)bus->spi)) { - LL_SPI_TransmitData8((SPI_TypeDef*)bus->spi, *buffer); + if(LL_SPI_IsActiveFlag_TXE(handle->bus->spi)) { + LL_SPI_TransmitData8(handle->bus->spi, *buffer); buffer++; size--; } } - furi_hal_spi_bus_end_txrx(bus, timeout); - LL_SPI_ClearFlag_OVR((SPI_TypeDef*)bus->spi); + furi_hal_spi_bus_end_txrx(handle, timeout); + LL_SPI_ClearFlag_OVR(handle->bus->spi); return ret; } bool furi_hal_spi_bus_trx( - const FuriHalSpiBus* bus, + FuriHalSpiBusHandle* handle, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { - assert(bus); + assert(handle); + assert(handle->bus->current_handle == handle); assert(tx_buffer); assert(rx_buffer); assert(size > 0); + bool ret = true; size_t tx_size = size; bool tx_allowed = true; while(size > 0) { - if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE((SPI_TypeDef*)bus->spi) && tx_allowed) { - LL_SPI_TransmitData8((SPI_TypeDef*)bus->spi, *tx_buffer); + if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE(handle->bus->spi) && tx_allowed) { + LL_SPI_TransmitData8(handle->bus->spi, *tx_buffer); tx_buffer++; tx_size--; tx_allowed = false; } - if(LL_SPI_IsActiveFlag_RXNE((SPI_TypeDef*)bus->spi)) { - *rx_buffer = LL_SPI_ReceiveData8((SPI_TypeDef*)bus->spi); + if(LL_SPI_IsActiveFlag_RXNE(handle->bus->spi)) { + *rx_buffer = LL_SPI_ReceiveData8(handle->bus->spi); rx_buffer++; size--; tx_allowed = true; } } - furi_hal_spi_bus_end_txrx(bus, timeout); - - return ret; -} - -void furi_hal_spi_device_configure(const FuriHalSpiDevice* device) { - assert(device); - assert(device->config); - - furi_hal_spi_bus_configure(device->bus, device->config); -} - -const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id) { - assert(device_id < FuriHalSpiDeviceIdMax); - - const FuriHalSpiDevice* device = &furi_hal_spi_devices[device_id]; - assert(device); - - furi_hal_spi_bus_lock(device->bus); - furi_hal_spi_device_configure(device); - - return device; -} - -void furi_hal_spi_device_return(const FuriHalSpiDevice* device) { - furi_hal_spi_bus_unlock(device->bus); -} - -bool furi_hal_spi_device_rx( - const FuriHalSpiDevice* device, - uint8_t* buffer, - size_t size, - uint32_t timeout) { - assert(device); - assert(buffer); - assert(size > 0); - - if(device->chip_select) { - hal_gpio_write(device->chip_select, false); - } - - bool ret = furi_hal_spi_bus_rx(device->bus, buffer, size, timeout); - - if(device->chip_select) { - hal_gpio_write(device->chip_select, true); - } - - return ret; -} - -bool furi_hal_spi_device_tx( - const FuriHalSpiDevice* device, - uint8_t* buffer, - size_t size, - uint32_t timeout) { - assert(device); - assert(buffer); - assert(size > 0); - - if(device->chip_select) { - hal_gpio_write(device->chip_select, false); - } - - bool ret = furi_hal_spi_bus_tx(device->bus, buffer, size, timeout); - - if(device->chip_select) { - hal_gpio_write(device->chip_select, true); - } - - return ret; -} - -bool furi_hal_spi_device_trx( - const FuriHalSpiDevice* device, - uint8_t* tx_buffer, - uint8_t* rx_buffer, - size_t size, - uint32_t timeout) { - assert(device); - assert(tx_buffer); - assert(rx_buffer); - assert(size > 0); - - if(device->chip_select) { - hal_gpio_write(device->chip_select, false); - } - - bool ret = furi_hal_spi_bus_trx(device->bus, tx_buffer, rx_buffer, size, timeout); - - if(device->chip_select) { - hal_gpio_write(device->chip_select, true); - } + furi_hal_spi_bus_end_txrx(handle, timeout); return ret; } diff --git a/bootloader/targets/f7/furi-hal/furi-hal-spi.h b/bootloader/targets/f7/furi-hal/furi-hal-spi.h deleted file mode 100644 index 8027eb5d..00000000 --- a/bootloader/targets/f7/furi-hal/furi-hal-spi.h +++ /dev/null @@ -1,129 +0,0 @@ -#pragma once - -#include "main.h" - -#include "furi-hal-spi-config.h" -#include - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Init SPI API - */ -void furi_hal_spi_init(); - -/* Bus Level API */ - -/** Lock SPI bus - * Takes bus mutex, if used - */ -void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus); - -/** Unlock SPI bus - * Releases BUS mutex, if used - */ -void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus); - -/** - * Configure SPI bus - * @param bus - spi bus handler - * @param config - spi configuration structure - */ -void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config); - -/** SPI Receive - * @param bus - spi bus handler - * @param buffer - receive buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); - -/** SPI Transmit - * @param bus - spi bus handler - * @param buffer - transmit buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); - -/** SPI Transmit and Receive - * @param bus - spi bus handlere - * @param tx_buffer - device handle - * @param rx_buffer - device handle - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_bus_trx( - const FuriHalSpiBus* bus, - uint8_t* tx_buffer, - uint8_t* rx_buffer, - size_t size, - uint32_t timeout); - -/* Device Level API */ - -/** Reconfigure SPI bus for device - * @param device - device description - */ -void furi_hal_spi_device_configure(const FuriHalSpiDevice* device); - -/** Get Device handle - * And lock access to the corresponding SPI BUS - * @param device_id - device identifier - * @return device handle - */ -const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id); - -/** Return Device handle - * And unlock access to the corresponding SPI BUS - * @param device - device handle - */ -void furi_hal_spi_device_return(const FuriHalSpiDevice* device); - -/** SPI Recieve - * @param device - device handle - * @param buffer - receive buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_device_rx( - const FuriHalSpiDevice* device, - uint8_t* buffer, - size_t size, - uint32_t timeout); - -/** SPI Transmit - * @param device - device handle - * @param buffer - transmit buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_device_tx( - const FuriHalSpiDevice* device, - uint8_t* buffer, - size_t size, - uint32_t timeout); - -/** SPI Transmit and Receive - * @param device - device handle - * @param tx_buffer - device handle - * @param rx_buffer - device handle - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_device_trx( - const FuriHalSpiDevice* device, - uint8_t* tx_buffer, - uint8_t* rx_buffer, - size_t size, - uint32_t timeout); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/bootloader/targets/furi-hal-include/furi-hal-spi.h b/bootloader/targets/furi-hal-include/furi-hal-spi.h new file mode 100644 index 00000000..b097bdd9 --- /dev/null +++ b/bootloader/targets/furi-hal-include/furi-hal-spi.h @@ -0,0 +1,102 @@ +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Initialize SPI HAL */ +void furi_hal_spi_init(); + +/** Initialize SPI Bus + * + * @param handle pointer to FuriHalSpiBus instance + */ +void furi_hal_spi_bus_init(FuriHalSpiBus* bus); + +/** Deinitialize SPI Bus + * + * @param handle pointer to FuriHalSpiBus instance + */ +void furi_hal_spi_bus_deinit(FuriHalSpiBus* bus); + +/** Initialize SPI Bus Handle + * + * @param handle pointer to FuriHalSpiBusHandle instance + */ +void furi_hal_spi_bus_handle_init(FuriHalSpiBusHandle* handle); + +/** Deinitialize SPI Bus Handle + * + * @param handle pointer to FuriHalSpiBusHandle instance + */ +void furi_hal_spi_bus_handle_deinit(FuriHalSpiBusHandle* handle); + +/** Acquire SPI bus + * + * @warning blocking, calls `furi_crash` on programming error, CS transition is up to handler event routine + * + * @param handle pointer to FuriHalSpiBusHandle instance + */ +void furi_hal_spi_acquire(FuriHalSpiBusHandle* handle); + +/** Release SPI bus + * + * @warning calls `furi_crash` on programming error, CS transition is up to handler event routine + * + * @param handle pointer to FuriHalSpiBusHandle instance + */ +void furi_hal_spi_release(FuriHalSpiBusHandle* handle); + +/** SPI Receive + * + * @param handle pointer to FuriHalSpiBusHandle instance + * @param buffer receive buffer + * @param size transaction size (buffer size) + * @param timeout operation timeout in ms + * + * @return true on sucess + */ +bool furi_hal_spi_bus_rx( + FuriHalSpiBusHandle* handle, + uint8_t* buffer, + size_t size, + uint32_t timeout); + +/** SPI Transmit + * + * @param handle pointer to FuriHalSpiBusHandle instance + * @param buffer transmit buffer + * @param size transaction size (buffer size) + * @param timeout operation timeout in ms + * + * @return true on success + */ +bool furi_hal_spi_bus_tx( + FuriHalSpiBusHandle* handle, + uint8_t* buffer, + size_t size, + uint32_t timeout); + +/** SPI Transmit and Receive + * + * @param handle pointer to FuriHalSpiBusHandle instance + * @param tx_buffer pointer to tx buffer + * @param rx_buffer pointer to rx buffer + * @param size transaction size (buffer size) + * @param timeout operation timeout in ms + * + * @return true on success + */ +bool furi_hal_spi_bus_trx( + FuriHalSpiBusHandle* handle, + uint8_t* tx_buffer, + uint8_t* rx_buffer, + size_t size, + uint32_t timeout); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/firmware/targets/f6/fatfs/spi_sd_hal.c b/firmware/targets/f6/fatfs/spi_sd_hal.c index 70e9bbf1..7e41799f 100644 --- a/firmware/targets/f6/fatfs/spi_sd_hal.c +++ b/firmware/targets/f6/fatfs/spi_sd_hal.c @@ -7,8 +7,6 @@ const uint32_t SpiTimeout = 1000; uint8_t SD_IO_WriteByte(uint8_t Data); -static const FuriHalSpiDevice* sd_spi_dev = &furi_hal_spi_devices[FuriHalSpiDeviceIdSdCardFast]; - /****************************************************************************** BUS OPERATIONS *******************************************************************************/ @@ -21,7 +19,7 @@ static const FuriHalSpiDevice* sd_spi_dev = &furi_hal_spi_devices[FuriHalSpiDevi * @retval None */ static void SPIx_WriteReadData(const uint8_t* DataIn, uint8_t* DataOut, uint16_t DataLength) { - furi_check(furi_hal_spi_bus_trx(sd_spi_dev->bus, (uint8_t*)DataIn, DataOut, DataLength, SpiTimeout)); + furi_check(furi_hal_spi_bus_trx(furi_hal_sd_spi_handle, (uint8_t*)DataIn, DataOut, DataLength, SpiTimeout)); } /** @@ -30,7 +28,7 @@ static void SPIx_WriteReadData(const uint8_t* DataIn, uint8_t* DataOut, uint16_t * @retval None */ __attribute__((unused)) static void SPIx_Write(uint8_t Value) { - furi_check(furi_hal_spi_bus_tx(sd_spi_dev->bus, (uint8_t*)&Value, 1, SpiTimeout)); + furi_check(furi_hal_spi_bus_tx(furi_hal_sd_spi_handle, (uint8_t*)&Value, 1, SpiTimeout)); } /****************************************************************************** @@ -47,7 +45,7 @@ void SD_IO_Init(void) { uint8_t counter = 0; /* SD chip select high */ - hal_gpio_write(sd_spi_dev->chip_select, true); + hal_gpio_write(furi_hal_sd_spi_handle->cs, true); delay_us(10); /* Send dummy byte 0xFF, 10 times with CS high */ @@ -67,9 +65,9 @@ void SD_IO_CSState(uint8_t val) { /* Some SD Cards are prone to fail if CLK-ed too soon after CS transition. Worst case found: 8us */ if(val == 1) { delay_us(10); // Exit guard time for some SD cards - hal_gpio_write(sd_spi_dev->chip_select, true); + hal_gpio_write(furi_hal_sd_spi_handle->cs, true); } else { - hal_gpio_write(sd_spi_dev->chip_select, false); + hal_gpio_write(furi_hal_sd_spi_handle->cs, false); delay_us(10); // Entry guard time for some SD cards } } diff --git a/firmware/targets/f6/fatfs/stm32_adafruit_sd.c b/firmware/targets/f6/fatfs/stm32_adafruit_sd.c index e90ebd62..0d7ff4c0 100644 --- a/firmware/targets/f6/fatfs/stm32_adafruit_sd.c +++ b/firmware/targets/f6/fatfs/stm32_adafruit_sd.c @@ -91,12 +91,7 @@ #include "stdlib.h" #include "string.h" #include "stdio.h" -#include -#include -#include -#include -#include -#include +#include /** @addtogroup BSP * @{ @@ -284,22 +279,22 @@ static uint8_t SD_ReadData(void); /* Private functions ---------------------------------------------------------*/ void SD_SPI_Bus_To_Down_State(){ - hal_gpio_init_ex(&gpio_spi_d_miso, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); - hal_gpio_init_ex(&gpio_spi_d_mosi, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); - hal_gpio_init_ex(&gpio_spi_d_sck, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); + hal_gpio_init_ex(furi_hal_sd_spi_handle->miso, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); + hal_gpio_init_ex(furi_hal_sd_spi_handle->mosi, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); + hal_gpio_init_ex(furi_hal_sd_spi_handle->sck, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); - hal_gpio_write(&gpio_sdcard_cs, false); - hal_gpio_write(&gpio_spi_d_miso, false); - hal_gpio_write(&gpio_spi_d_mosi, false); - hal_gpio_write(&gpio_spi_d_sck, false); + hal_gpio_write(furi_hal_sd_spi_handle->cs, false); + hal_gpio_write(furi_hal_sd_spi_handle->miso, false); + hal_gpio_write(furi_hal_sd_spi_handle->mosi, false); + hal_gpio_write(furi_hal_sd_spi_handle->sck, false); } void SD_SPI_Bus_To_Normal_State(){ - hal_gpio_write(&gpio_sdcard_cs, true); + hal_gpio_write(furi_hal_sd_spi_handle->cs, true); - hal_gpio_init_ex(&gpio_spi_d_miso, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); - hal_gpio_init_ex(&gpio_spi_d_mosi, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); - hal_gpio_init_ex(&gpio_spi_d_sck, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(furi_hal_sd_spi_handle->miso, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(furi_hal_sd_spi_handle->mosi, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(furi_hal_sd_spi_handle->sck, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); } /** @defgroup STM32_ADAFRUIT_SD_Private_Functions @@ -315,7 +310,8 @@ void SD_SPI_Bus_To_Normal_State(){ */ uint8_t BSP_SD_Init(bool reset_card) { /* Slow speed init */ - const FuriHalSpiDevice* sd_spi_slow_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardSlow); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_slow); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_slow; /* We must reset card in spi_lock context */ if(reset_card) { @@ -344,7 +340,8 @@ uint8_t BSP_SD_Init(bool reset_card) { if(res == BSP_SD_OK) break; } - furi_hal_spi_device_return(sd_spi_slow_dev); + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_slow); /* SD initialized and set to SPI mode properly */ return res; diff --git a/firmware/targets/f6/fatfs/user_diskio.c b/firmware/targets/f6/fatfs/user_diskio.c index ca3d60a5..df16245a 100644 --- a/firmware/targets/f6/fatfs/user_diskio.c +++ b/firmware/targets/f6/fatfs/user_diskio.c @@ -35,7 +35,7 @@ /* Includes ------------------------------------------------------------------*/ #include "user_diskio.h" -#include "furi-hal-spi.h" +#include /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ @@ -87,11 +87,13 @@ Diskio_drvTypeDef USER_Driver = { DSTATUS USER_initialize(BYTE pdrv) { /* USER CODE BEGIN INIT */ - const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast; DSTATUS status = User_CheckStatus(pdrv); - furi_hal_spi_device_return(sd_spi_fast_dev); + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); return status; /* USER CODE END INIT */ @@ -120,7 +122,8 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { /* USER CODE BEGIN READ */ DRESULT res = RES_ERROR; - const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast; if(BSP_SD_ReadBlocks((uint32_t*)buff, (uint32_t)(sector), count, SD_DATATIMEOUT) == MSD_OK) { /* wait until the read operation is finished */ @@ -129,7 +132,8 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { res = RES_OK; } - furi_hal_spi_device_return(sd_spi_fast_dev); + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); return res; /* USER CODE END READ */ @@ -149,7 +153,8 @@ DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { /* USER CODE HERE */ DRESULT res = RES_ERROR; - const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast; if(BSP_SD_WriteBlocks((uint32_t*)buff, (uint32_t)(sector), count, SD_DATATIMEOUT) == MSD_OK) { /* wait until the Write operation is finished */ @@ -158,7 +163,8 @@ DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { res = RES_OK; } - furi_hal_spi_device_return(sd_spi_fast_dev); + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); return res; /* USER CODE END WRITE */ @@ -180,7 +186,8 @@ DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) { if(Stat & STA_NOINIT) return RES_NOTRDY; - const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast; switch(cmd) { /* Make sure that no pending write process */ @@ -213,7 +220,8 @@ DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) { res = RES_PARERR; } - furi_hal_spi_device_return(sd_spi_fast_dev); + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); return res; /* USER CODE END IOCTL */ diff --git a/firmware/targets/f6/furi-hal/furi-hal-sd.c b/firmware/targets/f6/furi-hal/furi-hal-sd.c index 01cf9339..82549e16 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-sd.c +++ b/firmware/targets/f6/furi-hal/furi-hal-sd.c @@ -19,4 +19,6 @@ void hal_sd_detect_set_low(void) { bool hal_sd_detect(void) { bool result = !(LL_GPIO_IsInputPinSet(SD_CD_GPIO_Port, SD_CD_Pin)); return result; -} \ No newline at end of file +} + +FuriHalSpiBusHandle* furi_hal_sd_spi_handle = NULL; diff --git a/firmware/targets/f6/furi-hal/furi-hal-spi-config.c b/firmware/targets/f6/furi-hal/furi-hal-spi-config.c index 315d82a2..63253c90 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-spi-config.c +++ b/firmware/targets/f6/furi-hal/furi-hal-spi-config.c @@ -1,10 +1,9 @@ #include #include -#define SPI_R SPI1 -#define SPI_D SPI2 +/* SPI Presets */ -const LL_SPI_InitTypeDef furi_hal_spi_config_nfc = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_2edge_low_8m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -17,7 +16,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_nfc = { .CRCPoly = 7, }; -const LL_SPI_InitTypeDef furi_hal_spi_config_subghz = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_8m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -30,7 +29,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_subghz = { .CRCPoly = 7, }; -const LL_SPI_InitTypeDef furi_hal_spi_config_display = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_4m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -43,10 +42,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_display = { .CRCPoly = 7, }; -/** - * SD Card in fast mode (after init) - */ -const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_16m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -59,10 +55,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast = { .CRCPoly = 7, }; -/** - * SD Card in slow mode (before init) - */ -const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_2m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -75,29 +68,187 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow = { .CRCPoly = 7, }; -osMutexId_t spi_mutex_d = NULL; -osMutexId_t spi_mutex_r = NULL; +/* SPI Buses */ -const FuriHalSpiBus spi_r = { - .spi=SPI_R, - .mutex=&spi_mutex_r, +osMutexId_t furi_hal_spi_bus_r_mutex = NULL; + +static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { + if (event == FuriHalSpiBusEventInit) { + furi_hal_spi_bus_r_mutex = osMutexNew(NULL); + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); + bus->current_handle = NULL; + } else if (event == FuriHalSpiBusEventDeinit) { + furi_check(osMutexDelete(furi_hal_spi_bus_r_mutex)); + } else if (event == FuriHalSpiBusEventLock) { + furi_check(osMutexAcquire(furi_hal_spi_bus_r_mutex, osWaitForever) == osOK); + } else if (event == FuriHalSpiBusEventUnlock) { + furi_check(osMutexRelease(furi_hal_spi_bus_r_mutex) == osOK); + } else if (event == FuriHalSpiBusEventActivate) { + LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1); + } else if (event == FuriHalSpiBusEventDeactivate) { + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); + } +} + +FuriHalSpiBus furi_hal_spi_bus_r = { + .spi=SPI1, + .callback = furi_hal_spi_bus_r_event_callback, +}; + +osMutexId_t furi_hal_spi_bus_d_mutex = NULL; + +static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { + if (event == FuriHalSpiBusEventInit) { + furi_hal_spi_bus_d_mutex = osMutexNew(NULL); + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); + bus->current_handle = NULL; + } else if (event == FuriHalSpiBusEventDeinit) { + furi_check(osMutexDelete(furi_hal_spi_bus_d_mutex)); + } else if (event == FuriHalSpiBusEventLock) { + furi_check(osMutexAcquire(furi_hal_spi_bus_d_mutex, osWaitForever) == osOK); + } else if (event == FuriHalSpiBusEventUnlock) { + furi_check(osMutexRelease(furi_hal_spi_bus_d_mutex) == osOK); + } else if (event == FuriHalSpiBusEventActivate) { + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2); + } else if (event == FuriHalSpiBusEventDeactivate) { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); + } +} + +FuriHalSpiBus furi_hal_spi_bus_d = { + .spi=SPI2, + .callback = furi_hal_spi_bus_d_event_callback, +}; + +/* SPI Bus Handles */ + +inline static void furi_hal_spi_bus_r_handle_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event, const LL_SPI_InitTypeDef* preset) { + if (event == FuriHalSpiBusHandleEventInit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + } else if (event == FuriHalSpiBusHandleEventDeinit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + } else if (event == FuriHalSpiBusHandleEventActivate) { + LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset); + LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); + LL_SPI_Enable(handle->bus->spi); + + hal_gpio_init_ex(handle->miso, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); + hal_gpio_init_ex(handle->mosi, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); + hal_gpio_init_ex(handle->sck, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); + + hal_gpio_write(handle->cs, false); + } else if (event == FuriHalSpiBusHandleEventDeactivate) { + hal_gpio_write(handle->cs, true); + + hal_gpio_init(handle->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + hal_gpio_init(handle->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + hal_gpio_init(handle->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + + LL_SPI_Disable(handle->bus->spi); + } +} + +static void furi_hal_spi_bus_handle_subghz_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_8m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_subghz = { + .bus=&furi_hal_spi_bus_r, + .callback=furi_hal_spi_bus_handle_subghz_event_callback, .miso=&gpio_spi_r_miso, .mosi=&gpio_spi_r_mosi, - .clk=&gpio_spi_r_sck, + .sck=&gpio_spi_r_sck, + .cs=&gpio_subghz_cs, }; -const FuriHalSpiBus spi_d = { - .spi=SPI_D, - .mutex=&spi_mutex_d, +static void furi_hal_spi_bus_handle_nfc_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_2edge_low_8m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_nfc = { + .bus=&furi_hal_spi_bus_r, + .callback=furi_hal_spi_bus_handle_nfc_event_callback, + .miso=&gpio_spi_r_miso, + .mosi=&gpio_spi_r_mosi, + .sck=&gpio_spi_r_sck, + .cs=&gpio_nfc_cs, +}; + +static void furi_hal_spi_bus_handle_external_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_2m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_external = { + .bus=&furi_hal_spi_bus_r, + .callback=furi_hal_spi_bus_handle_external_event_callback, + .miso=&gpio_ext_pa6, + .mosi=&gpio_ext_pa7, + .sck=&gpio_ext_pb3, + .cs=&gpio_ext_pa4, +}; + +inline static void furi_hal_spi_bus_d_handle_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event, const LL_SPI_InitTypeDef* preset) { + if (event == FuriHalSpiBusHandleEventInit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh); + + hal_gpio_init_ex(handle->miso, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(handle->mosi, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(handle->sck, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI2); + + } else if (event == FuriHalSpiBusHandleEventDeinit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullUp, GpioSpeedLow); + } else if (event == FuriHalSpiBusHandleEventActivate) { + LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset); + LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); + LL_SPI_Enable(handle->bus->spi); + hal_gpio_write(handle->cs, false); + } else if (event == FuriHalSpiBusHandleEventDeactivate) { + hal_gpio_write(handle->cs, true); + LL_SPI_Disable(handle->bus->spi); + } +} + +static void furi_hal_spi_bus_handle_display_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_4m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_display = { + .bus=&furi_hal_spi_bus_d, + .callback=furi_hal_spi_bus_handle_display_event_callback, .miso=&gpio_spi_d_miso, .mosi=&gpio_spi_d_mosi, - .clk=&gpio_spi_d_sck, + .sck=&gpio_spi_d_sck, + .cs=&gpio_display_cs, }; -const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax] = { - { .bus=&spi_r, .config=&furi_hal_spi_config_subghz, .chip_select=&gpio_subghz_cs, }, - { .bus=&spi_d, .config=&furi_hal_spi_config_display, .chip_select=&gpio_display_cs, }, - { .bus=&spi_d, .config=&furi_hal_spi_config_sd_fast, .chip_select=&gpio_sdcard_cs, }, - { .bus=&spi_d, .config=&furi_hal_spi_config_sd_slow, .chip_select=&gpio_sdcard_cs, }, - { .bus=&spi_r, .config=&furi_hal_spi_config_nfc, .chip_select=&gpio_nfc_cs }, +static void furi_hal_spi_bus_handle_sd_fast_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_16m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast = { + .bus=&furi_hal_spi_bus_d, + .callback=furi_hal_spi_bus_handle_sd_fast_event_callback, + .miso=&gpio_spi_d_miso, + .mosi=&gpio_spi_d_mosi, + .sck=&gpio_spi_d_sck, + .cs=&gpio_sdcard_cs, +}; + +static void furi_hal_spi_bus_handle_sd_slow_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_2m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_slow = { + .bus=&furi_hal_spi_bus_d, + .callback=furi_hal_spi_bus_handle_sd_slow_event_callback, + .miso=&gpio_spi_d_miso, + .mosi=&gpio_spi_d_mosi, + .sck=&gpio_spi_d_sck, + .cs=&gpio_sdcard_cs, }; diff --git a/firmware/targets/f6/furi-hal/furi-hal-spi-config.h b/firmware/targets/f6/furi-hal/furi-hal-spi-config.h index 3398474a..d483e625 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-spi-config.h +++ b/firmware/targets/f6/furi-hal/furi-hal-spi-config.h @@ -1,62 +1,60 @@ #pragma once -#include -#include -#include +#include #ifdef __cplusplus extern "C" { #endif -extern const LL_SPI_InitTypeDef furi_hal_spi_config_nfc; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_subghz; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_display; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow; +/** Preset for ST25R916 */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_2edge_low_8m; -/** FURI HAL SPI BUS handler - * Structure content may change at some point +/** Preset for CC1101 */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_8m; + +/** Preset for ST7567 (Display) */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_4m; + +/** Preset for SdCard in fast mode */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_16m; + +/** Preset for SdCard in slow mode */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_2m; + +/** Furi Hal Spi Bus R (Radio: CC1101, Nfc, External)*/ +extern FuriHalSpiBus furi_hal_spi_bus_r; + +/** Furi Hal Spi Bus D (Display, SdCard) */ +extern FuriHalSpiBus furi_hal_spi_bus_d; + +/** CC1101 on `furi_hal_spi_bus_r` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_subghz; + +/** ST25R3916 on `furi_hal_spi_bus_r` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_nfc; + +/** External on `furi_hal_spi_bus_r` + * Preset: `furi_hal_spi_preset_1edge_low_2m` + * + * miso: pa6 + * mosi: pa7 + * sck: pb3 + * cs: pa4 (software controlled) + * + * @warning not initialized by default, call `furi_hal_spi_bus_handle_init` to initialize + * Bus pins are floating on inactive state, CS high after initialization + * */ -typedef struct { - const SPI_TypeDef* spi; - const osMutexId_t* mutex; - const GpioPin* miso; - const GpioPin* mosi; - const GpioPin* clk; -} FuriHalSpiBus; +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_external; -/** FURI HAL SPI Device handler - * Structure content may change at some point - */ -typedef struct { - const FuriHalSpiBus* bus; - const LL_SPI_InitTypeDef* config; - const GpioPin* chip_select; -} FuriHalSpiDevice; +/** ST7567(Display) on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_display; -/** FURI HAL SPI Standard Device IDs */ -typedef enum { - FuriHalSpiDeviceIdSubGhz, /** SubGhz: CC1101, non-standard SPI usage */ - FuriHalSpiDeviceIdDisplay, /** Display: ERC12864, only have MOSI */ - FuriHalSpiDeviceIdSdCardFast, /** SDCARD: fast mode, after initialization */ - FuriHalSpiDeviceIdSdCardSlow, /** SDCARD: slow mode, before initialization */ - FuriHalSpiDeviceIdNfc, /** NFC: ST25R3916, pretty standard, but RFAL makes it complex */ +/** SdCard in fast mode on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast; - FuriHalSpiDeviceIdMax, /** Service Value, do not use */ -} FuriHalSpiDeviceId; - -/** Furi Hal Spi Bus R - * CC1101, Nfc - */ -extern const FuriHalSpiBus spi_r; - -/** Furi Hal Spi Bus D - * Display, SdCard - */ -extern const FuriHalSpiBus spi_d; - -/** Furi Hal Spi devices */ -extern const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax]; +/** SdCard in slow mode on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_slow; #ifdef __cplusplus } diff --git a/firmware/targets/f6/furi-hal/furi-hal-spi-types.h b/firmware/targets/f6/furi-hal/furi-hal-spi-types.h new file mode 100644 index 00000000..c7520f4a --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-spi-types.h @@ -0,0 +1,62 @@ +#pragma once + +#include +#include + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct FuriHalSpiBus FuriHalSpiBus; +typedef struct FuriHalSpiBusHandle FuriHalSpiBusHandle; + +/** FuriHal spi bus states */ +typedef enum { + FuriHalSpiBusEventInit, /**< Bus initialization event, called on system start */ + FuriHalSpiBusEventDeinit, /**< Bus deinitialization event, called on system stop */ + FuriHalSpiBusEventLock, /**< Bus lock event, called before activation */ + FuriHalSpiBusEventUnlock, /**< Bus unlock event, called after deactivation */ + FuriHalSpiBusEventActivate, /**< Bus activation event, called before handle activation */ + FuriHalSpiBusEventDeactivate, /**< Bus deactivation event, called after handle deactivation */ +} FuriHalSpiBusEvent; + +/** FuriHal spi bus event callback */ +typedef void (*FuriHalSpiBusEventCallback)(FuriHalSpiBus* bus, FuriHalSpiBusEvent event); + +/** FuriHal spi bus */ +struct FuriHalSpiBus { + SPI_TypeDef* spi; + FuriHalSpiBusEventCallback callback; + FuriHalSpiBusHandle* current_handle; +}; + +/** FuriHal spi handle states */ +typedef enum { + FuriHalSpiBusHandleEventInit, /**< Handle init, called on system start, initialize gpio for idle state */ + FuriHalSpiBusHandleEventDeinit, /**< Handle deinit, called on system stop, deinitialize gpio for default state */ + FuriHalSpiBusHandleEventActivate, /**< Handle activate: connect gpio and apply bus config */ + FuriHalSpiBusHandleEventDeactivate, /**< Handle deactivate: disconnect gpio and reset bus config */ +} FuriHalSpiBusHandleEvent; + +/** FuriHal spi handle event callback */ +typedef void (*FuriHalSpiBusHandleEventCallback)(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event); + +/** FuriHal spi handle */ +struct FuriHalSpiBusHandle { + FuriHalSpiBus* bus; + FuriHalSpiBusHandleEventCallback callback; + const GpioPin* miso; + const GpioPin* mosi; + const GpioPin* sck; + const GpioPin* cs; +}; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/firmware/targets/f6/furi-hal/furi-hal-spi.c b/firmware/targets/f6/furi-hal/furi-hal-spi.c index da7c63df..a0ce7166 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-spi.c +++ b/firmware/targets/f6/furi-hal/furi-hal-spi.c @@ -12,89 +12,104 @@ #define TAG "FuriHalSpi" void furi_hal_spi_init() { - // Spi structure is const, but mutex is not - // Need some hell-ish casting to make it work - *(osMutexId_t*)spi_r.mutex = osMutexNew(NULL); - *(osMutexId_t*)spi_d.mutex = osMutexNew(NULL); - // - for (size_t i=0; imutex, osWaitForever) == osOK); + bus->callback(bus, FuriHalSpiBusEventInit); } -void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus) { +void furi_hal_spi_bus_deinit(FuriHalSpiBus* bus) { furi_assert(bus); - furi_check(osMutexRelease(*bus->mutex) == osOK); + bus->callback(bus, FuriHalSpiBusEventDeinit); } -void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config) { - furi_assert(bus); - - LL_SPI_DeInit((SPI_TypeDef*)bus->spi); - LL_SPI_Init((SPI_TypeDef*)bus->spi, (LL_SPI_InitTypeDef*)config); - LL_SPI_SetRxFIFOThreshold((SPI_TypeDef*)bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); - LL_SPI_Enable((SPI_TypeDef*)bus->spi); +void furi_hal_spi_bus_handle_init(FuriHalSpiBusHandle* handle) { + furi_assert(handle); + handle->callback(handle, FuriHalSpiBusHandleEventInit); } -void furi_hal_spi_bus_end_txrx(const FuriHalSpiBus* bus, uint32_t timeout) { - while(LL_SPI_GetTxFIFOLevel((SPI_TypeDef *)bus->spi) != LL_SPI_TX_FIFO_EMPTY); - while(LL_SPI_IsActiveFlag_BSY((SPI_TypeDef *)bus->spi)); - while(LL_SPI_GetRxFIFOLevel((SPI_TypeDef *)bus->spi) != LL_SPI_RX_FIFO_EMPTY) { - LL_SPI_ReceiveData8((SPI_TypeDef *)bus->spi); +void furi_hal_spi_bus_handle_deinit(FuriHalSpiBusHandle* handle) { + furi_assert(handle); + handle->callback(handle, FuriHalSpiBusHandleEventDeinit); +} + +void furi_hal_spi_acquire(FuriHalSpiBusHandle* handle) { + furi_assert(handle); + + handle->bus->callback(handle->bus, FuriHalSpiBusEventLock); + handle->bus->callback(handle->bus, FuriHalSpiBusEventActivate); + + furi_assert(handle->bus->current_handle == NULL); + + handle->bus->current_handle = handle; + handle->callback(handle, FuriHalSpiBusHandleEventActivate); +} + +void furi_hal_spi_release(FuriHalSpiBusHandle* handle) { + furi_assert(handle); + furi_assert(handle->bus->current_handle == handle); + + // Handle event and unset handle + handle->callback(handle, FuriHalSpiBusHandleEventDeactivate); + handle->bus->current_handle = NULL; + + // Bus events + handle->bus->callback(handle->bus, FuriHalSpiBusEventDeactivate); + handle->bus->callback(handle->bus, FuriHalSpiBusEventUnlock); +} + +static void furi_hal_spi_bus_end_txrx(FuriHalSpiBusHandle* handle, uint32_t timeout) { + while(LL_SPI_GetTxFIFOLevel(handle->bus->spi) != LL_SPI_TX_FIFO_EMPTY); + while(LL_SPI_IsActiveFlag_BSY(handle->bus->spi)); + while(LL_SPI_GetRxFIFOLevel(handle->bus->spi) != LL_SPI_RX_FIFO_EMPTY) { + LL_SPI_ReceiveData8(handle->bus->spi); } } -bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { - furi_assert(bus); +bool furi_hal_spi_bus_rx(FuriHalSpiBusHandle* handle, uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(handle); + furi_assert(handle->bus->current_handle == handle); furi_assert(buffer); furi_assert(size > 0); - return furi_hal_spi_bus_trx(bus, buffer, buffer, size, timeout); + return furi_hal_spi_bus_trx(handle, buffer, buffer, size, timeout); } -bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { - furi_assert(bus); +bool furi_hal_spi_bus_tx(FuriHalSpiBusHandle* handle, uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(handle); + furi_assert(handle->bus->current_handle == handle); furi_assert(buffer); furi_assert(size > 0); bool ret = true; while(size > 0) { - if (LL_SPI_IsActiveFlag_TXE((SPI_TypeDef *)bus->spi)) { - LL_SPI_TransmitData8((SPI_TypeDef *)bus->spi, *buffer); + if (LL_SPI_IsActiveFlag_TXE(handle->bus->spi)) { + LL_SPI_TransmitData8(handle->bus->spi, *buffer); buffer++; size--; } } - furi_hal_spi_bus_end_txrx(bus, timeout); - LL_SPI_ClearFlag_OVR((SPI_TypeDef *)bus->spi); + furi_hal_spi_bus_end_txrx(handle, timeout); + LL_SPI_ClearFlag_OVR(handle->bus->spi); return ret; } -bool furi_hal_spi_bus_trx(const FuriHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { - furi_assert(bus); +bool furi_hal_spi_bus_trx(FuriHalSpiBusHandle* handle, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { + furi_assert(handle); + furi_assert(handle->bus->current_handle == handle); furi_assert(tx_buffer); furi_assert(rx_buffer); furi_assert(size > 0); @@ -104,99 +119,22 @@ bool furi_hal_spi_bus_trx(const FuriHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* bool tx_allowed = true; while(size > 0) { - if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE((SPI_TypeDef *)bus->spi) && tx_allowed) { - LL_SPI_TransmitData8((SPI_TypeDef *)bus->spi, *tx_buffer); + if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE(handle->bus->spi) && tx_allowed) { + LL_SPI_TransmitData8(handle->bus->spi, *tx_buffer); tx_buffer++; tx_size--; tx_allowed = false; } - if(LL_SPI_IsActiveFlag_RXNE((SPI_TypeDef *)bus->spi)) { - *rx_buffer = LL_SPI_ReceiveData8((SPI_TypeDef *)bus->spi); + if(LL_SPI_IsActiveFlag_RXNE(handle->bus->spi)) { + *rx_buffer = LL_SPI_ReceiveData8(handle->bus->spi); rx_buffer++; size--; tx_allowed = true; } } - furi_hal_spi_bus_end_txrx(bus, timeout); - - return ret; -} - -void furi_hal_spi_device_configure(const FuriHalSpiDevice* device) { - furi_assert(device); - furi_assert(device->config); - - furi_hal_spi_bus_configure(device->bus, device->config); -} - -const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id) { - furi_assert(device_id < FuriHalSpiDeviceIdMax); - - const FuriHalSpiDevice* device = &furi_hal_spi_devices[device_id]; - furi_assert(device); - furi_hal_spi_bus_lock(device->bus); - furi_hal_spi_device_configure(device); - - return device; -} - -void furi_hal_spi_device_return(const FuriHalSpiDevice* device) { - furi_hal_spi_bus_unlock(device->bus); -} - -bool furi_hal_spi_device_rx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) { - furi_assert(device); - furi_assert(buffer); - furi_assert(size > 0); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, false); - } - - bool ret = furi_hal_spi_bus_rx(device->bus, buffer, size, timeout); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, true); - } - - return ret; -} - -bool furi_hal_spi_device_tx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) { - furi_assert(device); - furi_assert(buffer); - furi_assert(size > 0); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, false); - } - - bool ret = furi_hal_spi_bus_tx(device->bus, buffer, size, timeout); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, true); - } - - return ret; -} - -bool furi_hal_spi_device_trx(const FuriHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { - furi_assert(device); - furi_assert(tx_buffer); - furi_assert(rx_buffer); - furi_assert(size > 0); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, false); - } - - bool ret = furi_hal_spi_bus_trx(device->bus, tx_buffer, rx_buffer, size, timeout); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, true); - } + furi_hal_spi_bus_end_txrx(handle, timeout); return ret; } diff --git a/firmware/targets/f6/furi-hal/furi-hal-subghz.c b/firmware/targets/f6/furi-hal/furi-hal-subghz.c index 25fa3b7a..dac4514e 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-subghz.c +++ b/firmware/targets/f6/furi-hal/furi-hal-subghz.c @@ -269,7 +269,7 @@ void furi_hal_subghz_init() { furi_assert(furi_hal_subghz_state == SubGhzStateInit); furi_hal_subghz_state = SubGhzStateIdle; - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); #ifdef FURI_HAL_SUBGHZ_TX_GPIO hal_gpio_init(&FURI_HAL_SUBGHZ_TX_GPIO, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); @@ -277,58 +277,58 @@ void furi_hal_subghz_init() { // Reset hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - cc1101_reset(device); - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); + cc1101_reset(&furi_hal_spi_bus_handle_subghz); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance); // Prepare GD0 for power on self test hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); // GD0 low - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHW); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW); while(hal_gpio_read(&gpio_cc1101_g0) != false) ; // GD0 high - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); while(hal_gpio_read(&gpio_cc1101_g0) != true) ; // Reset GD0 to floating state - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance); hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); // RF switches hal_gpio_init(&gpio_rf_sw_0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW); // Go to sleep - cc1101_shutdown(device); + cc1101_shutdown(&furi_hal_spi_bus_handle_subghz); - furi_hal_spi_device_return(device); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); FURI_LOG_I(TAG, "Init OK"); } void furi_hal_subghz_sleep() { furi_assert(furi_hal_subghz_state == SubGhzStateIdle); - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); - cc1101_switch_to_idle(device); + cc1101_switch_to_idle(&furi_hal_spi_bus_handle_subghz); - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance); hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - cc1101_shutdown(device); + cc1101_shutdown(&furi_hal_spi_bus_handle_subghz); - furi_hal_spi_device_return(device); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_dump_state() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); printf( "[furi_hal_subghz] cc1101 chip %d, version %d\r\n", - cc1101_get_partnumber(device), - cc1101_get_version(device)); - furi_hal_spi_device_return(device); + cc1101_get_partnumber(&furi_hal_spi_bus_handle_subghz), + cc1101_get_version(&furi_hal_spi_bus_handle_subghz)); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { @@ -350,81 +350,81 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { } void furi_hal_subghz_load_registers(const uint8_t data[][2]) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_reset(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_reset(&furi_hal_spi_bus_handle_subghz); uint32_t i = 0; while(data[i][0]) { - cc1101_write_reg(device, data[i][0], data[i][1]); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, data[i][0], data[i][1]); i++; } - furi_hal_spi_device_return(device); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_load_patable(const uint8_t data[8]) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_set_pa_table(device, data); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_set_pa_table(&furi_hal_spi_bus_handle_subghz, data); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_write_packet(const uint8_t* data, uint8_t size) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_flush_tx(device); - cc1101_write_fifo(device, data, size); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_flush_tx(&furi_hal_spi_bus_handle_subghz); + cc1101_write_fifo(&furi_hal_spi_bus_handle_subghz, data, size); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_flush_rx() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_flush_rx(device); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_flush_rx(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_read_packet(uint8_t* data, uint8_t* size) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_read_fifo(device, data, size); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_read_fifo(&furi_hal_spi_bus_handle_subghz, data, size); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_shutdown() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); // Reset and shutdown - cc1101_shutdown(device); - furi_hal_spi_device_return(device); + cc1101_shutdown(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_reset() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - cc1101_switch_to_idle(device); - cc1101_reset(device); - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); - furi_hal_spi_device_return(device); + cc1101_switch_to_idle(&furi_hal_spi_bus_handle_subghz); + cc1101_reset(&furi_hal_spi_bus_handle_subghz); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_idle() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_switch_to_idle(device); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_switch_to_idle(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_rx() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_switch_to_rx(device); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_switch_to_rx(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } bool furi_hal_subghz_tx() { if(furi_hal_subghz_regulation != SubGhzRegulationTxRx) return false; - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_switch_to_tx(device); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_switch_to_tx(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); return true; } float furi_hal_subghz_get_rssi() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - int32_t rssi_dec = cc1101_get_rssi(device); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + int32_t rssi_dec = cc1101_get_rssi(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); float rssi = rssi_dec; if(rssi_dec >= 128) { @@ -461,7 +461,7 @@ uint32_t furi_hal_subghz_set_frequency_and_path(uint32_t value) { } uint32_t furi_hal_subghz_set_frequency(uint32_t value) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); //checking regional settings bool txrx = false; @@ -503,37 +503,37 @@ uint32_t furi_hal_subghz_set_frequency(uint32_t value) { furi_hal_subghz_regulation = SubGhzRegulationOnlyRx; } - uint32_t real_frequency = cc1101_set_frequency(device, value); - cc1101_calibrate(device); + uint32_t real_frequency = cc1101_set_frequency(&furi_hal_spi_bus_handle_subghz, value); + cc1101_calibrate(&furi_hal_spi_bus_handle_subghz); while(true) { - CC1101Status status = cc1101_get_status(device); + CC1101Status status = cc1101_get_status(&furi_hal_spi_bus_handle_subghz); if(status.STATE == CC1101StateIDLE) break; } - furi_hal_spi_device_return(device); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); return real_frequency; } void furi_hal_subghz_set_path(FuriHalSubGhzPath path) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); if(path == FuriHalSubGhzPath433) { hal_gpio_write(&gpio_rf_sw_0, 0); - cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); } else if(path == FuriHalSubGhzPath315) { hal_gpio_write(&gpio_rf_sw_0, 1); - cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW); } else if(path == FuriHalSubGhzPath868) { hal_gpio_write(&gpio_rf_sw_0, 1); - cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); } else if(path == FuriHalSubGhzPathIsolate) { hal_gpio_write(&gpio_rf_sw_0, 0); - cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW); } else { furi_crash(NULL); } - furi_hal_spi_device_return(device); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } volatile uint32_t furi_hal_subghz_capture_delta_duration = 0; diff --git a/firmware/targets/f7/fatfs/spi_sd_hal.c b/firmware/targets/f7/fatfs/spi_sd_hal.c index 70e9bbf1..7e41799f 100644 --- a/firmware/targets/f7/fatfs/spi_sd_hal.c +++ b/firmware/targets/f7/fatfs/spi_sd_hal.c @@ -7,8 +7,6 @@ const uint32_t SpiTimeout = 1000; uint8_t SD_IO_WriteByte(uint8_t Data); -static const FuriHalSpiDevice* sd_spi_dev = &furi_hal_spi_devices[FuriHalSpiDeviceIdSdCardFast]; - /****************************************************************************** BUS OPERATIONS *******************************************************************************/ @@ -21,7 +19,7 @@ static const FuriHalSpiDevice* sd_spi_dev = &furi_hal_spi_devices[FuriHalSpiDevi * @retval None */ static void SPIx_WriteReadData(const uint8_t* DataIn, uint8_t* DataOut, uint16_t DataLength) { - furi_check(furi_hal_spi_bus_trx(sd_spi_dev->bus, (uint8_t*)DataIn, DataOut, DataLength, SpiTimeout)); + furi_check(furi_hal_spi_bus_trx(furi_hal_sd_spi_handle, (uint8_t*)DataIn, DataOut, DataLength, SpiTimeout)); } /** @@ -30,7 +28,7 @@ static void SPIx_WriteReadData(const uint8_t* DataIn, uint8_t* DataOut, uint16_t * @retval None */ __attribute__((unused)) static void SPIx_Write(uint8_t Value) { - furi_check(furi_hal_spi_bus_tx(sd_spi_dev->bus, (uint8_t*)&Value, 1, SpiTimeout)); + furi_check(furi_hal_spi_bus_tx(furi_hal_sd_spi_handle, (uint8_t*)&Value, 1, SpiTimeout)); } /****************************************************************************** @@ -47,7 +45,7 @@ void SD_IO_Init(void) { uint8_t counter = 0; /* SD chip select high */ - hal_gpio_write(sd_spi_dev->chip_select, true); + hal_gpio_write(furi_hal_sd_spi_handle->cs, true); delay_us(10); /* Send dummy byte 0xFF, 10 times with CS high */ @@ -67,9 +65,9 @@ void SD_IO_CSState(uint8_t val) { /* Some SD Cards are prone to fail if CLK-ed too soon after CS transition. Worst case found: 8us */ if(val == 1) { delay_us(10); // Exit guard time for some SD cards - hal_gpio_write(sd_spi_dev->chip_select, true); + hal_gpio_write(furi_hal_sd_spi_handle->cs, true); } else { - hal_gpio_write(sd_spi_dev->chip_select, false); + hal_gpio_write(furi_hal_sd_spi_handle->cs, false); delay_us(10); // Entry guard time for some SD cards } } diff --git a/firmware/targets/f7/fatfs/stm32_adafruit_sd.c b/firmware/targets/f7/fatfs/stm32_adafruit_sd.c index e90ebd62..0d7ff4c0 100644 --- a/firmware/targets/f7/fatfs/stm32_adafruit_sd.c +++ b/firmware/targets/f7/fatfs/stm32_adafruit_sd.c @@ -91,12 +91,7 @@ #include "stdlib.h" #include "string.h" #include "stdio.h" -#include -#include -#include -#include -#include -#include +#include /** @addtogroup BSP * @{ @@ -284,22 +279,22 @@ static uint8_t SD_ReadData(void); /* Private functions ---------------------------------------------------------*/ void SD_SPI_Bus_To_Down_State(){ - hal_gpio_init_ex(&gpio_spi_d_miso, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); - hal_gpio_init_ex(&gpio_spi_d_mosi, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); - hal_gpio_init_ex(&gpio_spi_d_sck, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); + hal_gpio_init_ex(furi_hal_sd_spi_handle->miso, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); + hal_gpio_init_ex(furi_hal_sd_spi_handle->mosi, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); + hal_gpio_init_ex(furi_hal_sd_spi_handle->sck, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); - hal_gpio_write(&gpio_sdcard_cs, false); - hal_gpio_write(&gpio_spi_d_miso, false); - hal_gpio_write(&gpio_spi_d_mosi, false); - hal_gpio_write(&gpio_spi_d_sck, false); + hal_gpio_write(furi_hal_sd_spi_handle->cs, false); + hal_gpio_write(furi_hal_sd_spi_handle->miso, false); + hal_gpio_write(furi_hal_sd_spi_handle->mosi, false); + hal_gpio_write(furi_hal_sd_spi_handle->sck, false); } void SD_SPI_Bus_To_Normal_State(){ - hal_gpio_write(&gpio_sdcard_cs, true); + hal_gpio_write(furi_hal_sd_spi_handle->cs, true); - hal_gpio_init_ex(&gpio_spi_d_miso, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); - hal_gpio_init_ex(&gpio_spi_d_mosi, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); - hal_gpio_init_ex(&gpio_spi_d_sck, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(furi_hal_sd_spi_handle->miso, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(furi_hal_sd_spi_handle->mosi, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(furi_hal_sd_spi_handle->sck, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); } /** @defgroup STM32_ADAFRUIT_SD_Private_Functions @@ -315,7 +310,8 @@ void SD_SPI_Bus_To_Normal_State(){ */ uint8_t BSP_SD_Init(bool reset_card) { /* Slow speed init */ - const FuriHalSpiDevice* sd_spi_slow_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardSlow); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_slow); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_slow; /* We must reset card in spi_lock context */ if(reset_card) { @@ -344,7 +340,8 @@ uint8_t BSP_SD_Init(bool reset_card) { if(res == BSP_SD_OK) break; } - furi_hal_spi_device_return(sd_spi_slow_dev); + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_slow); /* SD initialized and set to SPI mode properly */ return res; diff --git a/firmware/targets/f7/fatfs/user_diskio.c b/firmware/targets/f7/fatfs/user_diskio.c index ca3d60a5..df16245a 100644 --- a/firmware/targets/f7/fatfs/user_diskio.c +++ b/firmware/targets/f7/fatfs/user_diskio.c @@ -35,7 +35,7 @@ /* Includes ------------------------------------------------------------------*/ #include "user_diskio.h" -#include "furi-hal-spi.h" +#include /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ @@ -87,11 +87,13 @@ Diskio_drvTypeDef USER_Driver = { DSTATUS USER_initialize(BYTE pdrv) { /* USER CODE BEGIN INIT */ - const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast; DSTATUS status = User_CheckStatus(pdrv); - furi_hal_spi_device_return(sd_spi_fast_dev); + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); return status; /* USER CODE END INIT */ @@ -120,7 +122,8 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { /* USER CODE BEGIN READ */ DRESULT res = RES_ERROR; - const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast; if(BSP_SD_ReadBlocks((uint32_t*)buff, (uint32_t)(sector), count, SD_DATATIMEOUT) == MSD_OK) { /* wait until the read operation is finished */ @@ -129,7 +132,8 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) { res = RES_OK; } - furi_hal_spi_device_return(sd_spi_fast_dev); + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); return res; /* USER CODE END READ */ @@ -149,7 +153,8 @@ DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { /* USER CODE HERE */ DRESULT res = RES_ERROR; - const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast; if(BSP_SD_WriteBlocks((uint32_t*)buff, (uint32_t)(sector), count, SD_DATATIMEOUT) == MSD_OK) { /* wait until the Write operation is finished */ @@ -158,7 +163,8 @@ DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) { res = RES_OK; } - furi_hal_spi_device_return(sd_spi_fast_dev); + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); return res; /* USER CODE END WRITE */ @@ -180,7 +186,8 @@ DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) { if(Stat & STA_NOINIT) return RES_NOTRDY; - const FuriHalSpiDevice* sd_spi_fast_dev = furi_hal_spi_device_get(FuriHalSpiDeviceIdSdCardFast); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast); + furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast; switch(cmd) { /* Make sure that no pending write process */ @@ -213,7 +220,8 @@ DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) { res = RES_PARERR; } - furi_hal_spi_device_return(sd_spi_fast_dev); + furi_hal_sd_spi_handle = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast); return res; /* USER CODE END IOCTL */ diff --git a/firmware/targets/f7/furi-hal/furi-hal-sd.c b/firmware/targets/f7/furi-hal/furi-hal-sd.c index 01cf9339..82549e16 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-sd.c +++ b/firmware/targets/f7/furi-hal/furi-hal-sd.c @@ -19,4 +19,6 @@ void hal_sd_detect_set_low(void) { bool hal_sd_detect(void) { bool result = !(LL_GPIO_IsInputPinSet(SD_CD_GPIO_Port, SD_CD_Pin)); return result; -} \ No newline at end of file +} + +FuriHalSpiBusHandle* furi_hal_sd_spi_handle = NULL; diff --git a/firmware/targets/f7/furi-hal/furi-hal-spi-config.c b/firmware/targets/f7/furi-hal/furi-hal-spi-config.c index 315d82a2..63253c90 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-spi-config.c +++ b/firmware/targets/f7/furi-hal/furi-hal-spi-config.c @@ -1,10 +1,9 @@ #include #include -#define SPI_R SPI1 -#define SPI_D SPI2 +/* SPI Presets */ -const LL_SPI_InitTypeDef furi_hal_spi_config_nfc = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_2edge_low_8m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -17,7 +16,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_nfc = { .CRCPoly = 7, }; -const LL_SPI_InitTypeDef furi_hal_spi_config_subghz = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_8m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -30,7 +29,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_subghz = { .CRCPoly = 7, }; -const LL_SPI_InitTypeDef furi_hal_spi_config_display = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_4m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -43,10 +42,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_display = { .CRCPoly = 7, }; -/** - * SD Card in fast mode (after init) - */ -const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_16m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -59,10 +55,7 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast = { .CRCPoly = 7, }; -/** - * SD Card in slow mode (before init) - */ -const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow = { +const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_2m = { .Mode = LL_SPI_MODE_MASTER, .TransferDirection = LL_SPI_FULL_DUPLEX, .DataWidth = LL_SPI_DATAWIDTH_8BIT, @@ -75,29 +68,187 @@ const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow = { .CRCPoly = 7, }; -osMutexId_t spi_mutex_d = NULL; -osMutexId_t spi_mutex_r = NULL; +/* SPI Buses */ -const FuriHalSpiBus spi_r = { - .spi=SPI_R, - .mutex=&spi_mutex_r, +osMutexId_t furi_hal_spi_bus_r_mutex = NULL; + +static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { + if (event == FuriHalSpiBusEventInit) { + furi_hal_spi_bus_r_mutex = osMutexNew(NULL); + LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); + bus->current_handle = NULL; + } else if (event == FuriHalSpiBusEventDeinit) { + furi_check(osMutexDelete(furi_hal_spi_bus_r_mutex)); + } else if (event == FuriHalSpiBusEventLock) { + furi_check(osMutexAcquire(furi_hal_spi_bus_r_mutex, osWaitForever) == osOK); + } else if (event == FuriHalSpiBusEventUnlock) { + furi_check(osMutexRelease(furi_hal_spi_bus_r_mutex) == osOK); + } else if (event == FuriHalSpiBusEventActivate) { + LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1); + } else if (event == FuriHalSpiBusEventDeactivate) { + LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); + } +} + +FuriHalSpiBus furi_hal_spi_bus_r = { + .spi=SPI1, + .callback = furi_hal_spi_bus_r_event_callback, +}; + +osMutexId_t furi_hal_spi_bus_d_mutex = NULL; + +static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { + if (event == FuriHalSpiBusEventInit) { + furi_hal_spi_bus_d_mutex = osMutexNew(NULL); + LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); + bus->current_handle = NULL; + } else if (event == FuriHalSpiBusEventDeinit) { + furi_check(osMutexDelete(furi_hal_spi_bus_d_mutex)); + } else if (event == FuriHalSpiBusEventLock) { + furi_check(osMutexAcquire(furi_hal_spi_bus_d_mutex, osWaitForever) == osOK); + } else if (event == FuriHalSpiBusEventUnlock) { + furi_check(osMutexRelease(furi_hal_spi_bus_d_mutex) == osOK); + } else if (event == FuriHalSpiBusEventActivate) { + LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2); + } else if (event == FuriHalSpiBusEventDeactivate) { + LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); + } +} + +FuriHalSpiBus furi_hal_spi_bus_d = { + .spi=SPI2, + .callback = furi_hal_spi_bus_d_event_callback, +}; + +/* SPI Bus Handles */ + +inline static void furi_hal_spi_bus_r_handle_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event, const LL_SPI_InitTypeDef* preset) { + if (event == FuriHalSpiBusHandleEventInit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + } else if (event == FuriHalSpiBusHandleEventDeinit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + } else if (event == FuriHalSpiBusHandleEventActivate) { + LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset); + LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); + LL_SPI_Enable(handle->bus->spi); + + hal_gpio_init_ex(handle->miso, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); + hal_gpio_init_ex(handle->mosi, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); + hal_gpio_init_ex(handle->sck, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); + + hal_gpio_write(handle->cs, false); + } else if (event == FuriHalSpiBusHandleEventDeactivate) { + hal_gpio_write(handle->cs, true); + + hal_gpio_init(handle->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + hal_gpio_init(handle->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + hal_gpio_init(handle->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + + LL_SPI_Disable(handle->bus->spi); + } +} + +static void furi_hal_spi_bus_handle_subghz_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_8m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_subghz = { + .bus=&furi_hal_spi_bus_r, + .callback=furi_hal_spi_bus_handle_subghz_event_callback, .miso=&gpio_spi_r_miso, .mosi=&gpio_spi_r_mosi, - .clk=&gpio_spi_r_sck, + .sck=&gpio_spi_r_sck, + .cs=&gpio_subghz_cs, }; -const FuriHalSpiBus spi_d = { - .spi=SPI_D, - .mutex=&spi_mutex_d, +static void furi_hal_spi_bus_handle_nfc_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_2edge_low_8m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_nfc = { + .bus=&furi_hal_spi_bus_r, + .callback=furi_hal_spi_bus_handle_nfc_event_callback, + .miso=&gpio_spi_r_miso, + .mosi=&gpio_spi_r_mosi, + .sck=&gpio_spi_r_sck, + .cs=&gpio_nfc_cs, +}; + +static void furi_hal_spi_bus_handle_external_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_2m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_external = { + .bus=&furi_hal_spi_bus_r, + .callback=furi_hal_spi_bus_handle_external_event_callback, + .miso=&gpio_ext_pa6, + .mosi=&gpio_ext_pa7, + .sck=&gpio_ext_pb3, + .cs=&gpio_ext_pa4, +}; + +inline static void furi_hal_spi_bus_d_handle_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event, const LL_SPI_InitTypeDef* preset) { + if (event == FuriHalSpiBusHandleEventInit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh); + + hal_gpio_init_ex(handle->miso, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(handle->mosi, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI2); + hal_gpio_init_ex(handle->sck, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI2); + + } else if (event == FuriHalSpiBusHandleEventDeinit) { + hal_gpio_write(handle->cs, true); + hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullUp, GpioSpeedLow); + } else if (event == FuriHalSpiBusHandleEventActivate) { + LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset); + LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); + LL_SPI_Enable(handle->bus->spi); + hal_gpio_write(handle->cs, false); + } else if (event == FuriHalSpiBusHandleEventDeactivate) { + hal_gpio_write(handle->cs, true); + LL_SPI_Disable(handle->bus->spi); + } +} + +static void furi_hal_spi_bus_handle_display_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_4m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_display = { + .bus=&furi_hal_spi_bus_d, + .callback=furi_hal_spi_bus_handle_display_event_callback, .miso=&gpio_spi_d_miso, .mosi=&gpio_spi_d_mosi, - .clk=&gpio_spi_d_sck, + .sck=&gpio_spi_d_sck, + .cs=&gpio_display_cs, }; -const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax] = { - { .bus=&spi_r, .config=&furi_hal_spi_config_subghz, .chip_select=&gpio_subghz_cs, }, - { .bus=&spi_d, .config=&furi_hal_spi_config_display, .chip_select=&gpio_display_cs, }, - { .bus=&spi_d, .config=&furi_hal_spi_config_sd_fast, .chip_select=&gpio_sdcard_cs, }, - { .bus=&spi_d, .config=&furi_hal_spi_config_sd_slow, .chip_select=&gpio_sdcard_cs, }, - { .bus=&spi_r, .config=&furi_hal_spi_config_nfc, .chip_select=&gpio_nfc_cs }, +static void furi_hal_spi_bus_handle_sd_fast_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_16m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast = { + .bus=&furi_hal_spi_bus_d, + .callback=furi_hal_spi_bus_handle_sd_fast_event_callback, + .miso=&gpio_spi_d_miso, + .mosi=&gpio_spi_d_mosi, + .sck=&gpio_spi_d_sck, + .cs=&gpio_sdcard_cs, +}; + +static void furi_hal_spi_bus_handle_sd_slow_event_callback(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event) { + furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_2m); +} + +FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_slow = { + .bus=&furi_hal_spi_bus_d, + .callback=furi_hal_spi_bus_handle_sd_slow_event_callback, + .miso=&gpio_spi_d_miso, + .mosi=&gpio_spi_d_mosi, + .sck=&gpio_spi_d_sck, + .cs=&gpio_sdcard_cs, }; diff --git a/firmware/targets/f7/furi-hal/furi-hal-spi-config.h b/firmware/targets/f7/furi-hal/furi-hal-spi-config.h index 3398474a..d483e625 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-spi-config.h +++ b/firmware/targets/f7/furi-hal/furi-hal-spi-config.h @@ -1,62 +1,60 @@ #pragma once -#include -#include -#include +#include #ifdef __cplusplus extern "C" { #endif -extern const LL_SPI_InitTypeDef furi_hal_spi_config_nfc; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_subghz; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_display; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_fast; -extern const LL_SPI_InitTypeDef furi_hal_spi_config_sd_slow; +/** Preset for ST25R916 */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_2edge_low_8m; -/** FURI HAL SPI BUS handler - * Structure content may change at some point +/** Preset for CC1101 */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_8m; + +/** Preset for ST7567 (Display) */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_4m; + +/** Preset for SdCard in fast mode */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_16m; + +/** Preset for SdCard in slow mode */ +extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_2m; + +/** Furi Hal Spi Bus R (Radio: CC1101, Nfc, External)*/ +extern FuriHalSpiBus furi_hal_spi_bus_r; + +/** Furi Hal Spi Bus D (Display, SdCard) */ +extern FuriHalSpiBus furi_hal_spi_bus_d; + +/** CC1101 on `furi_hal_spi_bus_r` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_subghz; + +/** ST25R3916 on `furi_hal_spi_bus_r` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_nfc; + +/** External on `furi_hal_spi_bus_r` + * Preset: `furi_hal_spi_preset_1edge_low_2m` + * + * miso: pa6 + * mosi: pa7 + * sck: pb3 + * cs: pa4 (software controlled) + * + * @warning not initialized by default, call `furi_hal_spi_bus_handle_init` to initialize + * Bus pins are floating on inactive state, CS high after initialization + * */ -typedef struct { - const SPI_TypeDef* spi; - const osMutexId_t* mutex; - const GpioPin* miso; - const GpioPin* mosi; - const GpioPin* clk; -} FuriHalSpiBus; +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_external; -/** FURI HAL SPI Device handler - * Structure content may change at some point - */ -typedef struct { - const FuriHalSpiBus* bus; - const LL_SPI_InitTypeDef* config; - const GpioPin* chip_select; -} FuriHalSpiDevice; +/** ST7567(Display) on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_display; -/** FURI HAL SPI Standard Device IDs */ -typedef enum { - FuriHalSpiDeviceIdSubGhz, /** SubGhz: CC1101, non-standard SPI usage */ - FuriHalSpiDeviceIdDisplay, /** Display: ERC12864, only have MOSI */ - FuriHalSpiDeviceIdSdCardFast, /** SDCARD: fast mode, after initialization */ - FuriHalSpiDeviceIdSdCardSlow, /** SDCARD: slow mode, before initialization */ - FuriHalSpiDeviceIdNfc, /** NFC: ST25R3916, pretty standard, but RFAL makes it complex */ +/** SdCard in fast mode on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast; - FuriHalSpiDeviceIdMax, /** Service Value, do not use */ -} FuriHalSpiDeviceId; - -/** Furi Hal Spi Bus R - * CC1101, Nfc - */ -extern const FuriHalSpiBus spi_r; - -/** Furi Hal Spi Bus D - * Display, SdCard - */ -extern const FuriHalSpiBus spi_d; - -/** Furi Hal Spi devices */ -extern const FuriHalSpiDevice furi_hal_spi_devices[FuriHalSpiDeviceIdMax]; +/** SdCard in slow mode on `furi_hal_spi_bus_d` */ +extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_slow; #ifdef __cplusplus } diff --git a/firmware/targets/f7/furi-hal/furi-hal-spi-types.h b/firmware/targets/f7/furi-hal/furi-hal-spi-types.h new file mode 100644 index 00000000..c7520f4a --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-spi-types.h @@ -0,0 +1,62 @@ +#pragma once + +#include +#include + +#include + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct FuriHalSpiBus FuriHalSpiBus; +typedef struct FuriHalSpiBusHandle FuriHalSpiBusHandle; + +/** FuriHal spi bus states */ +typedef enum { + FuriHalSpiBusEventInit, /**< Bus initialization event, called on system start */ + FuriHalSpiBusEventDeinit, /**< Bus deinitialization event, called on system stop */ + FuriHalSpiBusEventLock, /**< Bus lock event, called before activation */ + FuriHalSpiBusEventUnlock, /**< Bus unlock event, called after deactivation */ + FuriHalSpiBusEventActivate, /**< Bus activation event, called before handle activation */ + FuriHalSpiBusEventDeactivate, /**< Bus deactivation event, called after handle deactivation */ +} FuriHalSpiBusEvent; + +/** FuriHal spi bus event callback */ +typedef void (*FuriHalSpiBusEventCallback)(FuriHalSpiBus* bus, FuriHalSpiBusEvent event); + +/** FuriHal spi bus */ +struct FuriHalSpiBus { + SPI_TypeDef* spi; + FuriHalSpiBusEventCallback callback; + FuriHalSpiBusHandle* current_handle; +}; + +/** FuriHal spi handle states */ +typedef enum { + FuriHalSpiBusHandleEventInit, /**< Handle init, called on system start, initialize gpio for idle state */ + FuriHalSpiBusHandleEventDeinit, /**< Handle deinit, called on system stop, deinitialize gpio for default state */ + FuriHalSpiBusHandleEventActivate, /**< Handle activate: connect gpio and apply bus config */ + FuriHalSpiBusHandleEventDeactivate, /**< Handle deactivate: disconnect gpio and reset bus config */ +} FuriHalSpiBusHandleEvent; + +/** FuriHal spi handle event callback */ +typedef void (*FuriHalSpiBusHandleEventCallback)(FuriHalSpiBusHandle* handle, FuriHalSpiBusHandleEvent event); + +/** FuriHal spi handle */ +struct FuriHalSpiBusHandle { + FuriHalSpiBus* bus; + FuriHalSpiBusHandleEventCallback callback; + const GpioPin* miso; + const GpioPin* mosi; + const GpioPin* sck; + const GpioPin* cs; +}; + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/firmware/targets/f7/furi-hal/furi-hal-spi.c b/firmware/targets/f7/furi-hal/furi-hal-spi.c index da7c63df..a0ce7166 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-spi.c +++ b/firmware/targets/f7/furi-hal/furi-hal-spi.c @@ -12,89 +12,104 @@ #define TAG "FuriHalSpi" void furi_hal_spi_init() { - // Spi structure is const, but mutex is not - // Need some hell-ish casting to make it work - *(osMutexId_t*)spi_r.mutex = osMutexNew(NULL); - *(osMutexId_t*)spi_d.mutex = osMutexNew(NULL); - // - for (size_t i=0; imutex, osWaitForever) == osOK); + bus->callback(bus, FuriHalSpiBusEventInit); } -void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus) { +void furi_hal_spi_bus_deinit(FuriHalSpiBus* bus) { furi_assert(bus); - furi_check(osMutexRelease(*bus->mutex) == osOK); + bus->callback(bus, FuriHalSpiBusEventDeinit); } -void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config) { - furi_assert(bus); - - LL_SPI_DeInit((SPI_TypeDef*)bus->spi); - LL_SPI_Init((SPI_TypeDef*)bus->spi, (LL_SPI_InitTypeDef*)config); - LL_SPI_SetRxFIFOThreshold((SPI_TypeDef*)bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); - LL_SPI_Enable((SPI_TypeDef*)bus->spi); +void furi_hal_spi_bus_handle_init(FuriHalSpiBusHandle* handle) { + furi_assert(handle); + handle->callback(handle, FuriHalSpiBusHandleEventInit); } -void furi_hal_spi_bus_end_txrx(const FuriHalSpiBus* bus, uint32_t timeout) { - while(LL_SPI_GetTxFIFOLevel((SPI_TypeDef *)bus->spi) != LL_SPI_TX_FIFO_EMPTY); - while(LL_SPI_IsActiveFlag_BSY((SPI_TypeDef *)bus->spi)); - while(LL_SPI_GetRxFIFOLevel((SPI_TypeDef *)bus->spi) != LL_SPI_RX_FIFO_EMPTY) { - LL_SPI_ReceiveData8((SPI_TypeDef *)bus->spi); +void furi_hal_spi_bus_handle_deinit(FuriHalSpiBusHandle* handle) { + furi_assert(handle); + handle->callback(handle, FuriHalSpiBusHandleEventDeinit); +} + +void furi_hal_spi_acquire(FuriHalSpiBusHandle* handle) { + furi_assert(handle); + + handle->bus->callback(handle->bus, FuriHalSpiBusEventLock); + handle->bus->callback(handle->bus, FuriHalSpiBusEventActivate); + + furi_assert(handle->bus->current_handle == NULL); + + handle->bus->current_handle = handle; + handle->callback(handle, FuriHalSpiBusHandleEventActivate); +} + +void furi_hal_spi_release(FuriHalSpiBusHandle* handle) { + furi_assert(handle); + furi_assert(handle->bus->current_handle == handle); + + // Handle event and unset handle + handle->callback(handle, FuriHalSpiBusHandleEventDeactivate); + handle->bus->current_handle = NULL; + + // Bus events + handle->bus->callback(handle->bus, FuriHalSpiBusEventDeactivate); + handle->bus->callback(handle->bus, FuriHalSpiBusEventUnlock); +} + +static void furi_hal_spi_bus_end_txrx(FuriHalSpiBusHandle* handle, uint32_t timeout) { + while(LL_SPI_GetTxFIFOLevel(handle->bus->spi) != LL_SPI_TX_FIFO_EMPTY); + while(LL_SPI_IsActiveFlag_BSY(handle->bus->spi)); + while(LL_SPI_GetRxFIFOLevel(handle->bus->spi) != LL_SPI_RX_FIFO_EMPTY) { + LL_SPI_ReceiveData8(handle->bus->spi); } } -bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { - furi_assert(bus); +bool furi_hal_spi_bus_rx(FuriHalSpiBusHandle* handle, uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(handle); + furi_assert(handle->bus->current_handle == handle); furi_assert(buffer); furi_assert(size > 0); - return furi_hal_spi_bus_trx(bus, buffer, buffer, size, timeout); + return furi_hal_spi_bus_trx(handle, buffer, buffer, size, timeout); } -bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout) { - furi_assert(bus); +bool furi_hal_spi_bus_tx(FuriHalSpiBusHandle* handle, uint8_t* buffer, size_t size, uint32_t timeout) { + furi_assert(handle); + furi_assert(handle->bus->current_handle == handle); furi_assert(buffer); furi_assert(size > 0); bool ret = true; while(size > 0) { - if (LL_SPI_IsActiveFlag_TXE((SPI_TypeDef *)bus->spi)) { - LL_SPI_TransmitData8((SPI_TypeDef *)bus->spi, *buffer); + if (LL_SPI_IsActiveFlag_TXE(handle->bus->spi)) { + LL_SPI_TransmitData8(handle->bus->spi, *buffer); buffer++; size--; } } - furi_hal_spi_bus_end_txrx(bus, timeout); - LL_SPI_ClearFlag_OVR((SPI_TypeDef *)bus->spi); + furi_hal_spi_bus_end_txrx(handle, timeout); + LL_SPI_ClearFlag_OVR(handle->bus->spi); return ret; } -bool furi_hal_spi_bus_trx(const FuriHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { - furi_assert(bus); +bool furi_hal_spi_bus_trx(FuriHalSpiBusHandle* handle, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { + furi_assert(handle); + furi_assert(handle->bus->current_handle == handle); furi_assert(tx_buffer); furi_assert(rx_buffer); furi_assert(size > 0); @@ -104,99 +119,22 @@ bool furi_hal_spi_bus_trx(const FuriHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* bool tx_allowed = true; while(size > 0) { - if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE((SPI_TypeDef *)bus->spi) && tx_allowed) { - LL_SPI_TransmitData8((SPI_TypeDef *)bus->spi, *tx_buffer); + if(tx_size > 0 && LL_SPI_IsActiveFlag_TXE(handle->bus->spi) && tx_allowed) { + LL_SPI_TransmitData8(handle->bus->spi, *tx_buffer); tx_buffer++; tx_size--; tx_allowed = false; } - if(LL_SPI_IsActiveFlag_RXNE((SPI_TypeDef *)bus->spi)) { - *rx_buffer = LL_SPI_ReceiveData8((SPI_TypeDef *)bus->spi); + if(LL_SPI_IsActiveFlag_RXNE(handle->bus->spi)) { + *rx_buffer = LL_SPI_ReceiveData8(handle->bus->spi); rx_buffer++; size--; tx_allowed = true; } } - furi_hal_spi_bus_end_txrx(bus, timeout); - - return ret; -} - -void furi_hal_spi_device_configure(const FuriHalSpiDevice* device) { - furi_assert(device); - furi_assert(device->config); - - furi_hal_spi_bus_configure(device->bus, device->config); -} - -const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id) { - furi_assert(device_id < FuriHalSpiDeviceIdMax); - - const FuriHalSpiDevice* device = &furi_hal_spi_devices[device_id]; - furi_assert(device); - furi_hal_spi_bus_lock(device->bus); - furi_hal_spi_device_configure(device); - - return device; -} - -void furi_hal_spi_device_return(const FuriHalSpiDevice* device) { - furi_hal_spi_bus_unlock(device->bus); -} - -bool furi_hal_spi_device_rx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) { - furi_assert(device); - furi_assert(buffer); - furi_assert(size > 0); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, false); - } - - bool ret = furi_hal_spi_bus_rx(device->bus, buffer, size, timeout); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, true); - } - - return ret; -} - -bool furi_hal_spi_device_tx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout) { - furi_assert(device); - furi_assert(buffer); - furi_assert(size > 0); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, false); - } - - bool ret = furi_hal_spi_bus_tx(device->bus, buffer, size, timeout); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, true); - } - - return ret; -} - -bool furi_hal_spi_device_trx(const FuriHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout) { - furi_assert(device); - furi_assert(tx_buffer); - furi_assert(rx_buffer); - furi_assert(size > 0); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, false); - } - - bool ret = furi_hal_spi_bus_trx(device->bus, tx_buffer, rx_buffer, size, timeout); - - if (device->chip_select) { - hal_gpio_write(device->chip_select, true); - } + furi_hal_spi_bus_end_txrx(handle, timeout); return ret; } diff --git a/firmware/targets/f7/furi-hal/furi-hal-subghz.c b/firmware/targets/f7/furi-hal/furi-hal-subghz.c index 25fa3b7a..dac4514e 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-subghz.c +++ b/firmware/targets/f7/furi-hal/furi-hal-subghz.c @@ -269,7 +269,7 @@ void furi_hal_subghz_init() { furi_assert(furi_hal_subghz_state == SubGhzStateInit); furi_hal_subghz_state = SubGhzStateIdle; - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); #ifdef FURI_HAL_SUBGHZ_TX_GPIO hal_gpio_init(&FURI_HAL_SUBGHZ_TX_GPIO, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); @@ -277,58 +277,58 @@ void furi_hal_subghz_init() { // Reset hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - cc1101_reset(device); - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); + cc1101_reset(&furi_hal_spi_bus_handle_subghz); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance); // Prepare GD0 for power on self test hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); // GD0 low - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHW); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW); while(hal_gpio_read(&gpio_cc1101_g0) != false) ; // GD0 high - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); while(hal_gpio_read(&gpio_cc1101_g0) != true) ; // Reset GD0 to floating state - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance); hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); // RF switches hal_gpio_init(&gpio_rf_sw_0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW); // Go to sleep - cc1101_shutdown(device); + cc1101_shutdown(&furi_hal_spi_bus_handle_subghz); - furi_hal_spi_device_return(device); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); FURI_LOG_I(TAG, "Init OK"); } void furi_hal_subghz_sleep() { furi_assert(furi_hal_subghz_state == SubGhzStateIdle); - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); - cc1101_switch_to_idle(device); + cc1101_switch_to_idle(&furi_hal_spi_bus_handle_subghz); - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance); hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - cc1101_shutdown(device); + cc1101_shutdown(&furi_hal_spi_bus_handle_subghz); - furi_hal_spi_device_return(device); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_dump_state() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); printf( "[furi_hal_subghz] cc1101 chip %d, version %d\r\n", - cc1101_get_partnumber(device), - cc1101_get_version(device)); - furi_hal_spi_device_return(device); + cc1101_get_partnumber(&furi_hal_spi_bus_handle_subghz), + cc1101_get_version(&furi_hal_spi_bus_handle_subghz)); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { @@ -350,81 +350,81 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { } void furi_hal_subghz_load_registers(const uint8_t data[][2]) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_reset(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_reset(&furi_hal_spi_bus_handle_subghz); uint32_t i = 0; while(data[i][0]) { - cc1101_write_reg(device, data[i][0], data[i][1]); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, data[i][0], data[i][1]); i++; } - furi_hal_spi_device_return(device); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_load_patable(const uint8_t data[8]) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_set_pa_table(device, data); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_set_pa_table(&furi_hal_spi_bus_handle_subghz, data); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_write_packet(const uint8_t* data, uint8_t size) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_flush_tx(device); - cc1101_write_fifo(device, data, size); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_flush_tx(&furi_hal_spi_bus_handle_subghz); + cc1101_write_fifo(&furi_hal_spi_bus_handle_subghz, data, size); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_flush_rx() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_flush_rx(device); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_flush_rx(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_read_packet(uint8_t* data, uint8_t* size) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_read_fifo(device, data, size); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_read_fifo(&furi_hal_spi_bus_handle_subghz, data, size); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_shutdown() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); // Reset and shutdown - cc1101_shutdown(device); - furi_hal_spi_device_return(device); + cc1101_shutdown(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_reset() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - cc1101_switch_to_idle(device); - cc1101_reset(device); - cc1101_write_reg(device, CC1101_IOCFG0, CC1101IocfgHighImpedance); - furi_hal_spi_device_return(device); + cc1101_switch_to_idle(&furi_hal_spi_bus_handle_subghz); + cc1101_reset(&furi_hal_spi_bus_handle_subghz); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_idle() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_switch_to_idle(device); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_switch_to_idle(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } void furi_hal_subghz_rx() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_switch_to_rx(device); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_switch_to_rx(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } bool furi_hal_subghz_tx() { if(furi_hal_subghz_regulation != SubGhzRegulationTxRx) return false; - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - cc1101_switch_to_tx(device); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_switch_to_tx(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); return true; } float furi_hal_subghz_get_rssi() { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); - int32_t rssi_dec = cc1101_get_rssi(device); - furi_hal_spi_device_return(device); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + int32_t rssi_dec = cc1101_get_rssi(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); float rssi = rssi_dec; if(rssi_dec >= 128) { @@ -461,7 +461,7 @@ uint32_t furi_hal_subghz_set_frequency_and_path(uint32_t value) { } uint32_t furi_hal_subghz_set_frequency(uint32_t value) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); //checking regional settings bool txrx = false; @@ -503,37 +503,37 @@ uint32_t furi_hal_subghz_set_frequency(uint32_t value) { furi_hal_subghz_regulation = SubGhzRegulationOnlyRx; } - uint32_t real_frequency = cc1101_set_frequency(device, value); - cc1101_calibrate(device); + uint32_t real_frequency = cc1101_set_frequency(&furi_hal_spi_bus_handle_subghz, value); + cc1101_calibrate(&furi_hal_spi_bus_handle_subghz); while(true) { - CC1101Status status = cc1101_get_status(device); + CC1101Status status = cc1101_get_status(&furi_hal_spi_bus_handle_subghz); if(status.STATE == CC1101StateIDLE) break; } - furi_hal_spi_device_return(device); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); return real_frequency; } void furi_hal_subghz_set_path(FuriHalSubGhzPath path) { - const FuriHalSpiDevice* device = furi_hal_spi_device_get(FuriHalSpiDeviceIdSubGhz); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); if(path == FuriHalSubGhzPath433) { hal_gpio_write(&gpio_rf_sw_0, 0); - cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); } else if(path == FuriHalSubGhzPath315) { hal_gpio_write(&gpio_rf_sw_0, 1); - cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW); } else if(path == FuriHalSubGhzPath868) { hal_gpio_write(&gpio_rf_sw_0, 1); - cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); } else if(path == FuriHalSubGhzPathIsolate) { hal_gpio_write(&gpio_rf_sw_0, 0); - cc1101_write_reg(device, CC1101_IOCFG2, CC1101IocfgHW); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW); } else { furi_crash(NULL); } - furi_hal_spi_device_return(device); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } volatile uint32_t furi_hal_subghz_capture_delta_duration = 0; diff --git a/firmware/targets/furi-hal-include/furi-hal-sd.h b/firmware/targets/furi-hal-include/furi-hal-sd.h index 212ec3ee..9399726e 100644 --- a/firmware/targets/furi-hal-include/furi-hal-sd.h +++ b/firmware/targets/furi-hal-include/furi-hal-sd.h @@ -5,6 +5,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -24,6 +25,9 @@ void hal_sd_detect_set_low(void); */ bool hal_sd_detect(void); +/** Pointer to currently used SPI Handle */ +extern FuriHalSpiBusHandle* furi_hal_sd_spi_handle; + #ifdef __cplusplus } #endif diff --git a/firmware/targets/furi-hal-include/furi-hal-spi.h b/firmware/targets/furi-hal-include/furi-hal-spi.h index e42dcdc4..97913f63 100644 --- a/firmware/targets/furi-hal-include/furi-hal-spi.h +++ b/firmware/targets/furi-hal-include/furi-hal-spi.h @@ -1,106 +1,88 @@ #pragma once -#include "main.h" -#include "furi-hal-spi-config.h" -#include + +#include #include #ifdef __cplusplus extern "C" { #endif -/** - * Init SPI API - */ +/** Initialize SPI HAL */ void furi_hal_spi_init(); -/* Bus Level API */ - -/** Lock SPI bus - * Takes bus mutex, if used +/** Initialize SPI Bus + * + * @param handle pointer to FuriHalSpiBus instance */ -void furi_hal_spi_bus_lock(const FuriHalSpiBus* bus); +void furi_hal_spi_bus_init(FuriHalSpiBus* bus); -/** Unlock SPI bus - * Releases BUS mutex, if used +/** Deinitialize SPI Bus + * + * @param handle pointer to FuriHalSpiBus instance */ -void furi_hal_spi_bus_unlock(const FuriHalSpiBus* bus); +void furi_hal_spi_bus_deinit(FuriHalSpiBus* bus); -/** Configure SPI bus - * @param bus - spi bus handler - * @param config - spi configuration structure +/** Initialize SPI Bus Handle + * + * @param handle pointer to FuriHalSpiBusHandle instance */ -void furi_hal_spi_bus_configure(const FuriHalSpiBus* bus, const LL_SPI_InitTypeDef* config); +void furi_hal_spi_bus_handle_init(FuriHalSpiBusHandle* handle); + +/** Deinitialize SPI Bus Handle + * + * @param handle pointer to FuriHalSpiBusHandle instance + */ +void furi_hal_spi_bus_handle_deinit(FuriHalSpiBusHandle* handle); + +/** Acquire SPI bus + * + * @warning blocking, calls `furi_crash` on programming error, CS transition is up to handler event routine + * + * @param handle pointer to FuriHalSpiBusHandle instance + */ +void furi_hal_spi_acquire(FuriHalSpiBusHandle* handle); + +/** Release SPI bus + * + * @warning calls `furi_crash` on programming error, CS transition is up to handler event routine + * + * @param handle pointer to FuriHalSpiBusHandle instance + */ +void furi_hal_spi_release(FuriHalSpiBusHandle* handle); /** SPI Receive - * @param bus - spi bus handler - * @param buffer - receive buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms + * + * @param handle pointer to FuriHalSpiBusHandle instance + * @param buffer receive buffer + * @param size transaction size (buffer size) + * @param timeout operation timeout in ms + * + * @return true on sucess */ -bool furi_hal_spi_bus_rx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); +bool furi_hal_spi_bus_rx(FuriHalSpiBusHandle* handle, uint8_t* buffer, size_t size, uint32_t timeout); /** SPI Transmit - * @param bus - spi bus handler - * @param buffer - transmit buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms + * + * @param handle pointer to FuriHalSpiBusHandle instance + * @param buffer transmit buffer + * @param size transaction size (buffer size) + * @param timeout operation timeout in ms + * + * @return true on success */ -bool furi_hal_spi_bus_tx(const FuriHalSpiBus* bus, uint8_t* buffer, size_t size, uint32_t timeout); +bool furi_hal_spi_bus_tx(FuriHalSpiBusHandle* handle, uint8_t* buffer, size_t size, uint32_t timeout); /** SPI Transmit and Receive - * @param bus - spi bus handlere - * @param tx_buffer - device handle - * @param rx_buffer - device handle - * @param size - transaction size - * @param timeout - bus operation timeout in ms + * + * @param handle pointer to FuriHalSpiBusHandle instance + * @param tx_buffer pointer to tx buffer + * @param rx_buffer pointer to rx buffer + * @param size transaction size (buffer size) + * @param timeout operation timeout in ms + * + * @return true on success */ -bool furi_hal_spi_bus_trx(const FuriHalSpiBus* bus, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout); - -/* Device Level API */ - -/** Reconfigure SPI bus for device - * @param device - device description - */ -void furi_hal_spi_device_configure(const FuriHalSpiDevice* device); - -/** Get Device handle - * And lock access to the corresponding SPI BUS - * @param device_id - device identifier - * @return device handle - */ -const FuriHalSpiDevice* furi_hal_spi_device_get(FuriHalSpiDeviceId device_id); - -/** Return Device handle - * And unlock access to the corresponding SPI BUS - * @param device - device handle - */ -void furi_hal_spi_device_return(const FuriHalSpiDevice* device); - -/** SPI Recieve - * @param device - device handle - * @param buffer - receive buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_device_rx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout); - -/** SPI Transmit - * @param device - device handle - * @param buffer - transmit buffer - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_device_tx(const FuriHalSpiDevice* device, uint8_t* buffer, size_t size, uint32_t timeout); - -/** SPI Transmit and Receive - * @param device - device handle - * @param tx_buffer - device handle - * @param rx_buffer - device handle - * @param size - transaction size - * @param timeout - bus operation timeout in ms - */ -bool furi_hal_spi_device_trx(const FuriHalSpiDevice* device, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout); - +bool furi_hal_spi_bus_trx(FuriHalSpiBusHandle* handle, uint8_t* tx_buffer, uint8_t* rx_buffer, size_t size, uint32_t timeout); #ifdef __cplusplus } diff --git a/firmware/targets/furi-hal-include/furi-hal.h b/firmware/targets/furi-hal-include/furi-hal.h index eb1fefeb..2357e7fe 100644 --- a/firmware/targets/furi-hal-include/furi-hal.h +++ b/firmware/targets/furi-hal-include/furi-hal.h @@ -14,6 +14,7 @@ template struct STOP_EXTERNING_ME {}; #include "furi-hal-crypto.h" #include "furi-hal-console.h" #include "furi-hal-os.h" +#include "furi-hal-sd.h" #include "furi-hal-i2c.h" #include "furi-hal-resources.h" #include "furi-hal-gpio.h" diff --git a/lib/ST25RFAL002/platform.c b/lib/ST25RFAL002/platform.c index 58363cac..5e9dd5d2 100644 --- a/lib/ST25RFAL002/platform.c +++ b/lib/ST25RFAL002/platform.c @@ -7,7 +7,6 @@ static osThreadAttr_t platform_irq_thread_attr; static volatile osThreadId_t platform_irq_thread_id = NULL; static volatile PlatformIrqCallback platform_irq_callback = NULL; -static FuriHalSpiDevice* platform_st25r3916 = NULL; static const GpioPin pin = {ST25R_INT_PORT, ST25R_INT_PIN}; void nfc_isr(void* _ctx) { @@ -49,14 +48,13 @@ void platformSetIrqCallback(PlatformIrqCallback callback) { } HAL_StatusTypeDef platformSpiTxRx(const uint8_t *txBuf, uint8_t *rxBuf, uint16_t len) { - furi_assert(platform_st25r3916); bool ret = false; if (txBuf && rxBuf) { - ret = furi_hal_spi_bus_trx(platform_st25r3916->bus, (uint8_t*)txBuf, rxBuf, len, 1000); + ret = furi_hal_spi_bus_trx(&furi_hal_spi_bus_handle_nfc, (uint8_t*)txBuf, rxBuf, len, 1000); } else if (txBuf) { - ret = furi_hal_spi_bus_tx(platform_st25r3916->bus, (uint8_t*)txBuf, len, 1000); + ret = furi_hal_spi_bus_tx(&furi_hal_spi_bus_handle_nfc, (uint8_t*)txBuf, len, 1000); } else if (rxBuf) { - ret = furi_hal_spi_bus_rx(platform_st25r3916->bus, (uint8_t*)rxBuf, len, 1000); + ret = furi_hal_spi_bus_rx(&furi_hal_spi_bus_handle_nfc, (uint8_t*)rxBuf, len, 1000); } if(!ret) { @@ -68,15 +66,9 @@ HAL_StatusTypeDef platformSpiTxRx(const uint8_t *txBuf, uint8_t *rxBuf, uint16_t } void platformProtectST25RComm() { - // Don't check platform_st25r3916 since spi device is used simultaneously from nfc worker - // thread and platformIrqWorker thread with the highest priority - - // furi_assert(platform_st25r3916 == NULL); - platform_st25r3916 = (FuriHalSpiDevice*)furi_hal_spi_device_get(FuriHalSpiDeviceIdNfc); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_nfc); } void platformUnprotectST25RComm() { - // furi_assert(platform_st25r3916); - furi_hal_spi_device_return(platform_st25r3916); - // platform_st25r3916 = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_nfc); } diff --git a/lib/drivers/cc1101.c b/lib/drivers/cc1101.c index 0d5a23df..af37dea9 100644 --- a/lib/drivers/cc1101.c +++ b/lib/drivers/cc1101.c @@ -4,180 +4,164 @@ #include #include -CC1101Status cc1101_strobe(const FuriHalSpiDevice* device, uint8_t strobe) { +CC1101Status cc1101_strobe(FuriHalSpiBusHandle* handle, uint8_t strobe) { uint8_t tx[1] = { strobe }; CC1101Status rx[1] = { 0 }; - hal_gpio_write(device->chip_select, false); - while(hal_gpio_read(device->bus->miso)); - furi_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 1, CC1101_TIMEOUT); - hal_gpio_write(device->chip_select, true); + while(hal_gpio_read(handle->miso)); + furi_hal_spi_bus_trx(handle, tx, (uint8_t*)rx, 1, CC1101_TIMEOUT); assert(rx[0].CHIP_RDYn == 0); return rx[0]; } -CC1101Status cc1101_write_reg(const FuriHalSpiDevice* device, uint8_t reg, uint8_t data) { +CC1101Status cc1101_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data) { uint8_t tx[2] = { reg, data }; CC1101Status rx[2] = { 0 }; - hal_gpio_write(device->chip_select, false); - while(hal_gpio_read(device->bus->miso)); - furi_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); - hal_gpio_write(device->chip_select, true); + while(hal_gpio_read(handle->miso)); + furi_hal_spi_bus_trx(handle, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); assert((rx[0].CHIP_RDYn|rx[1].CHIP_RDYn) == 0); return rx[1]; } -CC1101Status cc1101_read_reg(const FuriHalSpiDevice* device, uint8_t reg, uint8_t* data) { +CC1101Status cc1101_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data) { assert(sizeof(CC1101Status) == 1); uint8_t tx[2] = { reg|CC1101_READ, 0}; CC1101Status rx[2] = { 0 }; - hal_gpio_write(device->chip_select, false); - while(hal_gpio_read(device->bus->miso)); - furi_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); - hal_gpio_write(device->chip_select, true); + while(hal_gpio_read(handle->miso)); + furi_hal_spi_bus_trx(handle, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); assert((rx[0].CHIP_RDYn) == 0); *data = *(uint8_t*)&rx[1]; return rx[0]; } -uint8_t cc1101_get_partnumber(const FuriHalSpiDevice* device) { +uint8_t cc1101_get_partnumber(FuriHalSpiBusHandle* handle) { uint8_t partnumber=0; - cc1101_read_reg(device, CC1101_STATUS_PARTNUM|CC1101_BURST, &partnumber); + cc1101_read_reg(handle, CC1101_STATUS_PARTNUM|CC1101_BURST, &partnumber); return partnumber; } -uint8_t cc1101_get_version(const FuriHalSpiDevice* device) { +uint8_t cc1101_get_version(FuriHalSpiBusHandle* handle) { uint8_t version=0; - cc1101_read_reg(device, CC1101_STATUS_VERSION|CC1101_BURST, &version); + cc1101_read_reg(handle, CC1101_STATUS_VERSION|CC1101_BURST, &version); return version; } -uint8_t cc1101_get_rssi(const FuriHalSpiDevice* device) { +uint8_t cc1101_get_rssi(FuriHalSpiBusHandle* handle) { uint8_t rssi=0; - cc1101_read_reg(device, CC1101_STATUS_RSSI|CC1101_BURST, &rssi); + cc1101_read_reg(handle, CC1101_STATUS_RSSI|CC1101_BURST, &rssi); return rssi; } -void cc1101_reset(const FuriHalSpiDevice* device) { - hal_gpio_write(device->chip_select, false); +void cc1101_reset(FuriHalSpiBusHandle* handle) { delay_us(1000); - hal_gpio_write(device->chip_select, true); delay_us(1000); - cc1101_strobe(device, CC1101_STROBE_SRES); + cc1101_strobe(handle, CC1101_STROBE_SRES); } -CC1101Status cc1101_get_status(const FuriHalSpiDevice* device) { - return cc1101_strobe(device, CC1101_STROBE_SNOP); +CC1101Status cc1101_get_status(FuriHalSpiBusHandle* handle) { + return cc1101_strobe(handle, CC1101_STROBE_SNOP); } -void cc1101_shutdown(const FuriHalSpiDevice* device) { - cc1101_strobe(device, CC1101_STROBE_SPWD); +void cc1101_shutdown(FuriHalSpiBusHandle* handle) { + cc1101_strobe(handle, CC1101_STROBE_SPWD); } -void cc1101_calibrate(const FuriHalSpiDevice* device) { - cc1101_strobe(device, CC1101_STROBE_SCAL); +void cc1101_calibrate(FuriHalSpiBusHandle* handle) { + cc1101_strobe(handle, CC1101_STROBE_SCAL); } -void cc1101_switch_to_idle(const FuriHalSpiDevice* device) { - cc1101_strobe(device, CC1101_STROBE_SIDLE); +void cc1101_switch_to_idle(FuriHalSpiBusHandle* handle) { + cc1101_strobe(handle, CC1101_STROBE_SIDLE); } -void cc1101_switch_to_rx(const FuriHalSpiDevice* device) { - cc1101_strobe(device, CC1101_STROBE_SRX); +void cc1101_switch_to_rx(FuriHalSpiBusHandle* handle) { + cc1101_strobe(handle, CC1101_STROBE_SRX); } -void cc1101_switch_to_tx(const FuriHalSpiDevice* device) { - cc1101_strobe(device, CC1101_STROBE_STX); +void cc1101_switch_to_tx(FuriHalSpiBusHandle* handle) { + cc1101_strobe(handle, CC1101_STROBE_STX); } -void cc1101_flush_rx(const FuriHalSpiDevice* device) { - cc1101_strobe(device, CC1101_STROBE_SFRX); +void cc1101_flush_rx(FuriHalSpiBusHandle* handle) { + cc1101_strobe(handle, CC1101_STROBE_SFRX); } -void cc1101_flush_tx(const FuriHalSpiDevice* device) { - cc1101_strobe(device, CC1101_STROBE_SFTX); +void cc1101_flush_tx(FuriHalSpiBusHandle* handle) { + cc1101_strobe(handle, CC1101_STROBE_SFTX); } -uint32_t cc1101_set_frequency(const FuriHalSpiDevice* device, uint32_t value) { +uint32_t cc1101_set_frequency(FuriHalSpiBusHandle* handle, uint32_t value) { uint64_t real_value = (uint64_t)value * CC1101_FDIV / CC1101_QUARTZ; // Sanity check assert((real_value & CC1101_FMASK) == real_value); - cc1101_write_reg(device, CC1101_FREQ2, (real_value >> 16) & 0xFF); - cc1101_write_reg(device, CC1101_FREQ1, (real_value >> 8 ) & 0xFF); - cc1101_write_reg(device, CC1101_FREQ0, (real_value >> 0 ) & 0xFF); + cc1101_write_reg(handle, CC1101_FREQ2, (real_value >> 16) & 0xFF); + cc1101_write_reg(handle, CC1101_FREQ1, (real_value >> 8 ) & 0xFF); + cc1101_write_reg(handle, CC1101_FREQ0, (real_value >> 0 ) & 0xFF); uint64_t real_frequency = real_value * CC1101_QUARTZ / CC1101_FDIV; return (uint32_t)real_frequency; } -uint32_t cc1101_set_intermediate_frequency(const FuriHalSpiDevice* device, uint32_t value) { +uint32_t cc1101_set_intermediate_frequency(FuriHalSpiBusHandle* handle, uint32_t value) { uint64_t real_value = value * CC1101_IFDIV / CC1101_QUARTZ; assert((real_value & 0xFF) == real_value); - cc1101_write_reg(device, CC1101_FSCTRL0, (real_value >> 0 ) & 0xFF); + cc1101_write_reg(handle, CC1101_FSCTRL0, (real_value >> 0 ) & 0xFF); uint64_t real_frequency = real_value * CC1101_QUARTZ / CC1101_IFDIV; return (uint32_t)real_frequency; } -void cc1101_set_pa_table(const FuriHalSpiDevice* device, const uint8_t value[8]) { +void cc1101_set_pa_table(FuriHalSpiBusHandle* handle, const uint8_t value[8]) { uint8_t tx[9] = { CC1101_PATABLE | CC1101_BURST }; CC1101Status rx[9] = { 0 }; memcpy(&tx[1], &value[0], 8); - hal_gpio_write(device->chip_select, false); - while(hal_gpio_read(device->bus->miso)); - furi_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, sizeof(rx), CC1101_TIMEOUT); - hal_gpio_write(device->chip_select, true); + while(hal_gpio_read(handle->miso)); + furi_hal_spi_bus_trx(handle, tx, (uint8_t*)rx, sizeof(rx), CC1101_TIMEOUT); assert((rx[0].CHIP_RDYn|rx[8].CHIP_RDYn) == 0); } -uint8_t cc1101_write_fifo(const FuriHalSpiDevice* device, const uint8_t* data, uint8_t size) { +uint8_t cc1101_write_fifo(FuriHalSpiBusHandle* handle, const uint8_t* data, uint8_t size) { uint8_t buff_tx[64]; uint8_t buff_rx[64]; buff_tx[0] = CC1101_FIFO | CC1101_BURST; memcpy(&buff_tx[1], data, size); // Start transaction - hal_gpio_write(device->chip_select, false); // Wait IC to become ready - while(hal_gpio_read(device->bus->miso)); + while(hal_gpio_read(handle->miso)); // Tell IC what we want - furi_hal_spi_bus_trx(device->bus, buff_tx, (uint8_t*) buff_rx, size + 1, CC1101_TIMEOUT); - - // Finish transaction - hal_gpio_write(device->chip_select, true); + furi_hal_spi_bus_trx(handle, buff_tx, (uint8_t*) buff_rx, size + 1, CC1101_TIMEOUT); return size; } -uint8_t cc1101_read_fifo(const FuriHalSpiDevice* device, uint8_t* data, uint8_t* size) { +uint8_t cc1101_read_fifo(FuriHalSpiBusHandle* handle, uint8_t* data, uint8_t* size) { uint8_t buff_tx[64]; buff_tx[0] = CC1101_FIFO | CC1101_READ | CC1101_BURST; uint8_t buff_rx[2]; // Start transaction - hal_gpio_write(device->chip_select, false); // Wait IC to become ready - while(hal_gpio_read(device->bus->miso)); + while(hal_gpio_read(handle->miso)); // First byte - packet length - furi_hal_spi_bus_trx(device->bus, buff_tx, buff_rx, 2, CC1101_TIMEOUT); + furi_hal_spi_bus_trx(handle, buff_tx, buff_rx, 2, CC1101_TIMEOUT); *size = buff_rx[1]; - furi_hal_spi_bus_trx(device->bus, &buff_tx[1], data, *size, CC1101_TIMEOUT); - cc1101_flush_rx(device); + furi_hal_spi_bus_trx(handle, &buff_tx[1], data, *size, CC1101_TIMEOUT); + cc1101_flush_rx(handle); - hal_gpio_write(device->chip_select, true); return *size; } diff --git a/lib/drivers/cc1101.h b/lib/drivers/cc1101.h index 295e4b61..f51373d6 100644 --- a/lib/drivers/cc1101.h +++ b/lib/drivers/cc1101.h @@ -13,131 +13,167 @@ extern "C" { /* Low level API */ /** Strobe command to the device - * @param device - pointer to FuriHalSpiDevice - * @param strobe - command to execute - * @return device status + * + * @param handle - pointer to FuriHalSpiHandle + * @param strobe - command to execute + * + * @return device status */ -CC1101Status cc1101_strobe(const FuriHalSpiDevice* device, uint8_t strobe); +CC1101Status cc1101_strobe(FuriHalSpiBusHandle* handle, uint8_t strobe); /** Write device register - * @param device - pointer to FuriHalSpiDevice - * @param reg - register - * @param data - data to write - * @return device status + * + * @param handle - pointer to FuriHalSpiHandle + * @param reg - register + * @param data - data to write + * + * @return device status */ -CC1101Status cc1101_write_reg(const FuriHalSpiDevice* device, uint8_t reg, uint8_t data); +CC1101Status cc1101_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t data); /** Read device register - * @param device - pointer to FuriHalSpiDevice - * @param reg - register - * @param[out] data - pointer to data - * @return device status + * + * @param handle - pointer to FuriHalSpiHandle + * @param reg - register + * @param[out] data - pointer to data + * + * @return device status */ -CC1101Status cc1101_read_reg(const FuriHalSpiDevice* device, uint8_t reg, uint8_t* data); +CC1101Status cc1101_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data); /* High level API */ /** Reset - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle */ -void cc1101_reset(const FuriHalSpiDevice* device); +void cc1101_reset(FuriHalSpiBusHandle* handle); /** Get status - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle + * + * @return CC1101Status structure */ -CC1101Status cc1101_get_status(const FuriHalSpiDevice* device); +CC1101Status cc1101_get_status(FuriHalSpiBusHandle* handle); /** Enable shutdown mode - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle */ -void cc1101_shutdown(const FuriHalSpiDevice* device); +void cc1101_shutdown(FuriHalSpiBusHandle* handle); /** Get Partnumber - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle + * + * @return part number id */ -uint8_t cc1101_get_partnumber(const FuriHalSpiDevice* device); +uint8_t cc1101_get_partnumber(FuriHalSpiBusHandle* handle); /** Get Version - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle + * + * @return version */ -uint8_t cc1101_get_version(const FuriHalSpiDevice* device); +uint8_t cc1101_get_version(FuriHalSpiBusHandle* handle); /** Get raw RSSI value - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle + * + * @return rssi value */ -uint8_t cc1101_get_rssi(const FuriHalSpiDevice* device); +uint8_t cc1101_get_rssi(FuriHalSpiBusHandle* handle); /** Calibrate oscillator - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle */ -void cc1101_calibrate(const FuriHalSpiDevice* device); +void cc1101_calibrate(FuriHalSpiBusHandle* handle); /** Switch to idle - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle */ -void cc1101_switch_to_idle(const FuriHalSpiDevice* device); +void cc1101_switch_to_idle(FuriHalSpiBusHandle* handle); /** Switch to RX - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle */ -void cc1101_switch_to_rx(const FuriHalSpiDevice* device); +void cc1101_switch_to_rx(FuriHalSpiBusHandle* handle); /** Switch to TX - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle */ -void cc1101_switch_to_tx(const FuriHalSpiDevice* device); +void cc1101_switch_to_tx(FuriHalSpiBusHandle* handle); /** Flush RX FIFO - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle */ -void cc1101_flush_rx(const FuriHalSpiDevice* device); +void cc1101_flush_rx(FuriHalSpiBusHandle* handle); /** Flush TX FIFO - * @param device - pointer to FuriHalSpiDevice + * + * @param handle - pointer to FuriHalSpiHandle */ -void cc1101_flush_tx(const FuriHalSpiDevice* device); +void cc1101_flush_tx(FuriHalSpiBusHandle* handle); /** Set Frequency - * @param device - pointer to FuriHalSpiDevice - * @param value - frequency in herz - * @return real frequency that were synthesized + * + * @param handle - pointer to FuriHalSpiHandle + * @param value - frequency in herz + * + * @return real frequency that were synthesized */ -uint32_t cc1101_set_frequency(const FuriHalSpiDevice* device, uint32_t value); +uint32_t cc1101_set_frequency(FuriHalSpiBusHandle* handle, uint32_t value); /** Set Intermediate Frequency - * @param device - pointer to FuriHalSpiDevice - * @param value - frequency in herz - * @return real inermediate frequency that were synthesized + * + * @param handle - pointer to FuriHalSpiHandle + * @param value - frequency in herz + * + * @return real inermediate frequency that were synthesized */ -uint32_t cc1101_set_intermediate_frequency(const FuriHalSpiDevice* device, uint32_t value); +uint32_t cc1101_set_intermediate_frequency(FuriHalSpiBusHandle* handle, uint32_t value); /** Set Power Amplifier level table, ramp - * @param device - pointer to FuriHalSpiDevice - * @param value - array of power level values + * + * @param handle - pointer to FuriHalSpiHandle + * @param value - array of power level values */ -void cc1101_set_pa_table(const FuriHalSpiDevice* device, const uint8_t value[8]); +void cc1101_set_pa_table(FuriHalSpiBusHandle* handle, const uint8_t value[8]); /** Set Power Amplifier level table, ramp - * @param device - pointer to FuriHalSpiDevice - * @param value - array of power level values + * + * @param handle - pointer to FuriHalSpiHandle + * @param value - array of power level values */ -void cc1101_set_pa_table(const FuriHalSpiDevice* device, const uint8_t value[8]); +void cc1101_set_pa_table(FuriHalSpiBusHandle* handle, const uint8_t value[8]); /** Write FIFO - * @param device - pointer to FuriHalSpiDevice - * @param data, pointer to byte array - * @param size, write bytes count - * @return size, written bytes count + * + * @param handle - pointer to FuriHalSpiHandle + * @param data pointer to byte array + * @param size write bytes count + * + * @return size, written bytes count */ -uint8_t cc1101_write_fifo(const FuriHalSpiDevice* device, const uint8_t* data, uint8_t size); +uint8_t cc1101_write_fifo(FuriHalSpiBusHandle* handle, const uint8_t* data, uint8_t size); /** Read FIFO - * @param device - pointer to FuriHalSpiDevice - * @param data, pointer to byte array - * @param size, bytes to read from fifo - * @return size, read bytes count + * + * @param handle - pointer to FuriHalSpiHandle + * @param data pointer to byte array + * @param size bytes to read from fifo + * + * @return size, read bytes count */ -uint8_t cc1101_read_fifo(const FuriHalSpiDevice* device, uint8_t* data, uint8_t* size); +uint8_t cc1101_read_fifo(FuriHalSpiBusHandle* handle, uint8_t* data, uint8_t* size); #ifdef __cplusplus } diff --git a/lib/u8g2/u8g2_glue.c b/lib/u8g2/u8g2_glue.c index e2ca8a9d..7d45a03e 100644 --- a/lib/u8g2/u8g2_glue.c +++ b/lib/u8g2/u8g2_glue.c @@ -2,8 +2,6 @@ #include -static FuriHalSpiDevice* u8g2_periphery_display = NULL; - uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr) { switch(msg) { case U8X8_MSG_GPIO_AND_DELAY_INIT: @@ -31,7 +29,7 @@ uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, vo uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ptr) { switch(msg) { case U8X8_MSG_BYTE_SEND: - furi_hal_spi_bus_tx(u8g2_periphery_display->bus, (uint8_t*)arg_ptr, arg_int, 10000); + furi_hal_spi_bus_tx(&furi_hal_spi_bus_handle_display, (uint8_t*)arg_ptr, arg_int, 10000); break; case U8X8_MSG_BYTE_SET_DC: hal_gpio_write(&gpio_display_di, arg_int); @@ -39,16 +37,10 @@ uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ case U8X8_MSG_BYTE_INIT: break; case U8X8_MSG_BYTE_START_TRANSFER: - furi_assert(u8g2_periphery_display == NULL); - u8g2_periphery_display = - (FuriHalSpiDevice*)furi_hal_spi_device_get(FuriHalSpiDeviceIdDisplay); - hal_gpio_write(u8g2_periphery_display->chip_select, false); + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_display); break; case U8X8_MSG_BYTE_END_TRANSFER: - furi_assert(u8g2_periphery_display); - hal_gpio_write(u8g2_periphery_display->chip_select, true); - furi_hal_spi_device_return(u8g2_periphery_display); - u8g2_periphery_display = NULL; + furi_hal_spi_release(&furi_hal_spi_bus_handle_display); break; default: return 0; From 6f56b8d61d0a265c94884c1c8fb6c6113b6eaca8 Mon Sep 17 00:00:00 2001 From: Nikolay Minaylov Date: Tue, 30 Nov 2021 15:46:18 +0300 Subject: [PATCH 04/32] [FL-1703] USB suspend/wakeup fix #849 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- lib/libusb_stm32 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libusb_stm32 b/lib/libusb_stm32 index fe3890e1..8a7846d0 160000 --- a/lib/libusb_stm32 +++ b/lib/libusb_stm32 @@ -1 +1 @@ -Subproject commit fe3890e10e35a837184cb05f835ef6ab14bfd04f +Subproject commit 8a7846d0213c51aa4167e7fbe3118e33848e79b7 From 9fc7fe7f322a6f7e9863ff214f8b781285625f64 Mon Sep 17 00:00:00 2001 From: fominykhandrei <70645657+fominykhandrei@users.noreply.github.com> Date: Tue, 30 Nov 2021 20:46:54 +0300 Subject: [PATCH 05/32] Fix build for Python versions <3.9 (#855) Co-authored-by: Andrei Fominykh --- scripts/meta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/meta.py b/scripts/meta.py index 1741a4ad..c3c4cac9 100755 --- a/scripts/meta.py +++ b/scripts/meta.py @@ -49,7 +49,7 @@ class Main(App): for path in self.args.input[0]: with open(path, mode="r") as file: dict = json.loads(file.read()) - full |= dict + full.update(dict) print(json.dumps(full, indent=4)) return 0 From 6f7d93fe724719a16e1315832c7ef69aabedd1ef Mon Sep 17 00:00:00 2001 From: Albert Kharisov Date: Tue, 30 Nov 2021 21:53:46 +0400 Subject: [PATCH 06/32] Fix Icons decompression on F6 (#856) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- firmware/targets/f6/furi-hal/furi-hal-compress.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/firmware/targets/f6/furi-hal/furi-hal-compress.c b/firmware/targets/f6/furi-hal/furi-hal-compress.c index eb6e9d51..369ab3a0 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-compress.c +++ b/firmware/targets/f6/furi-hal/furi-hal-compress.c @@ -6,7 +6,7 @@ #define TAG "FuriHalCompress" -#define FURI_HAL_COMPRESS_ICON_ENCODED_BUFF_SIZE (512) +#define FURI_HAL_COMPRESS_ICON_ENCODED_BUFF_SIZE (2*512) #define FURI_HAL_COMPRESS_ICON_DECODED_BUFF_SIZE (1024) #define FURI_HAL_COMPRESS_EXP_BUFF_SIZE (1 << FURI_HAL_COMPRESS_EXP_BUFF_SIZE_LOG) @@ -59,13 +59,17 @@ void furi_hal_compress_icon_decode(const uint8_t* icon_data, uint8_t** decoded_b if(header->is_compressed) { size_t data_processed = 0; heatshrink_decoder_sink(icon_decoder->decoder, (uint8_t*)&icon_data[4], header->compressed_buff_size, &data_processed); - while( - heatshrink_decoder_poll( + while (1) { + HSD_poll_res res = heatshrink_decoder_poll( icon_decoder->decoder, icon_decoder->decoded_buff, sizeof(icon_decoder->decoded_buff), - &data_processed) == HSDR_POLL_MORE - ) {}; + &data_processed); + furi_assert((res == HSDR_POLL_EMPTY) || (res == HSDR_POLL_MORE)); + if (res != HSDR_POLL_MORE) { + break; + } + } heatshrink_decoder_reset(icon_decoder->decoder); memset(icon_decoder->compress_buff, 0, sizeof(icon_decoder->compress_buff)); *decoded_buff = icon_decoder->decoded_buff; From 418c0939a0074ca0083fec62c4205bf36102616c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Wed, 1 Dec 2021 01:07:17 +0300 Subject: [PATCH 07/32] Guard RCC registers access with critical section (#854) * Core: critical section macros. FuriHal: guard rcc registers access with critical section, fix condition race. * FuriHal: update documentation. Co-authored-by: SG --- bootloader/targets/f6/furi-hal/furi-hal-i2c.h | 34 +++++++++---------- bootloader/targets/f7/furi-hal/furi-hal-i2c.h | 34 +++++++++---------- core/furi/common_defines.h | 10 ++++++ .../targets/f6/furi-hal/furi-hal-console.c | 8 ++--- .../targets/f6/furi-hal/furi-hal-i2c-config.c | 16 ++++++--- firmware/targets/f6/furi-hal/furi-hal-irda.c | 2 ++ .../targets/f6/furi-hal/furi-hal-spi-config.c | 12 +++++++ .../targets/f6/furi-hal/furi-hal-subghz.c | 9 +++++ .../targets/f7/furi-hal/furi-hal-console.c | 28 +++++++-------- .../targets/f7/furi-hal/furi-hal-i2c-config.c | 16 ++++++--- firmware/targets/f7/furi-hal/furi-hal-irda.c | 2 ++ .../targets/f7/furi-hal/furi-hal-spi-config.c | 12 +++++++ .../targets/f7/furi-hal/furi-hal-subghz.c | 9 +++++ .../targets/furi-hal-include/furi-hal-i2c.h | 34 +++++++++---------- 14 files changed, 148 insertions(+), 78 deletions(-) mode change 100755 => 100644 core/furi/common_defines.h diff --git a/bootloader/targets/f6/furi-hal/furi-hal-i2c.h b/bootloader/targets/f6/furi-hal/furi-hal-i2c.h index 7ef1db44..ab4052fb 100644 --- a/bootloader/targets/f6/furi-hal/furi-hal-i2c.h +++ b/bootloader/targets/f6/furi-hal/furi-hal-i2c.h @@ -31,11 +31,11 @@ void furi_hal_i2c_release(FuriHalI2cBusHandle* handle); /** Perform I2C tx transfer * - * @param instance I2C_TypeDef instance - * @param address I2C slave address - * @param data pointer to data buffer - * @param size size of data buffer - * @param timeout timeout in ticks + * @param handle pointer to FuriHalI2cBusHandle instance + * @param address I2C slave address + * @param data pointer to data buffer + * @param size size of data buffer + * @param timeout timeout in ticks * * @return true on successful transfer, false otherwise */ @@ -48,11 +48,11 @@ bool furi_hal_i2c_tx( /** Perform I2C rx transfer * - * @param instance I2C_TypeDef instance - * @param address I2C slave address - * @param data pointer to data buffer - * @param size size of data buffer - * @param timeout timeout in ticks + * @param handle pointer to FuriHalI2cBusHandle instance + * @param address I2C slave address + * @param data pointer to data buffer + * @param size size of data buffer + * @param timeout timeout in ticks * * @return true on successful transfer, false otherwise */ @@ -65,13 +65,13 @@ bool furi_hal_i2c_rx( /** Perform I2C tx and rx transfers * - * @param instance I2C_TypeDef instance - * @param address I2C slave address - * @param tx_data pointer to tx data buffer - * @param tx_size size of tx data buffer - * @param rx_data pointer to rx data buffer - * @param rx_size size of rx data buffer - * @param timeout timeout in ticks + * @param handle pointer to FuriHalI2cBusHandle instance + * @param address I2C slave address + * @param tx_data pointer to tx data buffer + * @param tx_size size of tx data buffer + * @param rx_data pointer to rx data buffer + * @param rx_size size of rx data buffer + * @param timeout timeout in ticks * * @return true on successful transfer, false otherwise */ diff --git a/bootloader/targets/f7/furi-hal/furi-hal-i2c.h b/bootloader/targets/f7/furi-hal/furi-hal-i2c.h index 7ef1db44..ab4052fb 100644 --- a/bootloader/targets/f7/furi-hal/furi-hal-i2c.h +++ b/bootloader/targets/f7/furi-hal/furi-hal-i2c.h @@ -31,11 +31,11 @@ void furi_hal_i2c_release(FuriHalI2cBusHandle* handle); /** Perform I2C tx transfer * - * @param instance I2C_TypeDef instance - * @param address I2C slave address - * @param data pointer to data buffer - * @param size size of data buffer - * @param timeout timeout in ticks + * @param handle pointer to FuriHalI2cBusHandle instance + * @param address I2C slave address + * @param data pointer to data buffer + * @param size size of data buffer + * @param timeout timeout in ticks * * @return true on successful transfer, false otherwise */ @@ -48,11 +48,11 @@ bool furi_hal_i2c_tx( /** Perform I2C rx transfer * - * @param instance I2C_TypeDef instance - * @param address I2C slave address - * @param data pointer to data buffer - * @param size size of data buffer - * @param timeout timeout in ticks + * @param handle pointer to FuriHalI2cBusHandle instance + * @param address I2C slave address + * @param data pointer to data buffer + * @param size size of data buffer + * @param timeout timeout in ticks * * @return true on successful transfer, false otherwise */ @@ -65,13 +65,13 @@ bool furi_hal_i2c_rx( /** Perform I2C tx and rx transfers * - * @param instance I2C_TypeDef instance - * @param address I2C slave address - * @param tx_data pointer to tx data buffer - * @param tx_size size of tx data buffer - * @param rx_data pointer to rx data buffer - * @param rx_size size of rx data buffer - * @param timeout timeout in ticks + * @param handle pointer to FuriHalI2cBusHandle instance + * @param address I2C slave address + * @param tx_data pointer to tx data buffer + * @param tx_size size of tx data buffer + * @param rx_data pointer to rx data buffer + * @param rx_size size of rx data buffer + * @param timeout timeout in ticks * * @return true on successful transfer, false otherwise */ diff --git a/core/furi/common_defines.h b/core/furi/common_defines.h old mode 100755 new mode 100644 index 00a68529..2cd85dcc --- a/core/furi/common_defines.h +++ b/core/furi/common_defines.h @@ -70,4 +70,14 @@ #define REVERSE_BYTES_U32(x) \ ((((x)&0x000000FF) << 24) | (((x)&0x0000FF00) << 8) | (((x)&0x00FF0000) >> 8) | \ (((x)&0xFF000000) >> 24)) +#endif + +#ifndef FURI_CRITICAL_ENTER +#define FURI_CRITICAL_ENTER() \ + uint32_t primask_bit = __get_PRIMASK(); \ + __disable_irq() +#endif + +#ifndef FURI_CRITICAL_EXIT +#define FURI_CRITICAL_EXIT() __set_PRIMASK(primask_bit) #endif \ No newline at end of file diff --git a/firmware/targets/f6/furi-hal/furi-hal-console.c b/firmware/targets/f6/furi-hal/furi-hal-console.c index a0b0083b..c3943497 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-console.c +++ b/firmware/targets/f6/furi-hal/furi-hal-console.c @@ -39,26 +39,26 @@ void furi_hal_console_tx(const uint8_t* buffer, size_t buffer_size) { if (!furi_hal_console_alive) return; - UTILS_ENTER_CRITICAL_SECTION(); + FURI_CRITICAL_ENTER(); // Transmit data furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)buffer, buffer_size); // Wait for TC flag to be raised for last char while (!LL_USART_IsActiveFlag_TC(USART1)); - UTILS_EXIT_CRITICAL_SECTION(); + FURI_CRITICAL_EXIT(); } void furi_hal_console_tx_with_new_line(const uint8_t* buffer, size_t buffer_size) { if (!furi_hal_console_alive) return; - UTILS_ENTER_CRITICAL_SECTION(); + FURI_CRITICAL_ENTER(); // Transmit data furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)buffer, buffer_size); // Transmit new line symbols furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)"\r\n", 2); // Wait for TC flag to be raised for last char while (!LL_USART_IsActiveFlag_TC(USART1)); - UTILS_EXIT_CRITICAL_SECTION(); + FURI_CRITICAL_EXIT(); } void furi_hal_console_printf(const char format[], ...) { diff --git a/firmware/targets/f6/furi-hal/furi-hal-i2c-config.c b/firmware/targets/f6/furi-hal/furi-hal-i2c-config.c index 273d46b1..3211000c 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-i2c-config.c +++ b/firmware/targets/f6/furi-hal/furi-hal-i2c-config.c @@ -19,9 +19,11 @@ osMutexId_t furi_hal_i2c_bus_power_mutex = NULL; static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { if (event == FuriHalI2cBusEventInit) { furi_hal_i2c_bus_power_mutex = osMutexNew(NULL); + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); + FURI_CRITICAL_EXIT(); bus->current_handle = NULL; } else if (event == FuriHalI2cBusEventDeinit) { osMutexDelete(furi_hal_i2c_bus_power_mutex); @@ -30,9 +32,13 @@ static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent } else if (event == FuriHalI2cBusEventUnlock) { furi_check(osMutexRelease(furi_hal_i2c_bus_power_mutex) == osOK); } else if (event == FuriHalI2cBusEventActivate) { + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1); + FURI_CRITICAL_EXIT(); } else if (event == FuriHalI2cBusEventDeactivate) { + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); + FURI_CRITICAL_EXIT(); } } @@ -45,11 +51,15 @@ osMutexId_t furi_hal_i2c_bus_external_mutex = NULL; static void furi_hal_i2c_bus_external_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { if (event == FuriHalI2cBusEventActivate) { + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C3); LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1); LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3); + FURI_CRITICAL_EXIT(); } else if (event == FuriHalI2cBusEventDeactivate) { + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3); + FURI_CRITICAL_EXIT(); } } @@ -76,13 +86,12 @@ void furi_hal_i2c_bus_handle_power_event(FuriHalI2cBusHandle* handle, FuriHalI2c I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100; } LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct); - + // I2C is enabled at this point LL_I2C_EnableAutoEndMode(handle->bus->i2c); LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK); LL_I2C_DisableOwnAddress2(handle->bus->i2c); LL_I2C_DisableGeneralCall(handle->bus->i2c); LL_I2C_EnableClockStretching(handle->bus->i2c); - LL_I2C_Enable(handle->bus->i2c); } else if (event == FuriHalI2cBusHandleEventDeactivate) { LL_I2C_Disable(handle->bus->i2c); hal_gpio_write(&gpio_i2c_power_sda, 1); @@ -111,13 +120,12 @@ void furi_hal_i2c_bus_handle_external_event(FuriHalI2cBusHandle* handle, FuriHal I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100; LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct); - + // I2C is enabled at this point LL_I2C_EnableAutoEndMode(handle->bus->i2c); LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK); LL_I2C_DisableOwnAddress2(handle->bus->i2c); LL_I2C_DisableGeneralCall(handle->bus->i2c); LL_I2C_EnableClockStretching(handle->bus->i2c); - LL_I2C_Enable(handle->bus->i2c); } else if (event == FuriHalI2cBusHandleEventDeactivate) { LL_I2C_Disable(handle->bus->i2c); hal_gpio_write(&gpio_ext_pc0, 1); diff --git a/firmware/targets/f6/furi-hal/furi-hal-irda.c b/firmware/targets/f6/furi-hal/furi-hal-irda.c index 503a3653..4d3d389b 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-irda.c +++ b/firmware/targets/f6/furi-hal/furi-hal-irda.c @@ -136,8 +136,10 @@ static void furi_hal_irda_tim_rx_isr() { void furi_hal_irda_async_rx_start(void) { furi_assert(furi_hal_irda_state == IrdaStateIdle); + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + FURI_CRITICAL_EXIT(); hal_gpio_init_ex(&gpio_irda_rx, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); diff --git a/firmware/targets/f6/furi-hal/furi-hal-spi-config.c b/firmware/targets/f6/furi-hal/furi-hal-spi-config.c index 63253c90..e84f0368 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-spi-config.c +++ b/firmware/targets/f6/furi-hal/furi-hal-spi-config.c @@ -75,8 +75,10 @@ osMutexId_t furi_hal_spi_bus_r_mutex = NULL; static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { if (event == FuriHalSpiBusEventInit) { furi_hal_spi_bus_r_mutex = osMutexNew(NULL); + FURI_CRITICAL_ENTER(); LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); + FURI_CRITICAL_EXIT(); bus->current_handle = NULL; } else if (event == FuriHalSpiBusEventDeinit) { furi_check(osMutexDelete(furi_hal_spi_bus_r_mutex)); @@ -85,9 +87,13 @@ static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusE } else if (event == FuriHalSpiBusEventUnlock) { furi_check(osMutexRelease(furi_hal_spi_bus_r_mutex) == osOK); } else if (event == FuriHalSpiBusEventActivate) { + FURI_CRITICAL_ENTER(); LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1); + FURI_CRITICAL_EXIT(); } else if (event == FuriHalSpiBusEventDeactivate) { + FURI_CRITICAL_ENTER(); LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); + FURI_CRITICAL_EXIT(); } } @@ -101,8 +107,10 @@ osMutexId_t furi_hal_spi_bus_d_mutex = NULL; static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { if (event == FuriHalSpiBusEventInit) { furi_hal_spi_bus_d_mutex = osMutexNew(NULL); + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); + FURI_CRITICAL_EXIT(); bus->current_handle = NULL; } else if (event == FuriHalSpiBusEventDeinit) { furi_check(osMutexDelete(furi_hal_spi_bus_d_mutex)); @@ -111,9 +119,13 @@ static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusE } else if (event == FuriHalSpiBusEventUnlock) { furi_check(osMutexRelease(furi_hal_spi_bus_d_mutex) == osOK); } else if (event == FuriHalSpiBusEventActivate) { + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2); + FURI_CRITICAL_EXIT(); } else if (event == FuriHalSpiBusEventDeactivate) { + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); + FURI_CRITICAL_EXIT(); } } diff --git a/firmware/targets/f6/furi-hal/furi-hal-subghz.c b/firmware/targets/f6/furi-hal/furi-hal-subghz.c index dac4514e..86540818 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-subghz.c +++ b/firmware/targets/f6/furi-hal/furi-hal-subghz.c @@ -575,7 +575,10 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* &gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); // Timer: base + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); + FURI_CRITICAL_EXIT(); + LL_TIM_InitTypeDef TIM_InitStruct = {0}; TIM_InitStruct.Prescaler = 64 - 1; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; @@ -635,8 +638,10 @@ void furi_hal_subghz_stop_async_rx() { // Shutdown radio furi_hal_subghz_idle(); + FURI_CRITICAL_ENTER(); LL_TIM_DeInit(TIM2); LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2); + FURI_CRITICAL_EXIT(); furi_hal_interrupt_set_timer_isr(TIM2, NULL); hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); @@ -761,7 +766,9 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); // Configure TIM2 + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); + FURI_CRITICAL_EXIT(); LL_TIM_InitTypeDef TIM_InitStruct = {0}; TIM_InitStruct.Prescaler = 64 - 1; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; @@ -820,6 +827,7 @@ void furi_hal_subghz_stop_async_tx() { #endif // Deinitialize Timer + FURI_CRITICAL_ENTER(); LL_TIM_DeInit(TIM2); LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2); furi_hal_interrupt_set_timer_isr(TIM2, NULL); @@ -830,6 +838,7 @@ void furi_hal_subghz_stop_async_tx() { // Deinitialize GPIO hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + FURI_CRITICAL_EXIT(); free(furi_hal_subghz_async_tx.buffer); diff --git a/firmware/targets/f7/furi-hal/furi-hal-console.c b/firmware/targets/f7/furi-hal/furi-hal-console.c index 66ff40ee..c3943497 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-console.c +++ b/firmware/targets/f7/furi-hal/furi-hal-console.c @@ -25,42 +25,40 @@ void furi_hal_console_init() { void furi_hal_console_enable() { furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, NULL, NULL); - while(!LL_USART_IsActiveFlag_TC(USART1)) - ; + while (!LL_USART_IsActiveFlag_TC(USART1)); furi_hal_uart_set_br(FuriHalUartIdUSART1, CONSOLE_BAUDRATE); furi_hal_console_alive = true; } void furi_hal_console_disable() { - while(!LL_USART_IsActiveFlag_TC(USART1)) - ; + while (!LL_USART_IsActiveFlag_TC(USART1)); furi_hal_console_alive = false; } void furi_hal_console_tx(const uint8_t* buffer, size_t buffer_size) { - if(!furi_hal_console_alive) return; + if (!furi_hal_console_alive) + return; - UTILS_ENTER_CRITICAL_SECTION(); + FURI_CRITICAL_ENTER(); // Transmit data furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)buffer, buffer_size); // Wait for TC flag to be raised for last char - while(!LL_USART_IsActiveFlag_TC(USART1)) - ; - UTILS_EXIT_CRITICAL_SECTION(); + while (!LL_USART_IsActiveFlag_TC(USART1)); + FURI_CRITICAL_EXIT(); } void furi_hal_console_tx_with_new_line(const uint8_t* buffer, size_t buffer_size) { - if(!furi_hal_console_alive) return; + if (!furi_hal_console_alive) + return; - UTILS_ENTER_CRITICAL_SECTION(); + FURI_CRITICAL_ENTER(); // Transmit data furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)buffer, buffer_size); // Transmit new line symbols furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)"\r\n", 2); // Wait for TC flag to be raised for last char - while(!LL_USART_IsActiveFlag_TC(USART1)) - ; - UTILS_EXIT_CRITICAL_SECTION(); + while (!LL_USART_IsActiveFlag_TC(USART1)); + FURI_CRITICAL_EXIT(); } void furi_hal_console_printf(const char format[], ...) { @@ -73,6 +71,6 @@ void furi_hal_console_printf(const char format[], ...) { string_clear(string); } -void furi_hal_console_puts(const char* data) { +void furi_hal_console_puts(const char *data) { furi_hal_console_tx((const uint8_t*)data, strlen(data)); } diff --git a/firmware/targets/f7/furi-hal/furi-hal-i2c-config.c b/firmware/targets/f7/furi-hal/furi-hal-i2c-config.c index 273d46b1..3211000c 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-i2c-config.c +++ b/firmware/targets/f7/furi-hal/furi-hal-i2c-config.c @@ -19,9 +19,11 @@ osMutexId_t furi_hal_i2c_bus_power_mutex = NULL; static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { if (event == FuriHalI2cBusEventInit) { furi_hal_i2c_bus_power_mutex = osMutexNew(NULL); + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); + FURI_CRITICAL_EXIT(); bus->current_handle = NULL; } else if (event == FuriHalI2cBusEventDeinit) { osMutexDelete(furi_hal_i2c_bus_power_mutex); @@ -30,9 +32,13 @@ static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent } else if (event == FuriHalI2cBusEventUnlock) { furi_check(osMutexRelease(furi_hal_i2c_bus_power_mutex) == osOK); } else if (event == FuriHalI2cBusEventActivate) { + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1); + FURI_CRITICAL_EXIT(); } else if (event == FuriHalI2cBusEventDeactivate) { + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); + FURI_CRITICAL_EXIT(); } } @@ -45,11 +51,15 @@ osMutexId_t furi_hal_i2c_bus_external_mutex = NULL; static void furi_hal_i2c_bus_external_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { if (event == FuriHalI2cBusEventActivate) { + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C3); LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1); LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3); + FURI_CRITICAL_EXIT(); } else if (event == FuriHalI2cBusEventDeactivate) { + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3); + FURI_CRITICAL_EXIT(); } } @@ -76,13 +86,12 @@ void furi_hal_i2c_bus_handle_power_event(FuriHalI2cBusHandle* handle, FuriHalI2c I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100; } LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct); - + // I2C is enabled at this point LL_I2C_EnableAutoEndMode(handle->bus->i2c); LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK); LL_I2C_DisableOwnAddress2(handle->bus->i2c); LL_I2C_DisableGeneralCall(handle->bus->i2c); LL_I2C_EnableClockStretching(handle->bus->i2c); - LL_I2C_Enable(handle->bus->i2c); } else if (event == FuriHalI2cBusHandleEventDeactivate) { LL_I2C_Disable(handle->bus->i2c); hal_gpio_write(&gpio_i2c_power_sda, 1); @@ -111,13 +120,12 @@ void furi_hal_i2c_bus_handle_external_event(FuriHalI2cBusHandle* handle, FuriHal I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100; LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct); - + // I2C is enabled at this point LL_I2C_EnableAutoEndMode(handle->bus->i2c); LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK); LL_I2C_DisableOwnAddress2(handle->bus->i2c); LL_I2C_DisableGeneralCall(handle->bus->i2c); LL_I2C_EnableClockStretching(handle->bus->i2c); - LL_I2C_Enable(handle->bus->i2c); } else if (event == FuriHalI2cBusHandleEventDeactivate) { LL_I2C_Disable(handle->bus->i2c); hal_gpio_write(&gpio_ext_pc0, 1); diff --git a/firmware/targets/f7/furi-hal/furi-hal-irda.c b/firmware/targets/f7/furi-hal/furi-hal-irda.c index 503a3653..4d3d389b 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-irda.c +++ b/firmware/targets/f7/furi-hal/furi-hal-irda.c @@ -136,8 +136,10 @@ static void furi_hal_irda_tim_rx_isr() { void furi_hal_irda_async_rx_start(void) { furi_assert(furi_hal_irda_state == IrdaStateIdle); + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); + FURI_CRITICAL_EXIT(); hal_gpio_init_ex(&gpio_irda_rx, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); diff --git a/firmware/targets/f7/furi-hal/furi-hal-spi-config.c b/firmware/targets/f7/furi-hal/furi-hal-spi-config.c index 63253c90..e84f0368 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-spi-config.c +++ b/firmware/targets/f7/furi-hal/furi-hal-spi-config.c @@ -75,8 +75,10 @@ osMutexId_t furi_hal_spi_bus_r_mutex = NULL; static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { if (event == FuriHalSpiBusEventInit) { furi_hal_spi_bus_r_mutex = osMutexNew(NULL); + FURI_CRITICAL_ENTER(); LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); + FURI_CRITICAL_EXIT(); bus->current_handle = NULL; } else if (event == FuriHalSpiBusEventDeinit) { furi_check(osMutexDelete(furi_hal_spi_bus_r_mutex)); @@ -85,9 +87,13 @@ static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusE } else if (event == FuriHalSpiBusEventUnlock) { furi_check(osMutexRelease(furi_hal_spi_bus_r_mutex) == osOK); } else if (event == FuriHalSpiBusEventActivate) { + FURI_CRITICAL_ENTER(); LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1); + FURI_CRITICAL_EXIT(); } else if (event == FuriHalSpiBusEventDeactivate) { + FURI_CRITICAL_ENTER(); LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); + FURI_CRITICAL_EXIT(); } } @@ -101,8 +107,10 @@ osMutexId_t furi_hal_spi_bus_d_mutex = NULL; static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { if (event == FuriHalSpiBusEventInit) { furi_hal_spi_bus_d_mutex = osMutexNew(NULL); + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); + FURI_CRITICAL_EXIT(); bus->current_handle = NULL; } else if (event == FuriHalSpiBusEventDeinit) { furi_check(osMutexDelete(furi_hal_spi_bus_d_mutex)); @@ -111,9 +119,13 @@ static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusE } else if (event == FuriHalSpiBusEventUnlock) { furi_check(osMutexRelease(furi_hal_spi_bus_d_mutex) == osOK); } else if (event == FuriHalSpiBusEventActivate) { + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2); + FURI_CRITICAL_EXIT(); } else if (event == FuriHalSpiBusEventDeactivate) { + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); + FURI_CRITICAL_EXIT(); } } diff --git a/firmware/targets/f7/furi-hal/furi-hal-subghz.c b/firmware/targets/f7/furi-hal/furi-hal-subghz.c index dac4514e..86540818 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-subghz.c +++ b/firmware/targets/f7/furi-hal/furi-hal-subghz.c @@ -575,7 +575,10 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* &gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); // Timer: base + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); + FURI_CRITICAL_EXIT(); + LL_TIM_InitTypeDef TIM_InitStruct = {0}; TIM_InitStruct.Prescaler = 64 - 1; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; @@ -635,8 +638,10 @@ void furi_hal_subghz_stop_async_rx() { // Shutdown radio furi_hal_subghz_idle(); + FURI_CRITICAL_ENTER(); LL_TIM_DeInit(TIM2); LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2); + FURI_CRITICAL_EXIT(); furi_hal_interrupt_set_timer_isr(TIM2, NULL); hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); @@ -761,7 +766,9 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); // Configure TIM2 + FURI_CRITICAL_ENTER(); LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); + FURI_CRITICAL_EXIT(); LL_TIM_InitTypeDef TIM_InitStruct = {0}; TIM_InitStruct.Prescaler = 64 - 1; TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; @@ -820,6 +827,7 @@ void furi_hal_subghz_stop_async_tx() { #endif // Deinitialize Timer + FURI_CRITICAL_ENTER(); LL_TIM_DeInit(TIM2); LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2); furi_hal_interrupt_set_timer_isr(TIM2, NULL); @@ -830,6 +838,7 @@ void furi_hal_subghz_stop_async_tx() { // Deinitialize GPIO hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + FURI_CRITICAL_EXIT(); free(furi_hal_subghz_async_tx.buffer); diff --git a/firmware/targets/furi-hal-include/furi-hal-i2c.h b/firmware/targets/furi-hal-include/furi-hal-i2c.h index 7ef1db44..ab4052fb 100644 --- a/firmware/targets/furi-hal-include/furi-hal-i2c.h +++ b/firmware/targets/furi-hal-include/furi-hal-i2c.h @@ -31,11 +31,11 @@ void furi_hal_i2c_release(FuriHalI2cBusHandle* handle); /** Perform I2C tx transfer * - * @param instance I2C_TypeDef instance - * @param address I2C slave address - * @param data pointer to data buffer - * @param size size of data buffer - * @param timeout timeout in ticks + * @param handle pointer to FuriHalI2cBusHandle instance + * @param address I2C slave address + * @param data pointer to data buffer + * @param size size of data buffer + * @param timeout timeout in ticks * * @return true on successful transfer, false otherwise */ @@ -48,11 +48,11 @@ bool furi_hal_i2c_tx( /** Perform I2C rx transfer * - * @param instance I2C_TypeDef instance - * @param address I2C slave address - * @param data pointer to data buffer - * @param size size of data buffer - * @param timeout timeout in ticks + * @param handle pointer to FuriHalI2cBusHandle instance + * @param address I2C slave address + * @param data pointer to data buffer + * @param size size of data buffer + * @param timeout timeout in ticks * * @return true on successful transfer, false otherwise */ @@ -65,13 +65,13 @@ bool furi_hal_i2c_rx( /** Perform I2C tx and rx transfers * - * @param instance I2C_TypeDef instance - * @param address I2C slave address - * @param tx_data pointer to tx data buffer - * @param tx_size size of tx data buffer - * @param rx_data pointer to rx data buffer - * @param rx_size size of rx data buffer - * @param timeout timeout in ticks + * @param handle pointer to FuriHalI2cBusHandle instance + * @param address I2C slave address + * @param tx_data pointer to tx data buffer + * @param tx_size size of tx data buffer + * @param rx_data pointer to rx data buffer + * @param rx_size size of rx data buffer + * @param timeout timeout in ticks * * @return true on successful transfer, false otherwise */ From 93fdf98588292b12711aaec51ade3f5b7338f4fb Mon Sep 17 00:00:00 2001 From: Oleg Kalachev Date: Wed, 1 Dec 2021 02:53:53 +0300 Subject: [PATCH 08/32] Fix typos (#857) --- ReadMe.md | 4 ++-- assets/ReadMe.md | 4 ++-- bootloader/ReadMe.md | 2 +- firmware/ReadMe.md | 2 +- scripts/ReadMe.md | 8 ++++---- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index ccfa2b59..d0cfd632 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -148,7 +148,7 @@ make whole * cli - Console service * debug_tools - different tools that we use on factory and for debug * dialogs - service for showing GUI dialogs - * dolphin - dolphin service and supplientary apps + * dolphin - dolphin service and supplementary apps * gpio-tester - GPIO control application * gui - GUI service * ibutton - ibutton application, onewire keys and more @@ -187,7 +187,7 @@ make whole * app-scened-template - scened template app library * app-template - template app library * callback-connector - callback connector library - * common-api - common api delaration library + * common-api - common api declaration library * cyfral - cyfral library * drivers - drivers that we wrote * fatfs - external storage file system diff --git a/assets/ReadMe.md b/assets/ReadMe.md index 307c27dc..4b554e0a 100644 --- a/assets/ReadMe.md +++ b/assets/ReadMe.md @@ -18,12 +18,12 @@ make all - `NAME` - mandatory - Asset name in CamelCase. [A-Za-z0-9], special symbols not allowed - `VARIANT` - optional - icon variant: can relate to state or rendering conditions. Examples: active, inactive, inverted. -- `SIZE` - mandatory - size in px. Example squere 10, 20, 24, etc. Example rectangular: 10x8, 19x5, etc. +- `SIZE` - mandatory - size in px. Example square 10, 20, 24, etc. Example rectangular: 10x8, 19x5, etc. Image names will be automatically prefixed with `I_`, animation names with `A_`. Icons and Animations will be gathered into `icon.h` and `icon.c`. # Important notes -Don't include assets that you are not using, compiller is not going to strip unusued assets. +Don't include assets that you are not using, compiler is not going to strip unused assets. diff --git a/bootloader/ReadMe.md b/bootloader/ReadMe.md index a8228e51..8a35cc5f 100644 --- a/bootloader/ReadMe.md +++ b/bootloader/ReadMe.md @@ -16,7 +16,7 @@ What it does? | f7 | 0x08000000 | 0x00008000 | L+Back | L+Back, hold L | Also there is a ST bootloader combo available on empty device: L+Ok+Back, release Back,Left. -Target independend code and headers in `src` and `target/include` folders. +Target independent code and headers in `src` and `target/include` folders. # Building diff --git a/firmware/ReadMe.md b/firmware/ReadMe.md index e3d29870..237adae9 100644 --- a/firmware/ReadMe.md +++ b/firmware/ReadMe.md @@ -16,7 +16,7 @@ What it does? | f7 | 0x08000000 | 0x00008000 | L+Back | L+Back, hold L | Also there is a ST bootloader combo available on empty device: L+Ok+Back, release Back,Left. -Target independend code and headers in `target/include` folders. +Target independent code and headers in `target/include` folders. # Building diff --git a/scripts/ReadMe.md b/scripts/ReadMe.md index 2cd1ee0b..b04ed0d1 100644 --- a/scripts/ReadMe.md +++ b/scripts/ReadMe.md @@ -6,7 +6,7 @@ You will need to add STM32_Programmer_CLI to your path to use them. # Flashing empty MCU/Flipper -Always flash your device in the folllowing sequence: +Always flash your device in the following sequence: - OTP (Only on empty MCU) - Core1 and Core2 firmware flashing @@ -19,7 +19,7 @@ Always flash your device in the folllowing sequence: Normally OTP data generated and flashed at the factory. In case if MCU was replaced you'll need correct OTP data to be able to use companion applications. Use `otp.py` to generate and flash OTP data. -You will need exact main board revision to genrate OTP data. It can be found on main PCB. +You will need exact main board revision to generate OTP data. It can be found on main PCB. Also display type, region and etc... !!! Flashing incorrect OTP may permanently brick your device !!! @@ -32,12 +32,12 @@ Never flash FUS or you will loose your job, girlfriend and keys in secure enclav ## Option Bytes -!!! Setting incorrect Otion Bytes may brick your MCU !!! +!!! Setting incorrect Option Bytes may brick your MCU !!! Defaults are mostly OK, but there are couple things that we'd like to tune. Also OB may be damaged, so we've made couple scripts to check and set option bytes. -!!! Setting incorrect Otion Bytes may brick your MCU !!! +!!! Setting incorrect Option Bytes may brick your MCU !!! Checking option bytes: From 54c41e4189c662c65c3e0a50086e73dc532c9165 Mon Sep 17 00:00:00 2001 From: Anna Prosvetova Date: Wed, 1 Dec 2021 13:21:26 +0300 Subject: [PATCH 09/32] CI: Remove pycache from artifacts (#858) * CI: Remove pycache from artifacts * CI: Move bundle scripts step even higher --- .github/workflows/build.yml | 22 +++++++++++----------- scripts/meta.py | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 48a70686..c1cafd42 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -73,6 +73,11 @@ jobs: echo "::set-output name=short-hash::${SHA}" echo "::set-output name=default-target::${DEFAULT_TARGET}" + - name: 'Bundle scripts' + if: ${{ !github.event.pull_request.head.repo.fork }} + run: | + tar czpf artifacts/flipper-z-any-scripts-${{steps.names.outputs.suffix}}.tgz scripts + - name: 'Build the firmware in docker' uses: ./.github/actions/docker with: @@ -92,6 +97,12 @@ jobs: mv dist/${TARGET}/* artifacts/ done + - name: 'Bundle resources' + if: ${{ !github.event.pull_request.head.repo.fork }} + run: | + ./scripts/assets.py manifest assets/resources + tar czpf artifacts/flipper-z-any-resources-${{steps.names.outputs.suffix}}.tgz -C assets resources + - name: 'Bundle core2 firmware' if: ${{ !github.event.pull_request.head.repo.fork }} run: | @@ -100,17 +111,6 @@ jobs: ./scripts/assets.py copro lib/STM32CubeWB core2_firmware STM32WB5x tar czpf artifacts/flipper-z-any-core2_firmware-${{steps.names.outputs.suffix}}.tgz core2_firmware - - name: 'Bundle scripts' - if: ${{ !github.event.pull_request.head.repo.fork }} - run: | - tar czpf artifacts/flipper-z-any-scripts-${{steps.names.outputs.suffix}}.tgz scripts - - - name: 'Bundle resources' - if: ${{ !github.event.pull_request.head.repo.fork }} - run: | - ./scripts/assets.py manifest assets/resources - tar czpf artifacts/flipper-z-any-resources-${{steps.names.outputs.suffix}}.tgz -C assets resources - - name: 'Upload artifacts to update server' if: ${{ !github.event.pull_request.head.repo.fork }} uses: burnett01/rsync-deployments@5.1 diff --git a/scripts/meta.py b/scripts/meta.py index c3c4cac9..ae2f213b 100755 --- a/scripts/meta.py +++ b/scripts/meta.py @@ -35,7 +35,7 @@ class Main(App): def generate(self): meta = {} for k, v in vars(self.args).items(): - if k == "project" or k == "func": + if k in ["project", "func", "debug"]: continue if isinstance(v, str): v = v.strip('"') From b912cc79914b74f256cd641b610001cdb8072a2f Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Wed, 1 Dec 2021 19:44:39 +0400 Subject: [PATCH 10/32] SubGhz: sending / receiving messages via subghz (#851) * SubGhz: add worker subghz_txrx * SubGhz: added support for transferring Russian characters and support for backspace in CLI subghz_txrx * SubGhz: refactoring subghz_txrx_worker, added a callback for accepting data in an empty one RX buffer * SubGhz: fix conflict * SubGhz: fix syntax errors * Cli: document string_move usage and its behavior * FuriHal: update subghz api and documentation. Subghz: move chat to subghz cli subcommand. * Subghz: update text in chat cli Co-authored-by: Aleksandr Kutuzov --- applications/cli/cli.c | 10 + applications/subghz/subghz_cli.c | 126 +++++++- .../targets/f6/furi-hal/furi-hal-subghz.c | 111 ++++++- .../targets/f7/furi-hal/furi-hal-subghz.c | 111 ++++++- .../furi-hal-include/furi-hal-subghz.h | 21 ++ lib/drivers/cc1101.c | 19 +- lib/drivers/cc1101_regs.h | 7 +- lib/subghz/subghz_tx_rx_worker.c | 273 ++++++++++++++++++ lib/subghz/subghz_tx_rx_worker.h | 81 ++++++ 9 files changed, 715 insertions(+), 44 deletions(-) create mode 100644 lib/subghz/subghz_tx_rx_worker.c create mode 100644 lib/subghz/subghz_tx_rx_worker.h diff --git a/applications/cli/cli.c b/applications/cli/cli.c index 7d60f7d1..fe449906 100644 --- a/applications/cli/cli.c +++ b/applications/cli/cli.c @@ -113,7 +113,9 @@ void cli_prompt(Cli* cli) { } void cli_reset(Cli* cli) { + // cli->last_line is cleared and cli->line's buffer moved to cli->last_line string_move(cli->last_line, cli->line); + // Reiniting cli->line string_init(cli->line); cli->cursor_position = 0; } @@ -129,7 +131,11 @@ static void cli_handle_backspace(Cli* cli) { string_reserve(temp, string_size(cli->line) - 1); string_set_strn(temp, string_get_cstr(cli->line), cli->cursor_position - 1); string_cat_str(temp, string_get_cstr(cli->line) + cli->cursor_position); + + // cli->line is cleared and temp's buffer moved to cli->line string_move(cli->line, temp); + // NO MEMORY LEAK, STOP REPORTING IT + cli->cursor_position--; } else { cli_putc(CliSymbolAsciiBell); @@ -332,7 +338,11 @@ void cli_process_input(Cli* cli) { string_set_strn(temp, string_get_cstr(cli->line), cli->cursor_position); string_push_back(temp, c); string_cat_str(temp, string_get_cstr(cli->line) + cli->cursor_position); + + // cli->line is cleared and temp's buffer moved to cli->line string_move(cli->line, temp); + // NO MEMORY LEAK, STOP REPORTING IT + // Print character in replace mode printf("\e[4h%c\e[4l", c); fflush(stdout); diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index 62d070ef..9b67614b 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -9,11 +9,12 @@ #include #include #include +#include #define SUBGHZ_FREQUENCY_RANGE_STR \ "299999755...348000000 or 386999938...464000000 or 778999847...928000000" -void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) { +static void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) { uint32_t frequency = 433920000; if(string_size(args)) { @@ -56,7 +57,7 @@ void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) { furi_hal_power_suppress_charge_exit(); } -void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { +static void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { uint32_t frequency = 433920000; if(string_size(args)) { @@ -96,7 +97,7 @@ void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { furi_hal_subghz_sleep(); } -void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { +static void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { uint32_t frequency = 433920000; uint32_t key = 0x0074BADE; size_t repeat = 10; @@ -187,7 +188,7 @@ static void subghz_cli_command_rx_text_callback(string_t text, void* context) { printf("%s", string_get_cstr(text)); } -void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { +static void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { uint32_t frequency = 433920000; if(string_size(args)) { @@ -260,7 +261,7 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { free(instance); } -void subghz_cli_command_print_usage() { +static void subghz_cli_command_print_usage() { printf("Usage:\r\n"); printf("subghz \r\n"); printf("Cmd list:\r\n"); @@ -268,9 +269,10 @@ void subghz_cli_command_print_usage() { "\tencrypt_keeloq \t - Encrypt keeloq manufacture keys\r\n"); printf( "\tencrypt_raw \t - Encrypt RAW data\r\n"); + printf("\tchat \t - Chat with other Flippers\r\n"); } -void subghz_cli_command_encrypt_keeloq(Cli* cli, string_t args) { +static void subghz_cli_command_encrypt_keeloq(Cli* cli, string_t args) { uint8_t iv[16]; string_t source; @@ -312,7 +314,7 @@ void subghz_cli_command_encrypt_keeloq(Cli* cli, string_t args) { string_clear(source); } -void subghz_cli_command_encrypt_raw(Cli* cli, string_t args) { +static void subghz_cli_command_encrypt_raw(Cli* cli, string_t args) { uint8_t iv[16]; string_t source; @@ -348,7 +350,110 @@ void subghz_cli_command_encrypt_raw(Cli* cli, string_t args) { string_clear(source); } -void subghz_cli_command(Cli* cli, string_t args, void* context) { +static void subghz_cli_command_chat(Cli* cli, string_t args) { + uint32_t frequency = 433920000; + + if(string_size(args)) { + int ret = sscanf(string_get_cstr(args), "%lu", &frequency); + if(ret != 1) { + printf("sscanf returned %d, frequency: %lu\r\n", ret, frequency); + cli_print_usage("subghz_txrx", "", string_get_cstr(args)); + return; + } + if(!furi_hal_subghz_is_frequency_valid(frequency)) { + printf( + "Frequency must be in " SUBGHZ_FREQUENCY_RANGE_STR " range, not %lu\r\n", + frequency); + return; + } + } + if(!furi_hal_subghz_is_tx_allowed(frequency)) { + printf( + "In your region, only reception on this frequency (%lu) is allowed,\r\n" + "the actual operation of the application is not possible\r\n ", + frequency); + return; + } + + SubGhzTxRxWorker* subghz_txrx = subghz_tx_rx_worker_alloc(); + subghz_tx_rx_worker_start(subghz_txrx, frequency); + + printf("Receiving at frequency %lu Hz\r\n", frequency); + printf("Press CTRL+C to stop\r\n"); + + furi_hal_power_suppress_charge_enter(); + size_t message_max_len = 64; + uint8_t message[64] = {0}; + string_t input; + string_init(input); + string_t name; + string_init(name); + char c; + bool exit = false; + + string_printf(name, "\033[0;33m%s\033[0m: ", furi_hal_version_get_name_ptr()); + string_set(input, name); + printf("%s", string_get_cstr(input)); + fflush(stdout); + + while(!exit) { + if(furi_hal_vcp_rx_with_timeout((uint8_t*)&c, 1, 0) == 1) { + if(c == CliSymbolAsciiETX) { + printf("\r\n"); + exit = true; + break; + } else if((c >= 0x20 && c < 0x7F) || (c >= 0x80 && c < 0xF0)) { + putc(c, stdout); + fflush(stdout); + string_push_back(input, c); + } else if(c == CliSymbolAsciiBackspace) { + size_t len = string_size(input); + if(len > string_size(name)) { + string_set_strn(input, string_get_cstr(input), len - 1); + printf("\r"); + for(uint8_t i = 0; i < len; i++) { + printf(" "); + } + printf("\r%s", string_get_cstr(input)); + fflush(stdout); + } + } else if(c == CliSymbolAsciiCR) { + printf("\r\n"); + subghz_tx_rx_worker_write( + subghz_txrx, (uint8_t*)string_get_cstr(input), strlen(string_get_cstr(input))); + string_printf(input, "%s", string_get_cstr(name)); + printf("%s", string_get_cstr(input)); + fflush(stdout); + } + } + + if(subghz_tx_rx_worker_available(subghz_txrx)) { + memset(message, 0x00, message_max_len); + subghz_tx_rx_worker_read(subghz_txrx, message, message_max_len); + printf("\r"); + for(uint8_t i = 0; i < 80; i++) { + printf(" "); + } + + printf("\r %s\r\n", message); + + printf("%s", string_get_cstr(input)); + fflush(stdout); + } + } + + printf("\r\nExit chat\r\n"); + string_clear(input); + string_clear(name); + furi_hal_power_suppress_charge_exit(); + + if(subghz_tx_rx_worker_is_running(subghz_txrx)) { + subghz_tx_rx_worker_stop(subghz_txrx); + subghz_tx_rx_worker_free(subghz_txrx); + } +} + +static void subghz_cli_command(Cli* cli, string_t args, void* context) { string_t cmd; string_init(cmd); @@ -368,6 +473,11 @@ void subghz_cli_command(Cli* cli, string_t args, void* context) { break; } + if(string_cmp_str(cmd, "chat") == 0) { + subghz_cli_command_chat(cli, args); + break; + } + subghz_cli_command_print_usage(); } while(false); diff --git a/firmware/targets/f6/furi-hal/furi-hal-subghz.c b/firmware/targets/f6/furi-hal/furi-hal-subghz.c index 86540818..20e9c1f9 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-subghz.c +++ b/firmware/targets/f6/furi-hal/furi-hal-subghz.c @@ -244,6 +244,54 @@ static const uint8_t furi_hal_subghz_preset_2fsk_dev4_76khz_async_regs[][2] = { /* End */ {0, 0}, }; +static const uint8_t furi_hal_subghz_preset_msk_99_97kb_async_regs[][2] = { + /* GPIO GD0 */ + {CC1101_IOCFG0, 0x06}, + + {CC1101_FIFOTHR, 0x07}, // The only important bit is ADC_RETENTION + {CC1101_SYNC1, 0x46}, + {CC1101_SYNC0, 0x4C}, + {CC1101_ADDR, 0x00}, + {CC1101_PKTLEN, 0x00}, + {CC1101_CHANNR, 0x00}, + + {CC1101_PKTCTRL0, 0x05}, + + {CC1101_FSCTRL0, 0x23}, + {CC1101_FSCTRL1, 0x06}, + + {CC1101_MDMCFG0, 0xF8}, + {CC1101_MDMCFG1, 0x22}, + {CC1101_MDMCFG2, 0x72}, + {CC1101_MDMCFG3, 0xF8}, + {CC1101_MDMCFG4, 0x5B}, + {CC1101_DEVIATN, 0x47}, + + {CC1101_MCSM0, 0x18}, + {CC1101_FOCCFG, 0x16}, + + {CC1101_AGCCTRL0, 0xB2}, + {CC1101_AGCCTRL1, 0x00}, + {CC1101_AGCCTRL2, 0xC7}, + + {CC1101_FREND0, 0x10}, + {CC1101_FREND1, 0x56}, + + {CC1101_FSCAL3, 0xE9}, + {CC1101_FSCAL2, 0x2A}, + {CC1101_FSCAL1, 0x00}, + {CC1101_FSCAL0, 0x1F}, + + {CC1101_BSCFG, 0x1C}, + {CC1101_FSTEST, 0x59}, + + {CC1101_TEST2, 0x81}, + {CC1101_TEST1, 0x35}, + {CC1101_TEST0, 0x09}, + /* End */ + {0, 0}, +}; + static const uint8_t furi_hal_subghz_preset_ook_async_patable[8] = { 0x00, 0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12 @@ -261,9 +309,16 @@ static const uint8_t furi_hal_subghz_preset_2fsk_async_patable[8] = { 0x00, 0x00, 0x00, - 0x00 - -}; + 0x00}; +static const uint8_t furi_hal_subghz_preset_msk_async_patable[8] = { + 0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12 + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00}; void furi_hal_subghz_init() { furi_assert(furi_hal_subghz_state == SubGhzStateInit); @@ -344,6 +399,9 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { } else if(preset == FuriHalSubGhzPreset2FSKDev476Async) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_2fsk_dev4_76khz_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_2fsk_async_patable); + } else if(preset == FuriHalSubGhzPresetMSK99_97KbAsync) { + furi_hal_subghz_load_registers(furi_hal_subghz_preset_msk_99_97kb_async_regs); + furi_hal_subghz_load_patable(furi_hal_subghz_preset_msk_async_patable); } else { furi_crash(NULL); } @@ -369,6 +427,7 @@ void furi_hal_subghz_load_patable(const uint8_t data[8]) { void furi_hal_subghz_write_packet(const uint8_t* data, uint8_t size) { furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); cc1101_flush_tx(&furi_hal_spi_bus_handle_subghz); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_FIFO, size); cc1101_write_fifo(&furi_hal_spi_bus_handle_subghz, data, size); furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } @@ -379,6 +438,31 @@ void furi_hal_subghz_flush_rx() { furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } +bool furi_hal_subghz_rx_pipe_not_empty() { + CC1101RxBytes status[1]; + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_read_reg(&furi_hal_spi_bus_handle_subghz, (CC1101_STATUS_RXBYTES) | CC1101_BURST, (uint8_t*)status); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); + // TODO: you can add a buffer overflow flag if needed + if(status->NUM_RXBYTES > 0) { + return true; + } else { + return false; + } +} + +bool furi_hal_subghz_is_rx_data_crc_valid() { + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + uint8_t data[1]; + cc1101_read_reg(&furi_hal_spi_bus_handle_subghz, CC1101_STATUS_LQI | CC1101_BURST, data); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); + if(((data[0] >> 7) & 0x01)) { + return true; + } else { + return false; + } +} + void furi_hal_subghz_read_packet(uint8_t* data, uint8_t* size) { furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); cc1101_read_fifo(&furi_hal_spi_bus_handle_subghz, data, size); @@ -460,18 +544,16 @@ uint32_t furi_hal_subghz_set_frequency_and_path(uint32_t value) { return value; } -uint32_t furi_hal_subghz_set_frequency(uint32_t value) { - furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); - +bool furi_hal_subghz_is_tx_allowed(uint32_t value) { //checking regional settings - bool txrx = false; + bool is_allowed = false; switch(furi_hal_version_get_hw_region()) { case FuriHalVersionRegionEuRu: //433,05..434,79; 868,15..868,55 if(!(value >= 433050000 && value <= 434790000) && !(value >= 868150000 && value <= 868550000)) { } else { - txrx = true; + is_allowed = true; } break; case FuriHalVersionRegionUsCaAu: @@ -480,7 +562,7 @@ uint32_t furi_hal_subghz_set_frequency(uint32_t value) { !(value >= 433050000 && value <= 434790000) && !(value >= 915000000 && value <= 928000000)) { } else { - txrx = true; + is_allowed = true; } break; case FuriHalVersionRegionJp: @@ -488,16 +570,21 @@ uint32_t furi_hal_subghz_set_frequency(uint32_t value) { if(!(value >= 312000000 && value <= 315250000) && !(value >= 920500000 && value <= 923500000)) { } else { - txrx = true; + is_allowed = true; } break; default: - txrx = true; + is_allowed = true; break; } + return is_allowed; +} - if(txrx) { +uint32_t furi_hal_subghz_set_frequency(uint32_t value) { + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + + if(furi_hal_subghz_is_tx_allowed(value)) { furi_hal_subghz_regulation = SubGhzRegulationTxRx; } else { furi_hal_subghz_regulation = SubGhzRegulationOnlyRx; diff --git a/firmware/targets/f7/furi-hal/furi-hal-subghz.c b/firmware/targets/f7/furi-hal/furi-hal-subghz.c index 86540818..20e9c1f9 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-subghz.c +++ b/firmware/targets/f7/furi-hal/furi-hal-subghz.c @@ -244,6 +244,54 @@ static const uint8_t furi_hal_subghz_preset_2fsk_dev4_76khz_async_regs[][2] = { /* End */ {0, 0}, }; +static const uint8_t furi_hal_subghz_preset_msk_99_97kb_async_regs[][2] = { + /* GPIO GD0 */ + {CC1101_IOCFG0, 0x06}, + + {CC1101_FIFOTHR, 0x07}, // The only important bit is ADC_RETENTION + {CC1101_SYNC1, 0x46}, + {CC1101_SYNC0, 0x4C}, + {CC1101_ADDR, 0x00}, + {CC1101_PKTLEN, 0x00}, + {CC1101_CHANNR, 0x00}, + + {CC1101_PKTCTRL0, 0x05}, + + {CC1101_FSCTRL0, 0x23}, + {CC1101_FSCTRL1, 0x06}, + + {CC1101_MDMCFG0, 0xF8}, + {CC1101_MDMCFG1, 0x22}, + {CC1101_MDMCFG2, 0x72}, + {CC1101_MDMCFG3, 0xF8}, + {CC1101_MDMCFG4, 0x5B}, + {CC1101_DEVIATN, 0x47}, + + {CC1101_MCSM0, 0x18}, + {CC1101_FOCCFG, 0x16}, + + {CC1101_AGCCTRL0, 0xB2}, + {CC1101_AGCCTRL1, 0x00}, + {CC1101_AGCCTRL2, 0xC7}, + + {CC1101_FREND0, 0x10}, + {CC1101_FREND1, 0x56}, + + {CC1101_FSCAL3, 0xE9}, + {CC1101_FSCAL2, 0x2A}, + {CC1101_FSCAL1, 0x00}, + {CC1101_FSCAL0, 0x1F}, + + {CC1101_BSCFG, 0x1C}, + {CC1101_FSTEST, 0x59}, + + {CC1101_TEST2, 0x81}, + {CC1101_TEST1, 0x35}, + {CC1101_TEST0, 0x09}, + /* End */ + {0, 0}, +}; + static const uint8_t furi_hal_subghz_preset_ook_async_patable[8] = { 0x00, 0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12 @@ -261,9 +309,16 @@ static const uint8_t furi_hal_subghz_preset_2fsk_async_patable[8] = { 0x00, 0x00, 0x00, - 0x00 - -}; + 0x00}; +static const uint8_t furi_hal_subghz_preset_msk_async_patable[8] = { + 0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12 + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00}; void furi_hal_subghz_init() { furi_assert(furi_hal_subghz_state == SubGhzStateInit); @@ -344,6 +399,9 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { } else if(preset == FuriHalSubGhzPreset2FSKDev476Async) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_2fsk_dev4_76khz_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_2fsk_async_patable); + } else if(preset == FuriHalSubGhzPresetMSK99_97KbAsync) { + furi_hal_subghz_load_registers(furi_hal_subghz_preset_msk_99_97kb_async_regs); + furi_hal_subghz_load_patable(furi_hal_subghz_preset_msk_async_patable); } else { furi_crash(NULL); } @@ -369,6 +427,7 @@ void furi_hal_subghz_load_patable(const uint8_t data[8]) { void furi_hal_subghz_write_packet(const uint8_t* data, uint8_t size) { furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); cc1101_flush_tx(&furi_hal_spi_bus_handle_subghz); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_FIFO, size); cc1101_write_fifo(&furi_hal_spi_bus_handle_subghz, data, size); furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } @@ -379,6 +438,31 @@ void furi_hal_subghz_flush_rx() { furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } +bool furi_hal_subghz_rx_pipe_not_empty() { + CC1101RxBytes status[1]; + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_read_reg(&furi_hal_spi_bus_handle_subghz, (CC1101_STATUS_RXBYTES) | CC1101_BURST, (uint8_t*)status); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); + // TODO: you can add a buffer overflow flag if needed + if(status->NUM_RXBYTES > 0) { + return true; + } else { + return false; + } +} + +bool furi_hal_subghz_is_rx_data_crc_valid() { + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + uint8_t data[1]; + cc1101_read_reg(&furi_hal_spi_bus_handle_subghz, CC1101_STATUS_LQI | CC1101_BURST, data); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); + if(((data[0] >> 7) & 0x01)) { + return true; + } else { + return false; + } +} + void furi_hal_subghz_read_packet(uint8_t* data, uint8_t* size) { furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); cc1101_read_fifo(&furi_hal_spi_bus_handle_subghz, data, size); @@ -460,18 +544,16 @@ uint32_t furi_hal_subghz_set_frequency_and_path(uint32_t value) { return value; } -uint32_t furi_hal_subghz_set_frequency(uint32_t value) { - furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); - +bool furi_hal_subghz_is_tx_allowed(uint32_t value) { //checking regional settings - bool txrx = false; + bool is_allowed = false; switch(furi_hal_version_get_hw_region()) { case FuriHalVersionRegionEuRu: //433,05..434,79; 868,15..868,55 if(!(value >= 433050000 && value <= 434790000) && !(value >= 868150000 && value <= 868550000)) { } else { - txrx = true; + is_allowed = true; } break; case FuriHalVersionRegionUsCaAu: @@ -480,7 +562,7 @@ uint32_t furi_hal_subghz_set_frequency(uint32_t value) { !(value >= 433050000 && value <= 434790000) && !(value >= 915000000 && value <= 928000000)) { } else { - txrx = true; + is_allowed = true; } break; case FuriHalVersionRegionJp: @@ -488,16 +570,21 @@ uint32_t furi_hal_subghz_set_frequency(uint32_t value) { if(!(value >= 312000000 && value <= 315250000) && !(value >= 920500000 && value <= 923500000)) { } else { - txrx = true; + is_allowed = true; } break; default: - txrx = true; + is_allowed = true; break; } + return is_allowed; +} - if(txrx) { +uint32_t furi_hal_subghz_set_frequency(uint32_t value) { + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + + if(furi_hal_subghz_is_tx_allowed(value)) { furi_hal_subghz_regulation = SubGhzRegulationTxRx; } else { furi_hal_subghz_regulation = SubGhzRegulationOnlyRx; diff --git a/firmware/targets/furi-hal-include/furi-hal-subghz.h b/firmware/targets/furi-hal-include/furi-hal-subghz.h index 97b57e27..cde71705 100644 --- a/firmware/targets/furi-hal-include/furi-hal-subghz.h +++ b/firmware/targets/furi-hal-include/furi-hal-subghz.h @@ -20,6 +20,7 @@ typedef enum { FuriHalSubGhzPresetOok650Async, /**< OOK, bandwidth 650kHz, asynchronous */ FuriHalSubGhzPreset2FSKDev238Async, /**< FM, deviation 2.380371 kHz, asynchronous */ FuriHalSubGhzPreset2FSKDev476Async, /**< FM, deviation 4.760742 kHz, asynchronous */ + FuriHalSubGhzPresetMSK99_97KbAsync, /**< MSK, deviation 47.60742 kHz, 99.97Kb/s, asynchronous */ } FuriHalSubGhzPreset; /** Switchable Radio Paths */ @@ -90,6 +91,18 @@ void furi_hal_subghz_load_patable(const uint8_t data[8]); */ void furi_hal_subghz_write_packet(const uint8_t* data, uint8_t size); +/** Check if recieve pipe is not empty + * + * @return true if not empty + */ +bool furi_hal_subghz_rx_pipe_not_empty(); + +/** Check if recieved data crc is valid + * + * @return true if valid + */ +bool furi_hal_subghz_is_rx_data_crc_valid(); + /** Read packet from FIFO * * @param data pointer @@ -148,6 +161,14 @@ bool furi_hal_subghz_is_frequency_valid(uint32_t value); */ uint32_t furi_hal_subghz_set_frequency_and_path(uint32_t value); +/** Сheck if transmission is allowed on this frequency for your flipper region + * + * @param value frequency in Hz + * + * @return true if allowed + */ +bool furi_hal_subghz_is_tx_allowed(uint32_t value); + /** Set frequency * * @param value frequency in Hz diff --git a/lib/drivers/cc1101.c b/lib/drivers/cc1101.c index af37dea9..94232da4 100644 --- a/lib/drivers/cc1101.c +++ b/lib/drivers/cc1101.c @@ -22,14 +22,14 @@ CC1101Status cc1101_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t while(hal_gpio_read(handle->miso)); furi_hal_spi_bus_trx(handle, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); - assert((rx[0].CHIP_RDYn|rx[1].CHIP_RDYn) == 0); + assert((rx[0].CHIP_RDYn | rx[1].CHIP_RDYn) == 0); return rx[1]; } CC1101Status cc1101_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* data) { assert(sizeof(CC1101Status) == 1); - uint8_t tx[2] = { reg|CC1101_READ, 0}; - CC1101Status rx[2] = { 0 }; + uint8_t tx[2] = {reg | CC1101_READ, 0}; + CC1101Status rx[2] = {0}; while(hal_gpio_read(handle->miso)); furi_hal_spi_bus_trx(handle, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); @@ -58,8 +58,6 @@ uint8_t cc1101_get_rssi(FuriHalSpiBusHandle* handle) { } void cc1101_reset(FuriHalSpiBusHandle* handle) { - delay_us(1000); - delay_us(1000); cc1101_strobe(handle, CC1101_STROBE_SRES); } @@ -130,7 +128,7 @@ void cc1101_set_pa_table(FuriHalSpiBusHandle* handle, const uint8_t value[8]) { while(hal_gpio_read(handle->miso)); furi_hal_spi_bus_trx(handle, tx, (uint8_t*)rx, sizeof(rx), CC1101_TIMEOUT); - assert((rx[0].CHIP_RDYn|rx[8].CHIP_RDYn) == 0); + assert((rx[0].CHIP_RDYn | rx[8].CHIP_RDYn) == 0); } uint8_t cc1101_write_fifo(FuriHalSpiBusHandle* handle, const uint8_t* data, uint8_t size) { @@ -159,9 +157,14 @@ uint8_t cc1101_read_fifo(FuriHalSpiBusHandle* handle, uint8_t* data, uint8_t* si // First byte - packet length furi_hal_spi_bus_trx(handle, buff_tx, buff_rx, 2, CC1101_TIMEOUT); - *size = buff_rx[1]; + + // Check that the packet is placed in the receive buffer + if(buff_rx[1] > 64) { + *size = 64; + } else { + *size = buff_rx[1]; + } furi_hal_spi_bus_trx(handle, &buff_tx[1], data, *size, CC1101_TIMEOUT); - cc1101_flush_rx(handle); return *size; } diff --git a/lib/drivers/cc1101_regs.h b/lib/drivers/cc1101_regs.h index 6e71cc37..b3e95b72 100644 --- a/lib/drivers/cc1101_regs.h +++ b/lib/drivers/cc1101_regs.h @@ -89,22 +89,21 @@ extern "C" { #define CC1101_STATUS_PARTNUM 0x30 /** Chip ID Part Number */ #define CC1101_STATUS_VERSION 0x31 /** Chip ID Version */ #define CC1101_STATUS_FREQEST 0x32 /** Frequency Offset Estimate from Demodulator */ -#define CC1101_STATUS_LQI 0x33 /** Demodulator Estimate for Link Quality */ +#define CC1101_STATUS_LQI 0x33 /** Demodulator Estimate for Link Quality, 7bit-CRC, 6..0-LQI*/ #define CC1101_STATUS_RSSI 0x34 /** Received Signal Strength Indication */ #define CC1101_STATUS_MARCSTATE 0x35 /** Main Radio Control State Machine State */ #define CC1101_STATUS_WORTIME1 0x36 /** High Byte of WOR Time */ #define CC1101_STATUS_WORTIME0 0x37 /** Low Byte of WOR Time */ #define CC1101_STATUS_PKTSTATUS 0x38 /** Current GDOx Status and Packet Status */ #define CC1101_STATUS_VCO_VC_DAC 0x39 /** Current Setting from PLL Calibration Module */ -#define CC1101_STATUS_TXBYTES 0x3A /** Underflow and Number of Bytes */ -#define CC1101_STATUS_RXBYTES 0x3B /** Overflow and Number of Bytes */ +#define CC1101_STATUS_TXBYTES 0x3A /** Underflow and Number of Bytes, 7bit-Underflow, 6..0-Number of Bytes*/ +#define CC1101_STATUS_RXBYTES 0x3B /** Overflow and Number of Bytes, 7bit-Overflow*, 6..0-Number of Bytes*/ #define CC1101_STATUS_RCCTRL1_STATUS 0x3C /** Last RC Oscillator Calibration Result */ #define CC1101_STATUS_RCCTRL0_STATUS 0x3D /** Last RC Oscillator Calibration Result */ /* Some special registers, use CC1101_BURST to read/write data */ #define CC1101_PATABLE 0x3E /** PATABLE register number, an 8-byte table that defines the PA control settings */ #define CC1101_FIFO 0x3F /** FIFO register nunmber, can be combined with CC1101_WRITE and/or CC1101_BURST */ - #define CC1101_IOCFG_INV (1<<6) /** IOCFG inversion */ typedef enum { diff --git a/lib/subghz/subghz_tx_rx_worker.c b/lib/subghz/subghz_tx_rx_worker.c new file mode 100644 index 00000000..d151babe --- /dev/null +++ b/lib/subghz/subghz_tx_rx_worker.c @@ -0,0 +1,273 @@ +#include "subghz_tx_rx_worker.h" + +#include +#include + +#define TAG "SubGhzTxRxWorker" + +#define GUBGHZ_TXRX_WORKER_BUF_SIZE 2048 +//you can not set more than 62 because it will not fit into the FIFO CC1101 +#define GUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE 60 + +#define GUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF 40 + +struct SubGhzTxRxWorker { + FuriThread* thread; + StreamBufferHandle_t stream_tx; + StreamBufferHandle_t stream_rx; + + volatile bool worker_running; + volatile bool worker_stoping; + + SubGhzTxRxWorkerStatus satus; + + uint32_t frequency; + + SubGhzTxRxWorkerCallbackHaveRead callback_have_read; + void* context_have_read; +}; + +bool subghz_tx_rx_worker_write(SubGhzTxRxWorker* instance, uint8_t* data, size_t size) { + furi_assert(instance); + bool ret = false; + size_t stream_tx_free_byte = xStreamBufferSpacesAvailable(instance->stream_tx); + if(size && (stream_tx_free_byte >= size)) { + if(xStreamBufferSend( + instance->stream_tx, data, size, GUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF) == + size) { + ret = true; + } + } + return ret; +} + +size_t subghz_tx_rx_worker_available(SubGhzTxRxWorker* instance) { + furi_assert(instance); + return xStreamBufferBytesAvailable(instance->stream_rx); +} + +size_t subghz_tx_rx_worker_read(SubGhzTxRxWorker* instance, uint8_t* data, size_t size) { + furi_assert(instance); + size_t len = 0; + size_t stream_rx_byte = xStreamBufferBytesAvailable(instance->stream_rx); + + if(stream_rx_byte > 0) { + if(stream_rx_byte <= size) { + len = xStreamBufferReceive( + instance->stream_rx, + data, + stream_rx_byte, + GUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); + } else { + len = xStreamBufferReceive( + instance->stream_rx, data, size, GUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); + } + } + return len; +} + +void subghz_tx_rx_worker_set_callback_have_read( + SubGhzTxRxWorker* instance, + SubGhzTxRxWorkerCallbackHaveRead callback, + void* context) { + furi_assert(instance); + furi_assert(callback); + furi_assert(context); + instance->callback_have_read = callback; + instance->context_have_read = context; +} + +bool subghz_tx_rx_worker_rx(SubGhzTxRxWorker* instance, uint8_t* data, uint8_t* size) { + uint8_t timeout = 20; + bool ret = false; + if(instance->satus != SubGhzTxRxWorkerStatusRx) { + furi_hal_subghz_rx(); + instance->satus = SubGhzTxRxWorkerStatusRx; + osDelay(1); + } + //waiting for reception to complete + while(hal_gpio_read(&gpio_cc1101_g0)) { + osDelay(1); + if(!--timeout) { + FURI_LOG_W(TAG, "RX cc1101_g0 timeout"); + furi_hal_subghz_flush_rx(); + furi_hal_subghz_rx(); + break; + } + } + + if(furi_hal_subghz_rx_pipe_not_empty()) { + if(furi_hal_subghz_is_rx_data_crc_valid()) { + furi_hal_subghz_read_packet(data, size); + ret = true; + } + furi_hal_subghz_flush_rx(); + furi_hal_subghz_rx(); + } + return ret; +} + +void subghz_tx_rx_worker_tx(SubGhzTxRxWorker* instance, uint8_t* data, size_t size) { + uint8_t timeout = 40; + if(instance->satus != SubGhzTxRxWorkerStatusIDLE) { + furi_hal_subghz_idle(); + } + furi_hal_subghz_write_packet(data, size); + instance->satus = SubGhzTxRxWorkerStatusTx; + + furi_hal_subghz_tx(); //start send + + while(!hal_gpio_read(&gpio_cc1101_g0)) { // Wait for GDO0 to be set -> sync transmitted + osDelay(1); + if(!--timeout) { + FURI_LOG_W(TAG, "TX !cc1101_g0 timeout"); + break; + } + } + while(hal_gpio_read(&gpio_cc1101_g0)) { // Wait for GDO0 to be cleared -> end of packet + osDelay(1); + if(!--timeout) { + FURI_LOG_W(TAG, "TX cc1101_g0 timeout"); + break; + } + } + furi_hal_subghz_idle(); + instance->satus = SubGhzTxRxWorkerStatusIDLE; +} +/** Worker thread + * + * @param context + * @return exit code + */ +static int32_t subghz_tx_rx_worker_thread(void* context) { + SubGhzTxRxWorker* instance = context; + FURI_LOG_I(TAG, "Worker start"); + + furi_hal_subghz_reset(); + furi_hal_subghz_idle(); + furi_hal_subghz_load_preset(FuriHalSubGhzPresetMSK99_97KbAsync); + hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); + + furi_hal_subghz_set_frequency_and_path(instance->frequency); + furi_hal_subghz_flush_rx(); + + uint8_t data[GUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE] = {0}; + size_t size_tx = 0; + uint8_t size_rx[1] = {0}; + uint8_t timeout_tx = 0; + bool callback_rx = false; + + while(instance->worker_running) { + //transmit + size_tx = xStreamBufferBytesAvailable(instance->stream_tx); + if(size_tx > 0 && !timeout_tx) { + timeout_tx = 20; //20ms + if(size_tx > GUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE) { + xStreamBufferReceive( + instance->stream_tx, + &data, + GUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE, + GUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); + subghz_tx_rx_worker_tx(instance, data, GUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE); + } else { + //todo checking that he managed to write all the data to the TX buffer + xStreamBufferReceive( + instance->stream_tx, &data, size_tx, GUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); + subghz_tx_rx_worker_tx(instance, data, size_tx); + } + } else { + //recive + if(subghz_tx_rx_worker_rx(instance, data, size_rx)) { + if(xStreamBufferSpacesAvailable(instance->stream_rx) >= size_rx[0]) { + if(instance->callback_have_read && + xStreamBufferBytesAvailable(instance->stream_rx) == 0) { + callback_rx = true; + } + //todo checking that he managed to write all the data to the RX buffer + xStreamBufferSend( + instance->stream_rx, + &data, + size_rx[0], + GUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); + if(callback_rx) { + instance->callback_have_read(instance->context_have_read); + callback_rx = false; + } + } else { + //todo RX buffer overflow + } + } + } + + if(timeout_tx) timeout_tx--; + osDelay(1); + } + + furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); + furi_hal_subghz_sleep(); + + FURI_LOG_I(TAG, "Worker stop"); + return 0; +} + +SubGhzTxRxWorker* subghz_tx_rx_worker_alloc() { + SubGhzTxRxWorker* instance = furi_alloc(sizeof(SubGhzTxRxWorker)); + + instance->thread = furi_thread_alloc(); + furi_thread_set_name(instance->thread, "SubghzTxRxWorker"); + furi_thread_set_stack_size(instance->thread, 2048); + furi_thread_set_context(instance->thread, instance); + furi_thread_set_callback(instance->thread, subghz_tx_rx_worker_thread); + instance->stream_tx = + xStreamBufferCreate(sizeof(uint8_t) * GUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t)); + instance->stream_rx = + xStreamBufferCreate(sizeof(uint8_t) * GUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t)); + + instance->satus = SubGhzTxRxWorkerStatusIDLE; + instance->worker_stoping = true; + + return instance; +} + +void subghz_tx_rx_worker_free(SubGhzTxRxWorker* instance) { + furi_assert(instance); + + vStreamBufferDelete(instance->stream_tx); + vStreamBufferDelete(instance->stream_rx); + furi_thread_free(instance->thread); + + free(instance); +} + +bool subghz_tx_rx_worker_start(SubGhzTxRxWorker* instance, uint32_t frequency) { + furi_assert(instance); + furi_assert(!instance->worker_running); + bool res = false; + xStreamBufferReset(instance->stream_tx); + xStreamBufferReset(instance->stream_rx); + + instance->worker_running = true; + + furi_thread_start(instance->thread); + + if(furi_hal_subghz_is_tx_allowed(frequency)) { + instance->frequency = frequency; + res = true; + } + + return res; +} + +void subghz_tx_rx_worker_stop(SubGhzTxRxWorker* instance) { + furi_assert(instance); + furi_assert(instance->worker_running); + + instance->worker_running = false; + + furi_thread_join(instance->thread); +} + +bool subghz_tx_rx_worker_is_running(SubGhzTxRxWorker* instance) { + furi_assert(instance); + return instance->worker_running; +} diff --git a/lib/subghz/subghz_tx_rx_worker.h b/lib/subghz/subghz_tx_rx_worker.h new file mode 100644 index 00000000..3c62136e --- /dev/null +++ b/lib/subghz/subghz_tx_rx_worker.h @@ -0,0 +1,81 @@ +#pragma once + +#include + +typedef void (*SubGhzTxRxWorkerCallbackHaveRead)(void* context); + +typedef struct SubGhzTxRxWorker SubGhzTxRxWorker; + +typedef enum { + SubGhzTxRxWorkerStatusIDLE, + SubGhzTxRxWorkerStatusTx, + SubGhzTxRxWorkerStatusRx, +} SubGhzTxRxWorkerStatus; + +/** SubGhzTxRxWorker, add data to transfer + * + * @param instance SubGhzTxRxWorker instance + * @param data *data + * @param size data size + * @return bool true if ok + */ +bool subghz_tx_rx_worker_write(SubGhzTxRxWorker* instance, uint8_t* data, size_t size); + +/** SubGhzTxRxWorker, get available data + * + * @param instance SubGhzTxRxWorker instance + * @return size_t data size + */ +size_t subghz_tx_rx_worker_available(SubGhzTxRxWorker* instance); + +/** SubGhzTxRxWorker, read data + * + * @param instance SubGhzTxRxWorker instance + * @param data *data + * @param size max data size, which can be read + * @return size_t data size, how much is actually read + */ +size_t subghz_tx_rx_worker_read(SubGhzTxRxWorker* instance, uint8_t* data, size_t size); + +/** Сallback SubGhzTxRxWorker when there is data to read in an empty buffer + * + * @param instance SubGhzTxRxWorker instance + * @param callback SubGhzTxRxWorkerCallbackHaveRead callback + * @param context + */ +void subghz_tx_rx_worker_set_callback_have_read( + SubGhzTxRxWorker* instance, + SubGhzTxRxWorkerCallbackHaveRead callback, + void* context); + +/** Allocate SubGhzTxRxWorker + * + * @return SubGhzTxRxWorker* + */ +SubGhzTxRxWorker* subghz_tx_rx_worker_alloc(); + +/** Free SubGhzTxRxWorker + * + * @param instance SubGhzTxRxWorker instance + */ +void subghz_tx_rx_worker_free(SubGhzTxRxWorker* instance); + +/** Start SubGhzTxRxWorker + * + * @param instance SubGhzTxRxWorker instance + * @return bool - true if ok + */ +bool subghz_tx_rx_worker_start(SubGhzTxRxWorker* instance, uint32_t frequency); + +/** Stop SubGhzTxRxWorker + * + * @param instance SubGhzTxRxWorker instance + */ +void subghz_tx_rx_worker_stop(SubGhzTxRxWorker* instance); + +/** Check if worker is running + * + * @param instance SubGhzTxRxWorker instance + * @return bool - true if running + */ +bool subghz_tx_rx_worker_is_running(SubGhzTxRxWorker* instance); From 41b5d5f5c9770430c38e47a2e1684f0a365d7929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Thu, 2 Dec 2021 01:13:21 +0300 Subject: [PATCH 11/32] Gui: fix random crashes under load in icon_animation (#859) --- applications/gui/icon_animation.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/applications/gui/icon_animation.c b/applications/gui/icon_animation.c index 842798ec..530f3fa7 100644 --- a/applications/gui/icon_animation.c +++ b/applications/gui/icon_animation.c @@ -13,6 +13,8 @@ IconAnimation* icon_animation_alloc(const Icon* icon) { void icon_animation_free(IconAnimation* instance) { furi_assert(instance); + icon_animation_stop(instance); + while(xTimerIsTimerActive(instance->timer) == pdTRUE) osDelay(1); furi_check(osTimerDelete(instance->timer) == osOK); free(instance); } @@ -65,8 +67,9 @@ void icon_animation_start(IconAnimation* instance) { furi_assert(instance->icon->frame_rate); furi_check( xTimerChangePeriod( - instance->timer, (osKernelGetTickFreq() / instance->icon->frame_rate), 0) == - pdPASS); + instance->timer, + (osKernelGetTickFreq() / instance->icon->frame_rate), + portMAX_DELAY) == pdPASS); } } @@ -74,7 +77,7 @@ void icon_animation_stop(IconAnimation* instance) { furi_assert(instance); if(instance->animating) { instance->animating = false; - furi_check(xTimerStop(instance->timer, 0) == pdPASS); + furi_check(xTimerStop(instance->timer, portMAX_DELAY) == pdPASS); instance->frame = 0; } } From 0b0629e6feccde088b67f8cc0674a513cc2be262 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Thu, 2 Dec 2021 02:21:57 +0300 Subject: [PATCH 12/32] Cli: add I2C scanning command (#860) * Cli: add I2C scanning command * Cli: proper scanning limits in i2c command * Cli: better output readability on i2c scan --- applications/cli/cli_commands.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/applications/cli/cli_commands.c b/applications/cli/cli_commands.c index 1a9f4a6d..e8837108 100644 --- a/applications/cli/cli_commands.c +++ b/applications/cli/cli_commands.c @@ -461,6 +461,26 @@ void cli_command_free_blocks(Cli* cli, string_t args, void* context) { memmgr_heap_printf_free_blocks(); } +void cli_command_i2c(Cli* cli, string_t args, void* context) { + furi_hal_i2c_acquire(&furi_hal_i2c_handle_external); + uint8_t test = 0; + printf("Scanning external i2c on PC0(SCL)/PC1(SDA)\r\n" + "Clock: 100khz, 7bit address\r\n" + "!!! Invasive mode (tx to device) !!!\r\n\r\n"); + printf(" | 0 1 2 3 4 5 6 7 8 9 A B C D E F\r\n"); + printf("--+--------------------------------\r\n"); + for(uint8_t row = 0; row < 0x8; row++) { + printf("%x | ", row); + for(uint8_t column = 0; column <= 0xF; column++) { + bool ret = + furi_hal_i2c_rx(&furi_hal_i2c_handle_external, (row << 4) + column, &test, 1, 2); + printf("%c ", ret ? '#' : '-'); + } + printf("\r\n"); + } + furi_hal_i2c_release(&furi_hal_i2c_handle_external); +} + void cli_commands_init(Cli* cli) { cli_add_command(cli, "!", CliCommandFlagParallelSafe, cli_command_device_info, NULL); cli_add_command(cli, "device_info", CliCommandFlagParallelSafe, cli_command_device_info, NULL); @@ -477,4 +497,5 @@ void cli_commands_init(Cli* cli) { cli_add_command(cli, "vibro", CliCommandFlagDefault, cli_command_vibro, NULL); cli_add_command(cli, "led", CliCommandFlagDefault, cli_command_led, NULL); cli_add_command(cli, "gpio_set", CliCommandFlagDefault, cli_command_gpio_set, NULL); + cli_add_command(cli, "i2c", CliCommandFlagDefault, cli_command_i2c, NULL); } From fbd05598adbb185472696d2a46551927d3af5517 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Thu, 2 Dec 2021 15:19:47 +0400 Subject: [PATCH 13/32] [FL-2086] SubGhz: Fix Errors (#861) * CLI: fix main GUI freeze while subghz chat is running * CLI: fix processing backspace in the web console * [FL-2086] SubGhz: fix can't save signals in sub'e to internal memory * Cli: remove warning message in i2c command Co-authored-by: Aleksandr Kutuzov --- applications/cli/cli_commands.c | 2 +- applications/subghz/subghz_cli.c | 11 ++++------- applications/subghz/subghz_i.c | 2 +- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/applications/cli/cli_commands.c b/applications/cli/cli_commands.c index e8837108..1834282f 100644 --- a/applications/cli/cli_commands.c +++ b/applications/cli/cli_commands.c @@ -466,7 +466,7 @@ void cli_command_i2c(Cli* cli, string_t args, void* context) { uint8_t test = 0; printf("Scanning external i2c on PC0(SCL)/PC1(SDA)\r\n" "Clock: 100khz, 7bit address\r\n" - "!!! Invasive mode (tx to device) !!!\r\n\r\n"); + "\r\n"); printf(" | 0 1 2 3 4 5 6 7 8 9 A B C D E F\r\n"); printf("--+--------------------------------\r\n"); for(uint8_t row = 0; row < 0x8; row++) { diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index 9b67614b..5246e478 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -406,16 +406,12 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { putc(c, stdout); fflush(stdout); string_push_back(input, c); - } else if(c == CliSymbolAsciiBackspace) { + } else if((c == CliSymbolAsciiBackspace) || (c == CliSymbolAsciiDel)) { size_t len = string_size(input); if(len > string_size(name)) { - string_set_strn(input, string_get_cstr(input), len - 1); - printf("\r"); - for(uint8_t i = 0; i < len; i++) { - printf(" "); - } - printf("\r%s", string_get_cstr(input)); + printf("%s", "\e[D\e[1P"); fflush(stdout); + string_set_strn(input, string_get_cstr(input), len - 1); } } else if(c == CliSymbolAsciiCR) { printf("\r\n"); @@ -440,6 +436,7 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { printf("%s", string_get_cstr(input)); fflush(stdout); } + osDelay(1); } printf("\r\nExit chat\r\n"); diff --git a/applications/subghz/subghz_i.c b/applications/subghz/subghz_i.c index ff1596e8..c04cdb34 100644 --- a/applications/subghz/subghz_i.c +++ b/applications/subghz/subghz_i.c @@ -320,7 +320,7 @@ bool subghz_save_protocol_to_file(SubGhz* subghz, const char* dev_name) { break; } // Create saved directory if necessary - if(!storage_simply_mkdir(storage, SUBGHZ_APP_FOLDER)) { + if(!storage_simply_mkdir(storage, SUBGHZ_APP_PATH_FOLDER)) { dialog_message_show_storage_error(subghz->dialogs, "Cannot create\nfolder"); break; } From c2c17c761ef789e4e5b7d81e49cc6e98198e907e Mon Sep 17 00:00:00 2001 From: Oleg Kalachev Date: Sat, 4 Dec 2021 16:21:58 +0300 Subject: [PATCH 14/32] Fix address in I2C scanner (#865) --- applications/cli/cli_commands.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/applications/cli/cli_commands.c b/applications/cli/cli_commands.c index 1834282f..4711b13d 100644 --- a/applications/cli/cli_commands.c +++ b/applications/cli/cli_commands.c @@ -472,8 +472,8 @@ void cli_command_i2c(Cli* cli, string_t args, void* context) { for(uint8_t row = 0; row < 0x8; row++) { printf("%x | ", row); for(uint8_t column = 0; column <= 0xF; column++) { - bool ret = - furi_hal_i2c_rx(&furi_hal_i2c_handle_external, (row << 4) + column, &test, 1, 2); + bool ret = furi_hal_i2c_rx( + &furi_hal_i2c_handle_external, ((row << 4) + column) << 1, &test, 1, 2); printf("%c ", ret ? '#' : '-'); } printf("\r\n"); From 4b8653e061175245b469cb309eaa6deb4c9ff5bc Mon Sep 17 00:00:00 2001 From: Lesha Lomalkin Date: Sat, 4 Dec 2021 16:40:17 +0300 Subject: [PATCH 15/32] =?UTF-8?q?Subghz=20chat:=20add=20vibration=20on=20i?= =?UTF-8?q?nput=20message,=20send=20joined/left=20events=20=E2=80=A6=20(#8?= =?UTF-8?q?63)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SubGhz: add vibration on input chat message, send joined/left events to room on start and exit app. * SubGhz: optimize notification api usage Co-authored-by: Aleksandr Kutuzov --- applications/subghz/subghz_cli.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index 5246e478..cd6c6ac2 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -11,6 +11,8 @@ #include #include +#include + #define SUBGHZ_FREQUENCY_RANGE_STR \ "299999755...348000000 or 386999938...464000000 or 778999847...928000000" @@ -388,14 +390,22 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { string_init(input); string_t name; string_init(name); + string_t sysmsg; + string_init(sysmsg); char c; bool exit = false; + NotificationApp* notification = furi_record_open("notification"); + string_printf(name, "\033[0;33m%s\033[0m: ", furi_hal_version_get_name_ptr()); string_set(input, name); printf("%s", string_get_cstr(input)); fflush(stdout); + string_printf(sysmsg, "\033[0;34m%s joined chat.\033[0m", furi_hal_version_get_name_ptr()); + subghz_tx_rx_worker_write( + subghz_txrx, (uint8_t*)string_get_cstr(sysmsg), strlen(string_get_cstr(sysmsg))); + while(!exit) { if(furi_hal_vcp_rx_with_timeout((uint8_t*)&c, 1, 0) == 1) { if(c == CliSymbolAsciiETX) { @@ -435,14 +445,23 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { printf("%s", string_get_cstr(input)); fflush(stdout); + + notification_message(notification, &sequence_single_vibro); } osDelay(1); } + string_printf(sysmsg, "\033[0;31m%s left chat.\033[0m", furi_hal_version_get_name_ptr()); + subghz_tx_rx_worker_write( + subghz_txrx, (uint8_t*)string_get_cstr(sysmsg), strlen(string_get_cstr(sysmsg))); + osDelay(10); + printf("\r\nExit chat\r\n"); string_clear(input); string_clear(name); + string_clear(sysmsg); furi_hal_power_suppress_charge_exit(); + furi_record_close("notification"); if(subghz_tx_rx_worker_is_running(subghz_txrx)) { subghz_tx_rx_worker_stop(subghz_txrx); From 98bc190ac4b1b370dfc1f3a182fd760597761610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Sun, 5 Dec 2021 14:47:02 +0300 Subject: [PATCH 16/32] Hackathone session: bugfixes and documentation update (#869) * ReadMe: update flashing scripts section * Furi: add record exists method to record store. * FuriHal: early OS init and i2c timeouts based on os ticks. * Storage: replace malloc with furi_alloc, fix errors found by pvs. * iButton: properly handle shutdown in cli search command * SubGhz: proper argument type in sscanf and incorrect position of logging in switch. --- ReadMe.md | 37 +++--- applications/ibutton/ibutton-cli.cpp | 1 - applications/storage/storage-processing.c | 2 +- applications/storage/storages/storage-ext.c | 2 +- applications/subghz/subghz_cli.c | 8 +- applications/subghz/subghz_i.c | 2 +- core/furi/record.c | 18 +++ core/furi/record.h | 8 ++ firmware/targets/f6/fatfs/stm32_adafruit_sd.c | 4 +- firmware/targets/f6/furi-hal/furi-hal-i2c.c | 117 +++++++++++------- firmware/targets/f6/furi-hal/furi-hal.c | 6 +- firmware/targets/f7/fatfs/stm32_adafruit_sd.c | 4 +- firmware/targets/f7/furi-hal/furi-hal-i2c.c | 117 +++++++++++------- firmware/targets/f7/furi-hal/furi-hal.c | 6 +- 14 files changed, 200 insertions(+), 132 deletions(-) diff --git a/ReadMe.md b/ReadMe.md index d0cfd632..f3c1098e 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -14,24 +14,14 @@ Our goal is to create nice and clean code with good documentation, to make it a Flipper Zero's firmware consists of three components: -- Core2 firmware set - proprietary components by ST: FUS + radio stack. -- Core1 Bootloader - controls basic hardware initialization and loads firmware -- Core1 Firmware - HAL + OS + Drivers + Applications +- Core2 firmware set - proprietary components by ST: FUS + radio stack. FUS is flashed at factory and you should never update it. +- Core1 Bootloader - controls basic hardware initialization and loads firmware. +- Core1 Firmware - HAL + OS + Drivers + Applications. All 3 of them must be flashed in order described. ## With STLink -### Core2 flashing procedures - -Prerequisites: - -- Linux / macOS -- Terminal -- STM32_Programmer_CLI added to $PATH - -One liner: `./flash_core2_ble.sh` - ### Core1 Bootloader + Firmware Prerequisites: @@ -41,13 +31,23 @@ Prerequisites: - [arm-gcc-none-eabi](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads) - openocd -One liner: `./flash_core1_main.sh` +One liner: `make flash` + +### Core2 flashing procedures + +Prerequisites: + +- Linux / macOS +- Terminal +- STM32_Programmer_CLI (v2.5.0) added to $PATH + +One liner: `make flash_radio` ## With USB DFU 1. Download latest [Firmware](https://update.flipperzero.one) -2. Reboot Flipper to Bootloader +2. Reboot Flipper to Bootloader - Press and hold `← Left` + `↩ Back` for reset - Release `↩ Back` and keep holding `← Left` until blue LED lights up - Release `← Left` @@ -61,9 +61,10 @@ One liner: `./flash_core1_main.sh` 1. Install [Docker Engine and Docker Compose](https://www.docker.com/get-started) 2. Prepare the container: - ```sh - docker-compose up -d - ``` + + ```sh + docker-compose up -d + ``` ## Compile everything diff --git a/applications/ibutton/ibutton-cli.cpp b/applications/ibutton/ibutton-cli.cpp index 3c26f5ec..c8744766 100644 --- a/applications/ibutton/ibutton-cli.cpp +++ b/applications/ibutton/ibutton-cli.cpp @@ -255,7 +255,6 @@ void onewire_cli_search(Cli* cli) { printf("Search finished\r\n"); onewire.reset_search(); done = true; - return; } else { printf("Found: "); for(uint8_t i = 0; i < 8; i++) { diff --git a/applications/storage/storage-processing.c b/applications/storage/storage-processing.c index 0ab7f551..8ae648aa 100644 --- a/applications/storage/storage-processing.c +++ b/applications/storage/storage-processing.c @@ -377,7 +377,7 @@ static FS_Error storage_process_common_rename(Storage* app, const char* old, con StorageType type_old = storage_get_type_by_path(old); StorageType type_new = storage_get_type_by_path(new); - if(storage_type_is_not_valid(type_old) || storage_type_is_not_valid(type_old)) { + if(storage_type_is_not_valid(type_old) || storage_type_is_not_valid(type_new)) { ret = FSE_INVALID_NAME; } else { if(type_old != type_new) { diff --git a/applications/storage/storages/storage-ext.c b/applications/storage/storages/storage-ext.c index 51de7612..22724a74 100644 --- a/applications/storage/storages/storage-ext.c +++ b/applications/storage/storages/storage-ext.c @@ -512,7 +512,7 @@ static FS_Error storage_ext_common_fs_info( /******************* Init Storage *******************/ void storage_ext_init(StorageData* storage) { - SDData* sd_data = malloc(sizeof(SDData)); + SDData* sd_data = furi_alloc(sizeof(SDData)); sd_data->fs = &USERFatFS; sd_data->path = "0:/"; sd_data->sd_was_present = true; diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index cd6c6ac2..2578fb26 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -102,13 +102,13 @@ static void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context static void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { uint32_t frequency = 433920000; uint32_t key = 0x0074BADE; - size_t repeat = 10; + uint32_t repeat = 10; if(string_size(args)) { - int ret = sscanf(string_get_cstr(args), "%lx %lu %u", &key, &frequency, &repeat); + int ret = sscanf(string_get_cstr(args), "%lx %lu %lu", &key, &frequency, &repeat); if(ret != 3) { printf( - "sscanf returned %d, key: %lx, frequency: %lu, repeat: %u\r\n", + "sscanf returned %d, key: %lx, frequency: %lu, repeat: %lu\r\n", ret, key, frequency, @@ -128,7 +128,7 @@ static void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { } printf( - "Transmitting at %lu, key %lx, repeat %u. Press CTRL+C to stop\r\n", + "Transmitting at %lu, key %lx, repeat %lu. Press CTRL+C to stop\r\n", frequency, key, repeat); diff --git a/applications/subghz/subghz_i.c b/applications/subghz/subghz_i.c index c04cdb34..ea06aae7 100644 --- a/applications/subghz/subghz_i.c +++ b/applications/subghz/subghz_i.c @@ -41,8 +41,8 @@ bool subghz_get_preset_name(SubGhz* subghz, string_t preset) { case FuriHalSubGhzPreset2FSKDev476Async: preset_name = "FuriHalSubGhzPreset2FSKDev476Async"; break; - FURI_LOG_E(SUBGHZ_PARSER_TAG, "Unknown preset"); default: + FURI_LOG_E(SUBGHZ_PARSER_TAG, "Unknown preset"); return false; break; } diff --git a/core/furi/record.c b/core/furi/record.c index 29e33caf..fe75c7bc 100644 --- a/core/furi/record.c +++ b/core/furi/record.c @@ -52,6 +52,24 @@ static void furi_record_unlock() { furi_check(osMutexRelease(furi_record->mutex) == osOK); } +bool furi_record_exists(const char* name) { + furi_assert(furi_record); + furi_assert(name); + + bool ret = false; + + string_t name_str; + string_init_set_str(name_str, name); + + furi_record_lock(); + ret = (FuriRecordDataDict_get(furi_record->records, name_str) != NULL); + furi_record_unlock(); + + string_clear(name_str); + + return ret; +} + void furi_record_create(const char* name, void* data) { furi_assert(furi_record); diff --git a/core/furi/record.h b/core/furi/record.h index d5d92deb..2d5f2c49 100644 --- a/core/furi/record.h +++ b/core/furi/record.h @@ -15,6 +15,14 @@ extern "C" { */ void furi_record_init(); +/** Check if record exists + * + * @param name record name + * @note Thread safe. Create and destroy must be executed from the same + * thread. + */ +bool furi_record_exists(const char* name); + /** Create record * * @param name record name diff --git a/firmware/targets/f6/fatfs/stm32_adafruit_sd.c b/firmware/targets/f6/fatfs/stm32_adafruit_sd.c index 0d7ff4c0..1c571d63 100644 --- a/firmware/targets/f6/fatfs/stm32_adafruit_sd.c +++ b/firmware/targets/f6/fatfs/stm32_adafruit_sd.c @@ -405,7 +405,7 @@ BSP_SD_ReadBlocks(uint32_t* pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint goto error; } - ptr = malloc(sizeof(uint8_t) * BlockSize); + ptr = furi_alloc(sizeof(uint8_t) * BlockSize); if(ptr == NULL) { goto error; } @@ -483,7 +483,7 @@ BSP_SD_WriteBlocks(uint32_t* pData, uint32_t WriteAddr, uint32_t NumOfBlocks, ui goto error; } - ptr = malloc(sizeof(uint8_t) * BlockSize); + ptr = furi_alloc(sizeof(uint8_t) * BlockSize); if(ptr == NULL) { goto error; } diff --git a/firmware/targets/f6/furi-hal/furi-hal-i2c.c b/firmware/targets/f6/furi-hal/furi-hal-i2c.c index 2fd5c5e3..3e64b390 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-i2c.c +++ b/firmware/targets/f6/furi-hal/furi-hal-i2c.c @@ -46,38 +46,48 @@ bool furi_hal_i2c_tx( const uint8_t* data, uint8_t size, uint32_t timeout) { + furi_check(handle->bus->current_handle == handle); - uint32_t time_left = timeout; + furi_assert(timeout > 0); + bool ret = true; + uint32_t timeout_tick = osKernelGetTickCount() + timeout; - while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) - ; - - LL_I2C_HandleTransfer( - handle->bus->i2c, - address, - LL_I2C_ADDRSLAVE_7BIT, - size, - LL_I2C_MODE_AUTOEND, - LL_I2C_GENERATE_START_WRITE); - - while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c) || size > 0) { - if(LL_I2C_IsActiveFlag_TXIS(handle->bus->i2c)) { - LL_I2C_TransmitData8(handle->bus->i2c, (*data)); - data++; - size--; - time_left = timeout; - } - - if(LL_SYSTICK_IsActiveCounterFlag()) { - if(--time_left == 0) { + do { + while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { + if(osKernelGetTickCount() >= timeout_tick) { ret = false; break; } } - } - LL_I2C_ClearFlag_STOP(handle->bus->i2c); + if(!ret) { + break; + } + + LL_I2C_HandleTransfer( + handle->bus->i2c, + address, + LL_I2C_ADDRSLAVE_7BIT, + size, + LL_I2C_MODE_AUTOEND, + LL_I2C_GENERATE_START_WRITE); + + while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c) || size > 0) { + if(LL_I2C_IsActiveFlag_TXIS(handle->bus->i2c)) { + LL_I2C_TransmitData8(handle->bus->i2c, (*data)); + data++; + size--; + } + + if(osKernelGetTickCount() >= timeout_tick) { + ret = false; + break; + } + } + + LL_I2C_ClearFlag_STOP(handle->bus->i2c); + } while(0); return ret; } @@ -88,38 +98,48 @@ bool furi_hal_i2c_rx( uint8_t* data, uint8_t size, uint32_t timeout) { + furi_check(handle->bus->current_handle == handle); - uint32_t time_left = timeout; + furi_assert(timeout > 0); + bool ret = true; + uint32_t timeout_tick = osKernelGetTickCount() + timeout; - while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) - ; - - LL_I2C_HandleTransfer( - handle->bus->i2c, - address, - LL_I2C_ADDRSLAVE_7BIT, - size, - LL_I2C_MODE_AUTOEND, - LL_I2C_GENERATE_START_READ); - - while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c) || size > 0) { - if(LL_I2C_IsActiveFlag_RXNE(handle->bus->i2c)) { - *data = LL_I2C_ReceiveData8(handle->bus->i2c); - data++; - size--; - time_left = timeout; - } - - if(LL_SYSTICK_IsActiveCounterFlag()) { - if(--time_left == 0) { + do { + while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { + if(osKernelGetTickCount() >= timeout_tick) { ret = false; break; } } - } - LL_I2C_ClearFlag_STOP(handle->bus->i2c); + if(!ret) { + break; + } + + LL_I2C_HandleTransfer( + handle->bus->i2c, + address, + LL_I2C_ADDRSLAVE_7BIT, + size, + LL_I2C_MODE_AUTOEND, + LL_I2C_GENERATE_START_READ); + + while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c) || size > 0) { + if(LL_I2C_IsActiveFlag_RXNE(handle->bus->i2c)) { + *data = LL_I2C_ReceiveData8(handle->bus->i2c); + data++; + size--; + } + + if(osKernelGetTickCount() >= timeout_tick) { + ret = false; + break; + } + } + + LL_I2C_ClearFlag_STOP(handle->bus->i2c); + } while(0); return ret; } @@ -132,6 +152,7 @@ bool furi_hal_i2c_trx( uint8_t* rx_data, uint8_t rx_size, uint32_t timeout) { + if(furi_hal_i2c_tx(handle, address, tx_data, tx_size, timeout) && furi_hal_i2c_rx(handle, address, rx_data, rx_size, timeout)) { return true; diff --git a/firmware/targets/f6/furi-hal/furi-hal.c b/firmware/targets/f6/furi-hal/furi-hal.c index 491cdf0d..d213af95 100644 --- a/firmware/targets/f6/furi-hal/furi-hal.c +++ b/firmware/targets/f6/furi-hal/furi-hal.c @@ -17,6 +17,9 @@ void furi_hal_init() { furi_hal_interrupt_init(); furi_hal_delay_init(); + // FreeRTOS glue + furi_hal_os_init(); + MX_GPIO_Init(); FURI_LOG_I(TAG, "GPIO OK"); @@ -56,9 +59,6 @@ void furi_hal_init() { furi_hal_bt_init(); furi_hal_compress_icon_init(); - // FreeRTOS glue - furi_hal_os_init(); - // FatFS driver initialization MX_FATFS_Init(); FURI_LOG_I(TAG, "FATFS OK"); diff --git a/firmware/targets/f7/fatfs/stm32_adafruit_sd.c b/firmware/targets/f7/fatfs/stm32_adafruit_sd.c index 0d7ff4c0..1c571d63 100644 --- a/firmware/targets/f7/fatfs/stm32_adafruit_sd.c +++ b/firmware/targets/f7/fatfs/stm32_adafruit_sd.c @@ -405,7 +405,7 @@ BSP_SD_ReadBlocks(uint32_t* pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint goto error; } - ptr = malloc(sizeof(uint8_t) * BlockSize); + ptr = furi_alloc(sizeof(uint8_t) * BlockSize); if(ptr == NULL) { goto error; } @@ -483,7 +483,7 @@ BSP_SD_WriteBlocks(uint32_t* pData, uint32_t WriteAddr, uint32_t NumOfBlocks, ui goto error; } - ptr = malloc(sizeof(uint8_t) * BlockSize); + ptr = furi_alloc(sizeof(uint8_t) * BlockSize); if(ptr == NULL) { goto error; } diff --git a/firmware/targets/f7/furi-hal/furi-hal-i2c.c b/firmware/targets/f7/furi-hal/furi-hal-i2c.c index 2fd5c5e3..3e64b390 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-i2c.c +++ b/firmware/targets/f7/furi-hal/furi-hal-i2c.c @@ -46,38 +46,48 @@ bool furi_hal_i2c_tx( const uint8_t* data, uint8_t size, uint32_t timeout) { + furi_check(handle->bus->current_handle == handle); - uint32_t time_left = timeout; + furi_assert(timeout > 0); + bool ret = true; + uint32_t timeout_tick = osKernelGetTickCount() + timeout; - while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) - ; - - LL_I2C_HandleTransfer( - handle->bus->i2c, - address, - LL_I2C_ADDRSLAVE_7BIT, - size, - LL_I2C_MODE_AUTOEND, - LL_I2C_GENERATE_START_WRITE); - - while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c) || size > 0) { - if(LL_I2C_IsActiveFlag_TXIS(handle->bus->i2c)) { - LL_I2C_TransmitData8(handle->bus->i2c, (*data)); - data++; - size--; - time_left = timeout; - } - - if(LL_SYSTICK_IsActiveCounterFlag()) { - if(--time_left == 0) { + do { + while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { + if(osKernelGetTickCount() >= timeout_tick) { ret = false; break; } } - } - LL_I2C_ClearFlag_STOP(handle->bus->i2c); + if(!ret) { + break; + } + + LL_I2C_HandleTransfer( + handle->bus->i2c, + address, + LL_I2C_ADDRSLAVE_7BIT, + size, + LL_I2C_MODE_AUTOEND, + LL_I2C_GENERATE_START_WRITE); + + while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c) || size > 0) { + if(LL_I2C_IsActiveFlag_TXIS(handle->bus->i2c)) { + LL_I2C_TransmitData8(handle->bus->i2c, (*data)); + data++; + size--; + } + + if(osKernelGetTickCount() >= timeout_tick) { + ret = false; + break; + } + } + + LL_I2C_ClearFlag_STOP(handle->bus->i2c); + } while(0); return ret; } @@ -88,38 +98,48 @@ bool furi_hal_i2c_rx( uint8_t* data, uint8_t size, uint32_t timeout) { + furi_check(handle->bus->current_handle == handle); - uint32_t time_left = timeout; + furi_assert(timeout > 0); + bool ret = true; + uint32_t timeout_tick = osKernelGetTickCount() + timeout; - while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) - ; - - LL_I2C_HandleTransfer( - handle->bus->i2c, - address, - LL_I2C_ADDRSLAVE_7BIT, - size, - LL_I2C_MODE_AUTOEND, - LL_I2C_GENERATE_START_READ); - - while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c) || size > 0) { - if(LL_I2C_IsActiveFlag_RXNE(handle->bus->i2c)) { - *data = LL_I2C_ReceiveData8(handle->bus->i2c); - data++; - size--; - time_left = timeout; - } - - if(LL_SYSTICK_IsActiveCounterFlag()) { - if(--time_left == 0) { + do { + while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { + if(osKernelGetTickCount() >= timeout_tick) { ret = false; break; } } - } - LL_I2C_ClearFlag_STOP(handle->bus->i2c); + if(!ret) { + break; + } + + LL_I2C_HandleTransfer( + handle->bus->i2c, + address, + LL_I2C_ADDRSLAVE_7BIT, + size, + LL_I2C_MODE_AUTOEND, + LL_I2C_GENERATE_START_READ); + + while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c) || size > 0) { + if(LL_I2C_IsActiveFlag_RXNE(handle->bus->i2c)) { + *data = LL_I2C_ReceiveData8(handle->bus->i2c); + data++; + size--; + } + + if(osKernelGetTickCount() >= timeout_tick) { + ret = false; + break; + } + } + + LL_I2C_ClearFlag_STOP(handle->bus->i2c); + } while(0); return ret; } @@ -132,6 +152,7 @@ bool furi_hal_i2c_trx( uint8_t* rx_data, uint8_t rx_size, uint32_t timeout) { + if(furi_hal_i2c_tx(handle, address, tx_data, tx_size, timeout) && furi_hal_i2c_rx(handle, address, rx_data, rx_size, timeout)) { return true; diff --git a/firmware/targets/f7/furi-hal/furi-hal.c b/firmware/targets/f7/furi-hal/furi-hal.c index 491cdf0d..d213af95 100644 --- a/firmware/targets/f7/furi-hal/furi-hal.c +++ b/firmware/targets/f7/furi-hal/furi-hal.c @@ -17,6 +17,9 @@ void furi_hal_init() { furi_hal_interrupt_init(); furi_hal_delay_init(); + // FreeRTOS glue + furi_hal_os_init(); + MX_GPIO_Init(); FURI_LOG_I(TAG, "GPIO OK"); @@ -56,9 +59,6 @@ void furi_hal_init() { furi_hal_bt_init(); furi_hal_compress_icon_init(); - // FreeRTOS glue - furi_hal_os_init(); - // FatFS driver initialization MX_FATFS_Init(); FURI_LOG_I(TAG, "FATFS OK"); From e09009e49759c27e92db74e76918875b968cd2cf Mon Sep 17 00:00:00 2001 From: SG Date: Tue, 7 Dec 2021 22:49:44 +1000 Subject: [PATCH 17/32] LFRFID-debug: proxy comparator to gpio (#876) --- .../scene/lfrfid-debug-app-scene-tune.cpp | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/applications/lfrfid-debug/scene/lfrfid-debug-app-scene-tune.cpp b/applications/lfrfid-debug/scene/lfrfid-debug-app-scene-tune.cpp index fea0e586..89cc2792 100644 --- a/applications/lfrfid-debug/scene/lfrfid-debug-app-scene-tune.cpp +++ b/applications/lfrfid-debug/scene/lfrfid-debug-app-scene-tune.cpp @@ -1,7 +1,35 @@ #include "lfrfid-debug-app-scene-tune.h" +#include + +extern COMP_HandleTypeDef hcomp1; + +static void comparator_trigger_callback(void* hcomp, void* comp_ctx) { + COMP_HandleTypeDef* _hcomp = static_cast(hcomp); + + if(hcomp == &hcomp1) { + hal_gpio_write(&gpio_ext_pa7, HAL_COMP_GetOutputLevel(_hcomp) == COMP_OUTPUT_LEVEL_HIGH); + } +} void LfRfidDebugAppSceneTune::on_enter(LfRfidDebugApp* app, bool need_restore) { app->view_controller.switch_to(); + hal_gpio_init_simple(&gpio_ext_pa7, GpioModeOutputPushPull); + + api_interrupt_add(comparator_trigger_callback, InterruptTypeComparatorTrigger, this); + + hcomp1.Init.InputMinus = COMP_INPUT_MINUS_1_2VREFINT; + hcomp1.Init.InputPlus = COMP_INPUT_PLUS_IO1; + hcomp1.Init.OutputPol = COMP_OUTPUTPOL_NONINVERTED; + hcomp1.Init.Hysteresis = COMP_HYSTERESIS_HIGH; + hcomp1.Init.BlankingSrce = COMP_BLANKINGSRC_NONE; + hcomp1.Init.Mode = COMP_POWERMODE_MEDIUMSPEED; + hcomp1.Init.WindowMode = COMP_WINDOWMODE_DISABLE; + hcomp1.Init.TriggerMode = COMP_TRIGGERMODE_IT_RISING_FALLING; + if(HAL_COMP_Init(&hcomp1) != HAL_OK) { + Error_Handler(); + } + + HAL_COMP_Start(&hcomp1); furi_hal_rfid_pins_read(); furi_hal_rfid_tim_read(125000, 0.5); @@ -22,6 +50,10 @@ bool LfRfidDebugAppSceneTune::on_event(LfRfidDebugApp* app, LfRfidDebugApp::Even } void LfRfidDebugAppSceneTune::on_exit(LfRfidDebugApp* app) { + HAL_COMP_Stop(&hcomp1); + api_interrupt_remove(comparator_trigger_callback, InterruptTypeComparatorTrigger); + + hal_gpio_init_simple(&gpio_ext_pa7, GpioModeAnalog); furi_hal_rfid_tim_read_stop(); furi_hal_rfid_tim_reset(); furi_hal_rfid_pins_reset(); From 185647a09af129a82b50e39002b4e63adf2db84b Mon Sep 17 00:00:00 2001 From: Albert Kharisov Date: Tue, 7 Dec 2021 17:02:19 +0400 Subject: [PATCH 18/32] Play only basic good animations (#872) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * New Basic Animations * Keep only basic calm animations Co-authored-by: あく --- .../desktop/helpers/desktop_animation.c | 11 +- .../desktop/helpers/desktop_animation_i.h | 30 +- assets/compiled/assets_icons.c | 663 +++++++++--------- assets/compiled/assets_icons.h | 176 ++--- .../LaptopActive_128x51/frame_01.png | Bin 2189 -> 0 bytes .../LaptopActive_128x51/frame_02.png | Bin 2150 -> 0 bytes .../LaptopActive_128x52/frame_01.png | Bin 0 -> 2250 bytes .../LaptopActive_128x52/frame_02.png | Bin 0 -> 2220 bytes .../LaptopActive_128x52/frame_03.png | Bin 0 -> 2213 bytes .../LaptopActive_128x52/frame_04.png | Bin 0 -> 2213 bytes .../LaptopActive_128x52/frame_05.png | Bin 0 -> 2200 bytes .../LaptopActive_128x52/frame_06.png | Bin 0 -> 2196 bytes .../LaptopActive_128x52/frame_07.png | Bin 0 -> 2200 bytes .../LaptopActive_128x52/frame_08.png | Bin 0 -> 2196 bytes .../frame_rate | 0 .../Animations/Laptop_128x51/frame_01.png | Bin 2243 -> 0 bytes .../Animations/Laptop_128x51/frame_02.png | Bin 2231 -> 0 bytes .../Animations/Laptop_128x52/frame_01.png | Bin 0 -> 2260 bytes .../Animations/Laptop_128x52/frame_02.png | Bin 0 -> 2268 bytes .../Animations/Laptop_128x52/frame_03.png | Bin 0 -> 2262 bytes .../Animations/Laptop_128x52/frame_04.png | Bin 0 -> 2262 bytes .../Animations/Laptop_128x52/frame_05.png | Bin 0 -> 2256 bytes .../Animations/Laptop_128x52/frame_06.png | Bin 0 -> 2252 bytes .../frame_rate | 0 .../SleepActive_128x51/frame_01.png | Bin 2540 -> 0 bytes .../SleepActive_128x51/frame_02.png | Bin 2647 -> 0 bytes .../SleepActive_128x52/frame_01.png | Bin 0 -> 1605 bytes .../SleepActive_128x52/frame_02.png | Bin 0 -> 1618 bytes .../SleepActive_128x52/frame_03.png | Bin 0 -> 1606 bytes .../SleepActive_128x52/frame_04.png | Bin 0 -> 1618 bytes .../SleepActive_128x52/frame_05.png | Bin 0 -> 1606 bytes .../frame_rate | 0 .../Animations/Sleep_128x51/frame_01.png | Bin 2526 -> 0 bytes .../Animations/Sleep_128x51/frame_02.png | Bin 2531 -> 0 bytes .../Animations/Sleep_128x51/frame_03.png | Bin 2526 -> 0 bytes .../Animations/Sleep_128x51/frame_04.png | Bin 2531 -> 0 bytes .../Animations/Sleep_128x52/frame_01.png | Bin 0 -> 1581 bytes .../Animations/Sleep_128x52/frame_02.png | Bin 0 -> 1591 bytes .../{Sleep_128x51 => Sleep_128x52}/frame_rate | 0 .../Animations/TVActive_128x51/frame_01.png | Bin 2673 -> 0 bytes .../Animations/TVActive_128x51/frame_02.png | Bin 2628 -> 0 bytes .../icons/Animations/TV_128x51/frame_01.png | Bin 2589 -> 0 bytes .../icons/Animations/TV_128x51/frame_02.png | Bin 2605 -> 0 bytes .../icons/Animations/TV_128x51/frame_03.png | Bin 2608 -> 0 bytes .../icons/Animations/TV_128x51/frame_04.png | Bin 2603 -> 0 bytes .../icons/Animations/TV_128x51/frame_05.png | Bin 2603 -> 0 bytes .../Animations/TvActive_128x52/frame_01.png | Bin 0 -> 1885 bytes .../Animations/TvActive_128x52/frame_02.png | Bin 0 -> 2139 bytes .../Animations/TvActive_128x52/frame_03.png | Bin 0 -> 2128 bytes .../Animations/TvActive_128x52/frame_04.png | Bin 0 -> 2139 bytes .../Animations/TvActive_128x52/frame_05.png | Bin 0 -> 2128 bytes .../Animations/TvActive_128x52/frame_06.png | Bin 0 -> 2139 bytes .../frame_rate | 0 .../icons/Animations/Tv_128x52/frame_01.png | Bin 0 -> 1905 bytes .../icons/Animations/Tv_128x52/frame_02.png | Bin 0 -> 1908 bytes .../icons/Animations/Tv_128x52/frame_03.png | Bin 0 -> 1893 bytes .../icons/Animations/Tv_128x52/frame_04.png | Bin 0 -> 1897 bytes .../icons/Animations/Tv_128x52/frame_05.png | Bin 0 -> 1898 bytes .../icons/Animations/Tv_128x52/frame_06.png | Bin 0 -> 1901 bytes .../{TV_128x51 => Tv_128x52}/frame_rate | 0 .../WavesActive_128x51/frame_01.png | Bin 2311 -> 0 bytes .../WavesActive_128x51/frame_02.png | Bin 2273 -> 0 bytes .../WavesActive_128x52/frame_01.png | Bin 0 -> 2092 bytes .../WavesActive_128x52/frame_02.png | Bin 0 -> 2097 bytes .../WavesActive_128x52/frame_03.png | Bin 0 -> 2092 bytes .../WavesActive_128x52/frame_04.png | Bin 0 -> 2144 bytes .../WavesActive_128x52/frame_05.png | Bin 0 -> 2132 bytes .../WavesActive_128x52/frame_06.png | Bin 0 -> 2144 bytes .../WavesActive_128x52/frame_07.png | Bin 0 -> 2132 bytes .../frame_rate | 0 .../Animations/Waves_128x51/frame_01.png | Bin 2236 -> 0 bytes .../Animations/Waves_128x51/frame_02.png | Bin 5146 -> 0 bytes .../Animations/Waves_128x52/frame_01.png | Bin 0 -> 2066 bytes .../Animations/Waves_128x52/frame_02.png | Bin 0 -> 2074 bytes .../{Waves_128x51 => Waves_128x52}/frame_rate | 0 75 files changed, 453 insertions(+), 427 deletions(-) delete mode 100644 assets/icons/Animations/LaptopActive_128x51/frame_01.png delete mode 100644 assets/icons/Animations/LaptopActive_128x51/frame_02.png create mode 100644 assets/icons/Animations/LaptopActive_128x52/frame_01.png create mode 100644 assets/icons/Animations/LaptopActive_128x52/frame_02.png create mode 100644 assets/icons/Animations/LaptopActive_128x52/frame_03.png create mode 100644 assets/icons/Animations/LaptopActive_128x52/frame_04.png create mode 100644 assets/icons/Animations/LaptopActive_128x52/frame_05.png create mode 100644 assets/icons/Animations/LaptopActive_128x52/frame_06.png create mode 100644 assets/icons/Animations/LaptopActive_128x52/frame_07.png create mode 100644 assets/icons/Animations/LaptopActive_128x52/frame_08.png rename assets/icons/Animations/{LaptopActive_128x51 => LaptopActive_128x52}/frame_rate (100%) delete mode 100644 assets/icons/Animations/Laptop_128x51/frame_01.png delete mode 100644 assets/icons/Animations/Laptop_128x51/frame_02.png create mode 100644 assets/icons/Animations/Laptop_128x52/frame_01.png create mode 100644 assets/icons/Animations/Laptop_128x52/frame_02.png create mode 100644 assets/icons/Animations/Laptop_128x52/frame_03.png create mode 100644 assets/icons/Animations/Laptop_128x52/frame_04.png create mode 100644 assets/icons/Animations/Laptop_128x52/frame_05.png create mode 100644 assets/icons/Animations/Laptop_128x52/frame_06.png rename assets/icons/Animations/{Laptop_128x51 => Laptop_128x52}/frame_rate (100%) delete mode 100644 assets/icons/Animations/SleepActive_128x51/frame_01.png delete mode 100644 assets/icons/Animations/SleepActive_128x51/frame_02.png create mode 100644 assets/icons/Animations/SleepActive_128x52/frame_01.png create mode 100644 assets/icons/Animations/SleepActive_128x52/frame_02.png create mode 100644 assets/icons/Animations/SleepActive_128x52/frame_03.png create mode 100644 assets/icons/Animations/SleepActive_128x52/frame_04.png create mode 100644 assets/icons/Animations/SleepActive_128x52/frame_05.png rename assets/icons/Animations/{SleepActive_128x51 => SleepActive_128x52}/frame_rate (100%) delete mode 100644 assets/icons/Animations/Sleep_128x51/frame_01.png delete mode 100644 assets/icons/Animations/Sleep_128x51/frame_02.png delete mode 100644 assets/icons/Animations/Sleep_128x51/frame_03.png delete mode 100644 assets/icons/Animations/Sleep_128x51/frame_04.png create mode 100644 assets/icons/Animations/Sleep_128x52/frame_01.png create mode 100644 assets/icons/Animations/Sleep_128x52/frame_02.png rename assets/icons/Animations/{Sleep_128x51 => Sleep_128x52}/frame_rate (100%) delete mode 100644 assets/icons/Animations/TVActive_128x51/frame_01.png delete mode 100644 assets/icons/Animations/TVActive_128x51/frame_02.png delete mode 100644 assets/icons/Animations/TV_128x51/frame_01.png delete mode 100644 assets/icons/Animations/TV_128x51/frame_02.png delete mode 100644 assets/icons/Animations/TV_128x51/frame_03.png delete mode 100644 assets/icons/Animations/TV_128x51/frame_04.png delete mode 100644 assets/icons/Animations/TV_128x51/frame_05.png create mode 100644 assets/icons/Animations/TvActive_128x52/frame_01.png create mode 100644 assets/icons/Animations/TvActive_128x52/frame_02.png create mode 100644 assets/icons/Animations/TvActive_128x52/frame_03.png create mode 100644 assets/icons/Animations/TvActive_128x52/frame_04.png create mode 100644 assets/icons/Animations/TvActive_128x52/frame_05.png create mode 100644 assets/icons/Animations/TvActive_128x52/frame_06.png rename assets/icons/Animations/{TVActive_128x51 => TvActive_128x52}/frame_rate (100%) create mode 100644 assets/icons/Animations/Tv_128x52/frame_01.png create mode 100644 assets/icons/Animations/Tv_128x52/frame_02.png create mode 100644 assets/icons/Animations/Tv_128x52/frame_03.png create mode 100644 assets/icons/Animations/Tv_128x52/frame_04.png create mode 100644 assets/icons/Animations/Tv_128x52/frame_05.png create mode 100644 assets/icons/Animations/Tv_128x52/frame_06.png rename assets/icons/Animations/{TV_128x51 => Tv_128x52}/frame_rate (100%) delete mode 100644 assets/icons/Animations/WavesActive_128x51/frame_01.png delete mode 100644 assets/icons/Animations/WavesActive_128x51/frame_02.png create mode 100644 assets/icons/Animations/WavesActive_128x52/frame_01.png create mode 100644 assets/icons/Animations/WavesActive_128x52/frame_02.png create mode 100644 assets/icons/Animations/WavesActive_128x52/frame_03.png create mode 100644 assets/icons/Animations/WavesActive_128x52/frame_04.png create mode 100644 assets/icons/Animations/WavesActive_128x52/frame_05.png create mode 100644 assets/icons/Animations/WavesActive_128x52/frame_06.png create mode 100644 assets/icons/Animations/WavesActive_128x52/frame_07.png rename assets/icons/Animations/{WavesActive_128x51 => WavesActive_128x52}/frame_rate (100%) delete mode 100644 assets/icons/Animations/Waves_128x51/frame_01.png delete mode 100644 assets/icons/Animations/Waves_128x51/frame_02.png create mode 100644 assets/icons/Animations/Waves_128x52/frame_01.png create mode 100644 assets/icons/Animations/Waves_128x52/frame_02.png rename assets/icons/Animations/{Waves_128x51 => Waves_128x52}/frame_rate (100%) diff --git a/applications/desktop/helpers/desktop_animation.c b/applications/desktop/helpers/desktop_animation.c index 9ded5c10..40f3b7e4 100644 --- a/applications/desktop/helpers/desktop_animation.c +++ b/applications/desktop/helpers/desktop_animation.c @@ -11,6 +11,8 @@ #include #include +#define KEEP_ONLY_CALM_BASIC_ANIMATIONS 1 + LIST_DEF(AnimationList, const PairedAnimation*, M_PTR_OPLIST) #define M_OPL_AnimationList_t() LIST_OPLIST(AnimationList) @@ -81,14 +83,16 @@ void desktop_start_new_idle_animation(DesktopAnimation* animation) { furi_record_close("dolphin"); furi_assert((stats.level >= 1) && (stats.level <= 3)); - uint8_t level = stats.level; AnimationList_t animation_list; AnimationList_init(animation_list); - PUSH_BACK_ANIMATIONS(animation_list, mad_animation, stats.butthurt); +#if KEEP_ONLY_CALM_BASIC_ANIMATIONS + PUSH_BACK_ANIMATIONS(animation_list, calm_animation, 0); +#else PUSH_BACK_ANIMATIONS(animation_list, calm_animation, stats.butthurt); - switch(level) { + PUSH_BACK_ANIMATIONS(animation_list, mad_animation, stats.butthurt); + switch(stats.level) { case 1: PUSH_BACK_ANIMATIONS(animation_list, level_1_animation, stats.butthurt); break; @@ -119,6 +123,7 @@ void desktop_start_new_idle_animation(DesktopAnimation* animation) { animation->sd_shown_error_card_bad = false; animation->sd_shown_error_db = false; } +#endif uint32_t whole_weight = 0; for diff --git a/applications/desktop/helpers/desktop_animation_i.h b/applications/desktop/helpers/desktop_animation_i.h index c89eba64..b7ac9f8b 100644 --- a/applications/desktop/helpers/desktop_animation_i.h +++ b/applications/desktop/helpers/desktop_animation_i.h @@ -6,9 +6,9 @@ // Calm/Mad Basic Idle Animations -#define COMMON_BASIC_DURATION (60 * 60) -#define COMMON_ACTIVE_CYCLES 7 -#define COMMON_ACTIVE_COOLDOWN 30 +#define COMMON_BASIC_DURATION (2 * 60 * 60) +#define COMMON_ACTIVE_CYCLES 1 +#define COMMON_ACTIVE_COOLDOWN 15 #define COMMON_WEIGHT 3 #define BUTTHURT_LEVEL(x) (1UL << (x)) @@ -18,7 +18,7 @@ #define COMMON_ACTIVE_DURATION(x) ((x)*COMMON_ACTIVE_CYCLES / 2) static const BasicAnimation animation_TV = { - .icon = &A_TV_128x51, + .icon = &A_Tv_128x52, .duration = COMMON_BASIC_DURATION, .weight = COMMON_WEIGHT, .active_cooldown = COMMON_ACTIVE_COOLDOWN, @@ -27,12 +27,12 @@ static const BasicAnimation animation_TV = { BUTTHURT_LEVEL(6) | BUTTHURT_LEVEL(7)}; static const ActiveAnimation animation_TV_active = { - .icon = &A_TVActive_128x51, - .duration = COMMON_ACTIVE_DURATION(2), + .icon = &A_TvActive_128x52, + .duration = COMMON_ACTIVE_DURATION(6), }; static const BasicAnimation animation_sleep = { - .icon = &A_Sleep_128x51, + .icon = &A_Sleep_128x52, .black_status_bar = true, .duration = COMMON_BASIC_DURATION, .weight = COMMON_WEIGHT, @@ -43,9 +43,9 @@ static const BasicAnimation animation_sleep = { BUTTHURT_LEVEL(9) | BUTTHURT_LEVEL(10)}; static const ActiveAnimation animation_sleep_active = { - .icon = &A_SleepActive_128x51, + .icon = &A_SleepActive_128x52, .black_status_bar = true, - .duration = COMMON_ACTIVE_DURATION(2), + .duration = COMMON_ACTIVE_DURATION(5), }; static const BasicAnimation animation_leaving = { @@ -62,7 +62,7 @@ static const ActiveAnimation animation_leaving_active = { }; static const BasicAnimation animation_laptop = { - .icon = &A_Laptop_128x51, + .icon = &A_Laptop_128x52, .duration = COMMON_BASIC_DURATION, .weight = COMMON_WEIGHT, .active_cooldown = COMMON_ACTIVE_COOLDOWN, @@ -70,8 +70,8 @@ static const BasicAnimation animation_laptop = { BUTTHURT_LEVEL(3) | BUTTHURT_LEVEL(4) | BUTTHURT_LEVEL(5)}; static const ActiveAnimation animation_laptop_active = { - .icon = &A_LaptopActive_128x51, - .duration = COMMON_ACTIVE_DURATION(2), + .icon = &A_LaptopActive_128x52, + .duration = COMMON_ACTIVE_DURATION(8), }; static const BasicAnimation animation_knife = { @@ -118,15 +118,15 @@ static const ActiveAnimation animation_box_active = { }; static const BasicAnimation animation_waves = { - .icon = &A_Waves_128x51, + .icon = &A_Waves_128x52, .duration = COMMON_BASIC_DURATION, .weight = COMMON_WEIGHT, .active_cooldown = COMMON_ACTIVE_COOLDOWN, .butthurt_level_mask = BUTTHURT_LEVEL(0) | BUTTHURT_LEVEL(1) | BUTTHURT_LEVEL(2)}; static const ActiveAnimation animation_waves_active = { - .icon = &A_WavesActive_128x51, - .duration = COMMON_ACTIVE_DURATION(2), + .icon = &A_WavesActive_128x52, + .duration = COMMON_ACTIVE_DURATION(7), }; // Level Idle Animations diff --git a/assets/compiled/assets_icons.c b/assets/compiled/assets_icons.c index 88a69620..b0276f28 100644 --- a/assets/compiled/assets_icons.c +++ b/assets/compiled/assets_icons.c @@ -63,13 +63,23 @@ const uint8_t _A_Knife_128x51_0[] = {0x01,0x00,0x84,0x01,0x00,0x78,0x02,0x2f,0xc const uint8_t _A_Knife_128x51_1[] = {0x01,0x00,0x8c,0x01,0x00,0x78,0x02,0xbf,0x9f,0xf8,0x08,0x3f,0x20,0xf0,0x08,0x18,0x3a,0xfc,0x01,0xd1,0x87,0x03,0xee,0x60,0x02,0x18,0xc0,0x3f,0x80,0x44,0x00,0x98,0x80,0x08,0x6c,0x06,0x1e,0xa0,0x03,0x2e,0x18,0x02,0x1e,0x00,0x3e,0xe0,0x80,0x21,0xc0,0x03,0xee,0x0c,0x0f,0xe8,0x10,0x3c,0x94,0x16,0x0f,0x28,0x00,0x3e,0xc1,0x66,0xb0,0xb0,0x79,0x88,0xcc,0x1f,0xe0,0xfb,0x31,0x90,0x3f,0x10,0x64,0x0f,0xf7,0xf4,0x43,0xe1,0xe0,0xfc,0xe0,0x7f,0xe0,0xec,0x34,0x0f,0xc7,0xfe,0x3e,0x04,0x18,0x40,0x3e,0x7e,0x1f,0xfd,0xf8,0x40,0x41,0xf5,0x98,0x10,0x08,0x7f,0x3f,0x1f,0xff,0xfa,0xb4,0x63,0x04,0xfa,0xf9,0xc7,0xcc,0x02,0x0f,0xac,0x07,0x7f,0xfc,0x0f,0x19,0x80,0x3e,0xbf,0x9c,0xf1,0x78,0xdc,0x01,0xf3,0x40,0x40,0x0f,0xfe,0x03,0xd0,0x07,0xcd,0x80,0xa2,0x3c,0x1f,0xfe,0xcd,0x68,0x69,0x55,0x1d,0x1f,0x82,0x46,0x0f,0x4b,0xe0,0x10,0xe2,0x00,0x43,0x90,0x3c,0x13,0x90,0x48,0x14,0x52,0x03,0x06,0x40,0xd0,0x22,0x38,0xc6,0x21,0xc0,0xf4,0xe0,0x05,0x86,0x40,0x3a,0x1f,0xc4,0xfe,0x01,0x13,0x33,0x18,0x4c,0x6f,0x02,0xf2,0x0a,0x88,0x9c,0xa7,0x9c,0x0f,0xed,0xfc,0x58,0x42,0x52,0x90,0x28,0x07,0x80,0x05,0x2c,0x04,0x0f,0xe1,0x80,0x8d,0x81,0x04,0x12,0x45,0x51,0xc4,0x01,0x86,0xc0,0x13,0x1c,0x04,0x1e,0xe1,0xe0,0x2f,0x98,0x3c,0x61,0x11,0xe1,0x10,0xd0,0x01,0x23,0x1e,0xe4,0x6f,0xcf,0x65,0x20,0x42,0x8c,0x23,0xc1,0x01,0xc0,0x60,0x01,0x42,0xee,0x1f,0x8a,0x90,0xe4,0x04,0xf2,0x10,0x0c,0x0c,0x94,0x38,0x0f,0xf7,0xfd,0x88,0x60,0xf3,0xf8,0x16,0xc7,0xf1,0x1f,0x80,0x7d,0xe3,0xe7,0x81,0x07,0x8b,0x14,0x41,0xe2,0x4b,0x14,0x28,0xfc,0x30,0x6d,0xd1,0x2f,0x95,0x00,0x92,0x27,0xf3,0x3a,0x8e,0x03,0xff,0xf0,0x17,0x90,0x38,0x41,0xe9,0xc0,0xbd,0x83,0xc7,0x83,0xef,0x2f,0x15,0xc3,0x81,0x47,0x80,0x06,0xc4,0x00,0x21,0xa1,0x30,0x8c,0xf0,0x0e,0x51,0xca,0x03,0xa8,0x48,0x22,0x00,0x1c,0x14,0x04,0xe8,0x2e,0x93,0x83,0x22,0x0b,0x01,0x13,0x03,0x94,0x1a,0x79,0x8f,0x17,0x17,0x82,0x06,0x0f,0x28,0x05,0xf8,0x04,0x30,0x4f,0xe4,0x5f,0xf0,0x09,0x26,0x62,0x00,0xc6,0x0e,0x0f,0x18,0x04,0x40,0x6c,0x63,0x21,0x07,0x9c,0x03,0xf8,0x0f,0x28,0xf8,0x24,0xb8,0x08,0x01,0xc0,0x40,0x00,}; const uint8_t *_A_Knife_128x51[] = {_A_Knife_128x51_0,_A_Knife_128x51_1}; -const uint8_t _A_LaptopActive_128x51_0[] = {0x01,0x00,0x2c,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0x4f,0x04,0xfc,0x1f,0xbb,0xcf,0x50,0x3f,0x6a,0xf5,0x58,0x18,0x3a,0xf8,0x1a,0xad,0x54,0x38,0x1f,0x76,0x0a,0xac,0x02,0x2a,0x0f,0xbd,0x84,0x2a,0x01,0x28,0x07,0xdd,0x62,0x0b,0x00,0xa8,0x03,0xef,0x58,0x71,0x20,0x7d,0xd5,0x0a,0x44,0x0f,0xb9,0x50,0x08,0x70,0x00,0xfb,0x8b,0x00,0xca,0x02,0x0f,0xa8,0x5c,0x78,0x3e,0x20,0xfb,0x82,0xc8,0x60,0x14,0x00,0x7d,0x60,0x30,0x54,0x02,0x78,0xac,0x2b,0x01,0x45,0xde,0x03,0xf6,0x85,0xfe,0x80,0x7a,0x83,0xf9,0xcf,0xa0,0x47,0x60,0x4d,0xea,0xa1,0x71,0xf5,0x10,0x38,0x60,0x3e,0x68,0x18,0x1f,0x3f,0x42,0x01,0x08,0x0f,0xd4,0x0a,0xff,0x38,0x07,0xd9,0xec,0x67,0xc2,0xd1,0x87,0x07,0xee,0xc7,0x02,0xe0,0x7f,0xc0,0x03,0x3f,0x07,0xb5,0x83,0x02,0xcd,0x19,0xc2,0x7c,0xa4,0x00,0xf6,0xf0,0x50,0x80,0x63,0x06,0x07,0xd5,0x42,0x82,0x82,0x1c,0x08,0x1c,0xa2,0x00,0xf6,0xf8,0x07,0xc6,0xc0,0xff,0x30,0x7b,0xd6,0x05,0x63,0x18,0x68,0x88,0x00,0x4e,0x4f,0xec,0x55,0x90,0x3e,0xea,0x84,0xb6,0x82,0x03,0xdb,0xd4,0x1f,0x20,0x7d,0xd5,0xa0,0xa4,0xb5,0x71,0x3f,0xac,0x10,0x51,0xc0,0x7d,0x55,0x43,0xe5,0x0b,0x03,0x91,0x18,0x80,0x09,0xff,0x8f,0x96,0xd4,0x1e,0xdb,0xc2,0x61,0x92,0xc9,0x24,0x63,0xe4,0x07,0xef,0x03,0xaa,0x0f,0x64,0x91,0x80,0x0b,0x41,0xaa,0x07,0x9a,0x89,0x9f,0xa7,0xd5,0x80,0x9f,0x09,0x24,0xc1,0xf4,0x07,0xe8,0x7c,0x60,0x46,0xc2,0x35,0x93,0xb9,0xb4,0x16,0xa8,0x2c,0x50,0x1f,0x5f,0xfb,0xff,0xd6,0x1f,0xfa,0xff,0xff,0xc1,0xe5,0xf8,0x02,0x88,0x00,0x8d,0xe3,0x7f,0xf8,0x02,0x13,0xff,0x0f,0x47,0xb0,0x00,0x61,0x82,0xf4,0x77,0x38,0xa5,0xe0,0x60,0xf8,0x00,0x78,0x02,0xc0,}; -const uint8_t _A_LaptopActive_128x51_1[] = {0x01,0x00,0x18,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0xf0,0x02,0x7f,0x23,0xe0,0xfd,0xa9,0xfd,0x41,0xd9,0xc0,0xd5,0x6a,0xa0,0x60,0xfb,0xb0,0x55,0x6a,0xb0,0x50,0x7d,0xec,0x35,0x5a,0x28,0x50,0x3e,0xeb,0x14,0x5a,0x24,0x54,0x1f,0x7a,0x80,0x10,0xc6,0x01,0xf7,0x54,0x80,0xc0,0x26,0x00,0xfb,0x97,0x00,0x86,0x40,0x0f,0xba,0xb0,0x08,0x68,0x00,0xfb,0xf5,0x00,0x86,0x8e,0x0f,0xb8,0xac,0x07,0x01,0x98,0x07,0xde,0x2e,0x07,0x40,0xce,0x03,0xef,0xda,0x0f,0x1c,0xf8,0x3e,0xfd,0x60,0xfe,0xf4,0x83,0xfa,0xf7,0xa2,0xe0,0x64,0xc1,0xf7,0x79,0xa9,0x70,0x41,0xf7,0x80,0xf9,0x6a,0x70,0x10,0xf5,0x90,0x83,0xe7,0xc3,0x50,0x80,0xc1,0xc1,0xf7,0x12,0x01,0x8c,0x23,0xfe,0x00,0x19,0xf8,0x3d,0xe1,0x20,0x31,0x88,0x07,0xc9,0xa6,0xf8,0x08,0x54,0x06,0x80,0x0f,0xc8,0x2c,0x0a,0x41,0x80,0x03,0x94,0x40,0x1e,0xf0,0x20,0x7f,0x41,0x7c,0x91,0x17,0xf9,0xc2,0x01,0xef,0x8a,0xff,0xc3,0xc1,0xf7,0x40,0xa2,0x8a,0x84,0x96,0x70,0x40,0x7b,0x70,0x2b,0x40,0xfd,0xa0,0x59,0xc1,0xe2,0x4b,0x38,0x10,0x7d,0xe8,0x20,0xfe,0xe0,0x92,0x84,0x96,0x6c,0x27,0xd0,0x70,0x01,0xfb,0x50,0xb0,0x40,0x60,0x84,0xb2,0x49,0x18,0x01,0x26,0x1a,0x05,0x00,0x83,0xee,0xb1,0x50,0x82,0x88,0x04,0xcc,0x40,0xf7,0xd6,0x6c,0x3f,0x45,0xb3,0x07,0xc5,0x50,0x3e,0x20,0xf3,0x77,0x3c,0x03,0x55,0xa8,0x85,0x03,0xf2,0xab,0x59,0x0f,0x89,0xac,0x9d,0xcf,0x00,0xd5,0x87,0xc8,0x1f,0x1f,0xf0,0x02,0x83,0xcb,0xf0,0x08,0x40,0x99,0xff,0x01,0x29,0x07,0x17,0xbc,0x02,0x18,0xab,0x47,0x73,0x8a,0x5e,0x06,0x0f,0x80,0x07,0x80,0x2c,}; -const uint8_t *_A_LaptopActive_128x51[] = {_A_LaptopActive_128x51_0,_A_LaptopActive_128x51_1}; +const uint8_t _A_LaptopActive_128x52_0[] = {0x01,0x00,0x3c,0x02,0x00,0x78,0x03,0x60,0x20,0x43,0xc0,0x40,0xc1,0xce,0x09,0x2c,0x04,0x1c,0x04,0x30,0x20,0x7d,0x51,0xf1,0x10,0x1f,0xe4,0x3c,0x1e,0xf4,0x08,0x24,0x02,0xd1,0x48,0x9d,0x40,0xe6,0x00,0xf7,0x90,0x42,0x20,0x1f,0x0a,0x7f,0x3a,0x01,0xc0,0x07,0xbc,0x42,0x21,0x00,0xfb,0xd3,0xe5,0xc0,0x71,0x28,0x3c,0x22,0x41,0x00,0xba,0xde,0x23,0xc0,0x71,0x1b,0x08,0x8c,0x60,0xf3,0xc8,0x07,0xfb,0xfe,0x00,0x1b,0xbd,0x2e,0x1c,0x17,0x20,0x10,0xd8,0x21,0x11,0x38,0x01,0x9c,0xb0,0x17,0x0a,0x44,0x18,0x6e,0x40,0x82,0xc8,0x05,0x07,0xf4,0x1e,0x1d,0xf8,0x7c,0x42,0xa4,0x0f,0x28,0x05,0x44,0x1e,0x30,0xa0,0x28,0xe8,0x03,0xe2,0x0f,0x22,0x30,0x80,0x06,0xa4,0x44,0x18,0x54,0x0b,0x01,0xa0,0x0f,0x8a,0xcc,0x81,0xe7,0x54,0x0b,0x8c,0x2a,0x0d,0xc1,0xd4,0x5d,0x69,0x00,0xf2,0xa0,0x03,0xcb,0xd0,0x07,0x1c,0x56,0xab,0x55,0xa4,0xbb,0xf2,0x20,0x17,0xc0,0x79,0xf8,0x2e,0xcc,0x81,0x85,0x74,0xf2,0xda,0xab,0x80,0x3c,0x70,0x40,0xf3,0xcc,0x7b,0x6e,0x30,0x0a,0x56,0x0a,0x05,0xa7,0x07,0x94,0xe6,0x02,0x0f,0x28,0x87,0xef,0x79,0x01,0xc5,0x60,0x60,0x5a,0xaf,0xfd,0xff,0x01,0x7c,0x2b,0x09,0x48,0xae,0xf1,0xe8,0x1c,0xa8,0x1e,0x3a,0x61,0x58,0xe0,0x3d,0xc0,0xf3,0xa0,0x5b,0xb1,0xe4,0xf1,0x07,0x8e,0x84,0x3e,0x5f,0xe8,0x17,0x02,0x1e,0x9f,0x1f,0xc5,0x3c,0x9e,0x3c,0x2c,0x36,0x80,0x3e,0x40,0xf1,0x98,0x28,0x0b,0xef,0x37,0x07,0x8e,0x92,0x95,0xa0,0x81,0x83,0xc4,0x7e,0x30,0xc4,0x80,0xf0,0x3f,0xd3,0xb0,0x78,0xea,0x21,0x5a,0x0b,0xf1,0x6c,0x4b,0xe3,0x03,0x07,0x8f,0x83,0xe3,0x1f,0x07,0x8e,0x42,0x25,0xa0,0xb9,0x03,0xc7,0xfd,0xe0,0x58,0x16,0x03,0xde,0x43,0x10,0x7b,0x23,0xc6,0x01,0x3e,0x52,0x0f,0xf9,0x5e,0x30,0xac,0x44,0x8b,0x41,0xf2,0xa0,0xc0,0x20,0x30,0x1c,0x04,0x86,0x01,0xc8,0xe3,0xf3,0xe0,0x70,0xa8,0x44,0x84,0x3e,0x34,0x26,0x59,0x58,0x3f,0x9f,0xf3,0xb8,0xdd,0xe0,0xc0,0xf4,0xbd,0x03,0xca,0x30,0xfb,0x13,0xb8,0xdf,0xe0,0xa2,0xf3,0xb9,0x52,0x81,0xe5,0x06,0x7d,0x89,0x80,0x6f,0xd0,0x18,0x55,0x22,0x48,0x0f,0x4c,0x04,0x04,0x1e,0x7b,0xe2,0x78,0x83,0xce,0x54,0x0a,0x1b,0xc1,0x48,0x40,0x83,0xf0,0xbf,0x83,0xe0,0x00,0x20,0xf3,0x9f,0x83,0xc6,0xa1,0x14,0x07,0xab,0x7c,0xa0,0x1f,0x8e,0xf9,0xbc,0x51,0xe7,0x1a,0x05,0x97,0x00,0x1e,0x7f,0xf2,0x78,0xe8,0x00,0x23,0xff,0x5b,0x09,0xfc,0x80,0x64,0x82,0x11,0x78,0xf0,0x20,0xee,0xf1,0x75,0x11,0xec,0x41,0xe6,0x3f,0x20,0x28,0x87,0xc5,0x8c,0x20,0x81,0x67,0x08,0x00,0x7f,0xc5,0xf1,0xfd,0x29,0x47,0x7f,0xc0,0x84,0x70,0x07,0xa2,0x0f,0x41,0xf8,0xa1,0x4b,0x01,0x20,0x82,0xcc,0x0d,0xa2,0x33,0x3f,0xcf,0xfe,0x06,0x12,0x10,0x00,0xce,0xe0,0xb0,0x88,0x04,0x08,0x1e,0x60,0xa1,0x83,0xa2,0x4e,0x49,0x03,0x65,0x8c,0x10,0x24,0x22,0x81,0xfb,0x83,0xd6,0x79,0x03,0x01,0x8c,0x20,0x1e,0x71,0x3f,0x80,0x3d,0x55,0x45,0x10,0x07,0x97,0x02,0x33,0x90,0x83,0x0b,0xd0,0x1e,0x30,0x69,0x03,0xf8,0xe3,0x9b,0x00,0x29,0x11,0x8d,0x42,0x29,0x61,0x0f,0x94,0x7f,0xa0,0x0a,0x20,0x00,0xb6,0x08,0x0e,0x93,0xff,0x04,0xbc,0x3c,0x60,0x02,0x3f,0x89,0x80,0x40,0x43,0x20,0x90,0x46,0x01,0xed,0xe0,0x0f,0xa0,0xd1,0x00,0x1e,0x00,0xf0,0x07,0x80,0x08,}; +const uint8_t _A_LaptopActive_128x52_1[] = {0x01,0x00,0x19,0x02,0x00,0x78,0x03,0x60,0x20,0x43,0xc0,0x40,0xc1,0xce,0x09,0x2c,0x04,0x1c,0x04,0x30,0x20,0x7d,0x51,0xf1,0x10,0x1f,0xe4,0x3c,0x1e,0xf4,0x08,0x24,0x02,0xd1,0x48,0x9d,0x40,0xe6,0x00,0xf7,0x90,0x42,0x20,0x1f,0x0a,0x7f,0x3a,0x01,0xc0,0x07,0xbc,0x42,0x21,0x00,0xfb,0xd3,0xe5,0xc0,0x71,0x28,0x3c,0x22,0x41,0x00,0xba,0xde,0x23,0xc0,0x71,0x1b,0x08,0x8c,0x60,0xf3,0xc8,0x07,0xfb,0xfe,0x00,0x1b,0xbd,0x2e,0x1c,0x17,0x20,0x10,0xd8,0x21,0x11,0x38,0x01,0x9c,0xb0,0x17,0x0a,0x44,0x18,0x6e,0x44,0x61,0x0d,0x10,0x01,0x03,0xe2,0x15,0x20,0x78,0x88,0x49,0x02,0xa1,0xf1,0x07,0x91,0x18,0x41,0xf0,0x1f,0x15,0x99,0x03,0xe2,0xa1,0x80,0xba,0xd2,0x01,0xe5,0x40,0x80,0x62,0x16,0xc3,0x00,0x8e,0x06,0x08,0x3e,0x3c,0x88,0x05,0xf0,0x1e,0x54,0x83,0x91,0x48,0x87,0xe8,0x0f,0x1c,0x10,0x3c,0xf0,0x95,0x48,0xcc,0x0a,0xe1,0x92,0xa4,0x83,0xce,0x73,0x01,0x17,0x96,0x1e,0xa9,0x25,0x8f,0x52,0x2a,0x54,0xac,0x07,0xfe,0xff,0x80,0xbe,0x40,0xb0,0x04,0xf1,0xc2,0xf9,0x27,0x92,0x2a,0x47,0x7a,0xd6,0x09,0x1a,0x06,0x03,0xdc,0x0f,0x18,0x7e,0x20,0x5e,0x30,0x50,0x78,0xd4,0xab,0x01,0xf3,0xff,0x40,0xac,0x11,0x02,0x78,0xd5,0xe7,0x31,0xcf,0xe6,0x4a,0x97,0x95,0x0f,0x90,0x3c,0x63,0x0f,0x82,0x30,0x16,0x10,0xbe,0x50,0x30,0x78,0x8f,0xc6,0x0d,0x20,0x06,0x8b,0xcd,0x70,0x17,0xe2,0xd8,0xce,0x70,0x30,0x19,0x02,0xd0,0x81,0xeb,0x72,0x07,0x8f,0xfa,0xc1,0x00,0x9f,0xa9,0x08,0x1f,0x08,0xf1,0xe0,0x67,0xdd,0xcf,0xff,0xf9,0x50,0x60,0x10,0x18,0x0f,0xc2,0x1f,0x00,0xe4,0x71,0xf9,0xf0,0x38,0x54,0x22,0x43,0xa0,0xb9,0x50,0x84,0xa5,0xfc,0x0c,0x15,0xfe,0xef,0x06,0x07,0xa5,0xe8,0x1e,0x5f,0xf8,0x2b,0x8c,0xaf,0xf0,0x58,0x56,0x22,0x44,0x0f,0x1a,0x50,0x28,0x78,0x1f,0xf2,0xf1,0x78,0x2f,0xd0,0x18,0x55,0x22,0x48,0x0f,0x4f,0x85,0xfc,0x1e,0x7b,0xe8,0x00,0x3d,0x25,0x40,0xa1,0xbe,0x7e,0x0d,0xc4,0x14,0x10,0x7c,0x31,0x04,0x1e,0x73,0xf0,0x78,0xd4,0x22,0x80,0xf4,0x20,0x08,0x0c,0xbf,0x1d,0xf3,0x78,0xe4,0x22,0x40,0xf1,0x8d,0x25,0x4c,0x1e,0x62,0x41,0x85,0x68,0x00,0x23,0xff,0x8f,0x82,0xc9,0x46,0x28,0x33,0x17,0x8f,0x02,0x0f,0xa0,0x80,0x44,0x03,0x44,0x0f,0x41,0xf9,0x01,0x44,0x3e,0x2a,0xa1,0x9f,0xf8,0x01,0x42,0x00,0x1f,0xf1,0x7c,0x7f,0x4a,0x51,0xdf,0xf0,0x21,0x1c,0x02,0x68,0x83,0xd0,0x7e,0x28,0x52,0xc0,0x48,0x20,0xb3,0x06,0x80,0xc6,0x01,0xe5,0xf9,0xff,0xc0,0xc2,0x42,0x00,0x19,0xdc,0x16,0x11,0x00,0x81,0x03,0xcc,0x14,0x30,0x70,0x29,0x40,0x24,0x90,0x38,0x24,0x02,0x08,0x12,0x11,0x40,0xfd,0xc1,0xeb,0x3c,0x81,0x80,0xc6,0x10,0x0f,0x38,0x9f,0xc0,0x1e,0xaa,0xa2,0x88,0x03,0xcb,0x81,0x19,0xc8,0x41,0x85,0xe8,0x0f,0x18,0x34,0x80,0x64,0x29,0x21,0x8e,0x6c,0x00,0xa4,0x46,0x35,0x08,0xa5,0x84,0x3e,0x51,0xfe,0x80,0x28,0x80,0x02,0xd8,0x20,0x3a,0x25,0x06,0x5e,0x1e,0x30,0x01,0x1f,0xc4,0xc0,0x20,0x21,0x90,0x48,0x0e,0x86,0x00,0x3f,0x00,0x7d,0x06,0x88,0x00,0xf0,0x07,0x80,0x3c,0x00,0x40,}; +const uint8_t _A_LaptopActive_128x52_2[] = {0x01,0x00,0x17,0x02,0x00,0x78,0x03,0x60,0x20,0x43,0xc0,0x40,0xc1,0xce,0x09,0x2c,0x04,0x1c,0x04,0x30,0x20,0x7d,0x51,0xf1,0x10,0x1f,0xe4,0x3c,0x1e,0xf4,0x08,0x24,0x02,0xd1,0x48,0x9d,0x40,0xe6,0x00,0xf7,0x90,0x42,0x20,0x1f,0x0a,0x7f,0x3a,0x01,0xc0,0x07,0xbc,0x42,0x21,0x00,0xfb,0xd3,0xe5,0xc0,0x71,0x28,0x3c,0x22,0x41,0x00,0xba,0xde,0x23,0xc0,0x71,0x1b,0x08,0x8c,0x60,0xf3,0xc8,0x07,0xfb,0xfe,0x00,0x1b,0xbd,0x2e,0x1c,0x17,0x20,0x10,0xd8,0x21,0x11,0x38,0x01,0x9c,0xb0,0x17,0x0a,0x44,0x18,0x6e,0x44,0x61,0x0d,0x10,0x01,0x03,0xe2,0x15,0x20,0x78,0x88,0x49,0x02,0xa1,0xf1,0x07,0x91,0x18,0x41,0xf0,0x1f,0x15,0x99,0x03,0xe2,0xa1,0x80,0xba,0xd2,0x01,0xe5,0x40,0x80,0x62,0x16,0xc3,0x00,0x8e,0x06,0x08,0x3e,0x3c,0x88,0x05,0xf0,0x1e,0x54,0x83,0x91,0x48,0x87,0xe8,0x0f,0x1c,0x10,0x3c,0xf0,0x95,0x48,0xcc,0x0a,0xe1,0x92,0xa4,0x83,0xce,0x73,0x01,0x17,0x96,0x1e,0xa9,0x25,0x8f,0x52,0x2a,0x54,0xac,0x07,0xfe,0xff,0x80,0xbe,0x40,0xb0,0x04,0xf1,0xc2,0xf9,0x27,0x92,0x2a,0x47,0x7a,0xd6,0x09,0x1a,0x06,0x03,0xdc,0x0f,0x2c,0x40,0xbc,0x60,0xa0,0xf1,0xa9,0x56,0x03,0xe7,0xfe,0x81,0x70,0x21,0xe4,0xf1,0xab,0xce,0x63,0x9f,0xcc,0x95,0x2f,0x2a,0x1f,0x20,0x78,0xcc,0x22,0x07,0xf1,0x30,0x16,0x10,0xbe,0x50,0x30,0x78,0x8f,0xc6,0x19,0x20,0x06,0x8b,0xcd,0x70,0x17,0xe2,0xd8,0x97,0xc6,0x07,0x20,0x5a,0x10,0x3d,0x6e,0x40,0xf1,0xff,0x78,0x12,0xe2,0xa4,0x20,0x7c,0x23,0xc6,0x01,0xbe,0x77,0x3f,0xff,0xe5,0x41,0x80,0x40,0x60,0x38,0x09,0x0c,0x03,0x91,0xc7,0xe7,0xc0,0xe1,0x50,0x89,0x0e,0x82,0xe5,0x42,0x12,0x95,0x83,0xf8,0x18,0x1b,0xfd,0xde,0x0c,0x0f,0x4b,0xd0,0x3c,0xa3,0x06,0xc2,0xa0,0x5f,0xe0,0xb0,0xac,0x44,0x88,0x1e,0x34,0xa0,0x79,0x41,0x8b,0xc5,0xe0,0xbf,0x40,0x61,0x54,0x89,0x20,0x3d,0x30,0x10,0x10,0x79,0xef,0xa0,0x00,0xf4,0x95,0x02,0x86,0xf0,0x52,0x10,0x20,0xfc,0x2f,0xe0,0xf8,0x00,0x08,0x3c,0xe7,0xe0,0xf1,0xa8,0x45,0x01,0xea,0xdf,0x10,0x00,0xfe,0x3b,0xe6,0xf1,0xc8,0x44,0x81,0xe3,0x1a,0x05,0x97,0x00,0x1e,0x7f,0xf2,0x78,0xe8,0x00,0x23,0xff,0x8f,0x9f,0xcc,0x06,0x48,0x21,0x17,0x8f,0x02,0x0f,0xa0,0x80,0x44,0x01,0x64,0xb3,0x10,0x79,0x0f,0xc8,0x0a,0x21,0xf1,0x87,0xc0,0x01,0x03,0x20,0x07,0x97,0xf8,0xbe,0x3f,0xa5,0x28,0xef,0xf8,0x10,0x8e,0x00,0xf4,0x41,0xe8,0x3f,0x14,0x29,0x60,0x24,0x10,0x59,0x81,0xb4,0x46,0x67,0xf9,0xff,0xc0,0xc2,0x42,0x00,0x19,0xdc,0x16,0x11,0x00,0x81,0x03,0xcc,0x14,0x30,0x74,0x49,0xc9,0x20,0x6c,0xb1,0x82,0x04,0x84,0x50,0x3f,0x70,0x7a,0xcf,0x20,0x60,0x31,0x84,0x03,0xce,0x27,0xf0,0x07,0xaa,0xa8,0xa2,0x00,0xf2,0xe0,0x46,0x72,0x10,0x61,0x7a,0x03,0xc6,0x0d,0x20,0x7f,0x1c,0x73,0x60,0x05,0x22,0x31,0xa8,0x45,0x2c,0x21,0xf2,0x8f,0xf4,0x01,0x44,0x00,0x16,0xc1,0x01,0xd2,0x7f,0xe0,0x97,0x87,0x8c,0x00,0x47,0xf1,0x30,0x08,0x08,0x64,0x12,0x08,0xc0,0x3d,0xbc,0x01,0xf4,0x1a,0x20,0x03,0xc0,0x1e,0x00,0xf0,0x01,0x00,}; +const uint8_t _A_LaptopActive_128x52_3[] = {0x01,0x00,0x17,0x02,0x00,0x78,0x03,0x60,0x20,0x43,0xc0,0x40,0xc1,0xce,0x09,0x2c,0x04,0x1c,0x04,0x30,0x20,0x7d,0x51,0xf1,0x10,0x1f,0xe4,0x3c,0x1e,0xf4,0x08,0x24,0x02,0xd1,0x48,0x9d,0x40,0xe6,0x00,0xf7,0x90,0x42,0x20,0x1f,0x0a,0x7f,0x3a,0x01,0xc0,0x07,0xbc,0x42,0x21,0x00,0xfb,0xd3,0xe5,0xc0,0x71,0x28,0x3c,0x22,0x41,0x00,0xba,0xde,0x23,0xc0,0x71,0x1b,0x08,0x8c,0x60,0xf3,0xc8,0x07,0xfb,0xfe,0x00,0x1b,0xbd,0x2e,0x1c,0x17,0x20,0x10,0xd8,0x21,0x11,0x38,0x01,0x9c,0xb0,0x17,0x0a,0x44,0x18,0x6e,0x44,0x61,0x0d,0x10,0x01,0x03,0xe2,0x15,0x20,0x78,0x88,0x49,0x02,0xa1,0xf1,0x07,0x91,0x18,0x41,0xf0,0x1f,0x15,0x99,0x03,0xe2,0xa1,0x80,0xba,0xd2,0x01,0xe5,0x40,0x80,0x62,0x16,0xc3,0x00,0x8e,0x06,0x08,0x3e,0x3c,0x88,0x05,0xf0,0x1e,0x54,0x83,0x91,0x48,0x87,0xe8,0x0f,0x1c,0x10,0x3c,0xf0,0x95,0x48,0xcc,0x0a,0xe1,0x92,0xa4,0x83,0xce,0x73,0x01,0x17,0x96,0x1e,0xa9,0x25,0x8f,0x52,0x2a,0x54,0xac,0x07,0xfe,0xff,0x80,0xbe,0x40,0xb0,0x04,0xf1,0xc2,0xf9,0x27,0x92,0x2a,0x47,0x7a,0xd6,0x09,0x1a,0x06,0x03,0xdc,0x0f,0x2c,0x40,0xbc,0x60,0xa0,0xf1,0xa9,0x56,0x03,0xe7,0xfe,0x81,0x70,0x21,0xe4,0xf1,0xab,0xce,0x63,0x9f,0xcc,0x95,0x2f,0x2a,0x1f,0x20,0x78,0xcc,0x22,0x07,0xf1,0x30,0x16,0x10,0xbe,0x50,0x30,0x78,0x8f,0xc6,0x19,0x20,0x06,0x8b,0xcd,0x70,0x17,0xe2,0xd8,0x97,0xc6,0x07,0x20,0x5a,0x10,0x3d,0x6e,0x40,0xf1,0xff,0x78,0x12,0xe2,0xa4,0x20,0x7c,0x23,0xc6,0x01,0xbe,0x77,0x3f,0xff,0xe5,0x41,0x80,0x40,0x60,0x38,0x09,0x0c,0x03,0x91,0xc7,0xe7,0xc0,0xe1,0x50,0x89,0x0e,0x82,0xe5,0x42,0x12,0x95,0x83,0xf8,0x18,0x1b,0xfd,0xde,0x0c,0x0f,0x4b,0xd0,0x3c,0xa3,0x06,0xc2,0xa0,0x5f,0xe0,0xb0,0xac,0x44,0x88,0x1e,0x34,0xa0,0x79,0x41,0x8b,0xc5,0xe0,0xbf,0x40,0x61,0x54,0x89,0x20,0x3d,0x30,0x10,0x10,0x79,0xef,0xa0,0x00,0xf4,0x95,0x02,0x86,0xf0,0x52,0x10,0x20,0xfc,0x2f,0xe0,0xf8,0x00,0x08,0x3c,0xe7,0xe0,0xf1,0xa8,0x45,0x01,0xea,0xdf,0x10,0x00,0xfe,0x3b,0xe6,0xf1,0xc8,0x44,0x81,0xe3,0x1a,0x05,0x97,0x00,0x1e,0x7f,0xf2,0x78,0xe8,0x00,0x23,0xff,0x8f,0x9f,0xcc,0x06,0x48,0x21,0x17,0x8f,0x02,0x0f,0xa0,0x80,0x44,0x01,0x64,0xb3,0x10,0x79,0x0f,0xc8,0x0a,0x21,0xf1,0x87,0xc0,0x01,0x03,0x20,0x07,0x97,0xf8,0xbe,0x3f,0xa5,0x28,0xef,0xf8,0x10,0x8e,0x00,0xf4,0x41,0xe8,0x3f,0x14,0x29,0x60,0x24,0x10,0x59,0x81,0xb4,0x46,0x67,0xf9,0xff,0xc0,0xc2,0x42,0x00,0x19,0xdc,0x16,0x11,0x00,0x81,0x03,0xcc,0x14,0x30,0x74,0x49,0xc9,0x20,0x6c,0xb1,0x82,0x04,0x84,0x50,0x3f,0x70,0x7a,0xcf,0x20,0x60,0x31,0x84,0x03,0xce,0x27,0xf0,0x07,0xaa,0xa8,0xa2,0x00,0xf2,0xe0,0x46,0x72,0x10,0x61,0x7a,0x03,0xc6,0x0d,0x20,0x7f,0x1c,0x73,0x60,0x05,0x22,0x31,0xa8,0x45,0x2c,0x21,0xf2,0x8f,0xf4,0x01,0x44,0x00,0x16,0xc1,0x01,0xd2,0x7f,0xe0,0x97,0x87,0x8c,0x00,0x47,0xf1,0x30,0x08,0x08,0x64,0x12,0x08,0xc0,0x3d,0xbc,0x01,0xf4,0x1a,0x20,0x03,0xc0,0x1e,0x00,0xf0,0x01,0x00,}; +const uint8_t _A_LaptopActive_128x52_4[] = {0x01,0x00,0x0b,0x02,0x00,0x78,0x03,0x60,0x20,0x43,0xc0,0x40,0xc1,0xce,0x09,0x2c,0x04,0x1c,0x04,0x30,0x20,0x7d,0x51,0xf1,0x10,0x1f,0xe4,0x3c,0x1e,0xf4,0x08,0x24,0x02,0xd1,0x48,0x9d,0x40,0xe6,0x00,0xf7,0x90,0x42,0x20,0x1f,0x0a,0x7f,0x3a,0x01,0xc0,0x07,0xbc,0x42,0x21,0x00,0xfb,0xd3,0xe5,0xc0,0x71,0x28,0x3c,0x22,0x41,0x00,0xba,0xde,0x23,0xc0,0x71,0x1b,0x08,0x8c,0x60,0xf3,0xc8,0x07,0xfb,0xfe,0x00,0x1b,0xbd,0x2e,0x1c,0x17,0x20,0x10,0xd8,0x21,0x11,0x38,0x01,0x9c,0xb0,0x17,0x0a,0x44,0x18,0x6e,0x44,0x61,0x0d,0x10,0x01,0x03,0xe2,0x15,0x20,0x78,0x88,0x49,0x02,0xa1,0xf1,0x07,0x91,0x18,0x41,0xf0,0x1f,0x15,0x99,0x03,0xea,0xeb,0x48,0x07,0x95,0x00,0x3f,0x5c,0x88,0x05,0xf0,0x1f,0x77,0x00,0x78,0xe0,0x81,0xe7,0x80,0xa4,0xd5,0x78,0x53,0x1e,0x3e,0xe7,0x08,0x0f,0x29,0xcc,0x04,0x1e,0x54,0x0a,0x55,0x56,0x85,0x4a,0xc1,0x69,0x30,0x5f,0xfb,0xfe,0x02,0xf9,0x02,0xc0,0x03,0xca,0xd1,0x4e,0xe1,0x52,0x41,0xe3,0x81,0x15,0x8e,0x03,0xdc,0x0f,0x18,0x78,0x3c,0x6b,0x41,0xf3,0xda,0x07,0xcf,0xfd,0x02,0xb0,0x44,0x21,0x19,0x5a,0x4e,0x57,0x87,0x31,0xc1,0x6a,0x30,0x81,0xf2,0x07,0x8c,0x61,0xf0,0x40,0x01,0x4c,0x11,0x7c,0x60,0x60,0xf1,0x1f,0x8c,0x1a,0x40,0xe1,0x2c,0x02,0x20,0x80,0x83,0x7e,0x2d,0x8c,0xe7,0x03,0x01,0x90,0x06,0xcc,0xfe,0x97,0x20,0x78,0xff,0xac,0x10,0x09,0xf8,0x6c,0xc1,0xee,0x8f,0x1e,0x06,0x7d,0xdc,0xff,0xff,0x95,0x06,0x01,0x01,0x80,0xfc,0x21,0xf0,0x0e,0x47,0x1f,0x9f,0x03,0x85,0x42,0x24,0x3a,0x0b,0x95,0x08,0x4a,0x5f,0xc0,0xc1,0x5f,0xee,0xf0,0x60,0x7a,0x5e,0x81,0xe5,0xff,0x82,0xb8,0xca,0xff,0x05,0x85,0x62,0x24,0x40,0xf1,0xa5,0x02,0x87,0x81,0xff,0x2f,0x17,0x82,0xfd,0x01,0x85,0x52,0x24,0x80,0xf4,0xf8,0x5f,0xc1,0xe7,0xbe,0x80,0x03,0xd2,0x54,0x0a,0x1b,0xe7,0xe0,0xdc,0x41,0x41,0x07,0xc6,0x03,0xfe,0x0f,0x39,0xf8,0x3c,0x6a,0x11,0x40,0x7a,0x10,0x04,0x06,0x5f,0x8e,0xf9,0xbc,0x72,0x11,0x20,0x78,0xc6,0x92,0xa6,0x0f,0x31,0x20,0xc2,0xb4,0x00,0x11,0xff,0xc7,0xc1,0x64,0xa3,0x14,0x19,0x8b,0xc7,0x81,0x07,0xd0,0x40,0x22,0x01,0xa2,0x07,0xa0,0xfc,0x80,0xa2,0x1f,0x15,0x50,0xcf,0xfc,0x00,0xa1,0x00,0x0f,0xf8,0xbe,0x3f,0xa5,0x28,0xef,0xf8,0x10,0x8e,0x01,0x34,0x41,0xe8,0x3f,0x14,0x29,0x60,0x24,0x10,0x59,0x83,0x40,0x63,0x00,0xf2,0xfc,0xff,0xe0,0x61,0x21,0x00,0x0c,0xee,0x0b,0x08,0x80,0x40,0x81,0xe6,0x0a,0x18,0x38,0x14,0xa0,0x12,0x48,0x1c,0x12,0x01,0x04,0x09,0x08,0xa0,0x7e,0xe0,0xf5,0x9e,0x40,0xc0,0x63,0x08,0x07,0x9c,0x4f,0xe0,0x0f,0x55,0x51,0x44,0x01,0xe5,0xc0,0x8c,0xe4,0x20,0xc2,0xf4,0x07,0x8c,0x1a,0x40,0x32,0x14,0x90,0xc7,0x36,0x00,0x52,0x23,0x1a,0x84,0x52,0xc2,0x1f,0x28,0xff,0x40,0x14,0x40,0x01,0x6c,0x10,0x1d,0x12,0x83,0x2f,0x0f,0x18,0x00,0x8f,0xe2,0x60,0x10,0x10,0xc8,0x24,0x07,0x43,0x00,0x1f,0x80,0x3e,0x83,0x44,0x00,0x78,0x03,0xc0,0x1e,0x00,0x20,}; +const uint8_t _A_LaptopActive_128x52_5[] = {0x01,0x00,0x04,0x02,0x00,0x78,0x03,0x60,0x20,0x43,0xc0,0x40,0xc1,0xce,0x09,0x2c,0x04,0x1c,0x04,0x30,0x20,0x7d,0x51,0xf1,0x10,0x1f,0xe4,0x3c,0x1e,0xf4,0x08,0x24,0x02,0xd1,0x48,0x9d,0x40,0xe6,0x00,0xf7,0x90,0x42,0x20,0x1f,0x0a,0x7f,0x3a,0x01,0xc0,0x07,0xbc,0x42,0x21,0x00,0xfb,0xd3,0xe5,0xc0,0x71,0x28,0x3c,0x22,0x41,0x00,0xba,0xde,0x23,0xc0,0x71,0x1b,0x08,0x8c,0x60,0xf3,0xc8,0x07,0xfb,0xfe,0x00,0x1b,0xbd,0x2e,0x1c,0x17,0x20,0x10,0xd8,0x21,0x11,0x38,0x01,0x9c,0xb0,0x17,0x0a,0x44,0x18,0x6e,0x44,0x61,0x0d,0x10,0x01,0x03,0xe2,0x15,0x20,0x78,0x88,0x49,0x02,0xa1,0xf1,0x07,0x91,0x18,0x41,0xf0,0x1f,0x15,0x99,0x03,0xea,0xeb,0x48,0x07,0x95,0x00,0x3f,0x5c,0x88,0x05,0xf0,0x1f,0x77,0x00,0x78,0xe0,0x81,0xe7,0x80,0xa4,0xd5,0x78,0x53,0x1e,0x3e,0xe7,0x08,0x0f,0x29,0xcc,0x04,0x1e,0x54,0x0a,0x55,0x56,0x85,0x4a,0xc1,0x69,0x30,0x5f,0xfb,0xfe,0x02,0xf9,0x02,0xc0,0x03,0xca,0xd1,0x4e,0xe1,0x52,0x41,0xe3,0x81,0x15,0x8e,0x03,0xdc,0x0f,0x4a,0xd0,0x7c,0xf6,0x81,0xf3,0xff,0x40,0xb8,0x10,0xf8,0x46,0x56,0x93,0x95,0xe1,0xcc,0x70,0x5a,0x8c,0x20,0x7c,0x81,0xe3,0x30,0x88,0x17,0xcd,0x30,0x45,0xf1,0x81,0x83,0xc4,0x7e,0x30,0xc9,0x03,0x84,0xb0,0x08,0x82,0x02,0x0d,0xf8,0xb6,0x25,0xf1,0x81,0xc8,0x03,0x66,0x7f,0x4b,0x90,0x3c,0x7f,0xde,0x05,0x80,0x86,0xcc,0x1e,0xe8,0xf1,0x80,0x6f,0x9d,0xcf,0xff,0xf9,0x50,0x60,0x10,0x18,0x0e,0x02,0x43,0x00,0xe4,0x71,0xf9,0xf0,0x38,0x54,0x22,0x43,0xa0,0xb9,0x50,0x84,0xa5,0x60,0xfe,0x06,0x06,0xff,0x77,0x83,0x03,0xd2,0xf4,0x0f,0x28,0xc1,0x78,0xa8,0x17,0xf8,0x2c,0x2b,0x11,0x22,0x07,0x8d,0x28,0x1e,0x50,0x62,0xf1,0x78,0x2f,0xd0,0x18,0x55,0x22,0x48,0x0f,0x43,0xc8,0x83,0xcf,0x7d,0x00,0x07,0xa4,0xa8,0x14,0x37,0x82,0x90,0x81,0x07,0xe1,0x7f,0x07,0xc0,0x00,0x41,0xe7,0x3f,0x07,0x8d,0x42,0x28,0x0f,0x56,0xf8,0x80,0x07,0xf1,0xdf,0x37,0x8e,0x42,0x24,0x0f,0x18,0xd0,0x2c,0xb8,0x00,0xf3,0xff,0x93,0xc7,0x40,0x01,0x1f,0xfc,0x7c,0xfe,0x60,0x32,0x41,0x08,0xbc,0x78,0x10,0x7d,0x04,0x02,0x20,0x0b,0x25,0x98,0x83,0xc8,0x7e,0x40,0x51,0x0f,0x8c,0x3e,0x00,0x08,0x19,0x00,0x3c,0xbf,0xc5,0xf1,0xfd,0x29,0x47,0x7f,0xc0,0x84,0x70,0x07,0xa2,0x0f,0x41,0xf8,0xa1,0x4b,0x01,0x20,0x82,0xcc,0x0d,0xa2,0x33,0x3f,0xcf,0xfe,0x06,0x12,0x10,0x00,0xce,0xe0,0xb0,0x88,0x04,0x08,0x1e,0x60,0xa1,0x83,0xa2,0x4e,0x49,0x03,0x65,0x8c,0x10,0x24,0x22,0x81,0xfb,0x83,0xd6,0x79,0x03,0x01,0x8c,0x20,0x1e,0x71,0x3f,0x80,0x3d,0x55,0x45,0x10,0x07,0x97,0x02,0x33,0x90,0x83,0x0b,0xd0,0x1e,0x30,0x69,0x03,0xf8,0xe3,0x9b,0x00,0x29,0x11,0x8d,0x42,0x29,0x61,0x0f,0x94,0x7f,0xa0,0x0a,0x20,0x00,0xb6,0x08,0x0e,0x93,0xff,0x04,0xbc,0x3c,0x60,0x02,0x3f,0x89,0x80,0x40,0x43,0x20,0x90,0x46,0x01,0xed,0xe0,0x0f,0xa0,0xd1,0x00,0x1e,0x00,0xf0,0x07,0x80,0x08,}; +const uint8_t _A_LaptopActive_128x52_6[] = {0x01,0x00,0x0b,0x02,0x00,0x78,0x03,0x60,0x20,0x43,0xc0,0x40,0xc1,0xce,0x09,0x2c,0x04,0x1c,0x04,0x30,0x20,0x7d,0x51,0xf1,0x10,0x1f,0xe4,0x3c,0x1e,0xf4,0x08,0x24,0x02,0xd1,0x48,0x9d,0x40,0xe6,0x00,0xf7,0x90,0x42,0x20,0x1f,0x0a,0x7f,0x3a,0x01,0xc0,0x07,0xbc,0x42,0x21,0x00,0xfb,0xd3,0xe5,0xc0,0x71,0x28,0x3c,0x22,0x41,0x00,0xba,0xde,0x23,0xc0,0x71,0x1b,0x08,0x8c,0x60,0xf3,0xc8,0x07,0xfb,0xfe,0x00,0x1b,0xbd,0x2e,0x1c,0x17,0x20,0x10,0xd8,0x21,0x11,0x38,0x01,0x9c,0xb0,0x17,0x0a,0x44,0x18,0x6e,0x44,0x61,0x0d,0x10,0x01,0x03,0xe2,0x15,0x20,0x78,0x88,0x49,0x02,0xa1,0xf1,0x07,0x91,0x18,0x41,0xf0,0x1f,0x15,0x99,0x03,0xea,0xeb,0x48,0x07,0x95,0x00,0x3f,0x5c,0x88,0x05,0xf0,0x1f,0x77,0x00,0x78,0xe0,0x81,0xe7,0x80,0xa4,0xd5,0x78,0x53,0x1e,0x3e,0xe7,0x08,0x0f,0x29,0xcc,0x04,0x1e,0x54,0x0a,0x55,0x56,0x85,0x4a,0xc1,0x69,0x30,0x5f,0xfb,0xfe,0x02,0xf9,0x02,0xc0,0x03,0xca,0xd1,0x4e,0xe1,0x52,0x41,0xe3,0x81,0x15,0x8e,0x03,0xdc,0x0f,0x18,0x78,0x3c,0x6b,0x41,0xf3,0xda,0x07,0xcf,0xfd,0x02,0xb0,0x44,0x21,0x19,0x5a,0x4e,0x57,0x87,0x31,0xc1,0x6a,0x30,0x81,0xf2,0x07,0x8c,0x61,0xf0,0x40,0x01,0x4c,0x11,0x7c,0x60,0x60,0xf1,0x1f,0x8c,0x1a,0x40,0xe1,0x2c,0x02,0x20,0x80,0x83,0x7e,0x2d,0x8c,0xe7,0x03,0x01,0x90,0x06,0xcc,0xfe,0x97,0x20,0x78,0xff,0xac,0x10,0x09,0xf8,0x6c,0xc1,0xee,0x8f,0x1e,0x06,0x7d,0xdc,0xff,0xff,0x95,0x06,0x01,0x01,0x80,0xfc,0x21,0xf0,0x0e,0x47,0x1f,0x9f,0x03,0x85,0x42,0x24,0x3a,0x0b,0x95,0x08,0x4a,0x5f,0xc0,0xc1,0x5f,0xee,0xf0,0x60,0x7a,0x5e,0x81,0xe5,0xff,0x82,0xb8,0xca,0xff,0x05,0x85,0x62,0x24,0x40,0xf1,0xa5,0x02,0x87,0x81,0xff,0x2f,0x17,0x82,0xfd,0x01,0x85,0x52,0x24,0x80,0xf4,0xf8,0x5f,0xc1,0xe7,0xbe,0x80,0x03,0xd2,0x54,0x0a,0x1b,0xe7,0xe0,0xdc,0x41,0x41,0x07,0xc6,0x03,0xfe,0x0f,0x39,0xf8,0x3c,0x6a,0x11,0x40,0x7a,0x10,0x04,0x06,0x5f,0x8e,0xf9,0xbc,0x72,0x11,0x20,0x78,0xc6,0x92,0xa6,0x0f,0x31,0x20,0xc2,0xb4,0x00,0x11,0xff,0xc7,0xc1,0x64,0xa3,0x14,0x19,0x8b,0xc7,0x81,0x07,0xd0,0x40,0x22,0x01,0xa2,0x07,0xa0,0xfc,0x80,0xa2,0x1f,0x15,0x50,0xcf,0xfc,0x00,0xa1,0x00,0x0f,0xf8,0xbe,0x3f,0xa5,0x28,0xef,0xf8,0x10,0x8e,0x01,0x34,0x41,0xe8,0x3f,0x14,0x29,0x60,0x24,0x10,0x59,0x83,0x40,0x63,0x00,0xf2,0xfc,0xff,0xe0,0x61,0x21,0x00,0x0c,0xee,0x0b,0x08,0x80,0x40,0x81,0xe6,0x0a,0x18,0x38,0x14,0xa0,0x12,0x48,0x1c,0x12,0x01,0x04,0x09,0x08,0xa0,0x7e,0xe0,0xf5,0x9e,0x40,0xc0,0x63,0x08,0x07,0x9c,0x4f,0xe0,0x0f,0x55,0x51,0x44,0x01,0xe5,0xc0,0x8c,0xe4,0x20,0xc2,0xf4,0x07,0x8c,0x1a,0x40,0x32,0x14,0x90,0xc7,0x36,0x00,0x52,0x23,0x1a,0x84,0x52,0xc2,0x1f,0x28,0xff,0x40,0x14,0x40,0x01,0x6c,0x10,0x1d,0x12,0x83,0x2f,0x0f,0x18,0x00,0x8f,0xe2,0x60,0x10,0x10,0xc8,0x24,0x07,0x43,0x00,0x1f,0x80,0x3e,0x83,0x44,0x00,0x78,0x03,0xc0,0x1e,0x00,0x20,}; +const uint8_t _A_LaptopActive_128x52_7[] = {0x01,0x00,0x04,0x02,0x00,0x78,0x03,0x60,0x20,0x43,0xc0,0x40,0xc1,0xce,0x09,0x2c,0x04,0x1c,0x04,0x30,0x20,0x7d,0x51,0xf1,0x10,0x1f,0xe4,0x3c,0x1e,0xf4,0x08,0x24,0x02,0xd1,0x48,0x9d,0x40,0xe6,0x00,0xf7,0x90,0x42,0x20,0x1f,0x0a,0x7f,0x3a,0x01,0xc0,0x07,0xbc,0x42,0x21,0x00,0xfb,0xd3,0xe5,0xc0,0x71,0x28,0x3c,0x22,0x41,0x00,0xba,0xde,0x23,0xc0,0x71,0x1b,0x08,0x8c,0x60,0xf3,0xc8,0x07,0xfb,0xfe,0x00,0x1b,0xbd,0x2e,0x1c,0x17,0x20,0x10,0xd8,0x21,0x11,0x38,0x01,0x9c,0xb0,0x17,0x0a,0x44,0x18,0x6e,0x44,0x61,0x0d,0x10,0x01,0x03,0xe2,0x15,0x20,0x78,0x88,0x49,0x02,0xa1,0xf1,0x07,0x91,0x18,0x41,0xf0,0x1f,0x15,0x99,0x03,0xea,0xeb,0x48,0x07,0x95,0x00,0x3f,0x5c,0x88,0x05,0xf0,0x1f,0x77,0x00,0x78,0xe0,0x81,0xe7,0x80,0xa4,0xd5,0x78,0x53,0x1e,0x3e,0xe7,0x08,0x0f,0x29,0xcc,0x04,0x1e,0x54,0x0a,0x55,0x56,0x85,0x4a,0xc1,0x69,0x30,0x5f,0xfb,0xfe,0x02,0xf9,0x02,0xc0,0x03,0xca,0xd1,0x4e,0xe1,0x52,0x41,0xe3,0x81,0x15,0x8e,0x03,0xdc,0x0f,0x4a,0xd0,0x7c,0xf6,0x81,0xf3,0xff,0x40,0xb8,0x10,0xf8,0x46,0x56,0x93,0x95,0xe1,0xcc,0x70,0x5a,0x8c,0x20,0x7c,0x81,0xe3,0x30,0x88,0x17,0xcd,0x30,0x45,0xf1,0x81,0x83,0xc4,0x7e,0x30,0xc9,0x03,0x84,0xb0,0x08,0x82,0x02,0x0d,0xf8,0xb6,0x25,0xf1,0x81,0xc8,0x03,0x66,0x7f,0x4b,0x90,0x3c,0x7f,0xde,0x05,0x80,0x86,0xcc,0x1e,0xe8,0xf1,0x80,0x6f,0x9d,0xcf,0xff,0xf9,0x50,0x60,0x10,0x18,0x0e,0x02,0x43,0x00,0xe4,0x71,0xf9,0xf0,0x38,0x54,0x22,0x43,0xa0,0xb9,0x50,0x84,0xa5,0x60,0xfe,0x06,0x06,0xff,0x77,0x83,0x03,0xd2,0xf4,0x0f,0x28,0xc1,0x78,0xa8,0x17,0xf8,0x2c,0x2b,0x11,0x22,0x07,0x8d,0x28,0x1e,0x50,0x62,0xf1,0x78,0x2f,0xd0,0x18,0x55,0x22,0x48,0x0f,0x43,0xc8,0x83,0xcf,0x7d,0x00,0x07,0xa4,0xa8,0x14,0x37,0x82,0x90,0x81,0x07,0xe1,0x7f,0x07,0xc0,0x00,0x41,0xe7,0x3f,0x07,0x8d,0x42,0x28,0x0f,0x56,0xf8,0x80,0x07,0xf1,0xdf,0x37,0x8e,0x42,0x24,0x0f,0x18,0xd0,0x2c,0xb8,0x00,0xf3,0xff,0x93,0xc7,0x40,0x01,0x1f,0xfc,0x7c,0xfe,0x60,0x32,0x41,0x08,0xbc,0x78,0x10,0x7d,0x04,0x02,0x20,0x0b,0x25,0x98,0x83,0xc8,0x7e,0x40,0x51,0x0f,0x8c,0x3e,0x00,0x08,0x19,0x00,0x3c,0xbf,0xc5,0xf1,0xfd,0x29,0x47,0x7f,0xc0,0x84,0x70,0x07,0xa2,0x0f,0x41,0xf8,0xa1,0x4b,0x01,0x20,0x82,0xcc,0x0d,0xa2,0x33,0x3f,0xcf,0xfe,0x06,0x12,0x10,0x00,0xce,0xe0,0xb0,0x88,0x04,0x08,0x1e,0x60,0xa1,0x83,0xa2,0x4e,0x49,0x03,0x65,0x8c,0x10,0x24,0x22,0x81,0xfb,0x83,0xd6,0x79,0x03,0x01,0x8c,0x20,0x1e,0x71,0x3f,0x80,0x3d,0x55,0x45,0x10,0x07,0x97,0x02,0x33,0x90,0x83,0x0b,0xd0,0x1e,0x30,0x69,0x03,0xf8,0xe3,0x9b,0x00,0x29,0x11,0x8d,0x42,0x29,0x61,0x0f,0x94,0x7f,0xa0,0x0a,0x20,0x00,0xb6,0x08,0x0e,0x93,0xff,0x04,0xbc,0x3c,0x60,0x02,0x3f,0x89,0x80,0x40,0x43,0x20,0x90,0x46,0x01,0xed,0xe0,0x0f,0xa0,0xd1,0x00,0x1e,0x00,0xf0,0x07,0x80,0x08,}; +const uint8_t *_A_LaptopActive_128x52[] = {_A_LaptopActive_128x52_0,_A_LaptopActive_128x52_1,_A_LaptopActive_128x52_2,_A_LaptopActive_128x52_3,_A_LaptopActive_128x52_4,_A_LaptopActive_128x52_5,_A_LaptopActive_128x52_6,_A_LaptopActive_128x52_7}; -const uint8_t _A_Laptop_128x51_0[] = {0x01,0x00,0x41,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0x4f,0x04,0xfc,0x1f,0xbb,0xcf,0x50,0x3f,0x6a,0xf5,0x58,0x18,0x3a,0xf8,0x1a,0xad,0x54,0x38,0x1f,0x76,0x0a,0xad,0x56,0x2a,0x0f,0xbd,0x84,0xaa,0x00,0x01,0x10,0x05,0x56,0x2a,0xb4,0x4a,0xa0,0x3e,0xf5,0x90,0x28,0x07,0xa0,0x1f,0x75,0x48,0x8c,0x03,0xa0,0x0f,0xbd,0x50,0x08,0x74,0x00,0xfb,0xab,0x00,0x86,0x81,0x01,0x07,0xd4,0xae,0x3d,0x00,0xc0,0x03,0xee,0x2b,0x21,0x0f,0xe6,0x03,0x15,0x40,0x51,0x0a,0xc2,0xb0,0x15,0x5d,0xe5,0x43,0xaa,0x0f,0xba,0x57,0xfb,0x41,0xea,0x0f,0xe7,0xfe,0xa1,0x1d,0x49,0x0b,0x7a,0x69,0x5c,0xfd,0x44,0x0e,0x18,0x0f,0x9a,0x06,0x17,0xdf,0xd4,0x80,0x42,0x03,0xf5,0x0a,0xbf,0xce,0x81,0xf7,0x40,0x8a,0xcf,0x85,0xa3,0x0e,0x0f,0xdd,0x8e,0x05,0xc0,0xff,0x80,0x06,0x7e,0x0f,0x6b,0x06,0x17,0x01,0x00,0x9c,0x27,0xca,0x40,0x0f,0x6f,0x05,0x08,0x06,0x30,0x60,0x7d,0x54,0x2a,0xa8,0x21,0xc0,0x81,0xca,0x20,0x0f,0x6f,0x80,0x7c,0x6c,0x03,0x11,0x07,0xcd,0x62,0x0b,0x00,0x8c,0x34,0x44,0x00,0x27,0x27,0xf6,0x2a,0xc8,0x1f,0x75,0x48,0xa9,0x2d,0x60,0x80,0xf6,0xf5,0x42,0x81,0xfb,0x56,0xa2,0x92,0xd5,0xc4,0xfe,0xb0,0xf9,0x47,0x01,0xf5,0x55,0x1f,0x94,0x2c,0x0e,0x49,0x22,0x4f,0x27,0xfc,0x18,0x45,0xb3,0x07,0xb0,0xe8,0x6a,0x84,0xb4,0x49,0x18,0x00,0xc7,0x42,0xed,0x10,0x7d,0xc4,0xa0,0x19,0x4f,0xfc,0x04,0x1e,0x49,0x23,0x00,0x1c,0x6a,0x01,0x6c,0x80,0xc1,0x94,0x4c,0x00,0x39,0xd4,0x03,0xfc,0x4e,0x10,0x79,0x3b,0x9e,0x48,0x90,0x12,0x98,0x83,0xea,0xf1,0x00,0x95,0x82,0xc4,0xd6,0x4e,0xe7,0xc0,0x60,0x2a,0xa3,0xb1,0x07,0xc7,0xfc,0x00,0x3c,0x10,0x19,0x03,0xcb,0xf0,0x06,0x20,0x00,0x84,0x8a,0x7d,0xfc,0x04,0xa4,0x1c,0x5e,0xc0,0x01,0x47,0x90,0x7c,0x9d,0xce,0x29,0x78,0x18,0x3e,0x00,0x1e,0x00,0xb0,}; -const uint8_t _A_Laptop_128x51_1[] = {0x01,0x00,0x3c,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0x4f,0x04,0xfc,0x1f,0xbb,0xcf,0x50,0x3f,0x6a,0xf5,0x58,0x18,0x3a,0xf8,0x1a,0xad,0x54,0x38,0x1f,0x76,0x0a,0xac,0x46,0x2a,0x0f,0xbd,0x84,0xaa,0x01,0x28,0x07,0xdd,0x62,0x8b,0x00,0xaa,0x03,0xef,0x59,0x02,0x38,0x88,0x3e,0xc3,0x85,0xd0,0x07,0xde,0xa8,0x04,0x38,0x00,0x7d,0xc5,0x80,0x43,0x40,0x80,0x83,0xea,0x57,0x1e,0x0f,0x88,0x3e,0xe0,0xb2,0x10,0xfe,0x60,0x31,0x54,0x05,0x10,0xac,0x2b,0x01,0x45,0xde,0x40,0x38,0x20,0xfb,0xa5,0x7f,0xb0,0x1e,0xa0,0xfe,0x7f,0xea,0x11,0xd4,0x90,0xb7,0xa6,0x85,0xcf,0xd4,0x40,0xe1,0x80,0xf9,0xa0,0x61,0x7c,0xfd,0x48,0x04,0x20,0x3f,0x50,0x2b,0xfc,0xe8,0x1f,0x74,0x08,0x2c,0xf8,0x5a,0x30,0xe0,0xfd,0xd8,0xe0,0x5c,0x0f,0xf8,0x00,0x67,0xe0,0xf6,0xb0,0x60,0x59,0xa3,0x38,0x4f,0x94,0x80,0x1e,0xde,0x0a,0x10,0x0c,0x60,0xc0,0xfa,0xa8,0x51,0x50,0x43,0x81,0x03,0x94,0x40,0x1e,0xdf,0x00,0xf8,0xd8,0x1f,0xe6,0x0f,0x7a,0xc0,0xac,0x63,0x0d,0x11,0x00,0x09,0xc9,0xfd,0x8a,0xb2,0x07,0xdd,0x52,0x0a,0x4b,0x58,0x20,0x3d,0xbd,0x41,0xf2,0x07,0xdd,0x58,0x3e,0x44,0xb3,0x71,0x3f,0xac,0x10,0x51,0xc0,0x7d,0x55,0x43,0xe5,0x0b,0x03,0x92,0x48,0x93,0xc9,0xff,0x81,0x96,0xd4,0x1e,0xc3,0xa1,0x24,0x10,0x08,0x92,0x46,0x00,0x31,0xd0,0xbb,0x44,0x1f,0x71,0x28,0x07,0xd2,0xfe,0x0f,0x34,0x91,0x80,0x0e,0x35,0x00,0xae,0x60,0x20,0x2a,0x26,0x00,0x1c,0xea,0x01,0x3e,0x35,0x0a,0x49,0x80,0x07,0x24,0x80,0x45,0x85,0xc2,0x0f,0xab,0xc1,0xf0,0xa1,0x06,0xb2,0x77,0x3e,0x03,0x01,0x15,0x05,0x88,0x3e,0x3f,0xe0,0x01,0xe0,0x80,0xc8,0x1e,0x5f,0x80,0x31,0x00,0x04,0x24,0x53,0xef,0xe0,0x25,0x20,0xe2,0xf6,0x00,0x0a,0x3c,0x83,0xe4,0xee,0x71,0x4b,0xb1,0x48,0x01,0xe0,0x0f,0x00,0x10,}; -const uint8_t *_A_Laptop_128x51[] = {_A_Laptop_128x51_0,_A_Laptop_128x51_1}; +const uint8_t _A_Laptop_128x52_0[] = {0x01,0x00,0x3e,0x02,0x00,0x78,0x03,0x60,0x20,0x43,0xc0,0x40,0xc1,0xce,0x09,0x2c,0x04,0x1c,0x04,0x30,0x20,0x7d,0x51,0xf1,0x10,0x1f,0xe4,0x3c,0x1e,0xf4,0x08,0x24,0x02,0xd1,0x48,0x9d,0x40,0xe6,0x00,0xf7,0x90,0x42,0x20,0x1f,0x0a,0x7f,0x3a,0x01,0xc0,0x07,0xbc,0x42,0x21,0x00,0xfb,0xd3,0xe5,0xc0,0x71,0x28,0x3c,0x22,0x41,0x00,0xba,0xde,0x23,0xc0,0x71,0x1b,0x08,0x8c,0x60,0xf3,0xc8,0x07,0xfb,0xfe,0x00,0x1b,0xbd,0x2e,0x1c,0x17,0x20,0x10,0xd8,0x21,0x11,0x38,0x01,0x9c,0xb0,0x17,0x0a,0x44,0x18,0x6e,0x40,0x82,0xc8,0x05,0x07,0xf4,0x1e,0x1d,0xf8,0x7c,0x42,0xa4,0x0f,0x28,0x05,0x44,0x1e,0x30,0xa0,0x28,0xe8,0x03,0xe2,0x0f,0x22,0x30,0x80,0x06,0xa4,0x44,0x18,0x54,0x0b,0x01,0xa0,0x0f,0x8a,0xcc,0x81,0xe7,0x54,0x0b,0x8c,0x2a,0x0d,0xc1,0xd4,0x5d,0x69,0x00,0xf2,0xa0,0x03,0xcb,0xd0,0x07,0x1c,0x56,0xab,0x55,0xa4,0xbb,0xf2,0x20,0x17,0xc0,0x79,0xf8,0x2e,0xcc,0x81,0x85,0x74,0xf2,0xda,0xab,0x80,0x3c,0x70,0x40,0xf3,0xcc,0x7b,0x6e,0x30,0x0a,0x56,0x0a,0x05,0xa7,0x07,0x94,0x06,0x02,0x0f,0x28,0x87,0xef,0x79,0x01,0xc5,0x60,0x60,0x5a,0xaf,0xfd,0xfd,0x04,0x25,0x61,0x29,0x15,0xde,0x3d,0x03,0x95,0x03,0xc7,0x4c,0x2b,0x1c,0x07,0xa0,0x1e,0x74,0x0b,0x76,0x3c,0x9e,0x20,0xf1,0xd0,0x87,0xcb,0xf9,0x03,0xe0,0x43,0xd3,0xe3,0xf8,0xa7,0x93,0xc7,0x85,0x86,0xd0,0x07,0xc8,0x1e,0x33,0x05,0x01,0x7d,0xe6,0xe0,0xf1,0xd2,0x52,0xb4,0x10,0x30,0x78,0xdf,0x20,0x50,0xc4,0x80,0xf0,0x3f,0xd3,0xb0,0x78,0xea,0x21,0x5a,0x0b,0xf1,0x6c,0x6f,0x30,0x18,0x18,0x3c,0x7c,0x1f,0x18,0xf8,0x3c,0x72,0x11,0x2d,0x05,0xc8,0x1e,0x3f,0xef,0x02,0xc0,0xb0,0x1e,0xf2,0x18,0x83,0xd9,0x1e,0x30,0x09,0xf2,0x90,0x7f,0xca,0xf1,0x85,0x62,0x24,0x5a,0x0f,0x95,0x05,0x1e,0x58,0x09,0x0c,0x03,0x91,0xc7,0xe7,0xc0,0xe1,0x50,0x89,0x08,0x7c,0x68,0x4c,0xb2,0xb0,0x7f,0x3f,0xe7,0x71,0xbb,0xc1,0x81,0xe9,0x7a,0x07,0x94,0x61,0xf6,0x27,0x71,0xbf,0xc1,0x45,0xe7,0x72,0xa5,0x13,0x0a,0x0c,0xfb,0x13,0x00,0xdf,0xa0,0x30,0xaa,0x44,0x90,0x1e,0x7c,0x0e,0x04,0x04,0x1e,0x7b,0xe2,0x78,0x83,0xce,0x54,0x0a,0x19,0xf9,0x48,0x40,0x83,0xf0,0xbf,0x83,0xe0,0x00,0x20,0xf3,0x0a,0x8c,0x2a,0xa1,0x14,0x07,0xab,0x7c,0xa0,0x1f,0x8e,0xf9,0xbc,0x51,0xe7,0x1a,0x05,0x97,0x00,0x1e,0x7f,0xf2,0x78,0xe8,0x00,0x23,0xff,0x5b,0x09,0xfc,0x80,0x65,0xfc,0xff,0x0b,0xc7,0x81,0x07,0x77,0x8b,0xa8,0x8f,0x62,0x0f,0x39,0xe0,0x3c,0x40,0xa2,0x1f,0x16,0x30,0x92,0x05,0x02,0x20,0x01,0xff,0x5f,0x20,0x1f,0xa5,0x28,0xef,0xf8,0x10,0x83,0xf0,0x83,0xd7,0xf8,0x85,0x3c,0x04,0x82,0x0b,0x30,0x36,0x88,0xcc,0xff,0x3f,0xe8,0x1f,0xf8,0x3e,0x3f,0xf9,0xdc,0x16,0x11,0x00,0x81,0x03,0xcc,0x14,0x30,0x74,0x49,0xc9,0x20,0x6c,0xb1,0x82,0x04,0x84,0x50,0x3f,0x70,0x7a,0xcf,0x20,0x60,0x31,0x84,0x03,0xce,0x27,0xf0,0x07,0xaa,0xa8,0xa2,0x00,0xf2,0xe0,0x46,0x72,0x10,0x61,0x7a,0x03,0xc6,0x0d,0x20,0x7f,0x1c,0x73,0x60,0x05,0x22,0x31,0xa8,0x45,0x2c,0x21,0xf2,0x8f,0xf4,0x01,0x44,0x00,0x16,0xc1,0x01,0xd2,0x7f,0xe0,0x97,0x87,0x8c,0x00,0x47,0xf1,0x30,0x08,0x08,0x64,0x12,0x08,0xc0,0x3d,0xbc,0x01,0xf4,0x1a,0x20,0x03,0xc0,0x1e,0x00,0xf0,0x01,0x00,}; +const uint8_t _A_Laptop_128x52_1[] = {0x01,0x00,0x40,0x02,0x00,0x78,0x03,0x60,0x20,0x43,0xc0,0x40,0xc1,0xce,0x09,0x2c,0x04,0x1c,0x04,0x30,0x20,0x7d,0x51,0xf1,0x10,0x1f,0xe4,0x3c,0x1e,0xf4,0x08,0x24,0x02,0xd1,0x48,0x9d,0x40,0xe6,0x00,0xf7,0x90,0x42,0x20,0x1f,0x0a,0x7f,0x3a,0x01,0xc0,0x07,0xbc,0x42,0x21,0x00,0xfb,0xd3,0xe5,0xc0,0x71,0x28,0x3c,0x22,0x41,0x00,0xba,0xde,0x23,0xc0,0x71,0x1b,0x08,0x8c,0x60,0xf3,0xc8,0x07,0xfb,0xfe,0x00,0x1b,0xbd,0x2e,0x1c,0x17,0x20,0x10,0xd8,0x21,0x11,0x38,0x01,0x9c,0xb0,0x17,0x0a,0x44,0x18,0x6e,0x40,0x82,0xc8,0x05,0x07,0xf4,0x1e,0x1d,0xf8,0x7c,0x42,0xa4,0x0f,0x28,0x05,0x44,0x1e,0x30,0xa0,0x28,0xe8,0x03,0xe2,0x0f,0x22,0x30,0x80,0x06,0xa4,0x44,0x18,0x54,0x0b,0x01,0xa0,0x0f,0x8a,0xcc,0x81,0xe7,0x54,0x0b,0x8c,0x2a,0x0d,0xc1,0xd4,0x5d,0x69,0x00,0xf2,0xa0,0x03,0xcb,0xd0,0x07,0x1c,0x56,0xab,0x55,0xa4,0xbb,0xf2,0x20,0x17,0xc0,0x79,0xf8,0x2e,0xcc,0x81,0x85,0x74,0xf2,0xda,0xab,0x80,0x3c,0x70,0x40,0xf3,0xcc,0x7b,0x6e,0x30,0x0a,0x56,0x0a,0x05,0xa7,0x07,0x94,0x06,0x02,0x0f,0x28,0x87,0xef,0x79,0x01,0xc5,0x60,0x60,0x5a,0xaf,0xfd,0xfd,0x04,0x25,0x61,0x29,0x15,0xde,0x3d,0x03,0x95,0x03,0xc7,0x4c,0x2b,0x1c,0x07,0xa0,0x1e,0x74,0x0b,0x76,0x3c,0x9e,0x20,0xf1,0xd0,0x87,0xcb,0xf9,0x03,0xe0,0x43,0xd3,0xe3,0xf8,0xa7,0x93,0xc7,0x85,0x86,0xd0,0x07,0xc8,0x1e,0x33,0x05,0x01,0x7d,0xe6,0xe0,0xf1,0xd2,0x52,0xb4,0x10,0x30,0x78,0xdf,0x20,0x50,0xc4,0x80,0xf0,0x3f,0xd3,0xb0,0x78,0xea,0x21,0x5a,0x0b,0xf1,0x6c,0x6f,0x30,0x18,0x18,0x3c,0x7c,0x1f,0x18,0xf8,0x3c,0x72,0x11,0x2d,0x05,0xc8,0x1e,0x3f,0xef,0x02,0xc0,0xb0,0x1e,0xf2,0x18,0x83,0xd9,0x1e,0x30,0x09,0xf2,0x90,0x7f,0xca,0xf1,0x85,0x62,0x24,0x5a,0x0f,0x95,0x05,0x1e,0x58,0x09,0x0c,0x03,0x91,0xc7,0xe7,0xc0,0xe1,0x50,0x89,0x08,0x7c,0x68,0x4c,0xb2,0xb0,0x7f,0x3f,0xe7,0x71,0xbb,0xc1,0x81,0xe9,0x7a,0x07,0x94,0x61,0xf6,0x27,0x71,0xbf,0xc1,0x45,0xe7,0x72,0xa5,0x13,0x0a,0x0c,0xfb,0x13,0x00,0xdf,0xa0,0x30,0xaa,0x44,0x90,0x1e,0x7c,0x0e,0x04,0x04,0x1e,0x7b,0xe2,0x78,0x83,0xce,0x54,0x0a,0x19,0xf9,0x48,0x40,0x83,0xf0,0xbf,0x83,0xe0,0x00,0x20,0xf3,0x0a,0x8c,0x2a,0xa1,0x14,0x07,0xab,0x7c,0xa0,0x1f,0x8e,0xd9,0xbc,0x51,0xe7,0x1a,0x05,0x97,0x00,0x1e,0x7f,0xd2,0x78,0xe8,0x00,0x23,0xff,0x5b,0x09,0xfc,0x80,0x65,0xfc,0xfe,0x8b,0xc7,0x81,0x07,0x77,0x8b,0xa8,0x7f,0x10,0x15,0x98,0x83,0xca,0x78,0x0f,0x10,0x28,0x87,0xc5,0x8c,0x30,0x68,0x32,0x04,0x40,0x03,0x7e,0xbe,0x40,0x3f,0x4a,0x51,0xdf,0xf0,0x21,0x18,0x08,0x0c,0x20,0x1e,0x9f,0xc4,0x29,0xe0,0x24,0x10,0x51,0x60,0xc4,0x06,0x62,0x00,0x1f,0xcf,0xfa,0x07,0xfe,0x0f,0x8f,0xfe,0x77,0x05,0x0e,0x0c,0x80,0x1e,0x60,0xa1,0x83,0xa2,0x4e,0x49,0x03,0x65,0x14,0x20,0x50,0x5f,0x70,0x7a,0xcf,0x01,0xe5,0x80,0x07,0x9c,0x4f,0xe0,0x0f,0x55,0x50,0xcc,0x20,0x10,0x94,0x91,0x46,0x72,0x10,0x61,0x7a,0x03,0xc4,0xa0,0x20,0x92,0xa0,0x47,0x36,0x10,0x40,0x79,0x94,0x88,0x92,0x9c,0x08,0xff,0x40,0x14,0x8d,0x82,0x03,0xa4,0xff,0xc1,0x2f,0x0f,0x18,0x00,0x87,0xc3,0x00,0x14,0x94,0x82,0x41,0x18,0x07,0xb7,0x80,0x3e,0x91,0xf6,0x58,0x83,0xd8,0x01,0xe0,0x0f,0x00,0x68,}; +const uint8_t _A_Laptop_128x52_2[] = {0x01,0x00,0x41,0x02,0x00,0x78,0x03,0x60,0x20,0x43,0xc0,0x40,0xc1,0xce,0x09,0x2c,0x04,0x1c,0x04,0x30,0x20,0x7d,0x51,0xf1,0x10,0x1f,0xe4,0x3c,0x1e,0xf4,0x08,0x24,0x02,0xd1,0x48,0x9d,0x40,0xe6,0x00,0xf7,0x90,0x42,0x20,0x1f,0x0a,0x7f,0x3a,0x01,0xc0,0x07,0xbc,0x42,0x21,0x00,0xfb,0xd3,0xe5,0xc0,0x71,0x28,0x3c,0x22,0x41,0x00,0xba,0xde,0x23,0xc0,0x71,0x1b,0x08,0x8c,0x60,0xf3,0xc8,0x07,0xfb,0xfe,0x00,0x1b,0xbd,0x2e,0x1c,0x17,0x20,0x10,0xd8,0x21,0x11,0x38,0x01,0x9c,0xb0,0x17,0x0a,0x44,0x18,0x6e,0x40,0x82,0xc8,0x05,0x07,0xf4,0x1e,0x1d,0xf8,0x7c,0x42,0xa4,0x0f,0x28,0x05,0x44,0x1e,0x30,0xa0,0x28,0xe8,0x03,0xe2,0x0f,0x22,0x30,0x80,0x06,0xa4,0x44,0x18,0x54,0x0b,0x01,0xa0,0x0f,0x8a,0xcc,0x81,0xe7,0x54,0x0b,0x8c,0x2a,0x0d,0xc1,0xd4,0x5d,0x69,0x00,0xf2,0xa0,0x03,0xcb,0xd0,0x07,0x1c,0x56,0xab,0x55,0xa4,0xbb,0xf2,0x20,0x17,0xc0,0x79,0xf8,0x2e,0xcc,0x81,0x85,0x74,0xf2,0xda,0xab,0x80,0x3c,0x70,0x40,0xf3,0xcc,0x7b,0x6e,0x30,0x0a,0x56,0x0a,0x05,0xa7,0x07,0x94,0x06,0x02,0x0f,0x28,0x87,0xef,0x79,0x01,0xc5,0x60,0x60,0x5a,0xaf,0xfd,0xfd,0x04,0x25,0x61,0x29,0x15,0xde,0x3d,0x03,0x95,0x03,0xc7,0x4c,0x2b,0x1c,0x07,0xa0,0x1e,0x74,0x0b,0x76,0x3c,0x9e,0x20,0xf1,0xd0,0x87,0xcb,0xf9,0x03,0xe0,0x43,0xd3,0xe3,0xf8,0xa7,0x93,0xc7,0x85,0x86,0xd0,0x07,0xc8,0x1e,0x33,0x05,0x01,0x7d,0xe6,0xe0,0xf1,0xd2,0x52,0xb4,0x10,0x30,0x78,0xdf,0x20,0x50,0xc4,0x80,0xf0,0x3f,0xd3,0xb0,0x78,0xea,0x21,0x5a,0x0b,0xf1,0x6c,0x6f,0x30,0x18,0x18,0x3c,0x7c,0x1f,0x18,0xf8,0x3c,0x72,0x11,0x2d,0x05,0xc8,0x1e,0x3f,0xef,0x02,0xc0,0xb0,0x1e,0xf2,0x18,0x83,0xd9,0x1e,0x30,0x09,0xf2,0x90,0x7f,0xca,0xf1,0x85,0x62,0x24,0x5a,0x0f,0x95,0x05,0x1e,0x58,0x09,0x0c,0x03,0x91,0xc7,0xe7,0xc0,0xe1,0x50,0x89,0x08,0x7c,0x68,0x4c,0xb2,0xb0,0x7f,0x3f,0xe7,0x71,0xbb,0xc1,0x81,0xe9,0x7a,0x07,0x94,0x61,0xf6,0x27,0x71,0xbf,0xc1,0x45,0xe7,0x72,0xa5,0x13,0x0a,0x0c,0xfb,0x13,0x00,0xdf,0xa0,0x30,0xaa,0x44,0x90,0x1e,0x7c,0x0e,0x04,0x04,0x1e,0x7b,0xe2,0x78,0x83,0xce,0x54,0x0a,0x19,0xf9,0x48,0x40,0x83,0xf0,0xbf,0x83,0xe0,0x00,0x20,0xf3,0x57,0x95,0x42,0x28,0x0f,0x56,0xf9,0x40,0x3f,0x1d,0x33,0x78,0xa3,0xce,0x34,0x0b,0x2e,0x00,0x3c,0xfe,0x24,0xf1,0xd0,0x00,0x47,0xfe,0xb6,0x13,0xf9,0x00,0xcb,0xf9,0xf8,0x17,0x8f,0x02,0x0e,0xef,0x17,0x51,0x1e,0xc4,0x06,0x57,0xc9,0xe0,0x3c,0x40,0xa2,0x1f,0x16,0x30,0xdf,0x90,0x24,0x00,0x1b,0xf5,0xf2,0x01,0xfa,0x52,0x8e,0xff,0x81,0x08,0xc0,0x60,0x60,0x20,0xf4,0x68,0x0a,0x14,0xb0,0x12,0x08,0x28,0xf0,0x60,0x43,0x33,0xfc,0xff,0xa0,0x7f,0xe0,0xf8,0xff,0xe7,0x70,0x50,0x60,0xc1,0x01,0xe6,0x0a,0x18,0x3a,0x24,0xe4,0x90,0x38,0x44,0x02,0x10,0x02,0x11,0x40,0xfd,0xc1,0xeb,0x3c,0x81,0x80,0xc6,0x20,0x0f,0x38,0x9f,0xc0,0x1e,0xaa,0xa2,0x90,0x03,0xcb,0x81,0x19,0xc8,0x41,0x85,0xe8,0x0f,0x18,0x65,0x01,0xfc,0x71,0xcd,0x80,0x14,0x88,0xc7,0xff,0x9f,0xe0,0x05,0x25,0xc0,0x8f,0xf4,0x01,0x44,0x00,0x16,0xc1,0x01,0xd2,0x7f,0xe0,0x97,0x87,0x8c,0x00,0x53,0x00,0x10,0x8a,0x4a,0x41,0x20,0x8c,0x03,0xdb,0xc0,0x1f,0x48,0xfb,0x2c,0x41,0xec,0x00,0xf0,0x07,0x80,0x34,}; +const uint8_t _A_Laptop_128x52_3[] = {0x01,0x00,0x3f,0x02,0x00,0x78,0x03,0x60,0x20,0x43,0xc0,0x40,0xc1,0xce,0x09,0x2c,0x04,0x1c,0x04,0x30,0x20,0x7d,0x51,0xf1,0x10,0x1f,0xe4,0x3c,0x1e,0xf4,0x08,0x24,0x02,0xd1,0x48,0x9d,0x40,0xe6,0x00,0xf7,0x90,0x42,0x20,0x1f,0x0a,0x7f,0x3a,0x01,0xc0,0x07,0xbc,0x42,0x21,0x00,0xfb,0xd3,0xe5,0xc0,0x71,0x28,0x3c,0x22,0x41,0x00,0xba,0xde,0x23,0xc0,0x71,0x1b,0x08,0x8c,0x60,0xf3,0xc8,0x07,0xfb,0xfe,0x00,0x1b,0xbd,0x2e,0x1c,0x17,0x20,0x10,0xd8,0x21,0x11,0x38,0x01,0x9c,0xb0,0x17,0x0a,0x44,0x18,0x6e,0x40,0x82,0xc8,0x05,0x07,0xf4,0x1e,0x1d,0xf8,0x7c,0x42,0xa4,0x0f,0x28,0x05,0x44,0x1e,0x30,0xa0,0x28,0xe8,0x03,0xe2,0x0f,0x22,0x30,0x80,0x06,0xa4,0x44,0x18,0x54,0x0b,0x01,0xa0,0x0f,0x8a,0xcc,0x81,0xe7,0x54,0x0b,0x8c,0x2a,0x0d,0xc1,0xd4,0x5d,0x69,0x00,0xf2,0xa0,0x03,0xcb,0xd0,0x07,0x1c,0x56,0xab,0x55,0xa4,0xbb,0xf2,0x20,0x17,0xc0,0x79,0xf8,0x2e,0xcc,0x81,0x85,0x74,0xf2,0xda,0xab,0x80,0x3c,0x70,0x40,0xf3,0xcc,0x7b,0x6e,0x30,0x0a,0x56,0x0a,0x05,0xa7,0x07,0x94,0x06,0x02,0x0f,0x28,0x87,0xef,0x79,0x01,0xc5,0x60,0x60,0x5a,0xaf,0xfd,0xfd,0x04,0x25,0x61,0x29,0x15,0xde,0x3d,0x03,0x95,0x03,0xc7,0x4c,0x2b,0x1c,0x07,0xa0,0x1e,0x74,0x0b,0x76,0x3c,0x9e,0x20,0xf1,0xd0,0x87,0xcb,0xf9,0x03,0xe0,0x43,0xd3,0xe3,0xf8,0xa7,0x93,0xc7,0x85,0x86,0xd0,0x07,0xc8,0x1e,0x33,0x05,0x01,0x7d,0xe6,0xe0,0xf1,0xd2,0x52,0xb4,0x10,0x30,0x78,0xdf,0x20,0x50,0xc4,0x80,0xf0,0x3f,0xd3,0xb0,0x78,0xea,0x21,0x5a,0x0b,0xf1,0x6c,0x6f,0x30,0x18,0x18,0x3c,0x7c,0x1f,0x18,0xf8,0x3c,0x72,0x11,0x2d,0x05,0xc8,0x1e,0x3f,0xef,0x02,0xc0,0xb0,0x1e,0xf2,0x18,0x83,0xd9,0x1e,0x30,0x09,0xf2,0x90,0x7f,0xca,0xf1,0x85,0x62,0x24,0x5a,0x0f,0x95,0x05,0x1e,0x58,0x09,0x0c,0x03,0x91,0xc7,0xe7,0xc0,0xe1,0x50,0x89,0x08,0x7c,0x68,0x4c,0xb2,0xb0,0x7f,0x3f,0xe7,0x71,0xbb,0xc1,0x81,0xe9,0x7a,0x07,0x94,0x61,0xf6,0x27,0x71,0xbf,0xc1,0x45,0xe7,0x72,0xa5,0x13,0x0a,0x0c,0xfb,0x13,0x00,0xdf,0xa0,0x30,0xaa,0x44,0x90,0x1e,0x7c,0x0e,0x04,0x04,0x1e,0x7b,0xe2,0x78,0x83,0xce,0x54,0x0a,0x19,0xf9,0x48,0x40,0x83,0xf0,0xbe,0x83,0xe0,0x00,0x20,0xf3,0x9c,0x83,0xc6,0xa1,0x14,0x07,0xab,0x7c,0xa0,0x1f,0x8e,0xc9,0xbc,0x51,0xe7,0x1a,0x05,0x97,0x00,0x1e,0x7f,0x82,0x78,0xe8,0x00,0x23,0xff,0x5b,0x09,0xfc,0x80,0x65,0xfc,0xfe,0x0b,0xc7,0x81,0x07,0x77,0x8b,0xa8,0x8f,0x62,0x0f,0x39,0xe8,0x3c,0x40,0xa2,0x1f,0x16,0x30,0x8a,0x05,0x02,0x20,0x01,0xff,0x5f,0xe0,0x1f,0xa5,0x28,0xef,0xf8,0x10,0x84,0x68,0xc1,0x81,0xe9,0xff,0x42,0x9e,0x02,0x41,0x05,0xc0,0x40,0x61,0x03,0x33,0xfc,0xff,0xe0,0x61,0x21,0x00,0x0c,0xee,0x0a,0x3c,0x18,0x80,0x3c,0xc1,0x43,0x07,0x44,0x9c,0x92,0x06,0x2c,0x19,0x00,0xcc,0x45,0x03,0xf7,0x07,0xac,0xf2,0x06,0x5e,0x20,0x79,0xc4,0xfe,0x00,0xf5,0x55,0x16,0x00,0x1e,0x5c,0x08,0xce,0x42,0x0c,0x2f,0x40,0x78,0xcc,0x20,0x10,0x51,0x19,0x47,0x36,0x10,0x40,0x79,0x94,0x8b,0xfe,0x71,0x10,0xf9,0x47,0xfa,0x00,0xa3,0x05,0x8b,0x60,0x40,0xe9,0x3f,0xf0,0x4b,0xc3,0xc6,0x00,0x21,0x70,0xc0,0x05,0x25,0x20,0x90,0x46,0x01,0xed,0xe0,0x0f,0xa4,0x7d,0x96,0x20,0xf6,0x00,0x78,0x03,0xc0,0x1a,}; +const uint8_t _A_Laptop_128x52_4[] = {0x01,0x00,0x44,0x02,0x00,0x78,0x03,0x60,0x20,0x43,0xc0,0x40,0xc1,0xce,0x09,0x2c,0x04,0x1c,0x04,0x30,0x20,0x7d,0x51,0xf1,0x10,0x1f,0xe4,0x3c,0x1e,0xf4,0x08,0x24,0x02,0xd1,0x48,0x9d,0x40,0xe6,0x00,0xf7,0x90,0x42,0x20,0x1f,0x0a,0x7f,0x3a,0x01,0xc0,0x07,0xbc,0x42,0x21,0x00,0xfb,0xd3,0xe5,0xc0,0x71,0x28,0x3c,0x22,0x41,0x00,0xba,0xde,0x23,0xc0,0x71,0x1b,0x08,0x8c,0x60,0xf3,0xc8,0x07,0xfb,0xfe,0x00,0x1b,0xbd,0x2e,0x1c,0x17,0x20,0x10,0xd8,0x21,0x11,0x38,0x01,0x9c,0xb0,0x17,0x0a,0x44,0x18,0x6e,0x40,0x82,0xc8,0x05,0x07,0xf4,0x1e,0x1d,0xf8,0x7c,0x42,0xa4,0x0f,0x28,0x05,0x44,0x1e,0x30,0xa0,0x28,0xe8,0x03,0xe2,0x0f,0x22,0x30,0x80,0x06,0xa4,0x44,0x18,0x54,0x0b,0x01,0xa0,0x0f,0x8a,0xcc,0x81,0xe7,0x54,0x0b,0x8c,0x2a,0x0d,0xc1,0xd4,0x5d,0x69,0x00,0xf2,0xa0,0x03,0xcb,0xd0,0x07,0x1c,0x56,0xab,0x55,0xa4,0xbb,0xf2,0x20,0x17,0xc0,0x79,0xf8,0x2e,0xcc,0x81,0x85,0x74,0xf2,0xda,0xab,0x80,0x3c,0x70,0x40,0xf3,0xcc,0x7b,0x6e,0x30,0x0a,0x56,0x0a,0x05,0xa7,0x07,0x94,0x06,0x02,0x0f,0x28,0x87,0xef,0x79,0x01,0xc5,0x60,0x60,0x5a,0xaf,0xfd,0xff,0x00,0x87,0x10,0x10,0x94,0x86,0xef,0x1e,0x81,0xca,0x81,0xe3,0xa6,0x15,0x8e,0x02,0xc0,0x0f,0x3a,0x05,0xbb,0x1e,0x4f,0x10,0x78,0xe8,0x43,0xe5,0xf8,0x81,0x70,0x21,0xe9,0xf1,0xfc,0x53,0xc9,0xe3,0xc2,0xc3,0x68,0x03,0xe5,0xfc,0x81,0xcc,0x14,0x05,0xf7,0x9b,0x83,0xc7,0x49,0x4a,0xd0,0x40,0xc1,0xe3,0x7c,0x81,0x43,0x12,0x03,0xc0,0xff,0x4e,0xc1,0xe3,0xa8,0x85,0x68,0x2f,0xc5,0xb1,0xbe,0xc0,0x60,0x60,0xf1,0xf0,0x7c,0x63,0xe0,0xf1,0xc8,0x44,0xb4,0x17,0x20,0x78,0xff,0xbc,0x0b,0x02,0xc0,0x7b,0xc8,0x62,0x0f,0x64,0x78,0xc0,0x27,0xca,0x41,0xff,0x2b,0xc6,0x15,0x88,0x91,0x68,0x3e,0x54,0x14,0x79,0x60,0x24,0x30,0x0e,0x47,0x1f,0x9f,0x03,0x85,0x42,0x24,0x21,0xf1,0xa1,0x32,0xca,0xc1,0xfc,0xff,0x9d,0xc6,0xef,0x06,0x07,0xa5,0xe8,0x1e,0x51,0x87,0xd8,0x9d,0xc6,0xff,0x05,0x17,0x9d,0xca,0x94,0x4c,0x28,0x33,0xec,0x4c,0x03,0x7e,0x80,0xc2,0xa9,0x12,0x40,0x79,0xf0,0x38,0x10,0x10,0x79,0xef,0x89,0xe2,0x0f,0x39,0x50,0x28,0x67,0xe5,0x21,0x02,0x0f,0xc2,0xf8,0x0f,0x80,0x00,0x83,0xce,0x72,0x0f,0x1a,0x84,0x50,0x1e,0xad,0xf2,0x80,0x7e,0x3b,0x66,0xf1,0x47,0x9c,0x68,0x16,0x5c,0x00,0x79,0xff,0xc9,0xe3,0xa0,0x00,0x8f,0xfd,0x6c,0x23,0xe1,0xb0,0x03,0xc9,0x04,0x22,0xf1,0xe0,0x41,0xdd,0xe3,0x10,0x2f,0x09,0xec,0x41,0xe6,0x16,0x18,0x50,0x14,0x43,0xe3,0x0f,0x98,0x13,0x45,0x02,0x20,0x01,0xff,0x5f,0xe0,0x1f,0xa5,0x28,0xef,0xf8,0x10,0x88,0x44,0x02,0x04,0x0f,0x41,0xf8,0xa1,0x4b,0x01,0x20,0x82,0xaa,0xc6,0x09,0x10,0x07,0x97,0xe7,0xff,0x03,0x09,0x08,0x00,0x67,0x70,0x50,0x50,0xc2,0x01,0xe6,0x0a,0x18,0x3a,0x24,0xe4,0x90,0x30,0x18,0xc4,0x06,0x42,0x28,0x1f,0xb8,0x3d,0x67,0x80,0xf1,0x83,0x48,0x01,0xe7,0x13,0xf8,0x03,0xd5,0x54,0x30,0x8a,0x00,0x3c,0xb8,0x11,0x9c,0x84,0x18,0x5e,0x80,0xf1,0x98,0x48,0x1f,0xc7,0x1c,0xd8,0x01,0x48,0x8c,0x60,0x02,0x14,0x97,0x02,0x3f,0xd0,0x05,0x23,0x60,0x80,0xe9,0x3f,0xf0,0x4b,0xc3,0xc6,0x00,0x24,0xf8,0xa0,0x04,0x04,0x32,0x09,0x04,0x60,0x1e,0xde,0x00,0xfa,0x47,0xd9,0x62,0x0f,0x60,0x07,0x80,0x3c,0x01,0xa0,}; +const uint8_t _A_Laptop_128x52_5[] = {0x01,0x00,0x3d,0x02,0x00,0x78,0x03,0x60,0x20,0x43,0xc0,0x40,0xc1,0xce,0x09,0x2c,0x04,0x1c,0x04,0x30,0x20,0x7d,0x51,0xf1,0x10,0x1f,0xe4,0x3c,0x1e,0xf4,0x08,0x24,0x02,0xd1,0x48,0x9d,0x40,0xe6,0x00,0xf7,0x90,0x42,0x20,0x1f,0x0a,0x7f,0x3a,0x01,0xc0,0x07,0xbc,0x42,0x21,0x00,0xfb,0xd3,0xe5,0xc0,0x71,0x28,0x3c,0x22,0x41,0x00,0xba,0xde,0x23,0xc0,0x71,0x1b,0x08,0x8c,0x60,0xf3,0xc8,0x07,0xfb,0xfe,0x00,0x1b,0xbd,0x2e,0x1c,0x17,0x20,0x10,0xd8,0x21,0x11,0x38,0x01,0x9c,0xb0,0x17,0x0a,0x44,0x18,0x6e,0x40,0x82,0xc8,0x05,0x07,0xf4,0x1e,0x1d,0xf8,0x7c,0x42,0xa4,0x0f,0x28,0x05,0x44,0x1e,0x30,0xa0,0x28,0xe8,0x03,0xe2,0x0f,0x22,0x30,0x80,0x06,0xa4,0x44,0x18,0x54,0x0b,0x01,0xa0,0x0f,0x8a,0xcc,0x81,0xe7,0x54,0x0b,0x8c,0x2a,0x0d,0xc1,0xd4,0x5d,0x69,0x00,0xf2,0xa0,0x03,0xcb,0xd0,0x07,0x1c,0x56,0xab,0x55,0xa4,0xbb,0xf2,0x20,0x17,0xc0,0x79,0xf8,0x2e,0xcc,0x81,0x85,0x74,0xf2,0xda,0xab,0x80,0x3c,0x70,0x40,0xf3,0xcc,0x7b,0x6e,0x30,0x0a,0x56,0x0a,0x05,0xa7,0x07,0x94,0x06,0x02,0x0f,0x28,0x87,0xef,0x79,0x01,0xc5,0x60,0x60,0x5a,0xaf,0xfd,0xff,0x00,0x87,0x10,0x10,0x94,0x86,0xef,0x1e,0x81,0xca,0x81,0xe3,0xa6,0x15,0x8e,0x02,0xc0,0x0f,0x3a,0x05,0xbb,0x1e,0x4f,0x10,0x78,0xe8,0x43,0xe5,0xf8,0x81,0x70,0x21,0xe9,0xf1,0xfc,0x53,0xc9,0xe3,0xc2,0xc3,0x68,0x03,0xe5,0xfc,0x81,0xcc,0x14,0x05,0xf7,0x9b,0x83,0xc7,0x49,0x4a,0xd0,0x40,0xc1,0xe3,0x7c,0x81,0x43,0x12,0x03,0xc0,0xff,0x4e,0xc1,0xe3,0xa8,0x85,0x68,0x2f,0xc5,0xb1,0xbe,0xc0,0x60,0x60,0xf1,0xf0,0x7c,0x63,0xe0,0xf1,0xc8,0x44,0xb4,0x17,0x20,0x78,0xff,0xbc,0x0b,0x02,0xc0,0x7b,0xc8,0x62,0x0f,0x64,0x78,0xc0,0x27,0xca,0x41,0xff,0x2b,0xc6,0x15,0x88,0x91,0x68,0x3e,0x54,0x14,0x79,0x60,0x24,0x30,0x0e,0x47,0x1f,0x9f,0x03,0x85,0x42,0x24,0x21,0xf1,0xa1,0x32,0xca,0xc1,0xfc,0xff,0x9d,0xc6,0xef,0x06,0x07,0xa5,0xe8,0x1e,0x51,0x87,0xd8,0x9d,0xc6,0xff,0x05,0x17,0x9d,0xca,0x94,0x4c,0x28,0x33,0xec,0x4c,0x03,0x7e,0x80,0xc2,0xa9,0x12,0x40,0x79,0xf0,0x38,0x10,0x10,0x79,0xef,0x89,0xe2,0x0f,0x39,0x50,0x28,0x67,0xe5,0x21,0x02,0x0f,0xc2,0xfe,0x0f,0x80,0x00,0x83,0xcc,0x2a,0x30,0xaa,0x84,0x50,0x1e,0xad,0xf2,0x80,0x7e,0x3b,0xe6,0xf1,0x47,0x9c,0x68,0x16,0x5c,0x00,0x79,0xff,0xc9,0xe3,0xa0,0x00,0x8f,0xfd,0x6c,0x27,0xf2,0x01,0x92,0x08,0x45,0xe3,0xc0,0x83,0xbb,0xc5,0xd4,0x47,0xb1,0x07,0x98,0xfc,0x80,0xa2,0x1f,0x16,0x30,0x82,0x05,0x02,0x20,0x01,0xff,0x17,0xc7,0xf4,0xa5,0x1d,0xff,0x02,0x10,0x7e,0x10,0x7a,0x8f,0xc5,0x0a,0x58,0x09,0x04,0x16,0x60,0x6d,0x11,0x99,0xfe,0x7f,0xf0,0x30,0x90,0x80,0x06,0x77,0x05,0x84,0x40,0x20,0x40,0xf3,0x05,0x0c,0x1d,0x12,0x72,0x48,0x1b,0x2c,0x60,0x81,0x21,0x14,0x0f,0xdc,0x1e,0xb3,0xc8,0x18,0x0c,0x61,0x00,0xf3,0x89,0xfc,0x01,0xea,0xaa,0x28,0x80,0x3c,0xb8,0x11,0x9c,0x84,0x18,0x5e,0x80,0xf1,0x83,0x48,0x1f,0xc7,0x1c,0xd8,0x01,0x48,0x8c,0x6a,0x11,0x4b,0x08,0x7c,0xa3,0xfd,0x00,0x51,0x00,0x05,0xb0,0x40,0x74,0x9f,0xf8,0x25,0xe1,0xe3,0x00,0x11,0xfc,0x4c,0x02,0x02,0x19,0x04,0x82,0x30,0x0f,0x6f,0x00,0x7d,0x06,0x88,0x00,0xf0,0x07,0x80,0x3c,0x00,0x40,}; +const uint8_t *_A_Laptop_128x52[] = {_A_Laptop_128x52_0,_A_Laptop_128x52_1,_A_Laptop_128x52_2,_A_Laptop_128x52_3,_A_Laptop_128x52_4,_A_Laptop_128x52_5}; const uint8_t _A_LeavingActive_128x51_0[] = {0x01,0x00,0x4b,0x01,0x00,0x78,0x01,0x3f,0xc0,0xed,0xc0,0x60,0xe7,0xe0,0xfc,0xe0,0x40,0x3c,0x00,0xfc,0xb0,0x08,0x46,0x06,0x0f,0xb9,0x00,0x08,0x60,0xc0,0xfb,0x88,0x00,0x86,0x18,0x0f,0xb8,0xc0,0x08,0x61,0x00,0xfb,0x06,0x10,0x48,0x80,0x13,0x04,0x01,0x0c,0xc0,0x1f,0x64,0xc2,0x29,0x10,0x02,0x4d,0x84,0x0f,0xc8,0x0a,0x08,0xd5,0xd4,0x0f,0x2a,0x00,0x3e,0xc0,0x64,0x0f,0xf0,0x7d,0xb3,0x84,0x1f,0xa0,0xb3,0x07,0xd9,0x6c,0xc1,0xf6,0x7b,0x30,0x7e,0x27,0xcb,0x80,0x73,0x20,0x03,0xcc,0x13,0xe5,0x40,0x01,0x93,0xfa,0x11,0xe6,0x23,0x20,0x03,0xe4,0x07,0xe6,0xe3,0x20,0x03,0xf4,0x01,0xfd,0x48,0x07,0x98,0xbe,0xad,0x00,0xf3,0x81,0x03,0xe6,0x50,0x0f,0x32,0xfd,0x46,0x18,0x66,0x7f,0xa8,0xe0,0x0c,0xa8,0x78,0x0b,0xf8,0x3e,0x21,0x80,0x32,0xa3,0x46,0x30,0x1f,0xf8,0x38,0x3d,0x8d,0x47,0x4c,0x0a,0x17,0xf0,0x66,0x93,0xc8,0x01,0xa8,0xeb,0x01,0x43,0xbf,0x00,0xcb,0x01,0x67,0x80,0x09,0xce,0xe0,0x0f,0x32,0xa1,0xfc,0x38,0x00,0xf4,0xe0,0x41,0x27,0x00,0x52,0x8f,0x17,0x0b,0x01,0xf9,0x4d,0x24,0x7e,0xdc,0x1c,0x29,0x81,0x30,0xed,0xe5,0x74,0xfe,0x70,0xe3,0xe2,0x52,0x01,0x0c,0x20,0x74,0x29,0xa5,0x87,0x07,0x0b,0x00,0x0a,0x10,0x78,0xcb,0x81,0xeb,0x08,0xf8,0x7f,0xc6,0x22,0xc5,0x18,0x46,0x02,0x27,0x03,0x65,0xa5,0xf0,0xa0,0x3f,0xe8,0x08,0xf4,0x63,0x1e,0x08,0xe4,0x0c,0x40,0x9e,0x48,0x78,0xcc,0x81,0xe3,0x10,0xf8,0x40,0xf8,0x69,0x74,0x32,0x9d,0xe0,0x3e,0x49,0x41,0xb1,0x96,0x10,0xca,0x7e,0x00,0x78,0xc3,0x00,0xe3,0x3b,0x2c,0x14,0x05,0x78,0x98,0x00,0x60,0xf1,0xa1,0xa1,0x94,0xff,0x41,0xc0,0xe2,0x34,0x4b,0xf1,0x58,0x43,0x27,0x10,0x0a,0xa0,0x3c,0xa0,0xdc,0x03,0xb1,0x03,0xcf,0xf8,0x9f,0x23,0xf9,0x00,0x08,0x1e,0xad,0x91,0x08,0x11,0xe5,0x01,0xec,0x5d,0x18,0x09,0x98,0x81,0xf5,0x00,0xff,0xdc,0x41,0xfb,0x00,0x51,0x10,}; const uint8_t _A_LeavingActive_128x51_1[] = {0x01,0x00,0x36,0x01,0x00,0x78,0x01,0x3e,0x11,0xf0,0x7e,0xc7,0x26,0x00,0xfd,0x83,0x78,0x01,0xfb,0x02,0xc0,0x03,0xf6,0x02,0x01,0x20,0x7f,0x83,0xf6,0x04,0x0e,0xbc,0x00,0x3c,0x60,0xc0,0xea,0xe0,0x7f,0xc0,0x63,0x04,0x07,0xd5,0xc0,0x06,0x57,0xc0,0x10,0xc6,0x02,0x6f,0x30,0x16,0x17,0x00,0x64,0x32,0x48,0xe4,0x20,0x1e,0xbe,0x08,0x78,0x10,0x96,0x23,0x64,0xfa,0x42,0x2e,0x61,0x05,0xfb,0xff,0xc0,0x03,0x3f,0x80,0x51,0xb0,0x9e,0x88,0x71,0x79,0x68,0x82,0xf2,0x01,0x0f,0xfb,0x09,0x68,0x8e,0x17,0xd4,0x1e,0x4b,0x02,0xe1,0x61,0x25,0x17,0x40,0x7a,0x58,0x2c,0x80,0xf3,0x98,0x60,0x7c,0x92,0x8e,0x11,0x7d,0x64,0x8a,0x23,0x8e,0x40,0x67,0x96,0x8c,0x18,0x3d,0x22,0x00,0xf4,0x3a,0x0c,0x33,0x91,0xc1,0x07,0xa4,0x62,0x28,0xc2,0x40,0x01,0x5e,0x01,0xe9,0x08,0x8a,0x03,0x0a,0x0e,0xaf,0x98,0x47,0x50,0x1e,0x5f,0x94,0xa1,0x83,0xda,0xd0,0x2f,0x35,0x63,0x03,0xce,0x70,0x0f,0x38,0x60,0x3e,0x41,0x47,0x01,0x20,0x4c,0x21,0xbe,0x50,0x0e,0x09,0x81,0x00,0x09,0x88,0x05,0x1d,0xe4,0xbf,0x39,0x80,0x21,0xc3,0x41,0xf3,0xd0,0x01,0x94,0x08,0x5d,0x30,0x0b,0x80,0x3f,0xac,0x00,0xff,0x01,0x94,0x18,0x1f,0x51,0x00,0x19,0x43,0x01,0xfc,0x73,0x40,0x7b,0xcf,0x81,0xe4,0x0e,0x98,0x07,0xc1,0x54,0x59,0x00,0x7d,0x40,0x20,0x8b,0x21,0xd8,0x03,0xf6,0x30,0x63,0x30,0x04,0x33,0xc6,0x61,0xc0,0x07,0xdc,0x0a,0x01,0x20,0xe0,0x17,0xe8,0x1e,0x5c,0x00,0x7e,0x0f,0xc7,0x01,0x01,0x81,0x83,0xf0,0x84,0x37,0xa0,0x7e,0xe3,0x39,0xe0,0xfd,0xfc,0x61,0xfc,0x11,0xf0,0x7d,0xcc,0x30,0x13,0xf9,0x80,0x3e,0xe2,0x1f,0xf8,0x0c,0x80,0x1f,0x7f,0xc3,0x78,0xa8,0xa4,0x1e,0x3c,0x08,0x58,0x14,0x41,0xf7,0x78,0x02,0x95,0x00,0x1f,0x50,0xe0,0x29,0x78,0x01,0x68,}; @@ -176,47 +186,47 @@ const uint8_t _A_Level3Lab_128x51_1[] = {0x01,0x00,0x9f,0x02,0x00,0x1e,0x20,0x04 const uint8_t _A_Level3Lab_128x51_2[] = {0x01,0x00,0xa6,0x02,0x00,0x1e,0x20,0x04,0x34,0x00,0x39,0xfc,0x3f,0xff,0xf9,0xff,0xf8,0x06,0x3f,0xfc,0xb8,0x3c,0xff,0x10,0x1d,0x84,0x04,0x26,0x59,0xef,0x27,0xe7,0xf7,0xbf,0x07,0x9c,0x1a,0x0d,0xb0,0xc4,0xc4,0x28,0x58,0x80,0x79,0x08,0x04,0x1e,0x70,0x18,0x40,0xdc,0x41,0xeb,0x07,0xfe,0x43,0xc1,0xe3,0x80,0xf8,0x44,0x03,0xef,0x81,0xe1,0xdf,0xc1,0xe3,0x40,0x86,0x48,0xc1,0xe5,0x47,0xc4,0x13,0xc6,0xfe,0x4b,0x3a,0x04,0x82,0x05,0x44,0x17,0x90,0x3c,0xe7,0xf2,0x08,0x07,0x02,0x07,0xf0,0x90,0x40,0x69,0x01,0xf4,0xcf,0x4f,0x23,0xe0,0xf1,0x80,0x41,0xe1,0x11,0x1b,0x0e,0x20,0x7e,0xb3,0xc8,0x7c,0x40,0x1e,0x31,0xe8,0x46,0x47,0x21,0x90,0x2f,0xac,0xf2,0x0e,0x0f,0x2f,0xe4,0x27,0x23,0x68,0xc8,0x83,0xcf,0x39,0x9e,0xde,0x40,0xcf,0x03,0x40,0xfa,0xc2,0xc1,0xe5,0xfc,0xe4,0xc4,0x41,0xe2,0x4f,0x14,0x41,0x6a,0x21,0xff,0x71,0x70,0x8b,0xc7,0x90,0x0f,0x5f,0xe4,0x02,0xeb,0x00,0xa7,0x44,0x09,0xe3,0xf0,0x0f,0x91,0xbc,0x41,0xa3,0x03,0xd1,0xc3,0xa0,0x14,0xc3,0x79,0x0f,0xcb,0xc4,0x0f,0x2c,0x07,0xe2,0xa9,0x07,0x07,0x92,0x3c,0x7f,0x86,0xf1,0x07,0x95,0xf2,0x81,0x04,0xd4,0xc6,0x01,0xe2,0xaf,0x20,0xfa,0x83,0xc7,0xe5,0x5a,0x48,0x8d,0x31,0x9e,0x5e,0x04,0x79,0xff,0xaf,0xf2,0x08,0x4c,0xd5,0x82,0x34,0xc7,0x79,0x5f,0x11,0xe6,0x0f,0x1d,0x04,0x52,0x35,0x80,0x81,0x03,0xc6,0x0d,0x06,0xff,0x63,0xc1,0xe5,0x92,0x9b,0xe4,0x2c,0x51,0xbc,0x00,0x7c,0x9c,0x63,0x03,0xfe,0x03,0xd7,0x24,0x1f,0x15,0x80,0xc0,0x56,0x83,0x03,0xf4,0x43,0xc0,0x83,0x92,0xff,0x83,0xcf,0x01,0xff,0x39,0x09,0x04,0x40,0xa2,0xfc,0x1c,0x94,0x7f,0x2f,0xea,0x07,0x8d,0x82,0x01,0x3f,0x80,0x60,0x04,0x43,0x80,0x8f,0xc0,0x3f,0xd1,0xfc,0xd4,0x12,0x33,0x80,0xbf,0x40,0x2f,0x0b,0xd1,0x19,0x17,0xfa,0x43,0x01,0x86,0x49,0x7f,0x30,0xcc,0x06,0x06,0x03,0xe0,0x80,0x78,0x01,0xe4,0x20,0x1f,0xf4,0x3e,0x55,0x02,0x83,0x5f,0x20,0x11,0x2e,0x04,0x07,0xd1,0x71,0x07,0x8c,0x02,0x11,0x08,0x83,0x51,0x7f,0x9f,0x32,0x60,0xc1,0x07,0xa3,0xc8,0xe0,0x7f,0xcb,0xe3,0x0c,0x07,0x8e,0x0a,0x0f,0x06,0x0b,0x90,0x3c,0x6d,0x00,0x51,0x75,0x88,0x3c,0x95,0x24,0x0f,0x24,0x00,0xda,0x22,0x10,0x08,0xf4,0x0e,0x09,0x08,0x83,0xa3,0x04,0x00,0x59,0x8e,0x38,0x3c,0x4e,0x83,0x1f,0x25,0x0c,0xfa,0x06,0x0f,0x4f,0x81,0x3c,0x67,0xc8,0xe1,0x3f,0x0c,0x1a,0x45,0x03,0x32,0x08,0x3c,0xa7,0x1e,0x0c,0x0c,0xd6,0x00,0x50,0x18,0x1c,0x1a,0x54,0x0f,0x58,0x77,0xc2,0x83,0x18,0x80,0x71,0x23,0x30,0xe8,0x18,0x7c,0x8a,0x02,0x12,0x18,0x1f,0xc2,0x40,0x0f,0x1f,0x44,0x65,0xa6,0x23,0xf1,0x07,0x8c,0x08,0x7c,0x23,0x01,0x90,0x19,0x47,0xe1,0x0c,0x07,0x8e,0x20,0x1e,0x51,0xc2,0xc0,0xc0,0x27,0xd1,0x08,0x64,0xc2,0xf1,0xc6,0x07,0xaf,0x83,0xfe,0x31,0x18,0x78,0x3c,0x7b,0x17,0x8c,0x36,0x1e,0x03,0x88,0x82,0x9b,0x8c,0x24,0x30,0x78,0x44,0x13,0x0d,0x3c,0x81,0x29,0x44,0x1e,0xdf,0xc1,0x40,0xc1,0xf8,0x79,0xf8,0x7e,0x02,0x3b,0x88,0x29,0x88,0x00,0xff,0xe5,0xc1,0x81,0xdc,0x3f,0xd1,0x8c,0x04,0x4f,0x11,0x61,0x17,0x21,0x40,0x6f,0x10,0x29,0x85,0xfe,0x60,0x0f,0x1c,0x86,0x84,0x96,0x20,0x01,0xfc,0x3c,0x44,0x78,0x39,0x8f,0x3d,0x83,0x81,0x12,0xc8,0x50,0x5d,0xa4,0xb9,0x10,0x18,0x83,0xc7,0xb1,0xc3,0xe0,0xd0,0x23,0xda,0x08,0x0c,0x24,0x9a,0x40,0xf2,0x8f,0x40,0xbf,0x1c,0x0c,0x0d,0x86,0x28,0x0f,0x18,0x90,0x2c,0x7f,0xc0,0xf2,0x87,0x40,0xaf,0x1c,0x08,0x1c,0x82,0x18,0xe7,0x18,0xa0,0x2c,0x7d,0x00,0xf2,0x87,0xc0,0x6e,0x2c,0x51,0x5a,0x0a,0x04,0x41,0xe5,0x54,0xee,0xc0,0x78,0x50,0x78,0x0d,0xe0,0x1e,0x33,0x03,0x08,0x83,0xcf,0x51,0xaa,0x80,0xec,0x20,0x60,0xf4,0xe0,0x07,0xd7,0xab,0x81,0xc1,0xc0,0x60,0x33,0xcc,0x04,0xfe,0x60,0x6a,0x10,0xfa,0xc0,0xff,0x0d,0x31,0x8e,0x07,0xc7,0xe1,0xff,}; const uint8_t *_A_Level3Lab_128x51[] = {_A_Level3Lab_128x51_0,_A_Level3Lab_128x51_1,_A_Level3Lab_128x51_2}; -const uint8_t _I_LevelUp2_03_0[] = {0x01,0x00,0xa3,0x00,0x00,0x37,0xf2,0x02,0x0f,0xdf,0xfc,0xfc,0x1d,0x9c,0x0f,0xff,0xfc,0x1f,0x9f,0x00,0x78,0x8c,0x33,0xf0,0x0f,0x18,0x19,0x3b,0x01,0xfe,0x0f,0x18,0x38,0x3e,0xff,0xc0,0xf1,0x87,0x83,0xfc,0xfd,0x80,0x01,0x8f,0x83,0xfc,0x1f,0xca,0x0c,0x07,0xf8,0x3c,0xaf,0xe0,0xff,0x07,0xf8,0x3f,0x9c,0x18,0x8f,0x20,0x7f,0x83,0xff,0xff,0x01,0x07,0xf8,0x3f,0xcb,0xfc,0x0f,0xac,0x00,0x3f,0xb8,0x00,0xfe,0xf0,0x03,0xfb,0xe0,0x0f,0xf0,0x7f,0x83,0xfc,0x9f,0xe6,0xff,0x07,0xf0,0xc1,0x01,0xf7,0xf8,0x07,0xf8,0x3f,0xc1,0xfd,0xfc,0x07,0xf8,0x3f,0xc1,0xfc,0x00,0xf0,0x06,0xe2,0x37,0xd2,0x48,0x25,0x7f,0xe9,0x05,0x8a,0x83,0xe3,0x04,0x0f,0x1a,0x0c,0x52,0x08,0x0f,0x8c,0xc0,0x3f,0xb5,0x19,0xe0,0x78,0xe3,0xfe,0x40,0xf9,0xe4,0x07,0xcb,0x03,0x12,0x07,0xc8,0xfc,0xe0,0x31,0x18,0x21,0x7e,0x67,0xd1,0xbb,0xe4,0x7f,0xe3,0x7d,0x0f,0xc0,0x03,0xc0,0x1e,0x00,0xb0,}; -const uint8_t *_I_LevelUp2_03[] = {_I_LevelUp2_03_0}; - -const uint8_t _I_LevelUp2_02_0[] = {0x01,0x00,0xe1,0x00,0x00,0x37,0xe2,0x02,0x0f,0xda,0xbc,0xfc,0x1d,0x9c,0x0d,0x5f,0xa8,0x1f,0x97,0x0a,0xaf,0x54,0x61,0x9b,0x8d,0x56,0xaa,0x06,0x0f,0xba,0xa5,0x56,0xaa,0x0f,0xcd,0x60,0x7c,0x60,0xc0,0xfb,0xab,0x07,0xc6,0x1a,0x0f,0xb0,0xf0,0xea,0xa1,0x47,0xec,0xfa,0xd5,0xe3,0xa0,0xfb,0xd5,0xfe,0xb5,0xd1,0xa0,0x7d,0xd5,0x6f,0xb5,0xd9,0xa8,0x7f,0x3d,0xda,0xa9,0x50,0x7f,0x3e,0xb5,0xfb,0xa8,0x7f,0x75,0x76,0xa0,0xff,0x55,0x43,0xfb,0xaf,0x70,0x65,0x5b,0xfb,0x57,0xea,0xa7,0xf3,0xd5,0xab,0xd5,0x2f,0xfb,0xab,0x01,0x5f,0xee,0xa8,0x1f,0x61,0xf2,0xaa,0x83,0xec,0x7a,0x21,0xfc,0xc0,0x07,0x88,0x3f,0x7c,0x0d,0x56,0xe8,0x3f,0x96,0x0a,0xaa,0x78,0x43,0xf7,0xb0,0xd5,0x10,0x08,0x1f,0x55,0x0b,0xf8,0xff,0x7e,0x1a,0xb1,0xfe,0xdc,0x07,0xfd,0xe0,0x5f,0x10,0x7e,0xf8,0x03,0xfe,0x30,0x12,0xff,0x6b,0x01,0xfe,0xd4,0x07,0xfc,0x3f,0xda,0xc0,0xff,0x55,0x03,0xfe,0x1f,0x20,0x75,0x00,0x3c,0x01,0xd8,0x8d,0xf4,0x92,0x09,0x5f,0xfa,0x41,0x62,0xa0,0xf8,0xc1,0x03,0xc6,0x83,0x14,0x82,0x03,0xe3,0x30,0x0f,0xed,0x46,0x78,0x1e,0x38,0xff,0x90,0x3e,0x79,0x01,0xf2,0xc0,0xc4,0x81,0xf2,0x3f,0x38,0x0c,0x46,0x08,0x5f,0x99,0xf4,0x6e,0xf9,0x1f,0xf8,0xdf,0x43,0xf0,0x00,0xf0,0x07,0x80,0x2c,}; -const uint8_t *_I_LevelUp2_02[] = {_I_LevelUp2_02_0}; - -const uint8_t _I_LevelUp2_05_0[] = {0x01,0x00,0x1d,0x01,0x00,0x37,0xf2,0x02,0x0f,0xd8,0x3c,0xfc,0x1d,0x9c,0x0e,0x0f,0x84,0x1f,0x96,0x0b,0x86,0x00,0x61,0x91,0x88,0xc4,0x02,0x06,0x0f,0xb8,0x24,0x32,0x01,0x02,0x07,0xe4,0x1a,0x00,0x01,0x10,0x05,0x41,0xbc,0x70,0xf1,0x08,0x80,0x1e,0x80,0x02,0x18,0x14,0x66,0x21,0x08,0x36,0x48,0x08,0x70,0x7c,0xd9,0x39,0x44,0x42,0xe4,0x00,0x43,0x51,0x7f,0xf4,0x96,0xf8,0x84,0x02,0xf8,0x20,0x73,0x50,0xe0,0x7a,0xf5,0xf9,0x86,0x02,0x0e,0x4d,0x88,0x04,0x07,0xa9,0xde,0x90,0x0d,0x88,0xda,0xe0,0xf2,0xcf,0xc8,0x0d,0xf7,0x49,0x07,0x89,0x35,0xc1,0xeb,0x94,0xeb,0x83,0xf2,0x97,0x2c,0xa4,0x03,0xf2,0x05,0xd8,0xbf,0xe0,0x01,0xf9,0x3f,0xa1,0x83,0xf3,0xf5,0xf1,0xc0,0x83,0xc7,0xfd,0x0f,0x06,0x2c,0x70,0x04,0x30,0xc0,0xe9,0x29,0x44,0x00,0xd7,0x04,0x89,0x83,0xe9,0x30,0x4b,0x11,0x6f,0x08,0x3e,0x1a,0x28,0xfe,0x10,0x7d,0x08,0x49,0x98,0x20,0xfa,0x5d,0x8f,0x80,0x7f,0x40,0x01,0x75,0x8c,0x7c,0x1f,0x91,0x0b,0xf1,0x7e,0xc0,0x03,0xf0,0x2f,0x88,0x3c,0xa6,0x02,0xf9,0x1f,0xa0,0x0c,0x80,0x0d,0x60,0x80,0x4f,0x01,0xe4,0x75,0x20,0x02,0x78,0x23,0xfc,0x0f,0xf8,0xc0,0x87,0xf1,0x38,0x28,0x11,0x3f,0x60,0x11,0x80,0x7f,0x2f,0x44,0x1f,0xe0,0xfd,0x66,0x88,0x3f,0x60,0x80,0xba,0x07,0xf8,0x03,0xc0,0x1e,0x00,0x1c,0x46,0xfa,0x49,0x04,0xaf,0xfd,0x20,0xb1,0x50,0x7c,0x60,0x81,0xe3,0x41,0x8a,0x41,0x01,0xf1,0x98,0x07,0xf6,0xa3,0x3c,0x0f,0x1c,0x7f,0xc8,0x1f,0x3c,0x80,0xf9,0x60,0x62,0x40,0xf9,0x1f,0x9c,0x06,0x22,0x83,0x9c,0x44,0xfa,0x37,0x7c,0x8f,0xfc,0x6f,0xa1,0xf8,0x00,0x78,0x03,0xc0,0x16,}; -const uint8_t *_I_LevelUp2_05[] = {_I_LevelUp2_05_0}; - const uint8_t _I_LevelUp2_04_0[] = {0x01,0x00,0x16,0x01,0x00,0x37,0xf2,0x02,0x0f,0xda,0xbc,0xfc,0x1d,0x9c,0x0f,0x5f,0xac,0x1f,0x97,0x0b,0xaf,0x54,0x61,0x9b,0x8d,0xd6,0xaa,0x06,0x0f,0xba,0xa5,0x76,0xaa,0x0f,0xcd,0x66,0xbb,0x55,0x06,0x07,0xdd,0x5b,0xef,0x5f,0x86,0x83,0xef,0x55,0xbb,0xdd,0x42,0x81,0xf7,0xd7,0xee,0xdd,0xe3,0xa0,0xfb,0xff,0xeb,0xbd,0xf1,0xa0,0x7d,0xf5,0x7a,0xf5,0xf9,0xa8,0x36,0x60,0x90,0x0d,0x5f,0xfb,0xfd,0x2a,0xb0,0x03,0xe2,0x39,0x00,0xaa,0xf5,0x7b,0xf7,0x59,0xc0,0x3e,0x26,0x10,0x0f,0x5f,0xfb,0x7f,0x6a,0x84,0x0f,0xea,0xba,0x40,0x1a,0xa9,0x3e,0xfd,0x7a,0xef,0x57,0xa9,0x3f,0x9d,0xdb,0xff,0x55,0x3f,0x9b,0xff,0x5e,0xa8,0x1f,0x7f,0xef,0xaf,0x57,0xab,0xf1,0x07,0xd3,0x78,0x40,0x03,0x01,0x06,0xc4,0x08,0x7e,0x35,0x50,0x00,0x83,0xe6,0x1c,0x9f,0x10,0xfe,0x46,0x30,0x01,0xd1,0xae,0x87,0xea,0x01,0xc0,0x0e,0x8e,0xbc,0x3f,0x50,0x0b,0x05,0x57,0xea,0x21,0x1e,0x08,0x3e,0x76,0x07,0xf1,0x10,0x8e,0x06,0x06,0x0f,0x8a,0x85,0xfc,0xbf,0x90,0x0f,0x81,0x7f,0x60,0x17,0x01,0xf9,0x83,0xe7,0x81,0xe1,0xd5,0x6f,0x83,0xf7,0x70,0xe0,0x7f,0xea,0xe3,0xfc,0x30,0x10,0xff,0x20,0x15,0x82,0xfe,0xc0,0x35,0x01,0xff,0x0f,0xf6,0xb0,0x3f,0xd5,0x40,0xff,0x87,0xc8,0x1d,0x40,0x0f,0x00,0x76,0x23,0x7d,0x24,0x82,0x57,0xfe,0x90,0x58,0xa8,0x3e,0x30,0x40,0xf1,0xa0,0xc5,0x20,0x80,0xf8,0xcc,0x03,0xfb,0x51,0x9e,0x07,0x8e,0x3f,0xe4,0x0f,0x9e,0x40,0x7c,0xb0,0x31,0x20,0x7c,0x8f,0xce,0x03,0x11,0x82,0x17,0xe6,0x7d,0x1b,0xbe,0x47,0xfe,0x37,0xd0,0xfc,0x00,0x3c,0x01,0xe0,0x0b,}; const uint8_t *_I_LevelUp2_04[] = {_I_LevelUp2_04_0}; -const uint8_t _I_LevelUp2_01_0[] = {0x01,0x00,0xdc,0x00,0x00,0x37,0xe2,0x02,0x0f,0xd8,0x3c,0xfc,0x1d,0x9c,0x08,0x0f,0x80,0x1f,0x96,0x08,0x06,0x00,0x61,0x91,0x80,0x10,0xc0,0xc1,0xf7,0x04,0x01,0x0c,0x08,0x1f,0xd0,0x60,0x7d,0x83,0x0a,0x18,0x0f,0xb1,0x61,0x42,0x01,0xf7,0x03,0xf8,0x41,0xca,0x44,0x00,0x98,0x0f,0x62,0x09,0x10,0x07,0xe5,0xa2,0x19,0x30,0x07,0xe7,0xb2,0x11,0x20,0x07,0xe7,0x92,0x1e,0x0f,0xe8,0x5d,0x00,0x1f,0x9a,0x48,0x78,0x3f,0x20,0x7e,0xc0,0x7e,0xc0,0xbf,0x10,0x7c,0x00,0x3f,0x3c,0x10,0x30,0x7e,0x80,0x84,0x1f,0x85,0x34,0x6f,0xe8,0x3f,0x20,0x60,0xfd,0xc0,0x02,0xcc,0x1f,0x5c,0x08,0x03,0x34,0x81,0xf4,0xbb,0x18,0x70,0x3f,0x26,0x18,0x02,0x01,0x03,0xea,0x21,0x7e,0x1f,0xef,0xc2,0x07,0x10,0x17,0xec,0x02,0x3c,0x0f,0xcb,0x07,0x00,0x18,0x46,0xfb,0xbf,0xa7,0xf8,0x7c,0x40,0xfc,0x8c,0x03,0xfa,0x10,0x0f,0xf0,0x7f,0x43,0x01,0xfd,0x04,0x05,0xd0,0x3f,0xc0,0x1e,0x00,0xf0,0x00,0xe2,0x37,0xd2,0x48,0x25,0x7f,0xe9,0x05,0x8a,0x83,0xe3,0x04,0x0f,0x1a,0x0c,0x52,0x08,0x0f,0x8c,0xc0,0x3f,0xb5,0x19,0xe0,0x78,0xe3,0xfe,0x40,0xf9,0xe4,0x07,0xcb,0x03,0x12,0x07,0xc8,0xfc,0xe0,0x31,0x14,0x1c,0xe2,0x27,0xd1,0xbb,0xe4,0x7f,0xe3,0x7d,0x0f,0xc0,0x03,0xc0,0x1e,0x00,0xb0,}; -const uint8_t *_I_LevelUp2_01[] = {_I_LevelUp2_01_0}; - -const uint8_t _I_LevelUp2_06_0[] = {0x01,0x00,0x11,0x01,0x00,0x37,0xf2,0x02,0x0f,0xd8,0x3c,0xfc,0x1d,0x9c,0x0e,0x0f,0x84,0x17,0x18,0x00,0x19,0x58,0x2e,0x18,0x01,0x84,0xc1,0x80,0x43,0x18,0x8c,0x40,0x20,0x60,0xf8,0x86,0x00,0x86,0x08,0x03,0x18,0x10,0xfe,0xe0,0x82,0x31,0x12,0x95,0xe0,0x65,0x3e,0x38,0x78,0x94,0xa1,0xc0,0xf8,0x81,0x46,0x62,0x10,0x80,0x29,0x03,0xe3,0x07,0xcd,0x93,0x94,0x44,0x01,0x5f,0xfd,0x25,0xbe,0x20,0x0f,0xbc,0x0f,0x5e,0xbf,0x30,0x07,0xdc,0x07,0xa9,0xde,0x90,0x03,0xf7,0x3e,0x0f,0xca,0x48,0x3c,0x68,0x00,0xfc,0xca,0x75,0xc1,0xf9,0x4b,0x96,0x52,0x01,0xf9,0x02,0xec,0x5f,0xdc,0xc6,0x0f,0x99,0xfd,0x0c,0x1e,0x5c,0x00,0x7c,0x7e,0xbe,0x38,0x10,0xf9,0xac,0xc8,0x00,0x36,0x07,0x91,0x83,0x4a,0x02,0x2f,0xa7,0x61,0x03,0xe1,0xaa,0x70,0x31,0x51,0x07,0xeb,0x00,0x0b,0x17,0xf0,0x83,0xe8,0xb0,0x50,0x70,0x7d,0xae,0xc7,0xc0,0x4f,0xc9,0x86,0x02,0x3e,0x0f,0xc8,0x85,0xf8,0xbf,0x40,0x02,0xf8,0x17,0xc4,0x5f,0xa3,0xfe,0x51,0x0c,0xf0,0x1f,0x9c,0x0f,0xf8,0xc0,0x81,0xf0,0xc5,0x28,0x80,0xfd,0x19,0xc8,0x00,0x48,0xc0,0x3e,0xd8,0x04,0x09,0x31,0x7c,0x0e,0xc8,0x1e,0xaa,0x61,0x66,0x23,0xfc,0xcf,0xfb,0x00,0x82,0x02,0xe8,0x1f,0xe0,0x0f,0x00,0x78,0x00,0x71,0x1b,0xe9,0x24,0x12,0xbf,0xf4,0x82,0xc5,0x41,0xf1,0x82,0x07,0x8d,0x06,0x29,0x04,0x07,0xc6,0x60,0x1f,0xda,0x8c,0xf0,0x3c,0x71,0xff,0x20,0x7c,0xf2,0x03,0xe5,0x81,0x89,0x03,0xe4,0x7e,0x70,0x18,0x8a,0x0e,0x71,0x13,0xe8,0xdd,0xf2,0x3f,0xf1,0xbe,0x87,0xe0,0x01,0xe0,0x0f,0x00,0x58,}; -const uint8_t *_I_LevelUp2_06[] = {_I_LevelUp2_06_0}; +const uint8_t _I_LevelUp2_03_0[] = {0x01,0x00,0xa3,0x00,0x00,0x37,0xf2,0x02,0x0f,0xdf,0xfc,0xfc,0x1d,0x9c,0x0f,0xff,0xfc,0x1f,0x9f,0x00,0x78,0x8c,0x33,0xf0,0x0f,0x18,0x19,0x3b,0x01,0xfe,0x0f,0x18,0x38,0x3e,0xff,0xc0,0xf1,0x87,0x83,0xfc,0xfd,0x80,0x01,0x8f,0x83,0xfc,0x1f,0xca,0x0c,0x07,0xf8,0x3c,0xaf,0xe0,0xff,0x07,0xf8,0x3f,0x9c,0x18,0x8f,0x20,0x7f,0x83,0xff,0xff,0x01,0x07,0xf8,0x3f,0xcb,0xfc,0x0f,0xac,0x00,0x3f,0xb8,0x00,0xfe,0xf0,0x03,0xfb,0xe0,0x0f,0xf0,0x7f,0x83,0xfc,0x9f,0xe6,0xff,0x07,0xf0,0xc1,0x01,0xf7,0xf8,0x07,0xf8,0x3f,0xc1,0xfd,0xfc,0x07,0xf8,0x3f,0xc1,0xfc,0x00,0xf0,0x06,0xe2,0x37,0xd2,0x48,0x25,0x7f,0xe9,0x05,0x8a,0x83,0xe3,0x04,0x0f,0x1a,0x0c,0x52,0x08,0x0f,0x8c,0xc0,0x3f,0xb5,0x19,0xe0,0x78,0xe3,0xfe,0x40,0xf9,0xe4,0x07,0xcb,0x03,0x12,0x07,0xc8,0xfc,0xe0,0x31,0x18,0x21,0x7e,0x67,0xd1,0xbb,0xe4,0x7f,0xe3,0x7d,0x0f,0xc0,0x03,0xc0,0x1e,0x00,0xb0,}; +const uint8_t *_I_LevelUp2_03[] = {_I_LevelUp2_03_0}; const uint8_t _I_LevelUp2_07_0[] = {0x01,0x00,0xf1,0x00,0x00,0x37,0xf2,0x02,0x0f,0xd8,0x3c,0xfc,0x1d,0x9c,0x0e,0x0f,0x84,0x1f,0x96,0x0b,0x86,0x00,0x61,0x91,0x88,0xc4,0x02,0x06,0x0f,0xb8,0x24,0x32,0x01,0x02,0x07,0xe4,0x1a,0x00,0x01,0x10,0x05,0x41,0xbc,0x70,0xf1,0x08,0x80,0x2a,0x05,0x19,0x88,0x42,0x01,0xf7,0x83,0xe6,0xc9,0xca,0x22,0x00,0xaf,0xfe,0x92,0xdf,0x10,0x07,0xde,0x07,0xaf,0x5f,0x98,0x03,0xee,0x03,0xd4,0xef,0x48,0x01,0xfb,0x9f,0x07,0xe5,0x24,0x1e,0x34,0x00,0x7e,0x65,0x3a,0xe0,0xfc,0xa5,0xcb,0x29,0x00,0xfc,0x81,0x76,0x2f,0xf8,0x00,0x7e,0x4f,0xe8,0x60,0xfc,0xfd,0x7c,0x70,0x20,0xfc,0x86,0x03,0x4a,0x02,0xdf,0xb4,0x19,0x83,0xea,0x07,0x00,0x6f,0x08,0x3e,0xb0,0x00,0xb1,0x7f,0x08,0x3e,0xb8,0x00,0x21,0x83,0x83,0xed,0x76,0x3e,0x01,0xfe,0x4c,0x30,0x11,0xf0,0x7e,0x44,0x2f,0xc5,0xfd,0xf8,0x17,0xc4,0x5f,0xa3,0xfe,0xb0,0x40,0x27,0x80,0xfc,0xe0,0x7f,0xc6,0x04,0x9f,0xb8,0x82,0xbf,0xa3,0x00,0xfe,0x5e,0x88,0x3f,0xc1,0xfa,0xcd,0x10,0x7e,0xc1,0x01,0x74,0x0f,0xf0,0x07,0x80,0x3c,0x00,0x38,0x8d,0xf4,0x92,0x09,0x5f,0xfa,0x41,0x62,0xa0,0xf8,0xc1,0x03,0xc6,0x83,0x14,0x82,0x03,0xe3,0x30,0x0f,0xed,0x46,0x78,0x1e,0x38,0xff,0x90,0x3e,0x79,0x01,0xf2,0xc0,0xc4,0x81,0xf2,0x3f,0x38,0x0c,0x45,0x07,0x38,0x89,0xf4,0x6e,0xf9,0x1f,0xf8,0xdf,0x43,0xf0,0x00,0xf0,0x07,0x80,0x2c,}; const uint8_t *_I_LevelUp2_07[] = {_I_LevelUp2_07_0}; -const uint8_t _I_LevelUp3_05_0[] = {0x01,0x00,0x34,0x01,0x00,0x37,0xf2,0x0e,0x0f,0xd8,0x3c,0xe0,0x1d,0x9c,0x08,0x6f,0xc0,0x1f,0x96,0x08,0xc6,0x42,0x02,0x0f,0xb8,0xc4,0xc2,0x21,0x03,0x07,0xdc,0x12,0x41,0x10,0x81,0x03,0xfa,0x0c,0x0f,0xb8,0x37,0x82,0x3f,0x0c,0x06,0x45,0x00,0x04,0x30,0x28,0xc4,0x42,0x10,0x6c,0x90,0x10,0xc0,0xf9,0x92,0x78,0xc0,0x5c,0xc0,0x09,0x80,0x35,0x0f,0xfe,0x49,0x69,0x88,0x40,0x2f,0x82,0x07,0x35,0x0f,0x06,0x2f,0x51,0x98,0x60,0x16,0x50,0x5a,0x1a,0x0e,0x53,0xa7,0x20,0x1b,0x11,0xb5,0xc1,0xe3,0xf4,0xcf,0x48,0x0d,0xf6,0x1f,0x1c,0x99,0x35,0xc1,0xeb,0x14,0xe8,0xd0,0xc1,0xf9,0x2c,0xa4,0xd1,0x01,0xf7,0xc2,0xec,0x5f,0xf9,0x00,0xfb,0xc1,0x4f,0xe8,0x7e,0x80,0x7d,0xfe,0xbe,0x78,0x1d,0x3c,0x03,0xfd,0x0f,0x06,0x2c,0x70,0x04,0x30,0xcc,0x16,0x02,0x60,0xa5,0x10,0x03,0x5c,0x12,0x24,0x0c,0x18,0xc0,0x3e,0x13,0x05,0x83,0x80,0x42,0x21,0x80,0xf8,0x68,0x95,0x04,0x62,0x22,0x22,0x78,0xcd,0x82,0x01,0x07,0x81,0x03,0xea,0x41,0x20,0xf0,0x40,0x01,0xf7,0x30,0xd0,0x47,0xc1,0xf9,0x10,0xbf,0x18,0x90,0x01,0x1f,0x08,0x1b,0xd0,0xa0,0x33,0x01,0x7c,0xc0,0x07,0xe2,0x6f,0x10,0x18,0x80,0x1c,0xbc,0x33,0xc8,0x04,0x3e,0x03,0x80,0x18,0xb7,0x82,0x3f,0xc0,0xff,0xc0,0xf8,0x10,0x11,0xfc,0x4e,0x0a,0x04,0xb4,0x22,0x7d,0x2f,0x04,0x02,0x40,0xfb,0x84,0x00,0x48,0x1f,0xe0,0xfb,0x86,0x03,0xfa,0x08,0x0f,0x20,0x05,0x83,0xfc,0x01,0xe0,0x0d,0xc4,0x6f,0xa4,0x90,0x4a,0xff,0xd2,0x0b,0x15,0x07,0xc6,0x08,0x1e,0x34,0x18,0xa4,0x10,0x1f,0x19,0x80,0x7f,0x6a,0x33,0xc0,0xf1,0xc7,0xfc,0x81,0xf3,0xc8,0x0f,0x96,0x06,0x24,0x0f,0x91,0xf9,0xc0,0x62,0x28,0x31,0x07,0xc4,0xfa,0x37,0x7c,0x8f,0xfc,0x6f,0xa1,0xf8,0x00,0x78,0x03,0xc0,0x16,}; -const uint8_t *_I_LevelUp3_05[] = {_I_LevelUp3_05_0}; +const uint8_t _I_LevelUp2_05_0[] = {0x01,0x00,0x1d,0x01,0x00,0x37,0xf2,0x02,0x0f,0xd8,0x3c,0xfc,0x1d,0x9c,0x0e,0x0f,0x84,0x1f,0x96,0x0b,0x86,0x00,0x61,0x91,0x88,0xc4,0x02,0x06,0x0f,0xb8,0x24,0x32,0x01,0x02,0x07,0xe4,0x1a,0x00,0x01,0x10,0x05,0x41,0xbc,0x70,0xf1,0x08,0x80,0x1e,0x80,0x02,0x18,0x14,0x66,0x21,0x08,0x36,0x48,0x08,0x70,0x7c,0xd9,0x39,0x44,0x42,0xe4,0x00,0x43,0x51,0x7f,0xf4,0x96,0xf8,0x84,0x02,0xf8,0x20,0x73,0x50,0xe0,0x7a,0xf5,0xf9,0x86,0x02,0x0e,0x4d,0x88,0x04,0x07,0xa9,0xde,0x90,0x0d,0x88,0xda,0xe0,0xf2,0xcf,0xc8,0x0d,0xf7,0x49,0x07,0x89,0x35,0xc1,0xeb,0x94,0xeb,0x83,0xf2,0x97,0x2c,0xa4,0x03,0xf2,0x05,0xd8,0xbf,0xe0,0x01,0xf9,0x3f,0xa1,0x83,0xf3,0xf5,0xf1,0xc0,0x83,0xc7,0xfd,0x0f,0x06,0x2c,0x70,0x04,0x30,0xc0,0xe9,0x29,0x44,0x00,0xd7,0x04,0x89,0x83,0xe9,0x30,0x4b,0x11,0x6f,0x08,0x3e,0x1a,0x28,0xfe,0x10,0x7d,0x08,0x49,0x98,0x20,0xfa,0x5d,0x8f,0x80,0x7f,0x40,0x01,0x75,0x8c,0x7c,0x1f,0x91,0x0b,0xf1,0x7e,0xc0,0x03,0xf0,0x2f,0x88,0x3c,0xa6,0x02,0xf9,0x1f,0xa0,0x0c,0x80,0x0d,0x60,0x80,0x4f,0x01,0xe4,0x75,0x20,0x02,0x78,0x23,0xfc,0x0f,0xf8,0xc0,0x87,0xf1,0x38,0x28,0x11,0x3f,0x60,0x11,0x80,0x7f,0x2f,0x44,0x1f,0xe0,0xfd,0x66,0x88,0x3f,0x60,0x80,0xba,0x07,0xf8,0x03,0xc0,0x1e,0x00,0x1c,0x46,0xfa,0x49,0x04,0xaf,0xfd,0x20,0xb1,0x50,0x7c,0x60,0x81,0xe3,0x41,0x8a,0x41,0x01,0xf1,0x98,0x07,0xf6,0xa3,0x3c,0x0f,0x1c,0x7f,0xc8,0x1f,0x3c,0x80,0xf9,0x60,0x62,0x40,0xf9,0x1f,0x9c,0x06,0x22,0x83,0x9c,0x44,0xfa,0x37,0x7c,0x8f,0xfc,0x6f,0xa1,0xf8,0x00,0x78,0x03,0xc0,0x16,}; +const uint8_t *_I_LevelUp2_05[] = {_I_LevelUp2_05_0}; -const uint8_t _I_LevelUp3_06_0[] = {0x01,0x00,0x30,0x01,0x00,0x37,0xf2,0x0e,0x0f,0xd8,0x3c,0xe0,0x1d,0x9c,0x08,0x6f,0xc0,0x17,0x18,0x00,0x19,0x58,0x23,0x19,0x08,0x08,0x42,0x20,0xc0,0x21,0x8c,0x4c,0x22,0x10,0x30,0x7c,0x43,0x00,0x43,0x04,0x90,0x44,0x20,0x43,0xfb,0x07,0x90,0x94,0xaf,0x03,0x29,0xf0,0x47,0xc4,0xa5,0x0e,0x07,0xc4,0x0a,0x31,0x10,0x84,0x01,0x48,0x1f,0x10,0x3e,0x64,0x9e,0x30,0x3f,0xbf,0xfc,0x92,0xd3,0x10,0x07,0xdf,0x06,0x2f,0x51,0x98,0x03,0xee,0x83,0x94,0xe9,0xc8,0x01,0xf9,0xf4,0xcf,0x03,0xf7,0x29,0x93,0xa0,0x03,0xf2,0x29,0xd1,0xa1,0x83,0xf2,0x59,0x49,0xa2,0x03,0xef,0x85,0xd8,0xbf,0xf2,0x01,0xf7,0x82,0x9f,0xd0,0xfd,0x00,0x51,0xe0,0x03,0xe3,0xf5,0xf3,0xc0,0xe9,0xc0,0xc4,0xb3,0x20,0x00,0xd8,0x1e,0x47,0x82,0xc0,0x4c,0x20,0x22,0xfa,0x83,0x03,0x06,0x30,0x0f,0x76,0xa9,0xe0,0xc5,0x43,0x0c,0x0f,0xd6,0x02,0x82,0x31,0x11,0x11,0x00,0x23,0x80,0x43,0x18,0x3c,0x08,0x1f,0x52,0x09,0x07,0x80,0x6c,0x20,0xfa,0x98,0x68,0x23,0xe0,0xfc,0x88,0x5f,0x8c,0x48,0x00,0x8f,0x84,0x0c,0x06,0x30,0x41,0x7d,0xc0,0x07,0xe2,0x6f,0xb2,0xf0,0xcf,0x20,0x10,0xf3,0x7d,0xff,0xe0,0x7c,0x08,0x08,0x3e,0x18,0xa5,0x10,0x80,0x5c,0x20,0x00,0xf1,0x67,0x20,0x01,0x23,0x00,0x12,0x07,0xc3,0x00,0x81,0x22,0x01,0x11,0x7c,0x1b,0x08,0x1e,0xb2,0x06,0x62,0xbf,0xcc,0x3f,0x60,0x02,0x82,0x12,0xe8,0x1f,0xe0,0x0f,0x00,0x78,0x00,0x71,0x1b,0xe9,0x24,0x12,0xbf,0xf4,0x82,0xc5,0x41,0xf1,0x82,0x07,0x8d,0x06,0x29,0x04,0x07,0xc6,0x60,0x1f,0xda,0x8c,0xf0,0x3c,0x71,0xff,0x20,0x7c,0xf2,0x03,0xe5,0x81,0x89,0x03,0xe4,0x7e,0x70,0x18,0x8a,0x0c,0x41,0xf1,0x3e,0x8d,0xdf,0x23,0xff,0x1b,0xe8,0x7e,0x00,0x1e,0x00,0xf0,0x05,0x80,}; -const uint8_t *_I_LevelUp3_06[] = {_I_LevelUp3_06_0}; +const uint8_t _I_LevelUp2_02_0[] = {0x01,0x00,0xe1,0x00,0x00,0x37,0xe2,0x02,0x0f,0xda,0xbc,0xfc,0x1d,0x9c,0x0d,0x5f,0xa8,0x1f,0x97,0x0a,0xaf,0x54,0x61,0x9b,0x8d,0x56,0xaa,0x06,0x0f,0xba,0xa5,0x56,0xaa,0x0f,0xcd,0x60,0x7c,0x60,0xc0,0xfb,0xab,0x07,0xc6,0x1a,0x0f,0xb0,0xf0,0xea,0xa1,0x47,0xec,0xfa,0xd5,0xe3,0xa0,0xfb,0xd5,0xfe,0xb5,0xd1,0xa0,0x7d,0xd5,0x6f,0xb5,0xd9,0xa8,0x7f,0x3d,0xda,0xa9,0x50,0x7f,0x3e,0xb5,0xfb,0xa8,0x7f,0x75,0x76,0xa0,0xff,0x55,0x43,0xfb,0xaf,0x70,0x65,0x5b,0xfb,0x57,0xea,0xa7,0xf3,0xd5,0xab,0xd5,0x2f,0xfb,0xab,0x01,0x5f,0xee,0xa8,0x1f,0x61,0xf2,0xaa,0x83,0xec,0x7a,0x21,0xfc,0xc0,0x07,0x88,0x3f,0x7c,0x0d,0x56,0xe8,0x3f,0x96,0x0a,0xaa,0x78,0x43,0xf7,0xb0,0xd5,0x10,0x08,0x1f,0x55,0x0b,0xf8,0xff,0x7e,0x1a,0xb1,0xfe,0xdc,0x07,0xfd,0xe0,0x5f,0x10,0x7e,0xf8,0x03,0xfe,0x30,0x12,0xff,0x6b,0x01,0xfe,0xd4,0x07,0xfc,0x3f,0xda,0xc0,0xff,0x55,0x03,0xfe,0x1f,0x20,0x75,0x00,0x3c,0x01,0xd8,0x8d,0xf4,0x92,0x09,0x5f,0xfa,0x41,0x62,0xa0,0xf8,0xc1,0x03,0xc6,0x83,0x14,0x82,0x03,0xe3,0x30,0x0f,0xed,0x46,0x78,0x1e,0x38,0xff,0x90,0x3e,0x79,0x01,0xf2,0xc0,0xc4,0x81,0xf2,0x3f,0x38,0x0c,0x46,0x08,0x5f,0x99,0xf4,0x6e,0xf9,0x1f,0xf8,0xdf,0x43,0xf0,0x00,0xf0,0x07,0x80,0x2c,}; +const uint8_t *_I_LevelUp2_02[] = {_I_LevelUp2_02_0}; -const uint8_t _I_LevelUp3_02_0[] = {0x01,0x00,0xf4,0x00,0x00,0x37,0xf2,0x02,0x0f,0xda,0xbc,0xfc,0x1d,0x9c,0x0f,0x5f,0xac,0x1f,0x97,0x0b,0xaf,0x54,0x61,0x9b,0x8d,0xd6,0xaa,0x06,0x0f,0xba,0xa5,0x76,0xaa,0x0f,0xcd,0x66,0xbb,0x55,0x06,0x07,0xdd,0x5b,0xef,0x5f,0x86,0x83,0xef,0x55,0xbb,0xdd,0x42,0x81,0xf7,0xd7,0xee,0xdd,0xe3,0xa0,0xfb,0xff,0xeb,0xbd,0xf1,0xa0,0x7d,0xf5,0x7a,0xf5,0xf9,0xa8,0x3e,0xf5,0x7f,0xef,0xf4,0xa8,0x1f,0x75,0x5e,0xaf,0x7e,0xea,0x0f,0xbf,0x5f,0xfb,0x7f,0x6a,0x07,0xdd,0x74,0x80,0x35,0x50,0xfe,0x6b,0xbd,0x5e,0xa4,0xfe,0x77,0x6f,0xfd,0x54,0xfe,0x6f,0xfd,0x7a,0xa0,0x7d,0xff,0xbe,0xbd,0x5e,0xac,0x04,0x1f,0x4d,0xe1,0x00,0x08,0x3e,0xea,0xd5,0x50,0x00,0x83,0xef,0x56,0x1f,0xdc,0x00,0x74,0x6b,0xa1,0xfb,0xe0,0x07,0x47,0x5e,0x1f,0xbb,0x05,0x57,0xea,0x3f,0xcd,0x81,0xfc,0x47,0xf9,0x50,0xbf,0x97,0xf7,0xe0,0x5f,0xeb,0x80,0xff,0xbc,0x1a,0xad,0xf0,0x7f,0x38,0x1f,0xfa,0xba,0x7f,0x4c,0x02,0xbf,0xda,0xc2,0xff,0xb5,0x01,0xff,0x0f,0xf6,0xb0,0x3f,0xd5,0x40,0xff,0x87,0xc8,0x1d,0x40,0x0f,0x00,0x76,0x23,0x7d,0x24,0x82,0x57,0xfe,0x90,0x58,0xa8,0x3e,0x30,0x40,0xf1,0xa0,0xc5,0x20,0x80,0xf8,0xcc,0x03,0xfb,0x51,0x9e,0x07,0x8e,0x3f,0xe4,0x0f,0x9e,0x40,0x7c,0xb0,0x31,0x20,0x7c,0x8f,0xce,0x03,0x11,0x82,0x17,0xe6,0x7d,0x1b,0xbe,0x47,0xfe,0x37,0xd0,0xfc,0x00,0x3c,0x01,0xe0,0x0b,}; -const uint8_t *_I_LevelUp3_02[] = {_I_LevelUp3_02_0}; +const uint8_t _I_LevelUp2_06_0[] = {0x01,0x00,0x11,0x01,0x00,0x37,0xf2,0x02,0x0f,0xd8,0x3c,0xfc,0x1d,0x9c,0x0e,0x0f,0x84,0x17,0x18,0x00,0x19,0x58,0x2e,0x18,0x01,0x84,0xc1,0x80,0x43,0x18,0x8c,0x40,0x20,0x60,0xf8,0x86,0x00,0x86,0x08,0x03,0x18,0x10,0xfe,0xe0,0x82,0x31,0x12,0x95,0xe0,0x65,0x3e,0x38,0x78,0x94,0xa1,0xc0,0xf8,0x81,0x46,0x62,0x10,0x80,0x29,0x03,0xe3,0x07,0xcd,0x93,0x94,0x44,0x01,0x5f,0xfd,0x25,0xbe,0x20,0x0f,0xbc,0x0f,0x5e,0xbf,0x30,0x07,0xdc,0x07,0xa9,0xde,0x90,0x03,0xf7,0x3e,0x0f,0xca,0x48,0x3c,0x68,0x00,0xfc,0xca,0x75,0xc1,0xf9,0x4b,0x96,0x52,0x01,0xf9,0x02,0xec,0x5f,0xdc,0xc6,0x0f,0x99,0xfd,0x0c,0x1e,0x5c,0x00,0x7c,0x7e,0xbe,0x38,0x10,0xf9,0xac,0xc8,0x00,0x36,0x07,0x91,0x83,0x4a,0x02,0x2f,0xa7,0x61,0x03,0xe1,0xaa,0x70,0x31,0x51,0x07,0xeb,0x00,0x0b,0x17,0xf0,0x83,0xe8,0xb0,0x50,0x70,0x7d,0xae,0xc7,0xc0,0x4f,0xc9,0x86,0x02,0x3e,0x0f,0xc8,0x85,0xf8,0xbf,0x40,0x02,0xf8,0x17,0xc4,0x5f,0xa3,0xfe,0x51,0x0c,0xf0,0x1f,0x9c,0x0f,0xf8,0xc0,0x81,0xf0,0xc5,0x28,0x80,0xfd,0x19,0xc8,0x00,0x48,0xc0,0x3e,0xd8,0x04,0x09,0x31,0x7c,0x0e,0xc8,0x1e,0xaa,0x61,0x66,0x23,0xfc,0xcf,0xfb,0x00,0x82,0x02,0xe8,0x1f,0xe0,0x0f,0x00,0x78,0x00,0x71,0x1b,0xe9,0x24,0x12,0xbf,0xf4,0x82,0xc5,0x41,0xf1,0x82,0x07,0x8d,0x06,0x29,0x04,0x07,0xc6,0x60,0x1f,0xda,0x8c,0xf0,0x3c,0x71,0xff,0x20,0x7c,0xf2,0x03,0xe5,0x81,0x89,0x03,0xe4,0x7e,0x70,0x18,0x8a,0x0e,0x71,0x13,0xe8,0xdd,0xf2,0x3f,0xf1,0xbe,0x87,0xe0,0x01,0xe0,0x0f,0x00,0x58,}; +const uint8_t *_I_LevelUp2_06[] = {_I_LevelUp2_06_0}; + +const uint8_t _I_LevelUp2_01_0[] = {0x01,0x00,0xdc,0x00,0x00,0x37,0xe2,0x02,0x0f,0xd8,0x3c,0xfc,0x1d,0x9c,0x08,0x0f,0x80,0x1f,0x96,0x08,0x06,0x00,0x61,0x91,0x80,0x10,0xc0,0xc1,0xf7,0x04,0x01,0x0c,0x08,0x1f,0xd0,0x60,0x7d,0x83,0x0a,0x18,0x0f,0xb1,0x61,0x42,0x01,0xf7,0x03,0xf8,0x41,0xca,0x44,0x00,0x98,0x0f,0x62,0x09,0x10,0x07,0xe5,0xa2,0x19,0x30,0x07,0xe7,0xb2,0x11,0x20,0x07,0xe7,0x92,0x1e,0x0f,0xe8,0x5d,0x00,0x1f,0x9a,0x48,0x78,0x3f,0x20,0x7e,0xc0,0x7e,0xc0,0xbf,0x10,0x7c,0x00,0x3f,0x3c,0x10,0x30,0x7e,0x80,0x84,0x1f,0x85,0x34,0x6f,0xe8,0x3f,0x20,0x60,0xfd,0xc0,0x02,0xcc,0x1f,0x5c,0x08,0x03,0x34,0x81,0xf4,0xbb,0x18,0x70,0x3f,0x26,0x18,0x02,0x01,0x03,0xea,0x21,0x7e,0x1f,0xef,0xc2,0x07,0x10,0x17,0xec,0x02,0x3c,0x0f,0xcb,0x07,0x00,0x18,0x46,0xfb,0xbf,0xa7,0xf8,0x7c,0x40,0xfc,0x8c,0x03,0xfa,0x10,0x0f,0xf0,0x7f,0x43,0x01,0xfd,0x04,0x05,0xd0,0x3f,0xc0,0x1e,0x00,0xf0,0x00,0xe2,0x37,0xd2,0x48,0x25,0x7f,0xe9,0x05,0x8a,0x83,0xe3,0x04,0x0f,0x1a,0x0c,0x52,0x08,0x0f,0x8c,0xc0,0x3f,0xb5,0x19,0xe0,0x78,0xe3,0xfe,0x40,0xf9,0xe4,0x07,0xcb,0x03,0x12,0x07,0xc8,0xfc,0xe0,0x31,0x14,0x1c,0xe2,0x27,0xd1,0xbb,0xe4,0x7f,0xe3,0x7d,0x0f,0xc0,0x03,0xc0,0x1e,0x00,0xb0,}; +const uint8_t *_I_LevelUp2_01[] = {_I_LevelUp2_01_0}; const uint8_t _I_LevelUp3_07_0[] = {0x01,0x00,0x0b,0x01,0x00,0x37,0xf2,0x0e,0x0f,0xd8,0x3c,0xe0,0x1d,0x9c,0x08,0x6f,0xc0,0x1f,0x96,0x08,0xc6,0x42,0x02,0x0f,0xb8,0xc4,0xc2,0x21,0x03,0x07,0xdc,0x12,0x41,0x10,0x81,0x03,0xfa,0x0c,0x0f,0xb8,0x37,0x82,0x3f,0x0c,0x07,0xdc,0x0a,0x31,0x10,0x84,0x03,0xee,0x07,0xcc,0x93,0xc6,0x01,0xf7,0xff,0x92,0x5a,0x62,0x00,0xfb,0xe0,0xc5,0xea,0x33,0x00,0x7d,0xd0,0x72,0x9d,0x39,0x00,0x3f,0x3e,0x99,0xe0,0x7e,0xe5,0x32,0x74,0x00,0x7e,0x45,0x3a,0x34,0x30,0x7e,0x4b,0x29,0x34,0x40,0x7d,0xf0,0xbb,0x17,0xfe,0x40,0x3e,0xf0,0x53,0xfa,0x1f,0xa0,0x1f,0x7f,0xaf,0x9e,0x07,0x4e,0x0f,0xb8,0x66,0x0b,0x01,0x30,0x80,0xb7,0xec,0x18,0x31,0x80,0x7d,0xe0,0xe0,0x10,0x88,0x60,0x3e,0xb0,0x14,0x11,0x88,0x88,0x88,0x01,0x1c,0x0b,0x04,0x02,0x0f,0x02,0x07,0xd4,0x82,0x41,0xe0,0x80,0x03,0xee,0x61,0xa0,0x8f,0x83,0xf2,0x21,0x7e,0x31,0x20,0x02,0x3e,0x10,0x30,0x18,0xc1,0x05,0xf7,0x00,0x1f,0x89,0xbe,0xcb,0xc3,0x3c,0x80,0x43,0xcd,0xf7,0xff,0x81,0xf0,0x20,0x29,0xfb,0x88,0x40,0x2e,0x10,0x00,0x7d,0xc6,0x00,0x24,0x0f,0xb8,0x40,0x04,0x81,0xfe,0x0f,0xb8,0x60,0x3f,0xa0,0x80,0xf2,0x00,0x58,0x3f,0xc0,0x1e,0x00,0xdc,0x46,0xfa,0x49,0x04,0xaf,0xfd,0x20,0xb1,0x50,0x7c,0x60,0x81,0xe3,0x41,0x8a,0x41,0x01,0xf1,0x98,0x07,0xf6,0xa3,0x3c,0x0f,0x1c,0x7f,0xc8,0x1f,0x3c,0x80,0xf9,0x60,0x62,0x40,0xf9,0x1f,0x9c,0x06,0x22,0x83,0x10,0x7c,0x4f,0xa3,0x77,0xc8,0xff,0xc6,0xfa,0x1f,0x80,0x07,0x80,0x3c,0x01,0x60,}; const uint8_t *_I_LevelUp3_07[] = {_I_LevelUp3_07_0}; +const uint8_t _I_LevelUp3_02_0[] = {0x01,0x00,0xf4,0x00,0x00,0x37,0xf2,0x02,0x0f,0xda,0xbc,0xfc,0x1d,0x9c,0x0f,0x5f,0xac,0x1f,0x97,0x0b,0xaf,0x54,0x61,0x9b,0x8d,0xd6,0xaa,0x06,0x0f,0xba,0xa5,0x76,0xaa,0x0f,0xcd,0x66,0xbb,0x55,0x06,0x07,0xdd,0x5b,0xef,0x5f,0x86,0x83,0xef,0x55,0xbb,0xdd,0x42,0x81,0xf7,0xd7,0xee,0xdd,0xe3,0xa0,0xfb,0xff,0xeb,0xbd,0xf1,0xa0,0x7d,0xf5,0x7a,0xf5,0xf9,0xa8,0x3e,0xf5,0x7f,0xef,0xf4,0xa8,0x1f,0x75,0x5e,0xaf,0x7e,0xea,0x0f,0xbf,0x5f,0xfb,0x7f,0x6a,0x07,0xdd,0x74,0x80,0x35,0x50,0xfe,0x6b,0xbd,0x5e,0xa4,0xfe,0x77,0x6f,0xfd,0x54,0xfe,0x6f,0xfd,0x7a,0xa0,0x7d,0xff,0xbe,0xbd,0x5e,0xac,0x04,0x1f,0x4d,0xe1,0x00,0x08,0x3e,0xea,0xd5,0x50,0x00,0x83,0xef,0x56,0x1f,0xdc,0x00,0x74,0x6b,0xa1,0xfb,0xe0,0x07,0x47,0x5e,0x1f,0xbb,0x05,0x57,0xea,0x3f,0xcd,0x81,0xfc,0x47,0xf9,0x50,0xbf,0x97,0xf7,0xe0,0x5f,0xeb,0x80,0xff,0xbc,0x1a,0xad,0xf0,0x7f,0x38,0x1f,0xfa,0xba,0x7f,0x4c,0x02,0xbf,0xda,0xc2,0xff,0xb5,0x01,0xff,0x0f,0xf6,0xb0,0x3f,0xd5,0x40,0xff,0x87,0xc8,0x1d,0x40,0x0f,0x00,0x76,0x23,0x7d,0x24,0x82,0x57,0xfe,0x90,0x58,0xa8,0x3e,0x30,0x40,0xf1,0xa0,0xc5,0x20,0x80,0xf8,0xcc,0x03,0xfb,0x51,0x9e,0x07,0x8e,0x3f,0xe4,0x0f,0x9e,0x40,0x7c,0xb0,0x31,0x20,0x7c,0x8f,0xce,0x03,0x11,0x82,0x17,0xe6,0x7d,0x1b,0xbe,0x47,0xfe,0x37,0xd0,0xfc,0x00,0x3c,0x01,0xe0,0x0b,}; +const uint8_t *_I_LevelUp3_02[] = {_I_LevelUp3_02_0}; + const uint8_t _I_LevelUp3_04_0[] = {0x01,0x00,0x21,0x01,0x00,0x37,0xf2,0x0e,0x0f,0xda,0xbc,0xf4,0x1d,0x9c,0x0d,0x7f,0xe8,0x1f,0x97,0x0a,0xef,0x56,0x02,0x0f,0xbd,0xc6,0xeb,0x75,0x03,0x07,0xdd,0x52,0xeb,0x55,0x07,0xe6,0xb3,0x55,0xba,0x83,0x03,0xee,0xad,0xf5,0xaf,0xc3,0x41,0xf6,0x1e,0x1d,0xd4,0x28,0xfd,0x9d,0xdb,0xbc,0x74,0x1f,0x7f,0xfd,0x77,0xae,0x34,0x0f,0xbe,0xad,0x5e,0xab,0x35,0x06,0xcc,0x12,0x01,0xeb,0xdf,0x7e,0xe5,0x56,0x00,0x7c,0x47,0x20,0x15,0x5f,0xaf,0x7e,0xeb,0x38,0x07,0xc4,0xc0,0x3e,0x5b,0xbb,0x54,0x20,0x7f,0x55,0x5a,0xa9,0x04,0x49,0xf7,0xeb,0x2f,0x8f,0xb8,0x1f,0x7d,0x6e,0xed,0xff,0xba,0x9f,0xcd,0xff,0xaf,0xd4,0x0f,0xbf,0xf7,0xdf,0xab,0xf7,0xf8,0x83,0xeb,0x5d,0xaa,0x60,0x8c,0x04,0x1b,0x10,0x26,0xf8,0x98,0x06,0xba,0x0f,0x98,0x74,0x03,0x56,0x1f,0x1d,0x70,0x3e,0x63,0x18,0x00,0xf1,0x55,0xc1,0xf3,0x00,0xe0,0x7a,0xb5,0x5a,0xfd,0x50,0x3e,0xac,0x17,0x5f,0xad,0x56,0xaf,0xc1,0x07,0xce,0xc0,0xfe,0x24,0x01,0xc0,0xc0,0xc1,0xf1,0x50,0xbf,0x90,0x04,0x7f,0x7f,0x02,0xfe,0xc0,0x2e,0x0f,0xf1,0x3f,0xdf,0x03,0xc3,0xaa,0xdf,0x18,0x04,0x1f,0x37,0x0e,0x07,0xfe,0xaf,0xd5,0xaa,0x8b,0xe8,0xc0,0x5f,0xa3,0xfd,0xc0,0x2b,0x03,0xe1,0x0f,0xe6,0xa0,0xbe,0x21,0xff,0x0f,0xe6,0xb0,0x3f,0xd5,0x40,0xff,0x87,0xc8,0x1d,0x40,0x0f,0x00,0x76,0x23,0x7d,0x24,0x82,0x57,0xfe,0x90,0x58,0xa8,0x3e,0x30,0x40,0xf1,0xa0,0xc5,0x20,0x80,0xf8,0xcc,0x03,0xfb,0x51,0x9e,0x07,0x8e,0x3f,0xe4,0x0f,0x9e,0x40,0x7c,0xb0,0x31,0x20,0x7c,0x8f,0xce,0x03,0x11,0x82,0x17,0xe6,0x7d,0x1b,0xbe,0x47,0xfe,0x37,0xd0,0xfc,0x00,0x3c,0x01,0xe0,0x0b,}; const uint8_t *_I_LevelUp3_04[] = {_I_LevelUp3_04_0}; +const uint8_t _I_LevelUp3_05_0[] = {0x01,0x00,0x34,0x01,0x00,0x37,0xf2,0x0e,0x0f,0xd8,0x3c,0xe0,0x1d,0x9c,0x08,0x6f,0xc0,0x1f,0x96,0x08,0xc6,0x42,0x02,0x0f,0xb8,0xc4,0xc2,0x21,0x03,0x07,0xdc,0x12,0x41,0x10,0x81,0x03,0xfa,0x0c,0x0f,0xb8,0x37,0x82,0x3f,0x0c,0x06,0x45,0x00,0x04,0x30,0x28,0xc4,0x42,0x10,0x6c,0x90,0x10,0xc0,0xf9,0x92,0x78,0xc0,0x5c,0xc0,0x09,0x80,0x35,0x0f,0xfe,0x49,0x69,0x88,0x40,0x2f,0x82,0x07,0x35,0x0f,0x06,0x2f,0x51,0x98,0x60,0x16,0x50,0x5a,0x1a,0x0e,0x53,0xa7,0x20,0x1b,0x11,0xb5,0xc1,0xe3,0xf4,0xcf,0x48,0x0d,0xf6,0x1f,0x1c,0x99,0x35,0xc1,0xeb,0x14,0xe8,0xd0,0xc1,0xf9,0x2c,0xa4,0xd1,0x01,0xf7,0xc2,0xec,0x5f,0xf9,0x00,0xfb,0xc1,0x4f,0xe8,0x7e,0x80,0x7d,0xfe,0xbe,0x78,0x1d,0x3c,0x03,0xfd,0x0f,0x06,0x2c,0x70,0x04,0x30,0xcc,0x16,0x02,0x60,0xa5,0x10,0x03,0x5c,0x12,0x24,0x0c,0x18,0xc0,0x3e,0x13,0x05,0x83,0x80,0x42,0x21,0x80,0xf8,0x68,0x95,0x04,0x62,0x22,0x22,0x78,0xcd,0x82,0x01,0x07,0x81,0x03,0xea,0x41,0x20,0xf0,0x40,0x01,0xf7,0x30,0xd0,0x47,0xc1,0xf9,0x10,0xbf,0x18,0x90,0x01,0x1f,0x08,0x1b,0xd0,0xa0,0x33,0x01,0x7c,0xc0,0x07,0xe2,0x6f,0x10,0x18,0x80,0x1c,0xbc,0x33,0xc8,0x04,0x3e,0x03,0x80,0x18,0xb7,0x82,0x3f,0xc0,0xff,0xc0,0xf8,0x10,0x11,0xfc,0x4e,0x0a,0x04,0xb4,0x22,0x7d,0x2f,0x04,0x02,0x40,0xfb,0x84,0x00,0x48,0x1f,0xe0,0xfb,0x86,0x03,0xfa,0x08,0x0f,0x20,0x05,0x83,0xfc,0x01,0xe0,0x0d,0xc4,0x6f,0xa4,0x90,0x4a,0xff,0xd2,0x0b,0x15,0x07,0xc6,0x08,0x1e,0x34,0x18,0xa4,0x10,0x1f,0x19,0x80,0x7f,0x6a,0x33,0xc0,0xf1,0xc7,0xfc,0x81,0xf3,0xc8,0x0f,0x96,0x06,0x24,0x0f,0x91,0xf9,0xc0,0x62,0x28,0x31,0x07,0xc4,0xfa,0x37,0x7c,0x8f,0xfc,0x6f,0xa1,0xf8,0x00,0x78,0x03,0xc0,0x16,}; +const uint8_t *_I_LevelUp3_05[] = {_I_LevelUp3_05_0}; + +const uint8_t _I_LevelUp3_01_0[] = {0x01,0x00,0xf1,0x00,0x00,0x37,0xf2,0x02,0x0f,0xd8,0x3c,0xfc,0x1d,0x9c,0x0e,0x0f,0x84,0x1f,0x96,0x0b,0x86,0x00,0x61,0x91,0x88,0xc4,0x02,0x06,0x0f,0xb8,0x24,0x32,0x01,0x02,0x07,0xe4,0x1a,0x00,0x01,0x10,0x05,0x41,0xbc,0x70,0xf1,0x08,0x80,0x2a,0x05,0x19,0x88,0x42,0x01,0xf7,0x83,0xe6,0xc9,0xca,0x22,0x00,0xaf,0xfe,0x92,0xdf,0x10,0x07,0xde,0x07,0xaf,0x5f,0x98,0x03,0xee,0x03,0xd4,0xef,0x48,0x01,0xfb,0x9f,0x07,0xe5,0x24,0x1e,0x34,0x00,0x7e,0x65,0x3a,0xe0,0xfc,0xa5,0xcb,0x29,0x00,0xfc,0x81,0x76,0x2f,0xf8,0x00,0x7e,0x4f,0xe8,0x60,0xfc,0xfd,0x7c,0x70,0x20,0xfc,0x86,0x03,0x4a,0x02,0xdf,0xb4,0x19,0x83,0xea,0x07,0x00,0x6f,0x08,0x3e,0xb0,0x00,0xb1,0x7f,0x08,0x3e,0xb8,0x00,0x21,0x83,0x83,0xed,0x76,0x3e,0x01,0xfe,0x4c,0x30,0x11,0xf0,0x7e,0x44,0x2f,0xc5,0xfd,0xf8,0x17,0xc4,0x5f,0xa3,0xfe,0xb0,0x40,0x27,0x80,0xfc,0xe0,0x7f,0xc6,0x04,0x9f,0xb8,0x82,0xbf,0xa3,0x00,0xfe,0x5e,0x88,0x3f,0xc1,0xfa,0xcd,0x10,0x7e,0xc1,0x01,0x74,0x0f,0xf0,0x07,0x80,0x3c,0x00,0x38,0x8d,0xf4,0x92,0x09,0x5f,0xfa,0x41,0x62,0xa0,0xf8,0xc1,0x03,0xc6,0x83,0x14,0x82,0x03,0xe3,0x30,0x0f,0xed,0x46,0x78,0x1e,0x38,0xff,0x90,0x3e,0x79,0x01,0xf2,0xc0,0xc4,0x81,0xf2,0x3f,0x38,0x0c,0x45,0x07,0x38,0x89,0xf4,0x6e,0xf9,0x1f,0xf8,0xdf,0x43,0xf0,0x00,0xf0,0x07,0x80,0x2c,}; +const uint8_t *_I_LevelUp3_01[] = {_I_LevelUp3_01_0}; + const uint8_t _I_LevelUp3_03_0[] = {0x01,0x00,0xa3,0x00,0x00,0x37,0xf2,0x02,0x0f,0xdf,0xfc,0xfc,0x1d,0x9c,0x0f,0xff,0xfc,0x1f,0x9f,0x00,0x78,0x8c,0x33,0xf0,0x0f,0x18,0x19,0x3b,0x01,0xfe,0x0f,0x18,0x38,0x3e,0xff,0xc0,0xf1,0x87,0x83,0xfc,0xfd,0x80,0x01,0x8f,0x83,0xfc,0x1f,0xca,0x0c,0x07,0xf8,0x3c,0xaf,0xe0,0xff,0x07,0xf8,0x3f,0x9c,0x18,0x8f,0x20,0x7f,0x83,0xff,0xff,0x01,0x07,0xf8,0x3f,0xcb,0xfc,0x0f,0xac,0x00,0x3f,0xb8,0x00,0xfe,0xf0,0x03,0xfb,0xe0,0x0f,0xf0,0x7f,0x83,0xfc,0x9f,0xe6,0xff,0x07,0xf0,0xc1,0x01,0xf7,0xf8,0x07,0xf8,0x3f,0xc1,0xfd,0xfc,0x07,0xf8,0x3f,0xc1,0xfc,0x00,0xf0,0x06,0xe2,0x37,0xd2,0x48,0x25,0x7f,0xe9,0x05,0x8a,0x83,0xe3,0x04,0x0f,0x1a,0x0c,0x52,0x08,0x0f,0x8c,0xc0,0x3f,0xb5,0x19,0xe0,0x78,0xe3,0xfe,0x40,0xf9,0xe4,0x07,0xcb,0x03,0x12,0x07,0xc8,0xfc,0xe0,0x31,0x18,0x21,0x7e,0x67,0xd1,0xbb,0xe4,0x7f,0xe3,0x7d,0x0f,0xc0,0x03,0xc0,0x1e,0x00,0xb0,}; const uint8_t *_I_LevelUp3_03[] = {_I_LevelUp3_03_0}; -const uint8_t _I_LevelUp3_01_0[] = {0x01,0x00,0xf1,0x00,0x00,0x37,0xf2,0x02,0x0f,0xd8,0x3c,0xfc,0x1d,0x9c,0x0e,0x0f,0x84,0x1f,0x96,0x0b,0x86,0x00,0x61,0x91,0x88,0xc4,0x02,0x06,0x0f,0xb8,0x24,0x32,0x01,0x02,0x07,0xe4,0x1a,0x00,0x01,0x10,0x05,0x41,0xbc,0x70,0xf1,0x08,0x80,0x2a,0x05,0x19,0x88,0x42,0x01,0xf7,0x83,0xe6,0xc9,0xca,0x22,0x00,0xaf,0xfe,0x92,0xdf,0x10,0x07,0xde,0x07,0xaf,0x5f,0x98,0x03,0xee,0x03,0xd4,0xef,0x48,0x01,0xfb,0x9f,0x07,0xe5,0x24,0x1e,0x34,0x00,0x7e,0x65,0x3a,0xe0,0xfc,0xa5,0xcb,0x29,0x00,0xfc,0x81,0x76,0x2f,0xf8,0x00,0x7e,0x4f,0xe8,0x60,0xfc,0xfd,0x7c,0x70,0x20,0xfc,0x86,0x03,0x4a,0x02,0xdf,0xb4,0x19,0x83,0xea,0x07,0x00,0x6f,0x08,0x3e,0xb0,0x00,0xb1,0x7f,0x08,0x3e,0xb8,0x00,0x21,0x83,0x83,0xed,0x76,0x3e,0x01,0xfe,0x4c,0x30,0x11,0xf0,0x7e,0x44,0x2f,0xc5,0xfd,0xf8,0x17,0xc4,0x5f,0xa3,0xfe,0xb0,0x40,0x27,0x80,0xfc,0xe0,0x7f,0xc6,0x04,0x9f,0xb8,0x82,0xbf,0xa3,0x00,0xfe,0x5e,0x88,0x3f,0xc1,0xfa,0xcd,0x10,0x7e,0xc1,0x01,0x74,0x0f,0xf0,0x07,0x80,0x3c,0x00,0x38,0x8d,0xf4,0x92,0x09,0x5f,0xfa,0x41,0x62,0xa0,0xf8,0xc1,0x03,0xc6,0x83,0x14,0x82,0x03,0xe3,0x30,0x0f,0xed,0x46,0x78,0x1e,0x38,0xff,0x90,0x3e,0x79,0x01,0xf2,0xc0,0xc4,0x81,0xf2,0x3f,0x38,0x0c,0x45,0x07,0x38,0x89,0xf4,0x6e,0xf9,0x1f,0xf8,0xdf,0x43,0xf0,0x00,0xf0,0x07,0x80,0x2c,}; -const uint8_t *_I_LevelUp3_01[] = {_I_LevelUp3_01_0}; +const uint8_t _I_LevelUp3_06_0[] = {0x01,0x00,0x30,0x01,0x00,0x37,0xf2,0x0e,0x0f,0xd8,0x3c,0xe0,0x1d,0x9c,0x08,0x6f,0xc0,0x17,0x18,0x00,0x19,0x58,0x23,0x19,0x08,0x08,0x42,0x20,0xc0,0x21,0x8c,0x4c,0x22,0x10,0x30,0x7c,0x43,0x00,0x43,0x04,0x90,0x44,0x20,0x43,0xfb,0x07,0x90,0x94,0xaf,0x03,0x29,0xf0,0x47,0xc4,0xa5,0x0e,0x07,0xc4,0x0a,0x31,0x10,0x84,0x01,0x48,0x1f,0x10,0x3e,0x64,0x9e,0x30,0x3f,0xbf,0xfc,0x92,0xd3,0x10,0x07,0xdf,0x06,0x2f,0x51,0x98,0x03,0xee,0x83,0x94,0xe9,0xc8,0x01,0xf9,0xf4,0xcf,0x03,0xf7,0x29,0x93,0xa0,0x03,0xf2,0x29,0xd1,0xa1,0x83,0xf2,0x59,0x49,0xa2,0x03,0xef,0x85,0xd8,0xbf,0xf2,0x01,0xf7,0x82,0x9f,0xd0,0xfd,0x00,0x51,0xe0,0x03,0xe3,0xf5,0xf3,0xc0,0xe9,0xc0,0xc4,0xb3,0x20,0x00,0xd8,0x1e,0x47,0x82,0xc0,0x4c,0x20,0x22,0xfa,0x83,0x03,0x06,0x30,0x0f,0x76,0xa9,0xe0,0xc5,0x43,0x0c,0x0f,0xd6,0x02,0x82,0x31,0x11,0x11,0x00,0x23,0x80,0x43,0x18,0x3c,0x08,0x1f,0x52,0x09,0x07,0x80,0x6c,0x20,0xfa,0x98,0x68,0x23,0xe0,0xfc,0x88,0x5f,0x8c,0x48,0x00,0x8f,0x84,0x0c,0x06,0x30,0x41,0x7d,0xc0,0x07,0xe2,0x6f,0xb2,0xf0,0xcf,0x20,0x10,0xf3,0x7d,0xff,0xe0,0x7c,0x08,0x08,0x3e,0x18,0xa5,0x10,0x80,0x5c,0x20,0x00,0xf1,0x67,0x20,0x01,0x23,0x00,0x12,0x07,0xc3,0x00,0x81,0x22,0x01,0x11,0x7c,0x1b,0x08,0x1e,0xb2,0x06,0x62,0xbf,0xcc,0x3f,0x60,0x02,0x82,0x12,0xe8,0x1f,0xe0,0x0f,0x00,0x78,0x00,0x71,0x1b,0xe9,0x24,0x12,0xbf,0xf4,0x82,0xc5,0x41,0xf1,0x82,0x07,0x8d,0x06,0x29,0x04,0x07,0xc6,0x60,0x1f,0xda,0x8c,0xf0,0x3c,0x71,0xff,0x20,0x7c,0xf2,0x03,0xe5,0x81,0x89,0x03,0xe4,0x7e,0x70,0x18,0x8a,0x0c,0x41,0xf1,0x3e,0x8d,0xdf,0x23,0xff,0x1b,0xe8,0x7e,0x00,0x1e,0x00,0xf0,0x05,0x80,}; +const uint8_t *_I_LevelUp3_06[] = {_I_LevelUp3_06_0}; const uint8_t _A_LevelUpPending_128x51_0[] = {0x01,0x00,0xa9,0x01,0x00,0x1c,0xfc,0x1d,0xbf,0x0e,0x04,0x04,0x1f,0x90,0xc8,0x04,0x18,0x1f,0x90,0x28,0x04,0x20,0x1d,0x62,0xd2,0x98,0x03,0xfe,0x01,0x80,0xf9,0xdf,0x39,0xd8,0x7f,0x45,0x2e,0xe4,0x2b,0x18,0x04,0x80,0x04,0x34,0x00,0x08,0xc5,0x20,0xb1,0x1c,0x0c,0xa2,0x91,0x8a,0x07,0x94,0x40,0x04,0x38,0x00,0x78,0xc4,0x01,0xe5,0x29,0xa4,0x42,0x81,0xe7,0xf8,0x07,0x8c,0x06,0x81,0xf6,0x9e,0x47,0xf0,0x3e,0xaa,0x48,0xbc,0xe1,0x10,0x48,0x0e,0x02,0x07,0x40,0xaa,0x41,0x03,0xe3,0x2c,0xa4,0x60,0x81,0xe5,0x00,0xba,0x40,0xbe,0x1d,0xfa,0x06,0x50,0x1e,0x43,0xf2,0x07,0x16,0x13,0x77,0x02,0x86,0x70,0x30,0x31,0x3b,0xe8,0x3c,0x7d,0x1b,0x3b,0x88,0x7c,0xa8,0x9f,0xa8,0x14,0x0e,0x00,0xb1,0xad,0x17,0xef,0x84,0x04,0x10,0x7d,0x78,0xae,0x72,0x20,0x7f,0x83,0xf3,0xf3,0x07,0x88,0xc0,0x3f,0xe0,0xf4,0x53,0x08,0x00,0xe8,0xb8,0xc2,0xf0,0xd5,0x60,0x1f,0x09,0xe6,0x7f,0xc7,0xc0,0x07,0x1e,0x03,0x09,0x79,0x81,0xfe,0x35,0x4a,0x51,0xa2,0xd0,0x62,0x9c,0x11,0x29,0xe0,0x30,0x42,0xe1,0xae,0x07,0xc4,0x1e,0x51,0x0e,0x01,0xdc,0x41,0xe6,0x15,0x1d,0x7d,0xa8,0x5e,0x58,0xf1,0x78,0x83,0xce,0xc1,0x81,0x5f,0x0d,0x56,0x6a,0x1f,0x18,0xa4,0x06,0x08,0x2f,0x40,0x78,0xc0,0xf8,0x1a,0xa8,0xd0,0x3c,0x64,0x83,0xf2,0x27,0x9f,0x81,0xb8,0x3e,0x0a,0xbc,0x74,0x1e,0x34,0x42,0xf8,0x9b,0xd3,0xe1,0x80,0x83,0xfe,0x35,0xf1,0xf4,0x74,0xdc,0x20,0x10,0xaf,0xf7,0xfe,0x66,0x0f,0xbf,0xd7,0xfc,0x1f,0xbc,0x20,0x78,0xc8,0x41,0xf3,0x18,0x80,0x40,0xa7,0xfc,0x09,0x18,0x3f,0x2f,0xd0,0x0f,0x78,0x3f,0x3f,0x90,0x1e,0xe0,0x3e,0x61,0x00,0xf2,0x83,0xfc,0x01,0xf9,0xa8,0x8f,0xf0,0x1f,0xe8,0x0f,0x7a,0x87,0xff,0xc2,0x0f,0x98,0x20,0x3c,0x74,0x1f,0xad,0xfb,0x64,0xc1,0xed,0x80,0x80,0xd0,0x2a,0xb8,0x70,0x7e,0x60,0x35,0x70,0x60,0x7c,0xc0,0x81,0xe3,0x00,0xab,0x41,0x60,0xc0,0xfb,0x84,0x6f,0x21,0xc4,0x51,0x00,0x38,0xb4,0x60,0x37,0x0f,0x84,0x3c,0x1f,0x03,0xd2,0x27,0x8a,0x90,0x61,0x80,0xf8,0x08,0x9c,0x0e,0x18,0xb5,0x10,0x03,0x70,0x20,0x01,0xd1,0x80,0x77,0xa1,0xf1,0x00,0x7b,0x83,0x44,0x1e,0x5f,0x08,0x3c,0xc0,0x1f,0x83,0x01,0x90,0x03,0xde,0xc0,0x0f,0x33,0xa0,0x81,0x0c,0x00,0x81,0x81,0x07,0xa1,0x18,0x40,0x0c,0x38,0x11,0x51,0xc1,0x8c,0xc2,0x00,0x62,0xc0,0x83,0xcd,0x1c,0x2f,0x07,0x3c,0x08,0x3f,0x61,0x00,0xf4,0x02,0x8b,0x81,0xc0,}; const uint8_t _A_LevelUpPending_128x51_1[] = {0x01,0x00,0xad,0x01,0x00,0x1c,0xfc,0x1d,0xbf,0x0e,0x04,0x04,0x1f,0x90,0xc8,0x04,0x18,0x1f,0x90,0x28,0x04,0x20,0x1d,0x62,0xd2,0x98,0x03,0xfe,0x01,0x80,0xf9,0xdf,0x39,0xd8,0x7f,0x45,0x2e,0xe4,0x2b,0x18,0x04,0x80,0x04,0x34,0x00,0x08,0xc5,0x20,0xb1,0x1c,0x0c,0xa2,0x91,0x8a,0x07,0x94,0x40,0x04,0x38,0x00,0x78,0xc4,0x01,0xe5,0x29,0xa4,0x42,0x81,0xe7,0xf8,0x07,0x8c,0x06,0x81,0xf6,0x9e,0x47,0xf0,0x3e,0xaa,0x48,0xbc,0xe1,0x10,0x48,0x0e,0x02,0x07,0x40,0xaa,0x41,0x03,0xe3,0x2c,0xa4,0x60,0x81,0xe5,0x00,0xba,0x40,0xbe,0x1d,0xfa,0x06,0x50,0x1e,0x43,0xf2,0x07,0x16,0x13,0x75,0x02,0x86,0x70,0x30,0x31,0x3b,0xe8,0x3c,0x7d,0x1b,0x3b,0x88,0x7c,0xa8,0x9f,0xa8,0x14,0x0e,0x00,0xb1,0xad,0x17,0xeb,0x84,0x04,0x10,0x7d,0x50,0xae,0x72,0x20,0x7e,0x68,0x81,0xfd,0x81,0x83,0xc4,0x60,0x1f,0xf0,0x7a,0x29,0x84,0x00,0x74,0x1c,0x61,0x78,0x6a,0xb0,0x0f,0x84,0xf3,0x3f,0xe3,0xe0,0x03,0x8f,0x01,0x3c,0xbc,0x40,0xff,0x1a,0xa5,0x28,0xd1,0x68,0x31,0x4e,0x08,0x94,0xf0,0x16,0x26,0x00,0xd7,0x03,0xe2,0x0f,0x28,0x87,0x00,0xee,0x20,0xf2,0x36,0x96,0xbe,0xd4,0x2f,0x2c,0x78,0xbc,0x41,0xe9,0x82,0x01,0x0d,0x56,0x6a,0x1f,0x18,0xa4,0x06,0x08,0x2f,0x4e,0x00,0x3c,0x78,0x1a,0xa8,0xd0,0x3c,0x64,0x83,0xf2,0x27,0x98,0x3c,0x60,0x3e,0x0a,0xbc,0x34,0x1e,0x34,0x42,0xf8,0x9b,0xd3,0x81,0x83,0x82,0xfe,0x35,0xf0,0xf4,0x74,0xf0,0x20,0x30,0x9f,0xf7,0xfe,0x16,0x0f,0x9f,0x04,0x07,0xf3,0xff,0x07,0xe4,0x03,0x82,0x0f,0x15,0x88,0x83,0xea,0x03,0x0f,0xe0,0x24,0x84,0x01,0x17,0x00,0x78,0xcf,0xa0,0x13,0x30,0x7e,0x7c,0x20,0x13,0x60,0x7e,0x70,0x21,0xf7,0xc0,0x7c,0xca,0x01,0xe3,0x00,0xff,0x5f,0xc1,0xf3,0x38,0x07,0x97,0xc3,0xa6,0x0f,0x98,0xc0,0x3c,0xa8,0x1b,0x00,0x7c,0xc2,0x30,0x10,0x18,0x64,0x03,0x30,0x0f,0xc1,0x90,0xc4,0x1d,0x26,0x00,0x58,0x20,0x3c,0x7c,0x10,0x78,0xe0,0x3f,0x30,0x1f,0xd8,0x38,0xbe,0x60,0x40,0xf1,0x80,0x00,0x86,0x04,0x0f,0x88,0x18,0x3c,0x8c,0x43,0x04,0x07,0xc0,0xb4,0x43,0xe6,0x0f,0x80,0x50,0xd0,0x00,0x83,0xc0,0x81,0xc2,0x01,0xef,0xc0,0x46,0x08,0x10,0x64,0x10,0x20,0x7c,0x03,0x44,0x1e,0x58,0x08,0x1a,0x94,0x40,0x0d,0x60,0x07,0x99,0x90,0x66,0x00,0xf7,0x90,0x03,0xd4,0x0c,0x20,0x06,0x0c,0x08,0x28,0xe0,0xc4,0x61,0x00,0x34,0x40,0x1e,0x8a,0x41,0x77,0x48,0x3d,0x58,0x0e,0x68,0x10,0x79,0x81,0x46,0x06,0x0f,0x60,}; @@ -226,253 +236,264 @@ const uint8_t _A_NoSdCard_128x51_0[] = {0x01,0x00,0x66,0x01,0x00,0x78,0x03,0xc0, const uint8_t _A_NoSdCard_128x51_1[] = {0x01,0x00,0x63,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0x2f,0xf7,0xfe,0x0e,0x0e,0xbe,0x04,0x0e,0x01,0x1c,0x07,0xdd,0xc0,0x04,0x33,0x00,0xcb,0x40,0x40,0xa7,0x08,0x01,0x0d,0x80,0x1e,0xb2,0x00,0x2a,0x43,0x03,0x04,0x02,0x1f,0x04,0x92,0xa9,0x9c,0xf0,0xe1,0x01,0xe7,0x04,0x01,0x0e,0x00,0x50,0x52,0x5a,0xa5,0x4a,0x45,0x85,0x07,0xb4,0x00,0x1e,0x3c,0x08,0xc8,0x3c,0x64,0x19,0xd0,0x7b,0x98,0x84,0x3e,0x55,0xa9,0x16,0x94,0x1e,0x70,0x20,0x1a,0x0f,0xc7,0xf9,0x94,0xe0,0xe7,0x01,0xef,0x06,0x01,0x96,0x00,0xfe,0xc0,0xf3,0x19,0x98,0x01,0xc1,0xe6,0x73,0x20,0x7e,0x24,0xc8,0x1f,0xe0,0x08,0x35,0x90,0x3f,0x11,0x63,0xe0,0x87,0xc6,0x01,0xf4,0xfc,0x1e,0x64,0x62,0x21,0x00,0xe4,0xfc,0x29,0x96,0x49,0x57,0x9d,0xf0,0x70,0xd8,0x06,0x1a,0x3a,0x0f,0x19,0x4e,0x47,0xa5,0x96,0xd5,0x69,0x22,0x40,0xe1,0xf8,0x7f,0xc1,0xe3,0x1f,0x07,0x8f,0xbf,0x23,0x52,0xfa,0x83,0xd2,0x21,0x80,0x83,0xc3,0x81,0xe5,0x29,0xc8,0x54,0xa2,0x9a,0xad,0x34,0x68,0x1e,0x24,0xa1,0x9c,0x42,0x21,0x83,0xf2,0xc8,0xd3,0x3c,0x93,0xec,0xac,0x50,0xd4,0x76,0x0f,0x84,0x1c,0x1e,0x20,0x08,0x55,0x0d,0x00,0x08,0x32,0x00,0x7c,0xf1,0x23,0xe0,0x42,0x07,0xd4,0x92,0x60,0x0f,0xe7,0xb9,0x83,0xea,0x58,0xc0,0x32,0x11,0x67,0x14,0xe2,0x00,0x42,0xf8,0xa9,0x08,0x1e,0x5a,0x26,0x9b,0x03,0x44,0x58,0x40,0xf2,0xc1,0x42,0x39,0x39,0xdb,0x98,0x3c,0xa7,0xc0,0xc3,0x17,0x9c,0x22,0x4b,0x25,0xa4,0x83,0xca,0x66,0x24,0x30,0x79,0x68,0x21,0x12,0x30,0x7a,0x48,0x41,0xe6,0x63,0x21,0xf8,0xe9,0x64,0xb6,0x90,0x51,0x58,0xc1,0xec,0x5f,0x1a,0x4c,0x76,0xa2,0x0a,0x2e,0x14,0x03,0xfc,0x0f,0x40,0x01,0x41,0x00,0x87,0x82,0xff,0xe1,0xc1,0xf9,0x02,0x81,0x83,0x08,0x1e,0xa0,0x04,0x81,0x03,0x0c,0x1f,0x50,0x68,0x07,0xc0,0x1e,0x50,0x10,0x7c,0x0d,0x06,0x30,0x05,0x20,0x7d,0xae,0x0c,0x1f,0xe0,0xff,0x07,0xfc,0x0c,0x1f,0xc7,0x51,0x07,0xcc,0x30,0x1f,0xbf,0x08,0x38,0x7f,0x89,0x66,0x0f,0xb2,0x59,0xa9,0x44,0x00,0xc0,}; const uint8_t *_A_NoSdCard_128x51[] = {_A_NoSdCard_128x51_0,_A_NoSdCard_128x51_1}; -const uint8_t _A_SleepActive_128x51_0[] = {0x01,0x00,0x1c,0x02,0xff,0x80,0x1e,0x1e,0x09,0x80,0x02,0xcf,0xff,0xc0,0xca,0xdf,0x80,0x86,0xff,0xfc,0x05,0x2f,0xec,0x24,0xc0,0xfa,0x80,0x7e,0x01,0xf5,0xe0,0xff,0xc7,0xff,0xfe,0x70,0xfe,0x79,0xe0,0x39,0xc2,0x7d,0x03,0xc6,0x77,0x00,0xb8,0x02,0xc8,0xde,0x9f,0xd0,0x21,0xc3,0x60,0x1c,0x00,0x3a,0x00,0x1e,0x0c,0x95,0x1f,0x98,0x3a,0xaf,0xf0,0x30,0x78,0xfb,0x91,0x77,0x01,0x07,0x8f,0x60,0x1f,0x5d,0xf6,0x29,0x4c,0x01,0xf5,0x5f,0x07,0x97,0x80,0xf8,0x6b,0x42,0x00,0x1d,0xbd,0x3c,0x30,0x0c,0x05,0xce,0x01,0xf0,0x4b,0x90,0x01,0x24,0xf0,0x08,0x21,0x04,0x71,0xdf,0xfc,0x78,0x7d,0xe7,0x30,0x08,0x14,0x08,0x44,0x57,0xc5,0x7b,0x7f,0xe3,0xd0,0x08,0x0c,0x11,0x42,0x30,0xce,0x02,0x0d,0xaf,0xf1,0x38,0x05,0xc4,0x1e,0x3c,0x08,0x3c,0x03,0x9c,0x7e,0x68,0x88,0x3c,0xe0,0x09,0x41,0x9c,0x1f,0x9a,0x20,0x0f,0x42,0x90,0xfa,0x3f,0x06,0xe5,0x07,0x88,0xfc,0xb0,0x01,0x11,0xc2,0x71,0xc1,0xe9,0x2f,0x07,0x89,0x7c,0xb8,0x00,0xf1,0x81,0x4f,0x01,0xe9,0x37,0x07,0x89,0xfc,0xa8,0x03,0x12,0x52,0x27,0xfe,0x36,0x0f,0x13,0xe0,0xc0,0x2c,0x03,0x12,0xc0,0x1c,0x52,0x17,0x18,0x5f,0x94,0x02,0x40,0x21,0x33,0x8a,0x43,0x66,0x80,0xf3,0x98,0x03,0xcc,0xe2,0x90,0x69,0x40,0x3c,0xc6,0x82,0x21,0x17,0x28,0xff,0x81,0xe5,0x02,0x0f,0xa0,0xd0,0x41,0xe5,0xc0,0xfc,0xab,0x8a,0x07,0x68,0x07,0x14,0x06,0x10,0x21,0x20,0x00,0xfd,0xc1,0xe5,0x01,0xfe,0x06,0x4a,0x03,0x0c,0x07,0x9c,0x43,0x9a,0xbe,0x28,0x0e,0x10,0x12,0x26,0xb1,0x50,0x88,0x7c,0xf7,0x40,0xf2,0x4b,0x8c,0x24,0x1e,0x50,0x68,0x00,0xc4,0x60,0x14,0x4b,0xa9,0x40,0x41,0xe5,0x0e,0xc0,0x2b,0x45,0x62,0x20,0xf2,0x80,0x72,0x3f,0xad,0xe1,0x05,0x0c,0x12,0xc0,0x9d,0x17,0x70,0x83,0xca,0x23,0x55,0x50,0x8d,0x7c,0x74,0x30,0x48,0x85,0xc1,0xdc,0x4f,0x32,0x80,0x68,0xbd,0xc0,0xf3,0x81,0x43,0x27,0x18,0x00,0x79,0xd0,0x28,0x95,0x5e,0xeb,0xf8,0x60,0x10,0xa7,0x70,0xc7,0x01,0xe8,0x56,0x1d,0x41,0x80,0x65,0xf0,0x08,0x66,0x06,0x03,0x0e,0x7f,0x19,0xc4,0x6a,0x35,0x5b,0xab,0xf8,0x60,0x11,0xaa,0x0e,0x02,0x0e,0x0f,0x45,0x90,0xe8,0xbd,0x5f,0xe8,0xbc,0x02,0x29,0x21,0xe0,0x40,0x5b,0x84,0x0f,0x1a,0x25,0x50,0x7e,0x3f,0xdb,0xbc,0x02,0x51,0x12,0xfc,0x3b,0x0c,0x82,0x30,0x0c,0x46,0xa3,0x55,0xfb,0x3f,0x8d,0x42,0x3d,0x3e,0x80,0x20,0x04,0x1e,0x31,0x03,0xf0,0xd5,0x6e,0xff,0x75,0xf8,0xea,0x3f,0x10,0xf8,0x02,0x00,0x43,0xe7,0x22,0xd5,0x6a,0xbd,0xd7,0xfa,0x1d,0x53,0x02,0x9c,0x19,0xc0,0x30,0x68,0xb4,0x43,0xf0,0xf5,0x7b,0xa8,0x01,0x83,0x68,0x38,0xc0,0xc1,0x9e,0x34,0x88,0x7c,0x38,0x80,0xf8,0xa0,0x06,0x3b,0x51,0x9e,0x82,0x86,0x7f,0x11,0xc8,0xc4,0x47,0xc5,0x75,0x1f,0x8f,0xfe,0x77,0xa0,0x95,0x40,0x38,0x13,0xf0,0xf9,0x48,0x24,0x5a,0x20,0xf8,0xda,0xbf,0xfe,0xfa,0xa7,0xd6,0x01,0xfc,0xbf,0xd1,0x38,0x81,0xd1,0x00,0x08,0xf8,0x47,0xe3,0xbf,0xc5,0xea,0xbf,0xff,0xb0,0xf8,0xf0,0x07,0xa2,0x3e,0x20,0x00,0xff,0xff,0xf7,0xe0,0xc1,0x0f,0xc5,0x76,0x20,0x02,0xbb,0x8f,0xc4,}; -const uint8_t _A_SleepActive_128x51_1[] = {0x01,0x00,0x42,0x02,0xff,0x80,0x1e,0x1e,0x09,0x80,0x02,0xcf,0xff,0xc0,0xca,0xdf,0x80,0x86,0xff,0xfc,0x05,0x2f,0xec,0x24,0xc0,0xfa,0x80,0x7e,0x01,0xf5,0xe0,0xff,0xc7,0xff,0xfe,0x70,0xfe,0x79,0xe0,0x39,0xc2,0x7d,0x03,0xc6,0x77,0x00,0xb8,0x02,0xc8,0xde,0x9f,0xd0,0x21,0xc3,0x60,0x1c,0x00,0x3a,0x00,0x1e,0x0c,0x95,0x1f,0x9c,0x0d,0x3d,0x37,0xf0,0x59,0x7b,0xa0,0x20,0xf6,0x1c,0x16,0xfc,0x16,0x5d,0x89,0x0c,0x97,0x1d,0x39,0x98,0x4a,0x63,0x20,0xf3,0xef,0x85,0x8a,0x60,0x0f,0x1a,0x94,0x2a,0x91,0xa9,0x92,0x03,0xce,0xbe,0x0f,0x2f,0x07,0x86,0x73,0x4e,0x9c,0x42,0x2d,0xd3,0xc0,0x79,0xdb,0xd3,0xc3,0x00,0xc0,0x48,0x64,0x21,0xf2,0xd4,0x07,0xd2,0x4f,0x00,0x82,0x10,0x46,0x43,0x39,0xc7,0x6e,0xe6,0x32,0x6d,0x2c,0x04,0x1e,0x53,0x98,0x04,0x0a,0x05,0x00,0x2f,0x98,0x0c,0x81,0xe7,0x1e,0x02,0x8c,0x10,0x1e,0x86,0xf5,0xbf,0xc4,0xe0,0x17,0x10,0x7d,0xef,0xe2,0x20,0xfd,0xef,0xc4,0x01,0xe7,0xe1,0x91,0x67,0x27,0x77,0x7e,0x65,0x54,0x7e,0x56,0xf0,0x78,0x8f,0xca,0x83,0x22,0xd1,0x52,0x22,0x35,0x2a,0xa0,0x3c,0xa5,0xe0,0xf1,0x2f,0x95,0x06,0x4d,0xa2,0x9c,0x5d,0xfb,0xd5,0x58,0x38,0x3c,0x66,0xe0,0xf1,0x3f,0x95,0x06,0x55,0xa2,0x84,0x64,0x43,0xe3,0x09,0x07,0x8c,0x6c,0x1e,0x29,0xf2,0xa0,0x4b,0xb3,0x90,0x8b,0xbf,0x4a,0xfb,0x27,0x07,0x8c,0x2e,0x30,0x56,0x2a,0x01,0x79,0x8b,0xe5,0x0d,0x9a,0x01,0x8a,0x40,0x0f,0x74,0xf0,0xc1,0xa5,0x00,0x62,0xf8,0x01,0xc4,0x00,0xf0,0x20,0xf9,0xc0,0x06,0x82,0x22,0x2e,0x07,0xe4,0x1c,0x37,0xf8,0x1d,0xa1,0x94,0x70,0x88,0x01,0x58,0x40,0x03,0xf7,0x07,0x94,0x07,0xf8,0x19,0x28,0x0c,0x30,0x1e,0x71,0x0e,0x68,0x3c,0x77,0xf0,0x1c,0x20,0x24,0x70,0x08,0x21,0x0f,0xa6,0xe8,0x1e,0x49,0xd1,0x84,0x83,0xca,0x0d,0x00,0x18,0x8c,0x02,0x89,0x75,0x6f,0x10,0x3c,0x61,0xd8,0x0e,0x00,0x10,0x41,0xe7,0x00,0xe4,0x7f,0x5b,0xc2,0x0a,0x18,0x25,0x82,0xc1,0x00,0x81,0x83,0xce,0x23,0x55,0xf9,0xff,0xeb,0xe3,0xa1,0x82,0x46,0x2e,0x0f,0xf2,0x20,0x88,0x00,0x74,0x5e,0xe0,0x79,0xc0,0xa1,0x93,0x8c,0x00,0x3c,0xe8,0x14,0x4a,0xaf,0x75,0xfc,0x30,0x08,0x51,0x00,0x63,0x80,0xf4,0x2b,0x0e,0xa0,0xc0,0x32,0xf8,0x04,0x33,0x03,0x07,0x87,0x14,0x04,0xa2,0x51,0x0a,0x8d,0x56,0xea,0xfe,0x18,0x04,0x6b,0x83,0x83,0x83,0x83,0xd1,0x64,0x3a,0x2f,0x57,0xfa,0x2f,0x00,0x8a,0x78,0x78,0x30,0x17,0x79,0x03,0xc6,0x89,0x54,0x1f,0x8f,0xf6,0xef,0x00,0x94,0x7c,0xbe,0x0f,0xf3,0x20,0x8c,0x03,0x11,0xa8,0xd5,0x7e,0xcf,0xe3,0x50,0x9f,0x4f,0x20,0x08,0x01,0x07,0x8c,0x40,0xfc,0x35,0x5b,0xbf,0xdd,0x7e,0x3a,0x8b,0xc4,0x3e,0x00,0x80,0x10,0xf9,0xc8,0xb5,0x5a,0xaf,0x75,0xfe,0x87,0x54,0xe0,0xa7,0x06,0x70,0x0c,0x1a,0x2d,0x10,0xfc,0x3d,0x5e,0xea,0x00,0x60,0xda,0x0e,0x30,0x30,0x46,0x22,0xd2,0x11,0xf0,0xe2,0x03,0xe2,0x80,0x18,0xed,0x46,0x7a,0x0a,0x19,0xfc,0x47,0x23,0x11,0x1f,0x15,0xd4,0x7e,0x3f,0xf9,0xde,0x82,0x55,0x00,0xe0,0x4f,0xc3,0xe5,0x20,0x91,0x68,0x83,0xe3,0x6a,0xff,0xfb,0xea,0x9f,0x58,0x07,0xf2,0xff,0x44,0xe2,0x07,0x44,0x00,0x23,0xe1,0x1f,0x8e,0xff,0x17,0xaa,0xff,0xfe,0xc3,0xe3,0xc0,0x1e,0x88,0xf8,0x80,0x03,0xff,0xff,0xdf,0x83,0x04,0x3f,0x15,0xd8,0x80,0x0a,0xee,0x3f,0x10,}; -const uint8_t *_A_SleepActive_128x51[] = {_A_SleepActive_128x51_0,_A_SleepActive_128x51_1}; +const uint8_t _A_SleepActive_128x52_0[] = {0x01,0x00,0x31,0x02,0xff,0x80,0x3c,0x00,0xf0,0xf0,0x65,0xef,0xc0,0x43,0x3f,0xff,0x03,0xea,0x3e,0x02,0x1b,0xff,0xf0,0x3f,0xa0,0xf7,0xfd,0x8a,0x46,0x00,0x2a,0x30,0x7b,0xfc,0x7f,0xfc,0x7f,0xff,0xe4,0x1f,0x41,0xf1,0xbc,0xc0,0x3c,0xe0,0x72,0x27,0xa7,0xf4,0x22,0x70,0xe8,0x06,0x70,0xde,0xff,0x81,0x41,0xc0,0xe0,0x17,0x02,0xbb,0x87,0xcf,0x7f,0x01,0x80,0x70,0x0d,0x77,0xdf,0x5a,0x0e,0x00,0x88,0x20,0x09,0xb7,0xb1,0x4b,0xec,0x0f,0xa9,0xb8,0x3c,0xb9,0x80,0xfa,0x8b,0x83,0xca,0x70,0x0f,0xa8,0xdc,0x02,0x7d,0x00,0xf0,0x47,0x20,0x05,0x21,0x5a,0x10,0x00,0xe1,0xb0,0x0a,0x09,0x40,0x7c,0x7f,0xfe,0x18,0x35,0x7e,0xf7,0xf8,0x36,0x03,0x00,0x30,0x11,0x10,0xcf,0x8e,0x6d,0xbf,0x83,0xd0,0x20,0x08,0x11,0x8e,0x40,0xfc,0x02,0x21,0x3f,0x2c,0x12,0x81,0x1c,0x07,0x8f,0xc0,0x04,0x31,0xe0,0x69,0xb1,0x06,0xde,0x0f,0x4e,0x00,0xc8,0x7f,0x03,0x05,0x9b,0x83,0xd0,0x66,0x2d,0x41,0xf9,0x9b,0x94,0x1e,0x23,0xf2,0x90,0x03,0xc6,0xc7,0xce,0x07,0xa4,0x2e,0x08,0x5f,0x39,0x81,0xc8,0x70,0x13,0x93,0xf2,0xc1,0x0f,0xe5,0x00,0x88,0x0c,0x4b,0xcc,0x40,0x48,0x30,0x3c,0x4f,0x83,0x00,0x8c,0x0c,0x4b,0x30,0x40,0x48,0x10,0x3c,0x40,0x05,0x08,0x10,0x89,0xa8,0x79,0xe0,0xe2,0xbf,0xc0,0xc1,0x42,0x00,0x28,0x64,0x03,0xa1,0x01,0xe0,0x4f,0x13,0xc7,0x01,0x07,0xa0,0x90,0x67,0x05,0x11,0xf0,0x90,0x0b,0x7e,0x2a,0x20,0x01,0x41,0x88,0x25,0x00,0xc3,0x7e,0xd5,0xc4,0x5a,0x22,0xd9,0x40,0xa0,0x17,0xc2,0x21,0x79,0x81,0xe3,0x5f,0x2e,0x88,0x80,0x41,0xe3,0x03,0x80,0x61,0x00,0x43,0x30,0xee,0x03,0xc6,0xdf,0x00,0x90,0x8e,0xc6,0xc0,0xa1,0x28,0x21,0x48,0x68,0x13,0x00,0x78,0xcb,0xf0,0x14,0x01,0x58,0xc8,0x30,0x00,0xf1,0x81,0x28,0x8b,0xc2,0x73,0x10,0x78,0xe0,0x20,0x72,0x09,0x82,0xc4,0xa0,0x5c,0x0c,0x07,0xff,0x07,0xfd,0x6f,0x08,0x28,0x60,0x31,0x88,0xc0,0x3c,0xf0,0x17,0xf2,0x98,0x98,0x06,0x2e,0x0e,0x18,0x0c,0x12,0x38,0xfe,0x24,0x70,0x9c,0xc7,0x31,0xf7,0x07,0x96,0x04,0xb8,0x30,0xe7,0xf1,0x40,0x4c,0xe5,0x20,0xf7,0x3f,0x86,0x01,0x82,0x16,0x0c,0x1c,0xc0,0x30,0x0f,0x0c,0x04,0xa0,0x34,0x0e,0xc3,0xf8,0x60,0x14,0x2b,0x01,0x44,0x8b,0x63,0x1c,0x42,0x96,0x03,0x60,0xfe,0x18,0x05,0x12,0x21,0xe0,0x80,0x83,0xc9,0x1c,0x27,0x42,0xb0,0xff,0xe0,0xa0,0xf1,0x84,0x5c,0x13,0x22,0x0c,0x35,0xa1,0x70,0xbf,0xd1,0xd8,0x06,0x22,0x09,0x3e,0x61,0x95,0x00,0xba,0x2f,0x42,0xc2,0x7f,0x66,0xf0,0x0c,0x86,0x1e,0x1e,0xdc,0x2a,0x03,0x7c,0x82,0xa3,0x78,0xfd,0xaf,0xc6,0x41,0xfe,0x1d,0x0a,0xec,0x8c,0x44,0xb6,0x1c,0xbf,0xdd,0xde,0x34,0x0f,0x00,0x24,0x61,0xc0,0x51,0x20,0x15,0x02,0xfd,0x20,0xfb,0x6f,0xe0,0x38,0x09,0x88,0x3c,0x46,0x22,0x61,0x12,0x00,0xfc,0x20,0x34,0x0f,0x65,0xfe,0x0e,0x0c,0x2e,0x00,0x10,0x41,0xe2,0x40,0x18,0x78,0x6c,0x52,0x02,0x2a,0x18,0x50,0x60,0x41,0xe7,0x60,0xfc,0x34,0xcb,0xa1,0xff,0x9d,0xc0,0x27,0xb0,0x0f,0xf8,0x3c,0x50,0x22,0x24,0x28,0x24,0x03,0x63,0xff,0xf7,0xc0,0x3d,0x5f,0xf3,0x09,0x1a,0xc6,0x7c,0x40,0x16,0x88,0xd8,0xbf,0xfb,0xf8,0x3d,0x52,0xab,0xd5,0x07,0x8f,0xc3,0xff,0x01,0x06,0x88,0x50,0x68,0x80,}; +const uint8_t _A_SleepActive_128x52_1[] = {0x01,0x00,0x29,0x02,0xff,0x80,0x3c,0x00,0xf0,0xf0,0x65,0xef,0xc0,0x43,0x3f,0xff,0x03,0xea,0x3e,0x02,0x1b,0xff,0xf0,0x3f,0xa0,0xf7,0xfd,0x8a,0x46,0x00,0x2a,0x30,0x7b,0xfc,0x7f,0xfc,0x7f,0xff,0xe4,0x1f,0x41,0xf1,0xbc,0xc0,0x3c,0xe6,0x9c,0x87,0x40,0x33,0x91,0xf4,0x73,0xe0,0x05,0x05,0x03,0x80,0x5c,0x01,0xf7,0xbf,0x80,0xc0,0x38,0x11,0xc0,0x7d,0x77,0xc0,0xa5,0x1b,0x81,0x40,0x20,0x94,0x08,0x44,0x10,0x1e,0x96,0xf0,0xb1,0x45,0x81,0xe5,0x00,0x07,0xb4,0xdc,0x1e,0x51,0xc9,0xd4,0xe3,0x29,0x4c,0x87,0x5d,0xf8,0xdd,0xd0,0x79,0x45,0xc1,0xe5,0x18,0xa5,0x49,0x32,0x95,0x2c,0x4c,0x52,0x53,0x25,0xc0,0x83,0xc6,0x37,0x00,0x9f,0x40,0x22,0x00,0xf2,0xa1,0x03,0xc6,0x5e,0x0f,0x38,0x6c,0x02,0x82,0x0f,0x40,0xf9,0x48,0x64,0xb8,0x9f,0xbd,0xfe,0x0d,0x80,0xc0,0x03,0xca,0x71,0xe4,0x1f,0x8c,0x5f,0x8c,0x0f,0x13,0xf0,0xc1,0xe8,0x10,0x08,0x0c,0x40,0xfe,0xf8,0x43,0xf0,0x9e,0x06,0x38,0x0f,0x92,0xf8,0xdb,0xc1,0xfd,0x37,0x07,0xf4,0x6c,0x1e,0x23,0xf3,0x02,0x08,0xec,0x40,0x43,0x05,0x07,0x8c,0x2e,0x08,0x5f,0x30,0x7c,0xc3,0x56,0xa2,0x7f,0x20,0x78,0xcc,0x24,0xde,0x5a,0x45,0xca,0x4a,0x0f,0x18,0x30,0x3c,0x53,0xe4,0x0f,0x1a,0x44,0xa7,0x2b,0x48,0xa5,0x45,0x41,0xe3,0x02,0x6a,0x90,0x3c,0xe1,0x00,0xf3,0x86,0xe0,0x2f,0xf0,0x38,0x40,0x3d,0x43,0xed,0xbf,0x80,0x83,0xda,0x61,0xc6,0xf2,0xec,0x2e,0x3a,0x5c,0x56,0xfe,0x00,0x0f,0x53,0xfb,0xf7,0xc1,0x66,0x3c,0x10,0x7c,0x57,0xcb,0xa2,0x0c,0x1a,0x01,0x4c,0xc1,0xeb,0x6f,0x80,0x48,0x41,0x83,0x60,0x81,0x03,0xe2,0x5f,0x80,0xa0,0x03,0x06,0x41,0xff,0x00,0x40,0x3c,0x70,0x10,0x39,0x04,0xc1,0x62,0x30,0x08,0x17,0x01,0x16,0x38,0x3f,0xeb,0x78,0x41,0x43,0x01,0x8c,0x46,0x01,0xe6,0x8a,0x18,0x05,0xf3,0xf7,0xff,0x8b,0x83,0x86,0x03,0x0c,0x8e,0x70,0x01,0xe3,0x01,0xe0,0x41,0xa0,0x19,0x8f,0xb8,0x3c,0xb0,0x30,0x08,0x3c,0x39,0xba,0x50,0x13,0x39,0x48,0x3d,0xcf,0xe1,0x80,0x60,0x88,0x03,0x07,0xb0,0x03,0xc7,0xc3,0x01,0x98,0x1d,0xc7,0xb0,0xfe,0x18,0x05,0x0a,0xc1,0x81,0x28,0x89,0xa0,0x63,0x80,0xd1,0x02,0x0e,0xc1,0xfc,0x30,0x0a,0x26,0xc3,0xc1,0x01,0x07,0x94,0x0c,0x04,0x30,0x18,0x05,0x87,0xff,0x05,0x07,0x8d,0x62,0xe1,0x00,0x15,0x08,0x30,0x8c,0x43,0x00,0xe1,0x7f,0xa3,0xb0,0x0c,0x44,0xf2,0x78,0xdf,0x32,0xe8,0xc0,0x21,0x90,0x0c,0x27,0xf6,0x6f,0x00,0xc8,0x47,0xe1,0xf0,0x08,0xc0,0x3c,0x40,0x42,0x15,0x2b,0xc7,0xed,0x7e,0x32,0x0e,0x40,0xe8,0x43,0x23,0x40,0x31,0x14,0x83,0x01,0x97,0xfb,0xbb,0xc6,0x81,0xf8,0x04,0x8c,0x38,0x0a,0x24,0x02,0xa0,0x5f,0xa4,0x1f,0x6d,0xfc,0x07,0x01,0x31,0x07,0x88,0xc4,0x4c,0x22,0x40,0x1f,0x84,0x06,0x81,0xec,0xbf,0xc1,0xc1,0x85,0xc0,0x02,0x08,0x3c,0x48,0x03,0x0f,0x0d,0x8a,0x40,0x45,0x43,0x0a,0x0c,0x08,0x3c,0xec,0x03,0x71,0x69,0x8f,0x43,0xff,0x3b,0x80,0x4f,0x60,0x1f,0xf0,0x78,0xa0,0x44,0x48,0x50,0x48,0x06,0xc7,0xff,0xef,0x80,0x7a,0xbf,0xff,0xe3,0x08,0x9a,0xc6,0x7c,0x40,0x16,0x88,0xd8,0xbf,0xfb,0xf8,0x3d,0x52,0xab,0xd5,0x07,0x8f,0xc3,0xff,0x01,0x06,0x88,0x50,0x68,0x80,}; +const uint8_t _A_SleepActive_128x52_2[] = {0x01,0x00,0x22,0x02,0xff,0x80,0x3c,0x00,0xf0,0xf0,0x7f,0x4f,0xff,0xc0,0xca,0xdf,0x80,0x86,0xff,0xfc,0x0f,0xe8,0x3e,0x67,0xf0,0x01,0x51,0x83,0xdf,0xf7,0xff,0xe3,0xff,0xff,0x20,0xf7,0xfe,0x84,0x4e,0xf3,0x00,0xf3,0x8e,0x72,0x1d,0x00,0xce,0x47,0xd1,0xcf,0x80,0x14,0x14,0x0e,0x01,0x70,0x07,0xde,0xfe,0x03,0x00,0xe0,0x47,0x01,0xf5,0xdf,0x02,0x94,0x6e,0x05,0x00,0x82,0x50,0x21,0x10,0x40,0x7a,0x5b,0xc2,0xc5,0x16,0x07,0x94,0x00,0x1e,0xd3,0x70,0x79,0x47,0x27,0x53,0x8c,0xa5,0x32,0x1d,0x77,0xe3,0x77,0x41,0xe5,0x17,0x07,0x94,0x62,0x95,0x24,0xca,0x54,0xb1,0x31,0x49,0x4c,0x97,0x02,0x0f,0x18,0xdc,0x02,0x7d,0x00,0x88,0x03,0xca,0x84,0x0f,0x19,0x78,0x3c,0xe1,0xb0,0x0a,0x08,0x3d,0x03,0xe5,0x21,0x92,0xe2,0x4f,0xc3,0x06,0xc0,0x60,0x01,0xe5,0x38,0xf2,0x0f,0xc6,0x2f,0xc6,0x07,0x96,0xfe,0x0f,0x40,0x80,0x40,0x62,0x07,0xf7,0xc2,0x1f,0x84,0xf0,0x31,0xc0,0x7c,0x97,0xc6,0xde,0x0f,0xe9,0xb8,0x3f,0xa3,0x60,0xf1,0x1f,0x98,0x10,0x47,0x62,0x02,0x18,0x28,0x3c,0x61,0x70,0x42,0xf9,0x83,0xe6,0x1a,0xb5,0x13,0xf9,0x03,0xc6,0x61,0x26,0xf2,0xd2,0x2e,0x52,0x50,0x78,0xc1,0x81,0xe2,0x9f,0x20,0x78,0xd2,0x25,0x39,0x5a,0x45,0x2a,0x2a,0x0f,0x18,0x13,0x54,0x81,0xe7,0x08,0x07,0x9c,0x37,0x01,0x7f,0x81,0xc2,0x01,0xea,0x1f,0x6d,0xfc,0x04,0x1e,0xd3,0x0e,0x37,0x97,0x61,0x71,0xd2,0xe2,0xb7,0xf0,0x00,0x7a,0x9f,0xdf,0xbe,0x0b,0x31,0xe0,0x83,0xe2,0xbe,0x5d,0x10,0x60,0xd0,0x0a,0x66,0x0f,0x5b,0x7c,0x02,0x42,0x0c,0x1b,0x04,0x08,0x1f,0x12,0xfc,0x05,0x00,0x18,0x32,0x0f,0xf8,0x02,0x01,0xe3,0x80,0x81,0xc8,0x26,0x0b,0x11,0x80,0x40,0xb8,0x08,0xb1,0xc1,0xff,0x5b,0xc2,0x0a,0x18,0x0c,0x62,0x30,0x0f,0x34,0x50,0xc0,0x2f,0x9f,0xbf,0xfc,0x5c,0x1c,0x30,0x18,0x24,0x73,0x80,0x0f,0x18,0x0f,0x02,0x0d,0x00,0xcc,0x7d,0xc1,0xe5,0x81,0x80,0x40,0xe1,0xcd,0xd2,0x80,0x99,0xca,0x41,0xee,0x7f,0x0c,0x03,0x04,0x2c,0x18,0x3d,0x80,0x1e,0x3e,0x18,0x0c,0xc0,0xee,0x3d,0x87,0xf0,0xc0,0x28,0x56,0x02,0x89,0x1a,0x06,0x38,0x0d,0x10,0x20,0xec,0x1f,0xc3,0x00,0xa2,0x44,0x3c,0x10,0x10,0x79,0x40,0xc0,0x43,0x01,0x80,0x58,0x7f,0xf0,0x50,0x78,0xc2,0x2e,0x10,0x01,0x50,0x83,0x08,0xc4,0x30,0x0e,0x17,0xfa,0x3b,0x00,0xc4,0x41,0x27,0xcd,0xf3,0x2e,0x8c,0x02,0x19,0x00,0xc2,0x7f,0x66,0xf0,0x0c,0x86,0x1e,0x1f,0x00,0x8c,0x03,0xc4,0x04,0x21,0x52,0xbc,0x7e,0xd7,0xe3,0x20,0xff,0x0e,0x84,0x32,0x34,0x03,0x11,0x48,0x30,0x19,0x7f,0xbb,0xbc,0x68,0x1e,0x00,0x48,0xc3,0x80,0xa2,0x40,0x2a,0x05,0xfa,0x41,0xf6,0xdf,0xc0,0x70,0x13,0x10,0x78,0x8c,0x44,0xc2,0x24,0x01,0xf8,0x40,0x68,0x1e,0xcb,0xfc,0x1c,0x18,0x5c,0x00,0x20,0x83,0xc4,0x80,0x30,0xf0,0xd8,0xa4,0x04,0x54,0x30,0xa0,0xc0,0x83,0xce,0xc1,0xf8,0x69,0x97,0x43,0xff,0x3b,0x80,0x4f,0x60,0x1f,0xf0,0x78,0xa0,0x44,0x48,0x50,0x48,0x06,0xc7,0xff,0xef,0x80,0x7a,0xbf,0xe6,0x12,0x35,0x8c,0xf8,0x80,0x2d,0x11,0xb1,0x7f,0xf7,0xf0,0x7a,0xa5,0x57,0xaa,0x0f,0x1f,0x87,0xfe,0x02,0x0d,0x10,0xa0,0xd1,0x00,}; +const uint8_t _A_SleepActive_128x52_3[] = {0x01,0x00,0x29,0x02,0xff,0x80,0x3c,0x00,0xf0,0xf0,0x65,0xef,0xc0,0x43,0x3f,0xff,0x03,0xea,0x3e,0x02,0x1b,0xff,0xf0,0x3f,0xa0,0xf7,0xfd,0x8a,0x46,0x00,0x2a,0x30,0x7b,0xfc,0x7f,0xfc,0x7f,0xff,0xe4,0x1f,0x41,0xf1,0xbc,0xc0,0x3c,0xe6,0x9c,0x87,0x40,0x33,0x91,0xf4,0x73,0xe0,0x05,0x05,0x03,0x80,0x5c,0x01,0xf7,0xbf,0x80,0xc0,0x38,0x11,0xc0,0x7d,0x77,0xc0,0xa5,0x1b,0x81,0x40,0x20,0x94,0x08,0x44,0x10,0x1e,0x96,0xf0,0xb1,0x45,0x81,0xe5,0x00,0x07,0xb4,0xdc,0x1e,0x51,0xc9,0xd4,0xe3,0x29,0x4c,0x87,0x5d,0xf8,0xdd,0xd0,0x79,0x45,0xc1,0xe5,0x18,0xa5,0x49,0x32,0x95,0x2c,0x4c,0x52,0x53,0x25,0xc0,0x83,0xc6,0x37,0x00,0x9f,0x40,0x22,0x00,0xf2,0xa1,0x03,0xc6,0x5e,0x0f,0x38,0x6c,0x02,0x82,0x0f,0x40,0xf9,0x48,0x64,0xb8,0x9f,0xbd,0xfe,0x0d,0x80,0xc0,0x03,0xca,0x71,0xe4,0x1f,0x8c,0x5f,0x8c,0x0f,0x13,0xf0,0xc1,0xe8,0x10,0x08,0x0c,0x40,0xfe,0xf8,0x43,0xf0,0x9e,0x06,0x38,0x0f,0x92,0xf8,0xdb,0xc1,0xfd,0x37,0x07,0xf4,0x6c,0x1e,0x23,0xf3,0x02,0x08,0xec,0x40,0x43,0x05,0x07,0x8c,0x2e,0x08,0x5f,0x30,0x7c,0xc3,0x56,0xa2,0x7f,0x20,0x78,0xcc,0x24,0xde,0x5a,0x45,0xca,0x4a,0x0f,0x18,0x30,0x3c,0x53,0xe4,0x0f,0x1a,0x44,0xa7,0x2b,0x48,0xa5,0x45,0x41,0xe3,0x02,0x6a,0x90,0x3c,0xe1,0x00,0xf3,0x86,0xe0,0x2f,0xf0,0x38,0x40,0x3d,0x43,0xed,0xbf,0x80,0x83,0xda,0x61,0xc6,0xf2,0xec,0x2e,0x3a,0x5c,0x56,0xfe,0x00,0x0f,0x53,0xfb,0xf7,0xc1,0x66,0x3c,0x10,0x7c,0x57,0xcb,0xa2,0x0c,0x1a,0x01,0x4c,0xc1,0xeb,0x6f,0x80,0x48,0x41,0x83,0x60,0x81,0x03,0xe2,0x5f,0x80,0xa0,0x03,0x06,0x41,0xff,0x00,0x40,0x3c,0x70,0x10,0x39,0x04,0xc1,0x62,0x30,0x08,0x17,0x01,0x16,0x38,0x3f,0xeb,0x78,0x41,0x43,0x01,0x8c,0x46,0x01,0xe6,0x8a,0x18,0x05,0xf3,0xf7,0xff,0x8b,0x83,0x86,0x03,0x0c,0x8e,0x70,0x01,0xe3,0x01,0xe0,0x41,0xa0,0x19,0x8f,0xb8,0x3c,0xb0,0x30,0x08,0x3c,0x39,0xba,0x50,0x13,0x39,0x48,0x3d,0xcf,0xe1,0x80,0x60,0x88,0x03,0x07,0xb0,0x03,0xc7,0xc3,0x01,0x98,0x1d,0xc7,0xb0,0xfe,0x18,0x05,0x0a,0xc1,0x81,0x28,0x89,0xa0,0x63,0x80,0xd1,0x02,0x0e,0xc1,0xfc,0x30,0x0a,0x26,0xc3,0xc1,0x01,0x07,0x94,0x0c,0x04,0x30,0x18,0x05,0x87,0xff,0x05,0x07,0x8d,0x62,0xe1,0x00,0x15,0x08,0x30,0x8c,0x43,0x00,0xe1,0x7f,0xa3,0xb0,0x0c,0x44,0xf2,0x78,0xdf,0x32,0xe8,0xc0,0x21,0x90,0x0c,0x27,0xf6,0x6f,0x00,0xc8,0x47,0xe1,0xf0,0x08,0xc0,0x3c,0x40,0x42,0x15,0x2b,0xc7,0xed,0x7e,0x32,0x0e,0x40,0xe8,0x43,0x23,0x40,0x31,0x14,0x83,0x01,0x97,0xfb,0xbb,0xc6,0x81,0xf8,0x04,0x8c,0x38,0x0a,0x24,0x02,0xa0,0x5f,0xa4,0x1f,0x6d,0xfc,0x07,0x01,0x31,0x07,0x88,0xc4,0x4c,0x22,0x40,0x1f,0x84,0x06,0x81,0xec,0xbf,0xc1,0xc1,0x85,0xc0,0x02,0x08,0x3c,0x48,0x03,0x0f,0x0d,0x8a,0x40,0x45,0x43,0x0a,0x0c,0x08,0x3c,0xec,0x03,0x71,0x69,0x8f,0x43,0xff,0x3b,0x80,0x4f,0x60,0x1f,0xf0,0x78,0xa0,0x44,0x48,0x50,0x48,0x06,0xc7,0xff,0xef,0x80,0x7a,0xbf,0xff,0xe3,0x08,0x9a,0xc6,0x7c,0x40,0x16,0x88,0xd8,0xbf,0xfb,0xf8,0x3d,0x52,0xab,0xd5,0x07,0x8f,0xc3,0xff,0x01,0x06,0x88,0x50,0x68,0x80,}; +const uint8_t _A_SleepActive_128x52_4[] = {0x01,0x00,0x22,0x02,0xff,0x80,0x3c,0x00,0xf0,0xf0,0x7f,0x4f,0xff,0xc0,0xca,0xdf,0x80,0x86,0xff,0xfc,0x0f,0xe8,0x3e,0x67,0xf0,0x01,0x51,0x83,0xdf,0xf7,0xff,0xe3,0xff,0xff,0x20,0xf7,0xfe,0x84,0x4e,0xf3,0x00,0xf3,0x8e,0x72,0x1d,0x00,0xce,0x47,0xd1,0xcf,0x80,0x14,0x14,0x0e,0x01,0x70,0x07,0xde,0xfe,0x03,0x00,0xe0,0x47,0x01,0xf5,0xdf,0x02,0x94,0x6e,0x05,0x00,0x82,0x50,0x21,0x10,0x40,0x7a,0x5b,0xc2,0xc5,0x16,0x07,0x94,0x00,0x1e,0xd3,0x70,0x79,0x47,0x27,0x53,0x8c,0xa5,0x32,0x1d,0x77,0xe3,0x77,0x41,0xe5,0x17,0x07,0x94,0x62,0x95,0x24,0xca,0x54,0xb1,0x31,0x49,0x4c,0x97,0x02,0x0f,0x18,0xdc,0x02,0x7d,0x00,0x88,0x03,0xca,0x84,0x0f,0x19,0x78,0x3c,0xe1,0xb0,0x0a,0x08,0x3d,0x03,0xe5,0x21,0x92,0xe2,0x4f,0xc3,0x06,0xc0,0x60,0x01,0xe5,0x38,0xf2,0x0f,0xc6,0x2f,0xc6,0x07,0x96,0xfe,0x0f,0x40,0x80,0x40,0x62,0x07,0xf7,0xc2,0x1f,0x84,0xf0,0x31,0xc0,0x7c,0x97,0xc6,0xde,0x0f,0xe9,0xb8,0x3f,0xa3,0x60,0xf1,0x1f,0x98,0x10,0x47,0x62,0x02,0x18,0x28,0x3c,0x61,0x70,0x42,0xf9,0x83,0xe6,0x1a,0xb5,0x13,0xf9,0x03,0xc6,0x61,0x26,0xf2,0xd2,0x2e,0x52,0x50,0x78,0xc1,0x81,0xe2,0x9f,0x20,0x78,0xd2,0x25,0x39,0x5a,0x45,0x2a,0x2a,0x0f,0x18,0x13,0x54,0x81,0xe7,0x08,0x07,0x9c,0x37,0x01,0x7f,0x81,0xc2,0x01,0xea,0x1f,0x6d,0xfc,0x04,0x1e,0xd3,0x0e,0x37,0x97,0x61,0x71,0xd2,0xe2,0xb7,0xf0,0x00,0x7a,0x9f,0xdf,0xbe,0x0b,0x31,0xe0,0x83,0xe2,0xbe,0x5d,0x10,0x60,0xd0,0x0a,0x66,0x0f,0x5b,0x7c,0x02,0x42,0x0c,0x1b,0x04,0x08,0x1f,0x12,0xfc,0x05,0x00,0x18,0x32,0x0f,0xf8,0x02,0x01,0xe3,0x80,0x81,0xc8,0x26,0x0b,0x11,0x80,0x40,0xb8,0x08,0xb1,0xc1,0xff,0x5b,0xc2,0x0a,0x18,0x0c,0x62,0x30,0x0f,0x34,0x50,0xc0,0x2f,0x9f,0xbf,0xfc,0x5c,0x1c,0x30,0x18,0x24,0x73,0x80,0x0f,0x18,0x0f,0x02,0x0d,0x00,0xcc,0x7d,0xc1,0xe5,0x81,0x80,0x40,0xe1,0xcd,0xd2,0x80,0x99,0xca,0x41,0xee,0x7f,0x0c,0x03,0x04,0x2c,0x18,0x3d,0x80,0x1e,0x3e,0x18,0x0c,0xc0,0xee,0x3d,0x87,0xf0,0xc0,0x28,0x56,0x02,0x89,0x1a,0x06,0x38,0x0d,0x10,0x20,0xec,0x1f,0xc3,0x00,0xa2,0x44,0x3c,0x10,0x10,0x79,0x40,0xc0,0x43,0x01,0x80,0x58,0x7f,0xf0,0x50,0x78,0xc2,0x2e,0x10,0x01,0x50,0x83,0x08,0xc4,0x30,0x0e,0x17,0xfa,0x3b,0x00,0xc4,0x41,0x27,0xcd,0xf3,0x2e,0x8c,0x02,0x19,0x00,0xc2,0x7f,0x66,0xf0,0x0c,0x86,0x1e,0x1f,0x00,0x8c,0x03,0xc4,0x04,0x21,0x52,0xbc,0x7e,0xd7,0xe3,0x20,0xff,0x0e,0x84,0x32,0x34,0x03,0x11,0x48,0x30,0x19,0x7f,0xbb,0xbc,0x68,0x1e,0x00,0x48,0xc3,0x80,0xa2,0x40,0x2a,0x05,0xfa,0x41,0xf6,0xdf,0xc0,0x70,0x13,0x10,0x78,0x8c,0x44,0xc2,0x24,0x01,0xf8,0x40,0x68,0x1e,0xcb,0xfc,0x1c,0x18,0x5c,0x00,0x20,0x83,0xc4,0x80,0x30,0xf0,0xd8,0xa4,0x04,0x54,0x30,0xa0,0xc0,0x83,0xce,0xc1,0xf8,0x69,0x97,0x43,0xff,0x3b,0x80,0x4f,0x60,0x1f,0xf0,0x78,0xa0,0x44,0x48,0x50,0x48,0x06,0xc7,0xff,0xef,0x80,0x7a,0xbf,0xe6,0x12,0x35,0x8c,0xf8,0x80,0x2d,0x11,0xb1,0x7f,0xf7,0xf0,0x7a,0xa5,0x57,0xaa,0x0f,0x1f,0x87,0xfe,0x02,0x0d,0x10,0xa0,0xd1,0x00,}; +const uint8_t *_A_SleepActive_128x52[] = {_A_SleepActive_128x52_0,_A_SleepActive_128x52_1,_A_SleepActive_128x52_2,_A_SleepActive_128x52_3,_A_SleepActive_128x52_4}; -const uint8_t _A_Sleep_128x51_0[] = {0x01,0x00,0x19,0x02,0xff,0x80,0x1e,0x1e,0x09,0x80,0x02,0xcf,0xff,0xc0,0xca,0xdf,0x80,0x86,0xff,0xfc,0x0f,0xe8,0x3e,0xa0,0x1f,0x80,0x7d,0x7e,0xff,0xf1,0xff,0xff,0x9c,0x1e,0xff,0xd0,0x89,0xf9,0xe0,0x39,0xc2,0x7b,0x83,0xd2,0x77,0x00,0xb8,0x02,0xc8,0xde,0x77,0xff,0x80,0x3c,0xe1,0xb0,0x0e,0x00,0x5d,0x03,0xef,0x06,0x4a,0x8f,0xcc,0x1f,0x57,0xf8,0x18,0x3c,0x7d,0xc8,0xbb,0x80,0x83,0xc7,0xb0,0x0f,0xae,0xfb,0x14,0xa6,0x00,0xfa,0xaf,0x83,0xcb,0xc0,0x7c,0x35,0xa1,0x00,0x0e,0xde,0x0f,0x2c,0x05,0xce,0x00,0x6a,0x14,0xb8,0x80,0x12,0x4e,0xf6,0x3c,0x77,0xff,0x1e,0x1f,0x79,0xc8,0x3c,0xff,0x10,0x0b,0xe3,0x3d,0xe3,0xc0,0xf3,0xb8,0x43,0x38,0x08,0x36,0xbf,0xc4,0xc1,0xa2,0x81,0x1e,0x04,0x1e,0x01,0xce,0x3f,0x34,0x44,0x1e,0x60,0x22,0x9c,0x34,0x0c,0xfc,0x51,0x02,0xe8,0x83,0xc9,0x28,0x3e,0x8f,0xc1,0xb9,0x41,0xe3,0xc0,0x06,0x0e,0x00,0x22,0x38,0x4e,0x38,0x3d,0x25,0xe0,0xf1,0x2e,0x08,0x48,0x40,0x43,0x02,0x9e,0x03,0xd2,0x6e,0x0f,0x1b,0xc0,0x30,0x68,0x03,0x12,0x52,0x27,0xfe,0x36,0x0f,0x10,0x01,0x58,0x06,0x25,0x80,0x38,0xa4,0x2e,0x30,0x0f,0x39,0x00,0x84,0xce,0x29,0x0d,0x9a,0x03,0xce,0x60,0x0f,0x39,0xc0,0x3c,0xe0,0xd2,0x80,0x79,0x8d,0x04,0x42,0x2e,0x51,0x40,0x9c,0x08,0x3e,0x83,0x41,0x07,0x97,0x03,0xf2,0xae,0x28,0x1d,0xa0,0x1c,0x50,0x18,0x40,0x84,0x80,0x03,0xf7,0x07,0x94,0x07,0xf8,0x19,0x28,0x0c,0x30,0x1e,0x71,0x0e,0x6a,0xf8,0xa0,0x38,0x40,0x48,0xe0,0x60,0x10,0x40,0xfa,0x6e,0x81,0xe4,0x97,0x18,0x48,0x3c,0xa0,0xd0,0x01,0x88,0xc0,0x28,0x97,0x52,0x80,0x83,0xca,0x1d,0x00,0xe0,0x81,0x04,0x1e,0x70,0x0e,0x47,0xf5,0xbc,0x20,0xa1,0x82,0x60,0x13,0xa2,0xe1,0x10,0x79,0x44,0x6a,0xaa,0x11,0xaf,0x8e,0x86,0x09,0x60,0xb8,0x3b,0x88,0x82,0x20,0x01,0xd1,0x7b,0x81,0xe7,0x02,0x8c,0x4e,0x30,0x00,0xf3,0xa0,0x51,0x2a,0xbd,0xd7,0xf0,0xc0,0x21,0x50,0x28,0x34,0x70,0x1e,0x8d,0x01,0xd4,0x18,0x06,0x5f,0x00,0x86,0x70,0x60,0x30,0xe7,0xf1,0x9c,0x46,0xa3,0x55,0xba,0xbf,0x86,0x01,0x1a,0xd0,0xe0,0x60,0xe0,0xf4,0x59,0x0e,0x8b,0xd5,0xfe,0x8b,0xc0,0x22,0x99,0x1e,0x04,0x05,0xb8,0x40,0xf1,0xa2,0x55,0x07,0xe3,0xfd,0xbb,0xc0,0x25,0x17,0x2f,0xc3,0xb0,0xc8,0x23,0x00,0xc4,0x6a,0x35,0x5f,0xb3,0xf8,0xd4,0x27,0xd3,0xe8,0x02,0x00,0x41,0xe3,0x10,0x3f,0x0d,0x56,0xef,0xf7,0x5f,0x8e,0xa3,0xf1,0x0f,0x80,0x20,0x04,0x3e,0x72,0x2d,0x56,0xab,0xdd,0x7f,0xa1,0xd5,0x30,0x29,0xc1,0x9c,0x03,0x06,0x8b,0x44,0x3f,0x0f,0x57,0xba,0x80,0x18,0x36,0x83,0x8c,0x0c,0x19,0xe1,0xec,0x47,0xc5,0x88,0x0f,0x8a,0x00,0x63,0xb5,0x19,0xe8,0x28,0x67,0xf1,0x1c,0x8c,0x44,0x7c,0x57,0x51,0xf8,0xff,0xe7,0x7a,0x09,0x54,0x03,0x81,0x3f,0x0f,0x94,0x82,0x45,0xa2,0x0f,0x8d,0xab,0xff,0xef,0xaa,0x7d,0x60,0x1f,0xcb,0xfd,0x13,0x88,0x1d,0x10,0x00,0x8f,0x84,0x7e,0x3b,0xfc,0x5e,0xab,0xff,0xfb,0x0f,0x8f,0x00,0x7a,0x23,0xe2,0x00,0x0f,0xff,0xff,0x7e,0x0c,0x10,0xfc,0x57,0x62,0x00,0x2b,0xb8,0xfc,0x40,}; -const uint8_t _A_Sleep_128x51_1[] = {0x01,0x00,0x1a,0x02,0xff,0x80,0x1e,0x1e,0x09,0x80,0x01,0x6f,0xc0,0x43,0x3f,0xff,0x03,0xea,0x3e,0x02,0x1b,0xff,0xf0,0x3f,0xa0,0xf7,0xfd,0x80,0x86,0x01,0xf8,0x03,0x90,0x3d,0xfe,0x22,0xc2,0xf3,0x83,0xe8,0x3e,0x3e,0x78,0x0e,0x70,0x0e,0x44,0xf4,0xfe,0x84,0x4e,0x77,0x00,0xb8,0x02,0xc8,0xde,0x83,0x83,0xff,0xc3,0x60,0x1c,0x00,0xba,0x07,0xde,0x0c,0x95,0x1f,0x99,0xae,0xaf,0xf0,0x30,0x78,0xfb,0x8f,0x77,0x01,0x07,0x8f,0x60,0x1f,0x5d,0xf6,0x29,0x4c,0x01,0xf5,0x5f,0x07,0x97,0x81,0x59,0x56,0xf0,0x79,0x60,0x2e,0x70,0x0f,0x82,0xd0,0xc0,0x07,0x27,0x7b,0x1e,0x3b,0xff,0x8f,0x0f,0xbc,0xe4,0x1e,0x7f,0x88,0x05,0xf0,0x64,0xf1,0xe0,0x79,0xdc,0x21,0x9c,0x04,0x1b,0x5f,0xe2,0x60,0xd1,0x40,0x8f,0x02,0x0f,0x00,0xe7,0x1f,0x9a,0x22,0x0f,0x30,0x11,0x4e,0x1a,0x06,0x7e,0x28,0x81,0x74,0x41,0xe4,0x94,0x1f,0x43,0x31,0x0d,0xc2,0x0f,0x1e,0x00,0x30,0x70,0x01,0x11,0xc2,0x71,0xc1,0xe9,0x2f,0x07,0x89,0x70,0x42,0x42,0x02,0x18,0x14,0xf0,0x1e,0x93,0x70,0x78,0xde,0x01,0x83,0x40,0x18,0x92,0x91,0x63,0x60,0xf1,0x00,0x15,0x80,0x62,0x58,0x03,0x8a,0x42,0xe3,0x00,0xf3,0x90,0x08,0x4c,0xe2,0x90,0xd9,0xa0,0x3c,0xe6,0x00,0xf3,0x9c,0x03,0xce,0x0d,0x28,0x07,0x98,0xd0,0x44,0x22,0xe5,0x14,0x09,0xc0,0x83,0xe8,0x34,0x10,0x79,0x70,0x3f,0x2a,0xe2,0x81,0xda,0x01,0xc5,0x01,0x84,0x08,0x48,0x00,0x3f,0x70,0x79,0x40,0x7f,0x81,0x92,0x80,0xc3,0x01,0xe7,0x10,0xe6,0xaf,0x8a,0x03,0x84,0x04,0x8e,0x06,0x01,0x04,0x0f,0xa6,0xe8,0x1e,0x49,0x71,0x84,0x83,0xca,0x0d,0x00,0x18,0x8c,0x02,0x89,0x75,0x28,0x08,0x3c,0xa1,0xd0,0x0e,0x08,0x10,0x41,0xe7,0x00,0xe4,0x7f,0x5b,0xc2,0x0a,0x18,0x26,0x01,0x3a,0x2e,0x11,0x07,0x94,0x46,0xaa,0xa1,0x1a,0xf8,0xe8,0x60,0x96,0x0b,0x83,0xb8,0x88,0x22,0x00,0x1d,0x17,0xb8,0x1e,0x70,0x28,0xc4,0xe3,0x00,0x0f,0x3a,0x05,0x12,0xab,0xdd,0x7f,0x0c,0x02,0x15,0x02,0x83,0x47,0x01,0xe8,0xd0,0x1d,0x41,0x80,0x65,0xf0,0x08,0x66,0x06,0x03,0x0e,0x7f,0x19,0xc4,0x6a,0x35,0x5b,0xab,0xf8,0x60,0x11,0xab,0x0e,0x02,0x0e,0x0f,0x45,0x90,0xe8,0xbd,0x5f,0xe8,0xbc,0x02,0x29,0x11,0xe0,0x40,0x5b,0x84,0x0f,0x1a,0x25,0x50,0x7e,0x3f,0xdb,0xbc,0x02,0x51,0x12,0xfc,0x3b,0x0c,0x82,0x30,0x0c,0x46,0xa3,0x55,0xfb,0x3f,0x8d,0x42,0x1d,0x3e,0x80,0x20,0x04,0x1e,0x31,0x03,0xf0,0xd5,0x6e,0xff,0x75,0xf8,0xea,0x3f,0x10,0xf8,0x02,0x00,0x43,0xe7,0x22,0xd5,0x6a,0xbd,0xd7,0xfa,0x1d,0x53,0x02,0x9c,0x19,0xc0,0x30,0x68,0xb4,0x43,0xf0,0xf5,0x7b,0xa8,0x01,0x83,0x68,0x38,0xc0,0xc1,0x9e,0x1e,0xc4,0x7c,0x58,0x80,0xf8,0xa0,0x06,0x3b,0x51,0x9e,0x82,0x86,0x7f,0x11,0xc8,0xc4,0x47,0xc5,0x75,0x1f,0x8f,0xfe,0x77,0xa0,0x95,0x40,0x38,0x13,0xf0,0xf9,0x48,0x24,0x5a,0x20,0xf8,0xda,0xbf,0xfe,0xfa,0xa7,0xd6,0x01,0xfc,0xbf,0xd1,0x38,0x81,0xd1,0x00,0x08,0xf8,0x47,0xe3,0xbf,0xc5,0xea,0xbf,0xff,0xb0,0xf8,0xf0,0x07,0xa2,0x3e,0x20,0x00,0xff,0xff,0xf7,0xe0,0xc1,0x0f,0xc5,0x76,0x20,0x02,0xbb,0x8f,0xc4,}; -const uint8_t _A_Sleep_128x51_2[] = {0x01,0x00,0x19,0x02,0xff,0x80,0x1e,0x1e,0x09,0x80,0x02,0xcf,0xff,0xc0,0xca,0xdf,0x80,0x86,0xff,0xfc,0x0f,0xe8,0x3e,0xa0,0x1f,0x80,0x7d,0x7e,0xff,0xf1,0xff,0xff,0x9c,0x1e,0xff,0xd0,0x89,0xf9,0xe0,0x39,0xc2,0x7b,0x83,0xd2,0x77,0x00,0xb8,0x02,0xc8,0xde,0x77,0xff,0x80,0x3c,0xe1,0xb0,0x0e,0x00,0x5d,0x03,0xef,0x06,0x4a,0x8f,0xcc,0x1f,0x57,0xf8,0x18,0x3c,0x7d,0xc8,0xbb,0x80,0x83,0xc7,0xb0,0x0f,0xae,0xfb,0x14,0xa6,0x00,0xfa,0xaf,0x83,0xcb,0xc0,0x7c,0x35,0xa1,0x00,0x0e,0xde,0x0f,0x2c,0x05,0xce,0x00,0x6a,0x14,0xb8,0x80,0x12,0x4e,0xf6,0x3c,0x77,0xff,0x1e,0x1f,0x79,0xc8,0x3c,0xff,0x10,0x0b,0xe3,0x3d,0xe3,0xc0,0xf3,0xb8,0x43,0x38,0x08,0x36,0xbf,0xc4,0xc1,0xa2,0x81,0x1e,0x04,0x1e,0x01,0xce,0x3f,0x34,0x44,0x1e,0x60,0x22,0x9c,0x34,0x0c,0xfc,0x51,0x02,0xe8,0x83,0xc9,0x28,0x3e,0x8f,0xc1,0xb9,0x41,0xe3,0xc0,0x06,0x0e,0x00,0x22,0x38,0x4e,0x38,0x3d,0x25,0xe0,0xf1,0x2e,0x08,0x48,0x40,0x43,0x02,0x9e,0x03,0xd2,0x6e,0x0f,0x1b,0xc0,0x30,0x68,0x03,0x12,0x52,0x27,0xfe,0x36,0x0f,0x10,0x01,0x58,0x06,0x25,0x80,0x38,0xa4,0x2e,0x30,0x0f,0x39,0x00,0x84,0xce,0x29,0x0d,0x9a,0x03,0xce,0x60,0x0f,0x39,0xc0,0x3c,0xe0,0xd2,0x80,0x79,0x8d,0x04,0x42,0x2e,0x51,0x40,0x9c,0x08,0x3e,0x83,0x41,0x07,0x97,0x03,0xf2,0xae,0x28,0x1d,0xa0,0x1c,0x50,0x18,0x40,0x84,0x80,0x03,0xf7,0x07,0x94,0x07,0xf8,0x19,0x28,0x0c,0x30,0x1e,0x71,0x0e,0x6a,0xf8,0xa0,0x38,0x40,0x48,0xe0,0x60,0x10,0x40,0xfa,0x6e,0x81,0xe4,0x97,0x18,0x48,0x3c,0xa0,0xd0,0x01,0x88,0xc0,0x28,0x97,0x52,0x80,0x83,0xca,0x1d,0x00,0xe0,0x81,0x04,0x1e,0x70,0x0e,0x47,0xf5,0xbc,0x20,0xa1,0x82,0x60,0x13,0xa2,0xe1,0x10,0x79,0x44,0x6a,0xaa,0x11,0xaf,0x8e,0x86,0x09,0x60,0xb8,0x3b,0x88,0x82,0x20,0x01,0xd1,0x7b,0x81,0xe7,0x02,0x8c,0x4e,0x30,0x00,0xf3,0xa0,0x51,0x2a,0xbd,0xd7,0xf0,0xc0,0x21,0x50,0x28,0x34,0x70,0x1e,0x8d,0x01,0xd4,0x18,0x06,0x5f,0x00,0x86,0x70,0x60,0x30,0xe7,0xf1,0x9c,0x46,0xa3,0x55,0xba,0xbf,0x86,0x01,0x1a,0xd0,0xe0,0x60,0xe0,0xf4,0x59,0x0e,0x8b,0xd5,0xfe,0x8b,0xc0,0x22,0x99,0x1e,0x04,0x05,0xb8,0x40,0xf1,0xa2,0x55,0x07,0xe3,0xfd,0xbb,0xc0,0x25,0x17,0x2f,0xc3,0xb0,0xc8,0x23,0x00,0xc4,0x6a,0x35,0x5f,0xb3,0xf8,0xd4,0x27,0xd3,0xe8,0x02,0x00,0x41,0xe3,0x10,0x3f,0x0d,0x56,0xef,0xf7,0x5f,0x8e,0xa3,0xf1,0x0f,0x80,0x20,0x04,0x3e,0x72,0x2d,0x56,0xab,0xdd,0x7f,0xa1,0xd5,0x30,0x29,0xc1,0x9c,0x03,0x06,0x8b,0x44,0x3f,0x0f,0x57,0xba,0x80,0x18,0x36,0x83,0x8c,0x0c,0x19,0xe1,0xec,0x47,0xc5,0x88,0x0f,0x8a,0x00,0x63,0xb5,0x19,0xe8,0x28,0x67,0xf1,0x1c,0x8c,0x44,0x7c,0x57,0x51,0xf8,0xff,0xe7,0x7a,0x09,0x54,0x03,0x81,0x3f,0x0f,0x94,0x82,0x45,0xa2,0x0f,0x8d,0xab,0xff,0xef,0xaa,0x7d,0x60,0x1f,0xcb,0xfd,0x13,0x88,0x1d,0x10,0x00,0x8f,0x84,0x7e,0x3b,0xfc,0x5e,0xab,0xff,0xfb,0x0f,0x8f,0x00,0x7a,0x23,0xe2,0x00,0x0f,0xff,0xff,0x7e,0x0c,0x10,0xfc,0x57,0x62,0x00,0x2b,0xb8,0xfc,0x40,}; -const uint8_t _A_Sleep_128x51_3[] = {0x01,0x00,0x1a,0x02,0xff,0x80,0x1e,0x1e,0x09,0x80,0x01,0x6f,0xc0,0x43,0x3f,0xff,0x03,0xea,0x3e,0x02,0x1b,0xff,0xf0,0x3f,0xa0,0xf7,0xfd,0x80,0x86,0x01,0xf8,0x03,0x90,0x3d,0xfe,0x22,0xc2,0xf3,0x83,0xe8,0x3e,0x3e,0x78,0x0e,0x70,0x0e,0x44,0xf4,0xfe,0x84,0x4e,0x77,0x00,0xb8,0x02,0xc8,0xde,0x83,0x83,0xff,0xc3,0x60,0x1c,0x00,0xba,0x07,0xde,0x0c,0x95,0x1f,0x99,0xae,0xaf,0xf0,0x30,0x78,0xfb,0x8f,0x77,0x01,0x07,0x8f,0x60,0x1f,0x5d,0xf6,0x29,0x4c,0x01,0xf5,0x5f,0x07,0x97,0x81,0x59,0x56,0xf0,0x79,0x60,0x2e,0x70,0x0f,0x82,0xd0,0xc0,0x07,0x27,0x7b,0x1e,0x3b,0xff,0x8f,0x0f,0xbc,0xe4,0x1e,0x7f,0x88,0x05,0xf0,0x64,0xf1,0xe0,0x79,0xdc,0x21,0x9c,0x04,0x1b,0x5f,0xe2,0x60,0xd1,0x40,0x8f,0x02,0x0f,0x00,0xe7,0x1f,0x9a,0x22,0x0f,0x30,0x11,0x4e,0x1a,0x06,0x7e,0x28,0x81,0x74,0x41,0xe4,0x94,0x1f,0x43,0x31,0x0d,0xc2,0x0f,0x1e,0x00,0x30,0x70,0x01,0x11,0xc2,0x71,0xc1,0xe9,0x2f,0x07,0x89,0x70,0x42,0x42,0x02,0x18,0x14,0xf0,0x1e,0x93,0x70,0x78,0xde,0x01,0x83,0x40,0x18,0x92,0x91,0x63,0x60,0xf1,0x00,0x15,0x80,0x62,0x58,0x03,0x8a,0x42,0xe3,0x00,0xf3,0x90,0x08,0x4c,0xe2,0x90,0xd9,0xa0,0x3c,0xe6,0x00,0xf3,0x9c,0x03,0xce,0x0d,0x28,0x07,0x98,0xd0,0x44,0x22,0xe5,0x14,0x09,0xc0,0x83,0xe8,0x34,0x10,0x79,0x70,0x3f,0x2a,0xe2,0x81,0xda,0x01,0xc5,0x01,0x84,0x08,0x48,0x00,0x3f,0x70,0x79,0x40,0x7f,0x81,0x92,0x80,0xc3,0x01,0xe7,0x10,0xe6,0xaf,0x8a,0x03,0x84,0x04,0x8e,0x06,0x01,0x04,0x0f,0xa6,0xe8,0x1e,0x49,0x71,0x84,0x83,0xca,0x0d,0x00,0x18,0x8c,0x02,0x89,0x75,0x28,0x08,0x3c,0xa1,0xd0,0x0e,0x08,0x10,0x41,0xe7,0x00,0xe4,0x7f,0x5b,0xc2,0x0a,0x18,0x26,0x01,0x3a,0x2e,0x11,0x07,0x94,0x46,0xaa,0xa1,0x1a,0xf8,0xe8,0x60,0x96,0x0b,0x83,0xb8,0x88,0x22,0x00,0x1d,0x17,0xb8,0x1e,0x70,0x28,0xc4,0xe3,0x00,0x0f,0x3a,0x05,0x12,0xab,0xdd,0x7f,0x0c,0x02,0x15,0x02,0x83,0x47,0x01,0xe8,0xd0,0x1d,0x41,0x80,0x65,0xf0,0x08,0x66,0x06,0x03,0x0e,0x7f,0x19,0xc4,0x6a,0x35,0x5b,0xab,0xf8,0x60,0x11,0xab,0x0e,0x02,0x0e,0x0f,0x45,0x90,0xe8,0xbd,0x5f,0xe8,0xbc,0x02,0x29,0x11,0xe0,0x40,0x5b,0x84,0x0f,0x1a,0x25,0x50,0x7e,0x3f,0xdb,0xbc,0x02,0x51,0x12,0xfc,0x3b,0x0c,0x82,0x30,0x0c,0x46,0xa3,0x55,0xfb,0x3f,0x8d,0x42,0x1d,0x3e,0x80,0x20,0x04,0x1e,0x31,0x03,0xf0,0xd5,0x6e,0xff,0x75,0xf8,0xea,0x3f,0x10,0xf8,0x02,0x00,0x43,0xe7,0x22,0xd5,0x6a,0xbd,0xd7,0xfa,0x1d,0x53,0x02,0x9c,0x19,0xc0,0x30,0x68,0xb4,0x43,0xf0,0xf5,0x7b,0xa8,0x01,0x83,0x68,0x38,0xc0,0xc1,0x9e,0x1e,0xc4,0x7c,0x58,0x80,0xf8,0xa0,0x06,0x3b,0x51,0x9e,0x82,0x86,0x7f,0x11,0xc8,0xc4,0x47,0xc5,0x75,0x1f,0x8f,0xfe,0x77,0xa0,0x95,0x40,0x38,0x13,0xf0,0xf9,0x48,0x24,0x5a,0x20,0xf8,0xda,0xbf,0xfe,0xfa,0xa7,0xd6,0x01,0xfc,0xbf,0xd1,0x38,0x81,0xd1,0x00,0x08,0xf8,0x47,0xe3,0xbf,0xc5,0xea,0xbf,0xff,0xb0,0xf8,0xf0,0x07,0xa2,0x3e,0x20,0x00,0xff,0xff,0xf7,0xe0,0xc1,0x0f,0xc5,0x76,0x20,0x02,0xbb,0x8f,0xc4,}; -const uint8_t *_A_Sleep_128x51[] = {_A_Sleep_128x51_0,_A_Sleep_128x51_1,_A_Sleep_128x51_2,_A_Sleep_128x51_3}; +const uint8_t _A_Sleep_128x52_0[] = {0x01,0x00,0x2b,0x02,0xff,0x80,0x3c,0x00,0xf0,0xf0,0x7f,0x4f,0xff,0xc0,0xca,0xdf,0x80,0x86,0xff,0xfc,0x0f,0xe8,0x3e,0x67,0xf0,0x01,0x51,0x83,0xdf,0xf7,0xff,0xe3,0xff,0xff,0x20,0xf7,0xfe,0x84,0x4e,0xf3,0x00,0xf3,0x93,0xdc,0x1e,0x90,0xe8,0x06,0x70,0xde,0xd7,0xff,0x80,0x10,0xe0,0x70,0x0b,0x81,0x29,0xc3,0xe7,0xbf,0x80,0xc0,0x38,0x05,0xb7,0x07,0x9f,0x7d,0x68,0x38,0x02,0xa0,0x80,0x26,0xde,0xc5,0x2f,0xb0,0x3e,0xa6,0xe0,0xf2,0xe6,0x03,0xea,0x2e,0x0f,0x29,0xc2,0xd1,0x80,0x07,0x1b,0x07,0x97,0x82,0x39,0x00,0x29,0x0c,0x7c,0x1e,0xb0,0xd0,0x79,0x60,0x3c,0x7f,0xfe,0x18,0x7d,0xaf,0xf0,0x60,0x79,0x40,0x27,0xc0,0x11,0x39,0xb6,0xfe,0x0e,0x0f,0x38,0xe4,0x0f,0xc0,0x22,0x10,0x02,0x77,0xe0,0x88,0xe1,0x07,0x8f,0xc1,0x28,0x31,0xe3,0xf3,0x03,0xd0,0x04,0x5f,0x81,0x82,0xcd,0xc1,0xe3,0xe0,0x06,0x0d,0x00,0x04,0x39,0xcf,0x99,0xb9,0x41,0xe3,0x70,0x06,0x0c,0x80,0x04,0x36,0x3e,0x70,0x3d,0x21,0x60,0xf1,0x2e,0x0c,0x02,0x60,0x72,0x1c,0x04,0xe4,0xfc,0xa0,0xf1,0x8f,0x03,0xc6,0x20,0x31,0x2f,0x31,0x01,0x20,0xc0,0xf1,0x00,0x14,0x60,0x62,0x59,0x82,0x02,0x40,0x81,0xe9,0x08,0x10,0x8f,0xfb,0xff,0xcf,0x4f,0x1c,0x0c,0x14,0x20,0x02,0x86,0x40,0x3a,0x10,0x1e,0x04,0xf1,0x3c,0x70,0x10,0x7a,0x09,0x06,0x70,0x51,0x1f,0x09,0x00,0xb7,0xe2,0xa2,0x00,0x13,0x10,0x48,0x23,0x00,0xc3,0x7e,0xd5,0xc4,0x5a,0x22,0xd9,0x40,0xa0,0x17,0xc2,0x21,0x79,0x81,0xe3,0x5f,0x3e,0x88,0x80,0x41,0xe3,0x03,0x80,0x61,0x00,0x43,0x30,0xee,0x2f,0x8a,0x01,0x21,0x82,0x50,0x2c,0x10,0x06,0x70,0xc1,0x0a,0x43,0x40,0x98,0x03,0xc6,0x5f,0x80,0xa0,0x40,0xa8,0x12,0x0c,0x00,0x3c,0x60,0x4a,0x22,0xf0,0x9c,0xc4,0x1e,0x38,0x08,0x18,0x5c,0x70,0x03,0xc1,0x81,0x70,0x30,0x1f,0xfc,0x1f,0xf5,0xbc,0x20,0xa1,0x80,0xc8,0x23,0x00,0xf3,0xc0,0x5f,0xca,0x62,0x60,0x18,0xb8,0x38,0x60,0x31,0x88,0xe3,0xf8,0x91,0xc2,0x73,0x1c,0xc7,0xdc,0x1e,0x58,0x13,0xe0,0xc3,0x9f,0xc5,0x01,0x33,0x94,0x83,0xdc,0xfe,0x18,0x06,0x08,0x98,0x30,0x73,0x00,0xc0,0x3c,0x30,0x12,0x80,0xd0,0x3b,0x0f,0xe1,0x80,0x50,0xac,0x05,0x11,0x6e,0x0e,0x02,0x38,0x85,0x2c,0x06,0xc1,0xfc,0x30,0x0a,0x24,0x63,0xc0,0x51,0x10,0x50,0xa3,0x84,0xe8,0x56,0x1f,0xfc,0x14,0x1e,0x30,0x4b,0x82,0x64,0x41,0x86,0xb4,0x2e,0x17,0xfa,0x3b,0x00,0xc4,0x41,0x27,0xcc,0x32,0xa0,0x17,0x45,0xe8,0x58,0x4f,0xec,0xde,0x01,0x90,0xc1,0xc3,0xdb,0x85,0x40,0x6f,0x90,0x54,0x6f,0x1f,0xb5,0xf8,0xc8,0x3f,0xc3,0xa1,0x5d,0x91,0x88,0x96,0xc3,0x97,0xfb,0xbb,0xc6,0x81,0xe0,0x04,0x8c,0x38,0x0a,0x24,0x02,0xa0,0x5f,0xa4,0x1f,0x6d,0xfc,0x07,0x01,0x31,0x07,0x88,0xc4,0x4c,0x22,0x40,0x1f,0x84,0x06,0x81,0xec,0xbf,0xc1,0xc1,0x85,0xc0,0x02,0x08,0x3c,0x48,0x03,0x0f,0x0d,0x8a,0x40,0x45,0x43,0x0a,0x0c,0x08,0x3c,0xec,0x1f,0x86,0x99,0x74,0x3f,0xf3,0xb8,0x04,0xf6,0x01,0xff,0x07,0x8a,0x04,0x44,0x85,0x04,0x80,0x6c,0x7f,0xfe,0xf8,0x07,0xab,0xfe,0x61,0x23,0x58,0xcf,0x88,0x02,0xd1,0x1b,0x17,0xff,0x7f,0x07,0xaa,0x55,0x7a,0xa0,0xf1,0xf8,0x7f,0xe0,0x20,0xd1,0x0a,0x0d,0x10,}; +const uint8_t _A_Sleep_128x52_1[] = {0x01,0x00,0x34,0x02,0xff,0x80,0x3c,0x00,0xf0,0xf0,0x65,0xef,0xc0,0x43,0x3f,0xff,0x03,0xea,0x3e,0x02,0x1b,0xff,0xf0,0x3f,0xa0,0xf7,0xfd,0x8a,0x46,0x00,0x2a,0x30,0x7b,0xfc,0x7f,0xfc,0x7f,0xff,0xe4,0x1f,0x41,0xf1,0xbc,0xc0,0x3c,0xe0,0x72,0x27,0xa7,0xf4,0x22,0x70,0xe8,0x06,0x70,0xde,0xff,0x81,0x41,0xc0,0xe0,0x17,0x02,0xbb,0x87,0xcf,0x7f,0x01,0x80,0x70,0x0d,0x77,0xdf,0x5a,0x0e,0x00,0x88,0x20,0x09,0xb7,0xb1,0x4b,0xec,0x0f,0xa9,0xb8,0x3c,0xb9,0x80,0xfa,0x8b,0x83,0xca,0x70,0x0f,0xa8,0xd8,0x3c,0xbc,0x11,0xc8,0x01,0x48,0x56,0x84,0x00,0x38,0x68,0x3c,0xb0,0x1e,0x3f,0xff,0x0c,0x1a,0xbf,0x7b,0xfc,0x18,0x1e,0x50,0x09,0xf0,0x04,0x4e,0x6d,0xbf,0x83,0x83,0xce,0x39,0x03,0xf0,0x08,0x84,0xfc,0xb0,0x44,0x70,0x83,0xc7,0xe0,0x94,0x18,0xf0,0x34,0xd8,0x83,0x6f,0x07,0xa0,0x08,0xbf,0x03,0x05,0x9b,0x83,0xc7,0xc0,0x0c,0x1a,0x00,0x08,0x73,0x9f,0x33,0x72,0x83,0xc6,0xe0,0x0c,0x19,0x00,0x08,0x6c,0x7c,0xe0,0x7a,0x42,0xc1,0xe2,0x5c,0x18,0x04,0xc0,0xe4,0x38,0x09,0xc9,0xf9,0x41,0xe3,0x1e,0x07,0x8c,0x40,0x62,0x5e,0x62,0x02,0x41,0x81,0xe2,0x00,0x28,0xc0,0xc4,0xb3,0x04,0x04,0x81,0x03,0xd2,0x10,0x21,0x13,0x50,0xf3,0xc1,0xc5,0x7f,0x81,0x82,0x84,0x00,0x50,0xc8,0x07,0x42,0x03,0xc0,0x9e,0x27,0x8e,0x02,0x0f,0x41,0x20,0xce,0x0a,0x23,0xe1,0x20,0x16,0xfc,0x54,0x40,0x02,0x62,0x09,0x04,0x60,0x18,0x6f,0xda,0xb8,0x8b,0x44,0x5b,0x28,0x14,0x02,0xf8,0x44,0x2f,0x30,0x3c,0x6b,0xe7,0xd1,0x10,0x08,0x3c,0x60,0x70,0x0c,0x20,0x08,0x66,0x1d,0xc0,0x78,0xdb,0xe0,0x12,0x18,0x25,0x02,0xc1,0x00,0x67,0x0c,0x10,0xa4,0x34,0x09,0x80,0x3c,0x65,0xf8,0x0a,0x04,0x0a,0x81,0x20,0xc0,0x03,0xc6,0x04,0xa2,0x2f,0x09,0xcc,0x41,0xe3,0x80,0x81,0x85,0xc7,0x00,0x3c,0x18,0x17,0x03,0x01,0xff,0xc1,0xff,0x5b,0xc2,0x0a,0x18,0x0c,0x82,0x30,0x0f,0x3c,0x05,0xfc,0xa6,0x26,0x01,0x8b,0x83,0x86,0x03,0x18,0x8e,0x3f,0x89,0x1c,0x27,0x31,0xcc,0x7d,0xc1,0xe5,0x81,0x3e,0x0c,0x39,0xfc,0x50,0x13,0x39,0x48,0x3d,0xcf,0xe1,0x80,0x60,0x88,0x03,0x07,0x30,0x0c,0x03,0xc3,0x01,0x28,0x0d,0x03,0xb0,0xfe,0x18,0x05,0x0a,0xc1,0x81,0x81,0xb7,0x07,0x01,0x1c,0x42,0x96,0x03,0x60,0xfe,0x18,0x05,0x13,0x71,0xe0,0x28,0x88,0x28,0x51,0xc2,0x74,0x2b,0x0f,0xfe,0x0a,0x0f,0x1a,0xe5,0xc1,0x32,0x20,0xc3,0x5a,0x17,0x0b,0xfd,0x1d,0x80,0x62,0x27,0x93,0xc6,0x19,0x50,0x0b,0xa2,0xf4,0x2c,0x27,0xf6,0x6f,0x00,0xc8,0x46,0xe1,0xed,0xc2,0xa0,0x37,0xc8,0x2a,0x37,0x8f,0xda,0xfc,0x64,0x1c,0x81,0xd0,0xae,0xc8,0xc4,0x4b,0x61,0xcb,0xfd,0xdd,0xe3,0x40,0xfc,0x02,0x46,0x1c,0x05,0x12,0x01,0x50,0x2f,0xd2,0x0f,0xb6,0xfe,0x03,0x80,0x98,0x83,0xc4,0x62,0x26,0x11,0x20,0x0f,0xc2,0x03,0x40,0xf6,0x5f,0xe0,0xe0,0xc2,0xe0,0x01,0x04,0x1e,0x24,0x01,0x87,0x86,0xc5,0x20,0x22,0xa1,0x85,0x06,0x04,0x1e,0x76,0x01,0xb8,0xb4,0xc7,0xa1,0xff,0x9d,0xc0,0x27,0xb0,0x0f,0xf8,0x3c,0x50,0x22,0x24,0x28,0x24,0x03,0x63,0xff,0xf7,0xc0,0x3d,0x5f,0xff,0xf1,0x84,0x4d,0x63,0x3e,0x20,0x0b,0x44,0x6c,0x5f,0xfd,0xfc,0x1e,0xa9,0x55,0xea,0x83,0xc7,0xe1,0xff,0x80,0x83,0x44,0x28,0x34,0x40,}; +const uint8_t *_A_Sleep_128x52[] = {_A_Sleep_128x52_0,_A_Sleep_128x52_1}; -const uint8_t _A_TVActive_128x51_0[] = {0x01,0x00,0x4a,0x02,0x80,0x40,0xa0,0x10,0x68,0x80,0x25,0x6b,0x95,0x58,0x18,0x3d,0x21,0x20,0xf6,0xd5,0xea,0xa0,0xc0,0x52,0x82,0x03,0xc6,0x10,0x0e,0x4c,0x04,0x02,0x81,0x0d,0x03,0x10,0x30,0x62,0x21,0x21,0x00,0x1d,0x00,0x22,0x31,0xa0,0x31,0x0b,0x06,0x22,0x32,0x10,0x01,0xc8,0x00,0x43,0x35,0x07,0xa4,0x84,0x8c,0x60,0xf4,0xb5,0x01,0x93,0x82,0x0e,0x4f,0x04,0x4c,0x06,0x35,0x41,0xb2,0x60,0x41,0xe9,0x10,0x8a,0x00,0xc7,0x50,0x56,0x4a,0x0c,0x06,0x01,0x1c,0x2b,0x94,0x60,0x06,0x3d,0x00,0x7a,0x48,0x78,0x5f,0xf1,0x59,0x42,0x2c,0x00,0x31,0xd0,0x06,0x44,0x00,0x30,0x19,0x0c,0xd0,0xa8,0x50,0x0f,0xc6,0x02,0x03,0x3e,0xa0,0x03,0xce,0x05,0x11,0x41,0x08,0x3c,0xb7,0x10,0x3d,0x37,0xff,0x04,0x0f,0x38,0x24,0x25,0x28,0x70,0x0a,0x84,0x17,0x31,0xff,0xa2,0x9e,0x4e,0x08,0xb5,0x20,0x11,0x6c,0x21,0x5a,0x0e,0xfe,0x0d,0x32,0x70,0x80,0x61,0x09,0xca,0xc1,0x15,0x80,0x7f,0x03,0xe9,0x10,0x07,0x8f,0x80,0x0c,0x5c,0x04,0xe0,0xf0,0x03,0xe9,0xf8,0x87,0xc0,0x23,0xe7,0x73,0xea,0xa6,0x84,0x3e,0x90,0x68,0xe0,0x78,0xdf,0xc5,0x01,0xc0,0x60,0x83,0xe7,0x01,0x90,0x1b,0x48,0x00,0x5d,0x60,0xe0,0xd0,0x43,0xe4,0x9f,0x1a,0x01,0xb4,0x80,0x05,0xfc,0x1b,0x8e,0x80,0x3e,0x4c,0xf1,0xc0,0x41,0x01,0xe9,0x7e,0x62,0x0d,0x40,0x3e,0x3f,0xff,0xfc,0x3c,0x1e,0x9f,0x08,0x0c,0x7e,0x70,0xdf,0x10,0xf8,0xd5,0x6a,0xbf,0x50,0x90,0x84,0xc6,0x01,0xae,0xc7,0x43,0xe7,0x90,0x0e,0xa0,0x1c,0x75,0x40,0x04,0x87,0x60,0x2a,0xbf,0xd8,0x18,0x30,0x6f,0x53,0x50,0xf9,0x00,0x0e,0x1f,0xc0,0xd5,0x7e,0xbf,0xe3,0x41,0xd6,0xa4,0xc4,0x3c,0x9e,0xa8,0x55,0x80,0x3e,0x45,0x81,0xab,0x24,0xc4,0x3c,0x97,0x58,0x6e,0x83,0x55,0x1e,0x35,0x16,0x0f,0x55,0x01,0x0f,0xa6,0xb8,0x3e,0x34,0x08,0xb8,0x3c,0x74,0x10,0x1a,0xac,0x0c,0x3e,0x95,0x79,0xec,0xfb,0x01,0x7d,0x80,0x45,0xea,0x01,0xd1,0x81,0x0f,0x93,0x55,0xca,0x90,0xe0,0x3b,0x5f,0xf8,0x16,0xa0,0x7a,0x30,0x33,0xe1,0x7f,0xef,0xf5,0x58,0x6c,0x80,0xe0,0x37,0xf8,0x29,0x34,0x7d,0x50,0x7c,0x40,0x00,0xb7,0x1a,0xa8,0x54,0x80,0xe0,0x3a,0xac,0x16,0xaa,0x01,0x1d,0x8c,0x0f,0x90,0x3e,0x54,0x00,0x30,0xd0,0x6a,0xaf,0xb1,0x90,0x48,0x80,0x03,0xa2,0xd9,0x87,0xc6,0x81,0x40,0x6d,0x8e,0x81,0x1a,0x30,0x39,0x01,0xf4,0xc0,0x43,0x0d,0xc0,0x39,0x85,0xba,0x26,0x21,0x80,0xd0,0x07,0xc5,0x98,0x1f,0x94,0x02,0x42,0x0f,0x1d,0x45,0x1f,0x00,0x92,0x11,0xf2,0x07,0xc6,0x01,0x3e,0x07,0x8f,0x56,0x80,0x0f,0x23,0x71,0x48,0xf6,0x41,0xf2,0x4e,0x95,0xa8,0x88,0x2c,0x21,0x80,0x80,0x84,0x44,0x41,0xf1,0x1f,0x14,0xd4,0x1e,0xc7,0xf3,0x07,0x96,0xaa,0x35,0x40,0x90,0x07,0xe8,0x92,0x31,0x50,0x79,0xcc,0x7f,0x98,0xf9,0x10,0xfd,0x35,0x08,0x42,0x88,0x03,0xc6,0x93,0x02,0xc8,0x07,0xca,0x3a,0x68,0x34,0x20,0x83,0xd4,0x7e,0x40,0x04,0x87,0x60,0x21,0x02,0xf2,0x0f,0xa5,0x75,0x8c,0x64,0xa1,0x83,0x93,0xc8,0x1e,0x23,0xf2,0xfb,0x6a,0xbd,0x48,0x71,0x07,0x8c,0x10,0x6c,0x31,0x12,0x78,0x86,0x8b,0x0b,0xd7,0x8f,0x94,0x46,0x3c,0x0f,0x39,0x49,0xfd,0x20,0xd6,0xc4,0x01,0x1b,0x44,0x1e,0x32,0x00,0x79,0x07,0xca,0x0b,0x38,0x07,0x92,0x74,0x41,0xe5,0x15,0x07,0x88,0xfc,0xa0,0xc6,0x91,0x00,0x0b,0x34,0x41,0xe5,0x0b,0x0f,0xa8,0x3c,0xe0,0x10,0x30,0x78,0xc4,0x00,}; -const uint8_t _A_TVActive_128x51_1[] = {0x01,0x00,0x34,0x02,0x80,0x40,0xa0,0x10,0x68,0x80,0x25,0x6b,0x95,0x58,0x18,0x3d,0x21,0x20,0xf6,0xd5,0xea,0xa0,0xc0,0x52,0x82,0x03,0xc6,0x10,0x0e,0x4c,0x04,0x02,0x81,0x0d,0x03,0x10,0x30,0x62,0x21,0x21,0x00,0x1d,0x00,0x22,0x31,0xa0,0x31,0x0b,0x06,0x22,0x32,0x10,0x01,0xc8,0x00,0x43,0x35,0x07,0xa4,0x84,0x8c,0x60,0xf4,0xb5,0x01,0x93,0x82,0x4e,0x52,0xa9,0x55,0x06,0xc9,0x81,0x07,0xc6,0xa0,0xac,0x94,0x18,0x0c,0x02,0x38,0x07,0x1f,0x84,0x64,0x06,0x3d,0x00,0x7a,0x48,0x78,0x5f,0xf8,0x99,0x9c,0xb5,0xc0,0x31,0xd0,0x06,0x44,0x00,0x30,0x19,0x0c,0xd0,0x56,0x70,0x4a,0xc0,0x30,0x68,0x00,0xf3,0x81,0x44,0x50,0x42,0x0f,0x3f,0x04,0x0a,0x7f,0x82,0x07,0x9c,0x12,0x12,0x94,0x38,0x05,0xf3,0x01,0x85,0xff,0xd1,0x4f,0x27,0x04,0x5a,0x90,0x08,0xbf,0x90,0x0c,0x57,0xff,0x04,0x99,0x38,0x40,0x30,0x84,0xe5,0xf0,0x0d,0x8f,0xf0,0x3e,0x91,0x00,0x78,0xf8,0x00,0xc5,0xe0,0x83,0x80,0x87,0x06,0x1f,0x3f,0xc4,0x3e,0x01,0x1f,0x02,0x8f,0x03,0x9e,0x04,0x1a,0x00,0x7d,0x20,0xd1,0xc0,0xf1,0xc8,0x32,0x17,0xf4,0x50,0x8f,0xd2,0x03,0x20,0x36,0x90,0xd4,0x62,0x1f,0xf0,0x20,0xd0,0x43,0xe4,0x9f,0x1a,0x01,0xb4,0x8a,0xa3,0x10,0xfe,0x03,0x07,0x40,0x1f,0x26,0x78,0xe0,0x20,0x87,0x53,0x86,0x7e,0x0a,0x03,0x50,0x09,0x0f,0xff,0xff,0x0f,0x07,0xa4,0x1a,0x05,0x7c,0x86,0x37,0xc4,0x3e,0x35,0x5a,0xaf,0xd4,0x24,0x21,0x31,0x80,0x42,0xb0,0x51,0xf0,0x20,0xf5,0x00,0x43,0xaa,0x00,0x24,0x3a,0x01,0x16,0xfd,0x13,0xca,0xf5,0x35,0x0f,0x90,0x00,0xc2,0xe3,0x8b,0x52,0x94,0x03,0x5b,0x6a,0x0f,0xaf,0xaa,0x14,0x17,0x12,0x68,0x96,0x06,0xad,0xd5,0x0f,0xad,0xd6,0x1b,0x00,0xd5,0x8c,0x84,0xd4,0x38,0x3d,0x54,0x04,0x3e,0x9a,0xe8,0x57,0x83,0xfe,0x9e,0x13,0xf0,0xc0,0x6a,0xb0,0x30,0xfa,0x55,0xe7,0xb1,0xe2,0xd9,0xd4,0x03,0xa3,0x02,0x1f,0x26,0xab,0x94,0xf0,0x1f,0x57,0xfe,0x07,0xa8,0x1e,0x8c,0x0c,0xf8,0x42,0xa1,0xaa,0x8f,0xc6,0x01,0xd5,0xff,0xc1,0x49,0xa3,0xea,0x83,0xe2,0x00,0x05,0xb8,0xd5,0x17,0xc4,0xd0,0x58,0x2d,0x54,0x02,0x3b,0x18,0x1f,0x20,0x7c,0xc0,0xc3,0x41,0xaa,0xad,0x46,0x41,0x22,0x00,0x0e,0x8b,0x66,0x1f,0x36,0xd8,0xe8,0x11,0xa3,0x03,0x90,0x1f,0x4c,0x04,0x21,0xf2,0x00,0x0d,0x42,0xfb,0x00,0x80,0xd0,0x07,0xc5,0x98,0x1f,0xa0,0x00,0x75,0x14,0x7c,0x02,0x48,0x47,0xc8,0x1f,0x5e,0xad,0x00,0x1e,0x46,0xe2,0x91,0xec,0x83,0xe8,0x3e,0x1a,0x05,0x01,0x84,0x28,0x81,0xc0,0x08,0x88,0x3e,0x75,0x09,0xa8,0x3d,0x8f,0xea,0x80,0x18,0xd5,0x02,0x40,0x1f,0xa2,0x48,0xc5,0x41,0xe7,0x31,0xfe,0x63,0xe4,0x43,0xf4,0xd4,0x01,0x06,0x81,0x10,0x07,0x8d,0x26,0x05,0x90,0x0f,0x94,0x74,0xd0,0x70,0xdc,0x00,0x3d,0x47,0xe4,0x00,0x48,0x76,0x02,0x10,0x2f,0x20,0xfa,0x57,0x58,0xc6,0x4a,0x18,0x39,0x3c,0x81,0xe2,0x3f,0x2f,0xb6,0xa9,0xfc,0x3f,0xf0,0x78,0xc1,0x06,0xc3,0x11,0x27,0x88,0x68,0xb0,0xbd,0x78,0xf9,0x44,0x63,0xc0,0xf3,0x94,0x9f,0xd2,0x0d,0x6c,0x40,0x11,0xb4,0x41,0xe3,0x20,0x07,0x90,0x7c,0xa0,0xb3,0x80,0x79,0x27,0x44,0x1e,0x51,0x50,0x78,0x8f,0xca,0x0c,0x69,0x10,0x00,0xb3,0x44,0x1e,0x50,0xb0,0xfa,0x83,0xce,0x01,0x03,0x07,0x8c,0x40,}; -const uint8_t *_A_TVActive_128x51[] = {_A_TVActive_128x51_0,_A_TVActive_128x51_1}; +const uint8_t _A_TvActive_128x52_0[] = {0x01,0x00,0xc9,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0xf0,0x07,0xc2,0x00,0x43,0x02,0x05,0xbf,0xc2,0x0e,0x0f,0xd8,0x74,0xe0,0x06,0x31,0x00,0x10,0xc0,0x41,0xcd,0x80,0x80,0xf0,0x01,0xf9,0x40,0x05,0x1c,0x80,0x2c,0x20,0xa2,0x83,0x03,0xcc,0x14,0x23,0xa2,0x07,0xac,0x24,0x1e,0x62,0xa2,0x82,0x09,0x08,0x4c,0x40,0xf5,0x2d,0x10,0x08,0x41,0xe9,0xc0,0x05,0x10,0x3d,0x85,0xa2,0x36,0x29,0xc0,0x3d,0x05,0x82,0x32,0x20,0x7a,0x41,0xc1,0xf2,0x62,0x10,0x18,0x9d,0x84,0x1f,0xa2,0x11,0x05,0x11,0xb0,0xb0,0x10,0xf3,0x91,0x86,0xc4,0x22,0x20,0xf5,0x41,0x28,0x3c,0x40,0x22,0xc2,0x48,0x17,0x82,0x7e,0x0f,0x1f,0xf8,0x00,0xa1,0xf0,0x0f,0xf0,0x18,0xe0,0x7e,0x09,0x3f,0x82,0x3e,0x2a,0x18,0x27,0x81,0xcc,0x2c,0x24,0x8f,0x58,0x24,0xde,0x09,0x18,0xb0,0x60,0xd1,0xc5,0x92,0x00,0x06,0x07,0xc0,0x89,0xf0,0x28,0x20,0xf1,0x8d,0x40,0xe0,0x16,0x00,0x71,0x9d,0x44,0xbe,0x3c,0x00,0xc8,0xc4,0x3c,0xa0,0xa1,0x8c,0x03,0xce,0x60,0x13,0x30,0x79,0x41,0x5d,0xc7,0xf8,0x20,0x8a,0x4c,0xc1,0xe5,0xa0,0x3d,0x90,0x30,0x60,0x97,0xe4,0x1a,0x03,0xcc,0x2e,0x40,0xf2,0xc0,0x47,0xfe,0x80,0xf5,0xf8,0x44,0x60,0x10,0xe1,0x61,0xf8,0x21,0xe7,0xb1,0x07,0x9f,0xf3,0xcf,0xc0,0x84,0xa7,0x85,0x90,0x48,0x71,0x08,0x08,0x3c,0xbf,0xd0,0xf9,0xfc,0x40,0x1e,0x2b,0x82,0x11,0x08,0x10,0x7e,0x18,0x3f,0xff,0xf7,0xee,0xaa,0x28,0xf9,0xf0,0x4d,0xe9,0x0c,0xce,0x7f,0xc7,0x02,0x0f,0x28,0xec,0x01,0x66,0x3c,0x04,0xb8,0xb4,0x87,0x70,0xc8,0x3f,0xfc,0xfc,0x72,0x37,0x8f,0xc0,0xa8,0x5a,0xe3,0x01,0xf8,0x03,0xd3,0x9e,0x0f,0x1c,0x00,0x80,0x5c,0x02,0x4d,0x1f,0x03,0x25,0x3e,0x00,0xf1,0xb8,0x01,0x47,0xf8,0xd7,0x21,0xe1,0x80,0x07,0xe6,0x0f,0x18,0x70,0x5c,0xe8,0x00,0xf6,0xfa,0x4f,0xfe,0x1c,0x10,0x7a,0xff,0x01,0xc7,0x7f,0xfb,0xf7,0xe1,0xfa,0x63,0x10,0x83,0xcf,0x86,0x0f,0x3c,0xff,0xde,0x3f,0xb0,0xbc,0xb4,0x04,0x00,0x32,0x0c,0x06,0x00,0x1e,0x7e,0xf0,0x78,0xd3,0xe9,0x39,0x26,0x20,0x83,0xc6,0x80,0x0f,0x4f,0x9f,0xdf,0x3e,0x05,0x23,0xe8,0x83,0xc4,0x40,0x24,0x63,0xfe,0x03,0xc4,0x0a,0x51,0x80,0x7a,0x07,0xcd,0x84,0x31,0xf1,0x61,0x47,0x01,0xe5,0x10,0x07,0xbb,0x84,0x60,0x11,0xe0,0x10,0xd8,0x01,0xf1,0x04,0x06,0x08,0xfc,0xae,0x10,0x8c,0x07,0x9c,0x1e,0xa3,0xc1,0xe0,0x28,0xc6,0x01,0xbc,0x07,0x8f,0x0c,0x2c,0x3f,0x80,0x79,0x58,0x18,0x63,0x7f,0x07,0x8c,0xfe,0x0e,0x0f,0x1d,0x7c,0xcb,0xf6,0x0f,0x15,0xaa,0x3d,0xc9,0xa2,0x3e,0x70,0xfa,0xb9,0x92,0x01,0x38,0x07,0x89,0x3d,0x81,0xeb,0x20,0x07,0xf8,0xbc,0x81,0xfc,}; +const uint8_t _A_TvActive_128x52_1[] = {0x01,0x00,0xcd,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0xf0,0x07,0xc2,0x00,0x43,0x02,0x05,0xbf,0xc2,0x0e,0x0f,0xd8,0x74,0xe0,0x06,0x31,0x00,0x10,0xc0,0x41,0xcd,0x80,0x80,0xf0,0x01,0xf9,0x40,0x05,0x1c,0x80,0x2c,0x20,0xa2,0x83,0x03,0xcc,0x14,0x23,0xa2,0xff,0x7f,0xc0,0x0d,0x0f,0x15,0x1c,0x10,0x59,0x00,0xd2,0x2d,0x10,0x08,0x41,0xfe,0x0f,0xa1,0x60,0x81,0x0b,0x12,0x4e,0x20,0xa8,0xc0,0xa2,0x40,0xfd,0x80,0x83,0xe6,0x99,0x0c,0xe3,0xc7,0x21,0xd7,0x1b,0xbf,0x32,0x22,0x24,0x1c,0x04,0x3c,0xe4,0x3f,0x98,0x94,0x0a,0x53,0x09,0x84,0xd2,0xf2,0x55,0x20,0xd0,0xad,0xc8,0x1e,0x38,0x98,0xf4,0x10,0x1e,0x54,0x9c,0x95,0x7a,0x21,0xf0,0x81,0xf8,0x27,0xe0,0xf2,0x81,0x42,0x01,0xe9,0x42,0xf8,0x43,0xe1,0xde,0x09,0x3f,0x82,0x3f,0x89,0x86,0x41,0xb9,0x30,0x81,0xf8,0xe4,0xa9,0x91,0x08,0x24,0xc2,0x40,0x0f,0x19,0xf9,0xfe,0x6e,0x9c,0x0e,0x04,0x4f,0x81,0x47,0x07,0xc4,0x83,0xf9,0x01,0x2f,0x8f,0x03,0x06,0x0f,0x8a,0x07,0xe2,0x0e,0x04,0x10,0x7d,0x60,0x09,0x62,0x0f,0x37,0x7c,0x7f,0xf0,0x37,0xf0,0x79,0xc0,0x34,0x0d,0x62,0x81,0xaa,0xc7,0x00,0x1d,0x1c,0x38,0x18,0x41,0xe5,0xf0,0x54,0x0c,0x38,0x72,0x21,0x41,0xf0,0x63,0xe0,0x21,0x21,0x07,0x97,0xf3,0xcf,0xc0,0x84,0xc1,0x99,0x05,0x00,0xfc,0x7f,0xd3,0xa2,0x0f,0x2f,0xf4,0x3e,0x7f,0x10,0x07,0x88,0x28,0x44,0x44,0x00,0x1f,0x86,0x7f,0xff,0xfd,0xfb,0x92,0xca,0x3f,0xc0,0x07,0xac,0x33,0x79,0xff,0x1c,0x08,0x3c,0xa3,0xb0,0x02,0x10,0xcc,0x01,0xe5,0x02,0x1a,0x08,0x00,0xe7,0xe4,0x91,0xbc,0x7e,0x38,0x62,0x51,0x80,0x40,0x7e,0x00,0xf4,0xe7,0x82,0x47,0x01,0x07,0xc0,0x7f,0xc0,0x42,0x2c,0x14,0xda,0x7c,0x01,0xe3,0x70,0x02,0x8f,0xf9,0x80,0x23,0xc4,0x00,0x0f,0xcc,0x1e,0x30,0xe6,0x1a,0x03,0xdb,0xe9,0x3f,0xf8,0x70,0x41,0xeb,0xfc,0x07,0x1d,0xff,0xef,0xdf,0x87,0xe9,0x8c,0x42,0x0f,0x30,0xf2,0x67,0xfe,0xf1,0xfd,0x85,0xe6,0xfc,0x0f,0x29,0x06,0x03,0x0e,0x0f,0x3f,0x78,0x3c,0x69,0xf4,0x9c,0x93,0xe4,0xa4,0x1c,0x0c,0x09,0x39,0x3e,0xea,0x61,0x00,0x10,0x3c,0xbc,0x06,0x11,0x00,0x17,0xf0,0x1e,0x20,0x52,0xfc,0x03,0xca,0xc0,0x84,0x10,0x01,0x30,0x86,0x3e,0x2c,0x2f,0xe0,0x3c,0xa6,0x00,0xf7,0x81,0x03,0x04,0xa0,0x56,0x00,0x7c,0x41,0x01,0x83,0x7f,0x01,0x0d,0xc2,0x31,0x80,0xf3,0x83,0xd6,0x31,0x00,0xe0,0x13,0xcb,0x78,0x0f,0x1e,0x1c,0x3c,0x90,0x20,0xf2,0xb0,0x30,0xc7,0xff,0x03,0x80,0x4f,0xe1,0xe0,0xf1,0xd7,0xcc,0xbf,0x60,0xf1,0x4b,0x23,0xdc,0x9c,0xc3,0xe7,0x0f,0xab,0x99,0x20,0x13,0x80,0x78,0x93,0xd8,0x1e,0xb2,0x00,0x7f,0x8b,0xc8,0x1f,0xc0,}; +const uint8_t _A_TvActive_128x52_2[] = {0x01,0x00,0xc2,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0xf0,0x07,0xc2,0x00,0x43,0x02,0x05,0xbf,0xc2,0x0e,0x0f,0xd8,0x74,0xe0,0x06,0x31,0x00,0x10,0xc0,0x41,0xcd,0x80,0x80,0xf0,0x01,0xf9,0x40,0x05,0x1c,0x80,0x2c,0x20,0xa2,0x83,0x03,0xcc,0x14,0x23,0xa2,0xff,0x7f,0xc0,0x0d,0x0f,0x15,0x1c,0x10,0x59,0x00,0xd2,0x2d,0x10,0x08,0x41,0xfe,0x0f,0xa1,0x60,0x81,0x0b,0x12,0x4e,0x20,0xa8,0xc0,0xa2,0x40,0xfd,0x80,0x83,0xe6,0x99,0x0c,0xe3,0xc7,0x21,0xd7,0x1b,0xbf,0x32,0x22,0x24,0x1c,0x04,0x3c,0xe4,0x3f,0x98,0x94,0x0a,0x53,0x09,0x84,0xd2,0xf2,0x55,0x20,0xd0,0xad,0xc8,0x1e,0x38,0x98,0xf4,0x10,0x1e,0x54,0x9c,0x95,0x78,0x1e,0x5e,0x09,0xf8,0x3c,0xa0,0x50,0x80,0x7a,0x50,0xbe,0x1f,0xf8,0x1f,0x82,0x4f,0xe0,0x8f,0xe2,0x61,0x90,0x6e,0x4c,0x20,0x7e,0x39,0x2a,0x60,0x7c,0x63,0xd6,0x09,0x37,0x82,0x46,0x7f,0xa8,0x1f,0x02,0x27,0xc0,0xa0,0x83,0xe2,0x40,0xec,0x12,0xf8,0xf0,0x1e,0x62,0x0f,0x7a,0x04,0xc0,0x08,0x40,0xfa,0xc0,0x2f,0x88,0x1e,0x4e,0xf8,0xff,0xc1,0x41,0xe9,0x00,0xd0,0x05,0xc8,0x48,0x30,0x4c,0x04,0x7f,0xe8,0x0f,0x5f,0x82,0xa0,0x61,0xc0,0xf1,0x0a,0x0f,0x82,0x1f,0x1f,0x07,0xa7,0xf3,0xcf,0xc0,0x84,0xaa,0x44,0xda,0x22,0x21,0x46,0x08,0x3c,0xff,0xd0,0xf9,0xfc,0x40,0x1e,0x2a,0x81,0x11,0x10,0x10,0x7e,0x18,0x3f,0xff,0xf7,0xee,0x4b,0x28,0xf9,0xf0,0x60,0x06,0xf3,0x86,0x67,0x3f,0xe3,0x81,0x07,0x94,0x76,0x01,0x07,0x15,0x8c,0x0c,0x1e,0x30,0x2d,0xc1,0xa9,0x27,0xe3,0x91,0xbc,0x7e,0x05,0x43,0x0f,0x34,0x0b,0x54,0x40,0x07,0xcf,0x07,0x8e,0x00,0x40,0x2e,0x01,0x26,0x8f,0x81,0x36,0x9f,0x00,0x78,0xdc,0x00,0xa3,0xfc,0x0a,0x08,0xf1,0x00,0x03,0xf3,0x07,0x8c,0x39,0x86,0x80,0xf6,0xfa,0x4f,0xfe,0x1c,0x10,0x7a,0xff,0x01,0xc7,0x7f,0xfb,0xf7,0xe1,0xfa,0x63,0x10,0x83,0xcf,0x86,0x0f,0x3c,0xff,0xde,0x3f,0xb0,0xbc,0xdf,0x81,0xe5,0x20,0xc0,0x60,0x01,0xe7,0xef,0x07,0x8d,0x3e,0x93,0x92,0x7c,0x94,0x82,0x80,0x0f,0x4f,0x9f,0xdf,0x3e,0x05,0x23,0xe8,0x83,0xc4,0x40,0x24,0x63,0xfe,0x03,0xc4,0x0a,0x51,0x80,0x7a,0x07,0xcd,0x84,0x31,0xf1,0x61,0x47,0x01,0xe5,0x10,0x07,0xbb,0x84,0x60,0x11,0xe0,0x10,0xd8,0x01,0xf1,0x04,0x06,0x08,0xfc,0xae,0x10,0x8c,0x07,0x9c,0x1e,0xa3,0xc1,0xe0,0x28,0xc6,0x01,0xbc,0x07,0x8f,0x0c,0x2c,0x3f,0x80,0x79,0x58,0x18,0x63,0x7f,0x07,0x8c,0xfe,0x0e,0x0f,0x1d,0x7c,0xcb,0xf6,0x0f,0x15,0xaa,0x3d,0xc9,0xa2,0x3e,0x70,0xfa,0xb9,0x92,0x01,0x38,0x07,0x89,0x3d,0x81,0xeb,0x20,0x07,0xf8,0xbc,0x81,0xfc,}; +const uint8_t _A_TvActive_128x52_3[] = {0x01,0x00,0xcd,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0xf0,0x07,0xc2,0x00,0x43,0x02,0x05,0xbf,0xc2,0x0e,0x0f,0xd8,0x74,0xe0,0x06,0x31,0x00,0x10,0xc0,0x41,0xcd,0x80,0x80,0xf0,0x01,0xf9,0x40,0x05,0x1c,0x80,0x2c,0x20,0xa2,0x83,0x03,0xcc,0x14,0x23,0xa2,0xff,0x7f,0xc0,0x0d,0x0f,0x15,0x1c,0x10,0x59,0x00,0xd2,0x2d,0x10,0x08,0x41,0xfe,0x0f,0xa1,0x60,0x81,0x0b,0x12,0x4e,0x20,0xa8,0xc0,0xa2,0x40,0xfd,0x80,0x83,0xe6,0x99,0x0c,0xe3,0xc7,0x21,0xd7,0x1b,0xbf,0x32,0x22,0x24,0x1c,0x04,0x3c,0xe4,0x3f,0x98,0x94,0x0a,0x53,0x09,0x84,0xd2,0xf2,0x55,0x20,0xd0,0xad,0xc8,0x1e,0x38,0x98,0xf4,0x10,0x1e,0x54,0x9c,0x95,0x7a,0x21,0xf0,0x81,0xf8,0x27,0xe0,0xf2,0x81,0x42,0x01,0xe9,0x42,0xf8,0x43,0xe1,0xde,0x09,0x3f,0x82,0x3f,0x89,0x86,0x41,0xb9,0x30,0x81,0xf8,0xe4,0xa9,0x91,0x08,0x24,0xc2,0x40,0x0f,0x19,0xf9,0xfe,0x6e,0x9c,0x0e,0x04,0x4f,0x81,0x47,0x07,0xc4,0x83,0xf9,0x01,0x2f,0x8f,0x03,0x06,0x0f,0x8a,0x07,0xe2,0x0e,0x04,0x10,0x7d,0x60,0x09,0x62,0x0f,0x37,0x7c,0x7f,0xf0,0x37,0xf0,0x79,0xc0,0x34,0x0d,0x62,0x81,0xaa,0xc7,0x00,0x1d,0x1c,0x38,0x18,0x41,0xe5,0xf0,0x54,0x0c,0x38,0x72,0x21,0x41,0xf0,0x63,0xe0,0x21,0x21,0x07,0x97,0xf3,0xcf,0xc0,0x84,0xc1,0x99,0x05,0x00,0xfc,0x7f,0xd3,0xa2,0x0f,0x2f,0xf4,0x3e,0x7f,0x10,0x07,0x88,0x28,0x44,0x44,0x00,0x1f,0x86,0x7f,0xff,0xfd,0xfb,0x92,0xca,0x3f,0xc0,0x07,0xac,0x33,0x79,0xff,0x1c,0x08,0x3c,0xa3,0xb0,0x02,0x10,0xcc,0x01,0xe5,0x02,0x1a,0x08,0x00,0xe7,0xe4,0x91,0xbc,0x7e,0x38,0x62,0x51,0x80,0x40,0x7e,0x00,0xf4,0xe7,0x82,0x47,0x01,0x07,0xc0,0x7f,0xc0,0x42,0x2c,0x14,0xda,0x7c,0x01,0xe3,0x70,0x02,0x8f,0xf9,0x80,0x23,0xc4,0x00,0x0f,0xcc,0x1e,0x30,0xe6,0x1a,0x03,0xdb,0xe9,0x3f,0xf8,0x70,0x41,0xeb,0xfc,0x07,0x1d,0xff,0xef,0xdf,0x87,0xe9,0x8c,0x42,0x0f,0x30,0xf2,0x67,0xfe,0xf1,0xfd,0x85,0xe6,0xfc,0x0f,0x29,0x06,0x03,0x0e,0x0f,0x3f,0x78,0x3c,0x69,0xf4,0x9c,0x93,0xe4,0xa4,0x1c,0x0c,0x09,0x39,0x3e,0xea,0x61,0x00,0x10,0x3c,0xbc,0x06,0x11,0x00,0x17,0xf0,0x1e,0x20,0x52,0xfc,0x03,0xca,0xc0,0x84,0x10,0x01,0x30,0x86,0x3e,0x2c,0x2f,0xe0,0x3c,0xa6,0x00,0xf7,0x81,0x03,0x04,0xa0,0x56,0x00,0x7c,0x41,0x01,0x83,0x7f,0x01,0x0d,0xc2,0x31,0x80,0xf3,0x83,0xd6,0x31,0x00,0xe0,0x13,0xcb,0x78,0x0f,0x1e,0x1c,0x3c,0x90,0x20,0xf2,0xb0,0x30,0xc7,0xff,0x03,0x80,0x4f,0xe1,0xe0,0xf1,0xd7,0xcc,0xbf,0x60,0xf1,0x4b,0x23,0xdc,0x9c,0xc3,0xe7,0x0f,0xab,0x99,0x20,0x13,0x80,0x78,0x93,0xd8,0x1e,0xb2,0x00,0x7f,0x8b,0xc8,0x1f,0xc0,}; +const uint8_t _A_TvActive_128x52_4[] = {0x01,0x00,0xc2,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0xf0,0x07,0xc2,0x00,0x43,0x02,0x05,0xbf,0xc2,0x0e,0x0f,0xd8,0x74,0xe0,0x06,0x31,0x00,0x10,0xc0,0x41,0xcd,0x80,0x80,0xf0,0x01,0xf9,0x40,0x05,0x1c,0x80,0x2c,0x20,0xa2,0x83,0x03,0xcc,0x14,0x23,0xa2,0xff,0x7f,0xc0,0x0d,0x0f,0x15,0x1c,0x10,0x59,0x00,0xd2,0x2d,0x10,0x08,0x41,0xfe,0x0f,0xa1,0x60,0x81,0x0b,0x12,0x4e,0x20,0xa8,0xc0,0xa2,0x40,0xfd,0x80,0x83,0xe6,0x99,0x0c,0xe3,0xc7,0x21,0xd7,0x1b,0xbf,0x32,0x22,0x24,0x1c,0x04,0x3c,0xe4,0x3f,0x98,0x94,0x0a,0x53,0x09,0x84,0xd2,0xf2,0x55,0x20,0xd0,0xad,0xc8,0x1e,0x38,0x98,0xf4,0x10,0x1e,0x54,0x9c,0x95,0x78,0x1e,0x5e,0x09,0xf8,0x3c,0xa0,0x50,0x80,0x7a,0x50,0xbe,0x1f,0xf8,0x1f,0x82,0x4f,0xe0,0x8f,0xe2,0x61,0x90,0x6e,0x4c,0x20,0x7e,0x39,0x2a,0x60,0x7c,0x63,0xd6,0x09,0x37,0x82,0x46,0x7f,0xa8,0x1f,0x02,0x27,0xc0,0xa0,0x83,0xe2,0x40,0xec,0x12,0xf8,0xf0,0x1e,0x62,0x0f,0x7a,0x04,0xc0,0x08,0x40,0xfa,0xc0,0x2f,0x88,0x1e,0x4e,0xf8,0xff,0xc1,0x41,0xe9,0x00,0xd0,0x05,0xc8,0x48,0x30,0x4c,0x04,0x7f,0xe8,0x0f,0x5f,0x82,0xa0,0x61,0xc0,0xf1,0x0a,0x0f,0x82,0x1f,0x1f,0x07,0xa7,0xf3,0xcf,0xc0,0x84,0xaa,0x44,0xda,0x22,0x21,0x46,0x08,0x3c,0xff,0xd0,0xf9,0xfc,0x40,0x1e,0x2a,0x81,0x11,0x10,0x10,0x7e,0x18,0x3f,0xff,0xf7,0xee,0x4b,0x28,0xf9,0xf0,0x60,0x06,0xf3,0x86,0x67,0x3f,0xe3,0x81,0x07,0x94,0x76,0x01,0x07,0x15,0x8c,0x0c,0x1e,0x30,0x2d,0xc1,0xa9,0x27,0xe3,0x91,0xbc,0x7e,0x05,0x43,0x0f,0x34,0x0b,0x54,0x40,0x07,0xcf,0x07,0x8e,0x00,0x40,0x2e,0x01,0x26,0x8f,0x81,0x36,0x9f,0x00,0x78,0xdc,0x00,0xa3,0xfc,0x0a,0x08,0xf1,0x00,0x03,0xf3,0x07,0x8c,0x39,0x86,0x80,0xf6,0xfa,0x4f,0xfe,0x1c,0x10,0x7a,0xff,0x01,0xc7,0x7f,0xfb,0xf7,0xe1,0xfa,0x63,0x10,0x83,0xcf,0x86,0x0f,0x3c,0xff,0xde,0x3f,0xb0,0xbc,0xdf,0x81,0xe5,0x20,0xc0,0x60,0x01,0xe7,0xef,0x07,0x8d,0x3e,0x93,0x92,0x7c,0x94,0x82,0x80,0x0f,0x4f,0x9f,0xdf,0x3e,0x05,0x23,0xe8,0x83,0xc4,0x40,0x24,0x63,0xfe,0x03,0xc4,0x0a,0x51,0x80,0x7a,0x07,0xcd,0x84,0x31,0xf1,0x61,0x47,0x01,0xe5,0x10,0x07,0xbb,0x84,0x60,0x11,0xe0,0x10,0xd8,0x01,0xf1,0x04,0x06,0x08,0xfc,0xae,0x10,0x8c,0x07,0x9c,0x1e,0xa3,0xc1,0xe0,0x28,0xc6,0x01,0xbc,0x07,0x8f,0x0c,0x2c,0x3f,0x80,0x79,0x58,0x18,0x63,0x7f,0x07,0x8c,0xfe,0x0e,0x0f,0x1d,0x7c,0xcb,0xf6,0x0f,0x15,0xaa,0x3d,0xc9,0xa2,0x3e,0x70,0xfa,0xb9,0x92,0x01,0x38,0x07,0x89,0x3d,0x81,0xeb,0x20,0x07,0xf8,0xbc,0x81,0xfc,}; +const uint8_t _A_TvActive_128x52_5[] = {0x01,0x00,0xcd,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0xf0,0x07,0xc2,0x00,0x43,0x02,0x05,0xbf,0xc2,0x0e,0x0f,0xd8,0x74,0xe0,0x06,0x31,0x00,0x10,0xc0,0x41,0xcd,0x80,0x80,0xf0,0x01,0xf9,0x40,0x05,0x1c,0x80,0x2c,0x20,0xa2,0x83,0x03,0xcc,0x14,0x23,0xa2,0xff,0x7f,0xc0,0x0d,0x0f,0x15,0x1c,0x10,0x59,0x00,0xd2,0x2d,0x10,0x08,0x41,0xfe,0x0f,0xa1,0x60,0x81,0x0b,0x12,0x4e,0x20,0xa8,0xc0,0xa2,0x40,0xfd,0x80,0x83,0xe6,0x99,0x0c,0xe3,0xc7,0x21,0xd7,0x1b,0xbf,0x32,0x22,0x24,0x1c,0x04,0x3c,0xe4,0x3f,0x98,0x94,0x0a,0x53,0x09,0x84,0xd2,0xf2,0x55,0x20,0xd0,0xad,0xc8,0x1e,0x38,0x98,0xf4,0x10,0x1e,0x54,0x9c,0x95,0x7a,0x21,0xf0,0x81,0xf8,0x27,0xe0,0xf2,0x81,0x42,0x01,0xe9,0x42,0xf8,0x43,0xe1,0xde,0x09,0x3f,0x82,0x3f,0x89,0x86,0x41,0xb9,0x30,0x81,0xf8,0xe4,0xa9,0x91,0x08,0x24,0xc2,0x40,0x0f,0x19,0xf9,0xfe,0x6e,0x9c,0x0e,0x04,0x4f,0x81,0x47,0x07,0xc4,0x83,0xf9,0x01,0x2f,0x8f,0x03,0x06,0x0f,0x8a,0x07,0xe2,0x0e,0x04,0x10,0x7d,0x60,0x09,0x62,0x0f,0x37,0x7c,0x7f,0xf0,0x37,0xf0,0x79,0xc0,0x34,0x0d,0x62,0x81,0xaa,0xc7,0x00,0x1d,0x1c,0x38,0x18,0x41,0xe5,0xf0,0x54,0x0c,0x38,0x72,0x21,0x41,0xf0,0x63,0xe0,0x21,0x21,0x07,0x97,0xf3,0xcf,0xc0,0x84,0xc1,0x99,0x05,0x00,0xfc,0x7f,0xd3,0xa2,0x0f,0x2f,0xf4,0x3e,0x7f,0x10,0x07,0x88,0x28,0x44,0x44,0x00,0x1f,0x86,0x7f,0xff,0xfd,0xfb,0x92,0xca,0x3f,0xc0,0x07,0xac,0x33,0x79,0xff,0x1c,0x08,0x3c,0xa3,0xb0,0x02,0x10,0xcc,0x01,0xe5,0x02,0x1a,0x08,0x00,0xe7,0xe4,0x91,0xbc,0x7e,0x38,0x62,0x51,0x80,0x40,0x7e,0x00,0xf4,0xe7,0x82,0x47,0x01,0x07,0xc0,0x7f,0xc0,0x42,0x2c,0x14,0xda,0x7c,0x01,0xe3,0x70,0x02,0x8f,0xf9,0x80,0x23,0xc4,0x00,0x0f,0xcc,0x1e,0x30,0xe6,0x1a,0x03,0xdb,0xe9,0x3f,0xf8,0x70,0x41,0xeb,0xfc,0x07,0x1d,0xff,0xef,0xdf,0x87,0xe9,0x8c,0x42,0x0f,0x30,0xf2,0x67,0xfe,0xf1,0xfd,0x85,0xe6,0xfc,0x0f,0x29,0x06,0x03,0x0e,0x0f,0x3f,0x78,0x3c,0x69,0xf4,0x9c,0x93,0xe4,0xa4,0x1c,0x0c,0x09,0x39,0x3e,0xea,0x61,0x00,0x10,0x3c,0xbc,0x06,0x11,0x00,0x17,0xf0,0x1e,0x20,0x52,0xfc,0x03,0xca,0xc0,0x84,0x10,0x01,0x30,0x86,0x3e,0x2c,0x2f,0xe0,0x3c,0xa6,0x00,0xf7,0x81,0x03,0x04,0xa0,0x56,0x00,0x7c,0x41,0x01,0x83,0x7f,0x01,0x0d,0xc2,0x31,0x80,0xf3,0x83,0xd6,0x31,0x00,0xe0,0x13,0xcb,0x78,0x0f,0x1e,0x1c,0x3c,0x90,0x20,0xf2,0xb0,0x30,0xc7,0xff,0x03,0x80,0x4f,0xe1,0xe0,0xf1,0xd7,0xcc,0xbf,0x60,0xf1,0x4b,0x23,0xdc,0x9c,0xc3,0xe7,0x0f,0xab,0x99,0x20,0x13,0x80,0x78,0x93,0xd8,0x1e,0xb2,0x00,0x7f,0x8b,0xc8,0x1f,0xc0,}; +const uint8_t *_A_TvActive_128x52[] = {_A_TvActive_128x52_0,_A_TvActive_128x52_1,_A_TvActive_128x52_2,_A_TvActive_128x52_3,_A_TvActive_128x52_4,_A_TvActive_128x52_5}; -const uint8_t _A_TV_128x51_0[] = {0x01,0x00,0x14,0x02,0x80,0x40,0xa0,0x14,0x08,0x88,0x21,0x38,0x10,0x0b,0x00,0x3f,0x24,0x10,0x0c,0x00,0x18,0xe0,0x80,0x81,0x84,0x83,0xd2,0x20,0x02,0x18,0x08,0x18,0xa1,0x00,0xf1,0x83,0x03,0xd0,0x10,0x22,0xb2,0x0b,0x18,0x3d,0x85,0x02,0x02,0x30,0x79,0xc2,0x8b,0x0c,0x22,0x32,0x31,0x48,0x09,0xea,0x0f,0x22,0x11,0x17,0x46,0x01,0xa0,0x09,0x08,0x00,0xc9,0x84,0x0f,0x33,0x20,0xd4,0x02,0x42,0x0f,0x60,0xc1,0x83,0xc6,0x60,0x77,0x40,0x7b,0x81,0xc4,0x1e,0x37,0xff,0x00,0x5c,0xa0,0x78,0x08,0x78,0x3d,0x20,0x43,0x51,0xc0,0x67,0xc1,0xe6,0x03,0x15,0x82,0x41,0x23,0x03,0x43,0x07,0xa1,0x21,0x20,0x91,0x40,0x42,0x03,0xc7,0xc1,0x3f,0x0f,0xa4,0x22,0x48,0x0f,0x4e,0x04,0x06,0x41,0x67,0x0f,0xa4,0x42,0x44,0x03,0x19,0x80,0xec,0xec,0x1a,0x7d,0x00,0x3c,0xff,0x14,0x70,0x18,0xc3,0x00,0x42,0x45,0x1e,0x05,0x4f,0x82,0x0f,0x38,0x35,0x60,0x06,0x24,0xb2,0x09,0x0e,0x03,0x5e,0x1f,0x48,0x08,0xa4,0x7e,0x01,0x63,0x01,0x0d,0x43,0xa0,0x9f,0x4a,0x07,0xe2,0x1e,0x07,0x21,0x11,0x32,0x45,0x9e,0x98,0x07,0xb1,0xab,0x8e,0x00,0x1f,0x2f,0xff,0xfe,0x1e,0x0f,0x41,0x91,0x20,0x47,0x50,0x04,0x1a,0xad,0x57,0xea,0x12,0x10,0x98,0xc0,0x35,0xc7,0x12,0x82,0x75,0x00,0xe3,0xaa,0x00,0x24,0x3b,0x01,0xd5,0x07,0x8c,0x72,0x01,0x78,0x9a,0x87,0xc8,0x00,0x70,0xfe,0x06,0xab,0xff,0xe1,0x28,0x8c,0x32,0xd4,0x1f,0x5f,0x54,0x2a,0xc1,0x81,0x80,0xc7,0x8e,0xe3,0x06,0xea,0x07,0xd6,0xeb,0x0d,0x7c,0x88,0x74,0x5e,0xe2,0x50,0x18,0x08,0x7d,0x35,0xd0,0xa0,0x78,0x92,0x86,0x5d,0x80,0x80,0xd4,0x20,0x61,0xf4,0xab,0xcf,0x67,0xd8,0x03,0x30,0xc1,0x68,0x10,0x1d,0x44,0x08,0x7c,0x9a,0xae,0x54,0x87,0x00,0x06,0x18,0x12,0x78,0x43,0xe2,0x7c,0x2f,0xfd,0xfe,0xaa,0x3f,0x1c,0x00,0x94,0x60,0x29,0xe1,0xf4,0x41,0xf1,0x00,0x02,0xdc,0x6a,0x87,0xe3,0x40,0x0f,0x09,0xac,0x5e,0x83,0x18,0x1f,0x20,0x7c,0x98,0xc2,0xab,0x28,0x04,0x12,0x41,0x22,0x00,0x0e,0x8b,0x66,0x1f,0x1a,0x00,0x3c,0xb0,0x08,0xd1,0x81,0x48,0x0f,0xa6,0x02,0x18,0x6e,0x00,0x1e,0x54,0x0b,0xeb,0x90,0x68,0x03,0xe2,0xcc,0x0f,0xca,0x01,0x21,0x7e,0x95,0x1f,0x00,0x13,0x11,0xf2,0x07,0xc6,0x01,0x3e,0x7e,0x95,0x00,0x1e,0x46,0xe2,0x91,0xec,0x83,0xe4,0x00,0x2b,0x51,0x10,0x94,0x42,0x02,0x11,0x11,0x07,0xc4,0x7c,0x53,0x50,0x7b,0x1f,0xcc,0x1e,0x5a,0x08,0xd5,0x01,0x8a,0x21,0xfa,0xaa,0x45,0x41,0xe7,0x31,0xfe,0x63,0xe4,0x43,0xf4,0x60,0x0a,0x10,0x5e,0x23,0x80,0xa4,0xc0,0xb2,0x01,0xf5,0xa8,0x21,0x08,0x1e,0xa3,0xf2,0x95,0x07,0x8b,0x55,0x0e,0xc0,0x42,0x05,0xe4,0x1f,0x4a,0xeb,0x18,0xc9,0x43,0x07,0x27,0x90,0x3c,0x47,0xe5,0xf6,0xd5,0x7a,0x90,0xe2,0x0f,0x18,0x21,0xd0,0x62,0x24,0xf1,0x0d,0x16,0x17,0xaf,0x1f,0x20,0x8c,0x78,0x1e,0x72,0x93,0xfa,0x41,0xad,0x87,0x02,0x36,0x88,0x3c,0x64,0x00,0xf2,0x0f,0x94,0x16,0x70,0xa0,0x30,0x79,0xc5,0x41,0xe2,0x3f,0x28,0x31,0xa4,0x50,0x24,0x0f,0x38,0x58,0x7d,0x41,0xe7,0x00,0x81,0x83,0xc6,0x20,}; -const uint8_t _A_TV_128x51_1[] = {0x01,0x00,0x29,0x02,0x80,0x40,0xa0,0x1e,0x08,0x80,0x21,0x38,0x15,0x5b,0xa8,0x3d,0x74,0x00,0xf5,0xd0,0x6a,0xb5,0x40,0x63,0x82,0x40,0x2a,0x10,0x90,0x7a,0x05,0x46,0xa1,0x01,0x03,0x14,0x22,0x01,0xb0,0x82,0x83,0xd0,0x10,0x3a,0x01,0x58,0x85,0x90,0x0c,0x62,0x83,0xa0,0x06,0x0c,0x1e,0x3b,0x08,0x39,0x61,0xb0,0x10,0xa0,0x31,0x48,0x07,0xee,0x25,0x28,0xa8,0x18,0xa8,0x01,0xf1,0x2f,0xa9,0x30,0xa3,0x40,0x62,0xc0,0x40,0x2b,0x02,0x21,0x07,0xb4,0xd0,0x1e,0x92,0x8e,0x07,0xfc,0x1e,0xd2,0x80,0x3a,0x4e,0x00,0x63,0x83,0x81,0x85,0xc6,0x07,0x80,0x87,0xcc,0x08,0xe9,0x18,0x01,0x8f,0xf0,0xb8,0x41,0x21,0x80,0x58,0x0e,0xe8,0x0f,0x23,0x61,0x83,0xca,0xa0,0x0f,0x48,0xa0,0xf1,0x01,0xe3,0xe0,0xdf,0x87,0xd2,0x11,0x24,0x2a,0x1b,0x78,0x60,0x3e,0x0b,0x3d,0x45,0x8e,0x92,0x24,0x21,0x8e,0xca,0xc1,0xa7,0xd0,0x03,0xcf,0xf1,0x47,0x01,0x89,0x60,0x88,0xa3,0xc0,0xa9,0xf4,0x41,0xe7,0x06,0xac,0x00,0xc6,0x18,0x02,0x3c,0x06,0xbc,0x3e,0x90,0x1b,0x07,0xc3,0xfe,0x5b,0x28,0x31,0x78,0xba,0x09,0xf4,0xa0,0x3e,0x44,0x00,0x41,0x22,0x80,0x6a,0x19,0xe9,0x80,0x7c,0x8a,0xb9,0x60,0x1d,0x40,0x10,0xff,0xff,0xf0,0xf0,0x7a,0x7c,0x05,0x25,0x03,0xd5,0x01,0x06,0xab,0x55,0xfa,0x84,0x84,0x26,0x30,0x0d,0x71,0xc4,0xa0,0x9d,0x40,0x38,0xea,0x80,0x09,0x0e,0xc0,0x75,0x41,0xe3,0x1c,0x80,0x5e,0xa6,0xa1,0xf2,0x00,0x1c,0x3f,0x81,0xaa,0xff,0xf8,0x4a,0x23,0xad,0xb5,0x07,0xd7,0xd5,0x0a,0xb0,0x75,0x60,0x31,0xeb,0x06,0x02,0xac,0x25,0x10,0xf2,0x5d,0x61,0xba,0x0d,0x50,0x74,0x6a,0x14,0x0c,0x1e,0xaa,0x02,0x1f,0x4d,0x70,0x7c,0x68,0x04,0xa1,0x97,0x68,0x20,0x35,0x58,0x18,0x7d,0x2a,0xf3,0xd9,0xf6,0x00,0xcc,0x31,0x5a,0x80,0x74,0x60,0x43,0xe4,0xd5,0x72,0xa4,0x38,0x00,0x30,0xc2,0x93,0xc2,0x1f,0x13,0xe1,0x7f,0xef,0xf5,0x58,0x6c,0x83,0x00,0x25,0x18,0x29,0x34,0x7d,0x50,0x7c,0x40,0x00,0xb7,0x01,0xa1,0x90,0x1c,0x07,0x55,0x82,0x4f,0x0c,0x76,0x30,0x3e,0x40,0xf9,0x50,0x03,0xc2,0x02,0x17,0x20,0xc8,0x24,0x40,0x01,0xd1,0x6c,0xc3,0xe3,0x40,0x6b,0x0c,0x03,0x40,0x8d,0x18,0x1c,0x80,0xfa,0x60,0x21,0x86,0xe0,0x01,0xe5,0x50,0xbe,0xb9,0x06,0x80,0x3e,0x2c,0xc0,0xfc,0xa0,0x12,0x17,0xe9,0x51,0xf0,0x0f,0xd1,0x1f,0x20,0x7c,0x60,0x13,0xe0,0x78,0xf5,0x68,0x00,0xf2,0x37,0x14,0x8f,0x64,0x1f,0x21,0xf1,0x91,0x0b,0x01,0x01,0x01,0x08,0x88,0x83,0xe2,0x3e,0x29,0xa8,0x3d,0x8f,0xe6,0x0f,0x2d,0x54,0x6a,0x81,0x20,0x0f,0xd1,0x24,0x62,0xa0,0xf3,0x98,0xff,0x31,0xf2,0x21,0xfa,0x6a,0x10,0x85,0x10,0x07,0x8d,0x26,0x05,0x90,0x0f,0x94,0x74,0xd0,0x68,0x41,0x07,0xa8,0xfc,0x80,0x09,0x0e,0xc0,0x42,0x05,0xe4,0x1f,0x4a,0xeb,0x18,0xc9,0x43,0x07,0x27,0x90,0x3c,0x47,0xe5,0xf6,0xd5,0x7a,0x90,0xe2,0x0f,0x18,0x20,0xd8,0x62,0x24,0xf1,0x0d,0x16,0x17,0xaf,0x1f,0x28,0x8c,0x78,0x1e,0x72,0x93,0xfa,0x41,0xad,0x88,0x02,0x36,0x88,0x3c,0x64,0x00,0xf2,0x0f,0x94,0x16,0x70,0x0f,0x24,0xe8,0x83,0xca,0x2a,0x0f,0x11,0xf9,0x41,0x8d,0x22,0x00,0x16,0x68,0x83,0xca,0x16,0x1f,0x50,0x79,0xc0,0x20,0x60,0xf1,0x88,0x00,}; -const uint8_t _A_TV_128x51_2[] = {0x01,0x00,0x15,0x02,0x80,0x40,0xa0,0x11,0xc8,0x80,0x21,0x38,0x10,0x0b,0x00,0x3d,0x62,0xc0,0xf5,0x90,0x40,0x30,0x00,0x63,0x82,0x40,0x25,0x50,0x80,0x7a,0x05,0x4a,0x02,0x06,0x20,0x60,0xcd,0x82,0x42,0x00,0x30,0xa9,0x0a,0xc4,0x2c,0x76,0x20,0x31,0x8a,0x0c,0x04,0x60,0xf2,0xe3,0x40,0xcb,0x0c,0x22,0x32,0x31,0x42,0xa0,0xe0,0xf7,0x2c,0x1d,0x02,0x01,0x86,0x27,0xa9,0x30,0x81,0xe6,0x64,0x1a,0x50,0x3e,0x05,0x62,0x0f,0x39,0x20,0x3f,0x00,0xe3,0x3c,0xf8,0x4f,0xf0,0x00,0xc1,0xc0,0x40,0xf0,0x10,0xf0,0x7a,0x40,0xa3,0x0a,0xa1,0xb0,0x03,0xcc,0x14,0x2b,0x04,0x82,0x4e,0x00,0x63,0x1f,0x07,0xa9,0x6c,0x41,0xe7,0x14,0x22,0x18,0x3c,0xbc,0x13,0xf0,0xfa,0x42,0x01,0xe4,0x18,0x2e,0x04,0x06,0x41,0x67,0x0f,0xa4,0x42,0x44,0x58,0x40,0xd8,0xd8,0x34,0xfa,0x00,0x79,0xfe,0x24,0xe0,0x31,0x29,0x08,0x08,0xb8,0x15,0x3e,0x08,0x3c,0xe0,0xd5,0x80,0x19,0x00,0x86,0x18,0x41,0x1d,0x78,0x7d,0x20,0x36,0x0c,0x07,0xfd,0x16,0x41,0x22,0xa8,0x74,0x13,0xe9,0x40,0xbc,0x05,0x8d,0xc8,0x61,0xf3,0x29,0x8e,0x01,0xec,0x6a,0xe3,0x80,0x07,0xcb,0xff,0xff,0x87,0x83,0xd3,0xe0,0x81,0x3d,0x40,0x10,0x6a,0xb5,0x5f,0xa8,0x48,0x42,0x63,0x00,0xd7,0x1c,0x4a,0x09,0xd4,0x03,0x8e,0xa8,0x00,0x90,0xec,0x07,0x54,0x1e,0x31,0xc8,0x05,0xe2,0x6a,0x1f,0x20,0x01,0xc3,0xf8,0x1a,0xaf,0xff,0x84,0xa2,0x30,0xcb,0x50,0x7d,0x7d,0x50,0xab,0x06,0x06,0x03,0x1e,0x50,0x8c,0x1b,0xa8,0x1f,0x5b,0xac,0x35,0x60,0x21,0xd1,0x88,0x00,0xc7,0x51,0x01,0x0f,0xa6,0xba,0x14,0x0f,0x12,0x50,0xcb,0xb0,0x10,0x1a,0x84,0x0c,0x3e,0x95,0x79,0xec,0xfb,0x00,0x66,0x18,0x2d,0x02,0x03,0xa8,0x81,0x0f,0x93,0x55,0xca,0x90,0xe0,0x00,0xc3,0x02,0x4f,0x08,0x7c,0x4f,0x85,0xff,0xbf,0xd5,0x47,0xe3,0x80,0x12,0x8c,0x05,0x3c,0x3e,0x88,0x3e,0x20,0x00,0x5b,0x8d,0x50,0xfc,0x68,0x01,0xe1,0x35,0x8b,0xd0,0x63,0x03,0xe4,0x0f,0x93,0x18,0x55,0x65,0x00,0x82,0x48,0x24,0x40,0x01,0xd1,0x6c,0xc3,0xe3,0x40,0x07,0x96,0x01,0x1a,0x30,0x29,0x01,0xf4,0xc0,0x43,0x0d,0xc0,0x03,0xca,0x81,0x7d,0x72,0x0d,0x00,0x7c,0x59,0x81,0xf9,0x40,0x24,0x2f,0xd2,0xa3,0xe0,0x02,0x62,0x3e,0x40,0xf8,0xc0,0x27,0xcf,0xd2,0xa0,0x03,0xc8,0xdc,0x52,0x3d,0x90,0x7c,0x80,0x05,0x6a,0x22,0x12,0x88,0x40,0x42,0x22,0x20,0xf8,0x8f,0x8a,0x6a,0x0f,0x63,0xf9,0x83,0xcb,0x41,0x1a,0xa0,0x31,0x44,0x3f,0x55,0x48,0xa8,0x3c,0xe6,0x3f,0xcc,0x7c,0x88,0x7e,0x8c,0x01,0x42,0x0b,0xc4,0x70,0x14,0x98,0x16,0x40,0x3e,0xb5,0x04,0x21,0x03,0xd4,0x7e,0x52,0xa0,0xf1,0x6a,0xa1,0xd8,0x08,0x40,0xbc,0x83,0xe9,0x5d,0x63,0x19,0x28,0x60,0xe4,0xf2,0x07,0x88,0xfc,0xbe,0xda,0xaf,0x52,0x1c,0x41,0xe3,0x04,0x3a,0x0c,0x44,0x9e,0x21,0xa2,0xc2,0xf5,0xe3,0xe4,0x11,0x8f,0x03,0xce,0x52,0x7f,0x48,0x35,0xb0,0xe0,0x46,0xd1,0x07,0x8c,0x80,0x1e,0x41,0xf2,0x82,0xce,0x14,0x06,0x0f,0x38,0xa8,0x3c,0x47,0xe5,0x06,0x34,0x8a,0x04,0x81,0xe7,0x0b,0x0f,0xa8,0x3c,0xe0,0x10,0x30,0x78,0xc4,0x00,}; -const uint8_t _A_TV_128x51_3[] = {0x01,0x00,0x26,0x02,0x80,0x40,0xa0,0x10,0xa8,0x80,0x21,0x38,0x15,0x5b,0xa8,0x3d,0x62,0x40,0xf5,0xd0,0x6a,0xb5,0x40,0x63,0x82,0x40,0x22,0x30,0x80,0x7a,0x05,0x46,0xa1,0x01,0x03,0x10,0x30,0x62,0x21,0x21,0x00,0x18,0x20,0x74,0x02,0xb1,0x0b,0x1c,0x84,0x0c,0x62,0x83,0xa0,0x41,0x41,0xe9,0xc1,0x07,0xa8,0x14,0x70,0x10,0xa0,0x31,0x48,0x20,0x18,0x18,0x18,0x3d,0xa0,0x11,0x50,0x31,0x50,0x01,0xee,0x4c,0x28,0xd0,0x18,0xb0,0x10,0x0a,0x09,0x3d,0x41,0xe5,0x34,0x07,0xa4,0x88,0xde,0xa0,0xf2,0x94,0x01,0xd2,0x45,0xf0,0x87,0xf0,0x02,0xe5,0x03,0xc0,0x43,0xe6,0x04,0x74,0x8a,0x40,0x3e,0x1a,0x00,0x79,0x80,0xc6,0xc0,0x77,0x41,0x71,0x67,0xc1,0xeb,0x50,0x07,0xa0,0x7c,0x4c,0x84,0x0f,0x2f,0x06,0xfc,0x3e,0x90,0x80,0x7a,0xf0,0x20,0x3e,0x0b,0x3d,0x45,0x8e,0x92,0x20,0x18,0x92,0x08,0x36,0x36,0x0d,0x39,0x18,0x80,0x03,0xf8,0x93,0x80,0xc6,0x18,0x02,0x18,0xc0,0x84,0x6a,0x7d,0x10,0x79,0xc1,0xab,0x00,0x31,0x25,0x90,0x48,0x70,0x1a,0xf0,0xfa,0x40,0x45,0x23,0xfc,0x0b,0x19,0x78,0xba,0x09,0xf4,0xa0,0x7e,0x18,0x06,0x03,0x3d,0x43,0x3d,0x30,0x0b,0xf4,0x57,0x14,0x03,0xa8,0x02,0x1f,0xff,0xfe,0x1e,0x0f,0x4f,0x82,0x04,0xf5,0x40,0x41,0xaa,0xd5,0x7e,0xa1,0x21,0x09,0x8c,0x03,0x5c,0x71,0x28,0x27,0x50,0x0e,0x3a,0xa0,0x02,0x43,0xb0,0x1d,0x50,0x78,0xc7,0x20,0x17,0xa9,0xa8,0x7c,0x80,0x06,0xe0,0x1d,0x57,0xff,0xc2,0x51,0x1d,0x6d,0xa8,0x3e,0xbe,0xa8,0x55,0x83,0xab,0x01,0x8f,0x58,0x30,0x15,0x61,0x28,0x87,0x92,0xeb,0x0d,0xd0,0x6a,0x83,0xa3,0x50,0xa0,0x60,0xf5,0x50,0x10,0xfa,0x6b,0x83,0xe3,0x40,0x25,0x0c,0xbb,0x41,0x01,0xaa,0xc0,0xc3,0xe9,0x57,0x9e,0xcf,0xb0,0x06,0x61,0x8a,0xd4,0x03,0xa3,0x02,0x1f,0x26,0xab,0x95,0x21,0xc0,0x01,0x86,0x14,0x9e,0x10,0xf8,0x9f,0x0b,0xff,0x7f,0xaa,0xc3,0x64,0x18,0x01,0x28,0xc1,0x49,0xa3,0xea,0x83,0xe2,0x00,0x05,0xb8,0x0d,0x0c,0x80,0xe0,0x3a,0xac,0x12,0x78,0x63,0xb1,0x81,0xf2,0x07,0xca,0x80,0x1e,0x10,0x10,0xb9,0x06,0x41,0x22,0x00,0x0e,0x8b,0x66,0x1f,0x1a,0x03,0x58,0x60,0x1a,0x04,0x68,0xc0,0xe4,0x07,0xd3,0x01,0x0c,0x37,0x00,0x0f,0x2a,0x85,0xf5,0xc8,0x34,0x01,0xf1,0x66,0x07,0xe5,0x00,0x90,0xbf,0x4a,0x8f,0x80,0x7e,0x88,0xf9,0x03,0xe3,0x00,0x9f,0x03,0xc7,0xab,0x40,0x07,0x91,0xb8,0xa4,0x7b,0x20,0xf9,0x0f,0x8c,0x88,0x58,0x08,0x08,0x08,0x44,0x44,0x1f,0x11,0xf1,0x4d,0x41,0xec,0x7f,0x30,0x79,0x6a,0xa3,0x54,0x09,0x00,0x7e,0x89,0x23,0x15,0x07,0x9c,0xc7,0xf9,0x8f,0x91,0x0f,0xd3,0x50,0x84,0x28,0x80,0x3c,0x69,0x30,0x2c,0x80,0x7c,0xa3,0xa6,0x83,0x42,0x08,0x3d,0x47,0xe4,0x00,0x48,0x76,0x02,0x10,0x2f,0x20,0xfa,0x57,0x58,0xc6,0x4a,0x18,0x39,0x3c,0x81,0xe2,0x3f,0x2f,0xb6,0xab,0xd4,0x87,0x10,0x78,0xc1,0x06,0xc3,0x11,0x27,0x88,0x68,0xb0,0xbd,0x78,0xf9,0x44,0x63,0xc0,0xf3,0x94,0x9f,0xd2,0x0d,0x6c,0x40,0x11,0xb4,0x41,0xe3,0x20,0x07,0x90,0x7c,0xa0,0xb3,0x80,0x79,0x27,0x44,0x1e,0x51,0x50,0x78,0x8f,0xca,0x0c,0x69,0x10,0x00,0xb3,0x44,0x1e,0x50,0xb0,0xfa,0x83,0xce,0x01,0x03,0x07,0x8c,0x40,}; -const uint8_t _A_TV_128x51_4[] = {0x01,0x00,0x26,0x02,0x80,0x40,0xa0,0x10,0xa8,0x80,0x21,0x38,0x15,0x5b,0xa8,0x3d,0x62,0x40,0xf5,0xd0,0x6a,0xb5,0x40,0x63,0x82,0x40,0x22,0x30,0x80,0x7a,0x05,0x46,0xa1,0x01,0x03,0x10,0x30,0x62,0x21,0x21,0x00,0x18,0x20,0x74,0x02,0xb1,0x0b,0x1c,0x84,0x0c,0x62,0x83,0xa0,0x41,0x41,0xe9,0xc1,0x07,0xa8,0x14,0x70,0x10,0xa0,0x31,0x48,0x20,0x18,0x18,0x18,0x3d,0xa0,0x11,0x50,0x31,0x50,0x01,0xee,0x4c,0x28,0xd0,0x18,0xb0,0x10,0x0a,0x09,0x3d,0x41,0xe5,0x34,0x07,0xa4,0x88,0xde,0xa0,0xf2,0x94,0x01,0xd2,0x45,0xf0,0x87,0xf0,0x02,0xe5,0x03,0xc0,0x43,0xe6,0x04,0x74,0x8a,0x40,0x3e,0x1a,0x00,0x79,0x80,0xc6,0xc0,0x77,0x41,0x71,0x67,0xc1,0xeb,0x50,0x07,0xa0,0x7c,0x4c,0x84,0x0f,0x2f,0x06,0xfc,0x3e,0x90,0x80,0x7a,0xf0,0x20,0x3e,0x0b,0x3d,0x45,0x8e,0x92,0x20,0x18,0x92,0x08,0x36,0x36,0x0d,0x39,0x18,0x80,0x03,0xf8,0x93,0x80,0xc6,0x18,0x02,0x18,0xc0,0x84,0x6a,0x7d,0x10,0x79,0xc1,0xab,0x00,0x31,0x25,0x90,0x48,0x70,0x1a,0xf0,0xfa,0x40,0x45,0x23,0xfc,0x0b,0x19,0x78,0xba,0x09,0xf4,0xa0,0x7e,0x18,0x06,0x03,0x3d,0x43,0x3d,0x30,0x0b,0xf4,0x57,0x14,0x03,0xa8,0x02,0x1f,0xff,0xfe,0x1e,0x0f,0x4f,0x82,0x04,0xf5,0x40,0x41,0xaa,0xd5,0x7e,0xa1,0x21,0x09,0x8c,0x03,0x5c,0x71,0x28,0x27,0x50,0x0e,0x3a,0xa0,0x02,0x43,0xb0,0x1d,0x50,0x78,0xc7,0x20,0x17,0xa9,0xa8,0x7c,0x80,0x06,0xe0,0x1d,0x57,0xff,0xc2,0x51,0x1d,0x6d,0xa8,0x3e,0xbe,0xa8,0x55,0x83,0xab,0x01,0x8f,0x58,0x30,0x15,0x61,0x28,0x87,0x92,0xeb,0x0d,0xd0,0x6a,0x83,0xa3,0x50,0xa0,0x60,0xf5,0x50,0x10,0xfa,0x6b,0x83,0xe3,0x40,0x25,0x0c,0xbb,0x41,0x01,0xaa,0xc0,0xc3,0xe9,0x57,0x9e,0xcf,0xb0,0x06,0x61,0x8a,0xd4,0x03,0xa3,0x02,0x1f,0x26,0xab,0x95,0x21,0xc0,0x01,0x86,0x14,0x9e,0x10,0xf8,0x9f,0x0b,0xff,0x7f,0xaa,0xc3,0x64,0x18,0x01,0x28,0xc1,0x49,0xa3,0xea,0x83,0xe2,0x00,0x05,0xb8,0x0d,0x0c,0x80,0xe0,0x3a,0xac,0x12,0x78,0x63,0xb1,0x81,0xf2,0x07,0xca,0x80,0x1e,0x10,0x10,0xb9,0x06,0x41,0x22,0x00,0x0e,0x8b,0x66,0x1f,0x1a,0x03,0x58,0x60,0x1a,0x04,0x68,0xc0,0xe4,0x07,0xd3,0x01,0x0c,0x37,0x00,0x0f,0x2a,0x85,0xf5,0xc8,0x34,0x01,0xf1,0x66,0x07,0xe5,0x00,0x90,0xbf,0x4a,0x8f,0x80,0x7e,0x88,0xf9,0x03,0xe3,0x00,0x9f,0x03,0xc7,0xab,0x40,0x07,0x91,0xb8,0xa4,0x7b,0x20,0xf9,0x0f,0x8c,0x88,0x58,0x08,0x08,0x08,0x44,0x44,0x1f,0x11,0xf1,0x4d,0x41,0xec,0x7f,0x30,0x79,0x6a,0xa3,0x54,0x09,0x00,0x7e,0x89,0x23,0x15,0x07,0x9c,0xc7,0xf9,0x8f,0x91,0x0f,0xd3,0x50,0x84,0x28,0x80,0x3c,0x69,0x30,0x2c,0x80,0x7c,0xa3,0xa6,0x83,0x42,0x08,0x3d,0x47,0xe4,0x00,0x48,0x76,0x02,0x10,0x2f,0x20,0xfa,0x57,0x58,0xc6,0x4a,0x18,0x39,0x3c,0x81,0xe2,0x3f,0x2f,0xb6,0xab,0xd4,0x87,0x10,0x78,0xc1,0x06,0xc3,0x11,0x27,0x88,0x68,0xb0,0xbd,0x78,0xf9,0x44,0x63,0xc0,0xf3,0x94,0x9f,0xd2,0x0d,0x6c,0x40,0x11,0xb4,0x41,0xe3,0x20,0x07,0x90,0x7c,0xa0,0xb3,0x80,0x79,0x27,0x44,0x1e,0x51,0x50,0x78,0x8f,0xca,0x0c,0x69,0x10,0x00,0xb3,0x44,0x1e,0x50,0xb0,0xfa,0x83,0xce,0x01,0x03,0x07,0x8c,0x40,}; -const uint8_t *_A_TV_128x51[] = {_A_TV_128x51_0,_A_TV_128x51_1,_A_TV_128x51_2,_A_TV_128x51_3,_A_TV_128x51_4}; +const uint8_t _A_Tv_128x52_0[] = {0x01,0x00,0xd2,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0xf0,0x07,0xc2,0x00,0x43,0x02,0x05,0xbf,0xc2,0x0e,0x0f,0xd8,0x74,0xe0,0x06,0x31,0x00,0x10,0xc0,0x41,0xcd,0x80,0x80,0xf0,0x01,0xf9,0x40,0x05,0x1c,0x80,0x2c,0x20,0xb3,0x19,0x98,0x28,0x40,0xc4,0x0f,0x68,0x28,0x0c,0x85,0x45,0x04,0x12,0x10,0x98,0xa0,0x1c,0x00,0x40,0x96,0x90,0x04,0x20,0xf5,0x9c,0x03,0xe0,0x5a,0x23,0x62,0x3c,0x08,0x3c,0xc0,0x64,0x32,0x10,0x7a,0x43,0x01,0x66,0x0f,0x53,0x10,0xf4,0x20,0x10,0xf2,0xb0,0xc1,0x30,0x17,0xf0,0x7b,0xd4,0x3c,0x33,0x03,0xb0,0xc0,0xac,0x08,0xd1,0x81,0x60,0x21,0xe7,0x23,0xa4,0x47,0x92,0xc5,0x02,0x98,0x40,0x20,0xc8,0x32,0x07,0xa1,0xfc,0xe0,0x3f,0x82,0xd8,0xc0,0xbc,0x13,0xf0,0x78,0xff,0xff,0xe3,0x81,0x5d,0x10,0x18,0x60,0x3f,0x08,0x1f,0x82,0x4f,0xe0,0x8f,0x91,0x47,0x08,0x0f,0x2b,0x00,0x9c,0x81,0x63,0x60,0x93,0x78,0x24,0x62,0x61,0xc1,0x03,0xca,0x3c,0x0f,0x2e,0x04,0x0f,0x81,0x13,0xe0,0x50,0x46,0xc5,0x03,0x80,0x78,0x1c,0x45,0x04,0x2a,0x89,0x7c,0x78,0x08,0xe1,0x88,0x40,0x51,0xa2,0x76,0x20,0xb8,0x98,0x45,0x8e,0x40,0xf3,0xf8,0x4f,0xd7,0x24,0x0f,0x10,0x21,0x83,0xcb,0x40,0x05,0x1a,0x00,0x28,0xe2,0x0b,0x23,0x07,0xd4,0x83,0xe8,0x0f,0x5f,0x81,0x2c,0x41,0xeb,0x0c,0x2f,0x88,0x3c,0xff,0x90,0x70,0x78,0x93,0xce,0x81,0x04,0xbe,0x31,0xc4,0x1e,0x5f,0xe8,0x78,0x3d,0x70,0x10,0x83,0x70,0x8b,0x07,0x07,0xff,0xfe,0xfd,0xd5,0x63,0xff,0x53,0x08,0x3c,0x4d,0xe7,0x0c,0xce,0x7f,0xd1,0x82,0x0f,0x28,0xe8,0x2c,0xb8,0x29,0x71,0x52,0x0e,0xe0,0x18,0x40,0x01,0x9f,0x87,0xcb,0xf0,0x2a,0x11,0x78,0xa2,0xc4,0x1e,0x9c,0xf0,0x78,0xe0,0x0a,0xc3,0xff,0x81,0x93,0x47,0xc0,0xfc,0x32,0x30,0x83,0xc6,0xe0,0x05,0x1f,0xe0,0x50,0x47,0x88,0x00,0x1f,0x98,0x3c,0x61,0xc1,0x73,0xa0,0x03,0xdb,0xe9,0x3f,0xf8,0x70,0x41,0xeb,0xfc,0x07,0x1d,0xff,0xef,0xdf,0x87,0xe9,0x8c,0x46,0x0f,0x1e,0x18,0x3c,0xf3,0xff,0x78,0xfe,0xc2,0xf3,0x7e,0x59,0x9e,0x03,0x00,0x0f,0x3f,0x78,0x3c,0x69,0xf4,0x9c,0x93,0x1c,0x41,0xe3,0x40,0x07,0xa7,0xcf,0xef,0x9f,0x02,0x91,0xf4,0x41,0xe2,0x20,0x12,0x31,0xff,0x01,0xe2,0x05,0x28,0xc0,0x3d,0x03,0xe6,0xc2,0x18,0xf8,0xb0,0xa3,0x80,0xf2,0x88,0x03,0xde,0x04,0x0c,0x18,0xf0,0x08,0x6c,0x00,0xf8,0x82,0x03,0x04,0x7e,0x57,0x07,0x98,0xf9,0xc1,0xea,0x3c,0x1e,0x03,0x4c,0xb7,0x80,0xf1,0xe1,0x85,0x87,0xf0,0x0f,0x2b,0x03,0x0c,0x6f,0xe0,0xf1,0x9f,0xc1,0xc1,0xe3,0xaf,0x99,0x7e,0xc1,0xe2,0xb5,0x47,0xb9,0x34,0x47,0xce,0x1f,0x57,0x32,0x40,0x27,0x00,0xf1,0x27,0xb0,0x3d,0x64,0x00,0xff,0x17,0x90,0x3f,0x80,}; +const uint8_t _A_Tv_128x52_1[] = {0x01,0x00,0xd4,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0xf0,0x07,0xc2,0x00,0x43,0x02,0x05,0xbf,0xc2,0x0e,0x0f,0xd8,0x74,0xe0,0x06,0x31,0x00,0x10,0xc0,0x41,0xcd,0x80,0x80,0xf0,0x01,0xf9,0x40,0x05,0x1c,0x80,0x2c,0x20,0xa2,0x83,0x03,0xcc,0x14,0x23,0xa2,0x07,0xac,0x24,0x1e,0x62,0xa2,0x82,0x09,0x08,0x4c,0x40,0xf5,0x2d,0x10,0x08,0x41,0xe9,0xc0,0x05,0x10,0x3d,0x85,0xa2,0x36,0x29,0xc0,0x3d,0x05,0x82,0x32,0x20,0x7a,0x41,0xc1,0xf2,0x62,0x10,0x18,0x9d,0x84,0x4e,0x57,0xf0,0x7c,0x88,0x44,0x14,0x36,0x04,0x68,0xc0,0xb0,0x10,0xf3,0x91,0x86,0xc4,0x22,0x20,0xf1,0x98,0x20,0xc5,0x6e,0x40,0xf5,0x00,0x88,0x28,0x7f,0x00,0x51,0x81,0x78,0x27,0xe0,0xf1,0xff,0x80,0x0a,0x1f,0x00,0xff,0x01,0x06,0x03,0xf0,0x81,0xf8,0x24,0xfe,0x08,0xf8,0xa8,0x60,0x9e,0x07,0x30,0x84,0x44,0x44,0x20,0xb1,0x90,0x03,0xc6,0x7e,0x26,0x18,0x34,0x70,0xb8,0x30,0x30,0x79,0x70,0x20,0x7c,0x08,0x9f,0x02,0x8e,0x0f,0x18,0xd0,0x30,0x7c,0x07,0xd3,0x3a,0x89,0x7c,0x78,0x18,0x32,0xe0,0xf9,0x41,0x63,0x78,0x56,0x99,0x84,0x57,0x04,0x0f,0x28,0x28,0x18,0x63,0xc0,0xf3,0x51,0x98,0x3c,0xb4,0x09,0x62,0x28,0x0a,0x68,0x80,0xe4,0x0f,0x40,0xb9,0x13,0x89,0x14,0x3f,0x40,0x7a,0xfc,0x22,0x30,0x08,0x70,0x7c,0xe4,0x10,0xc2,0xf8,0x83,0xcf,0xf9,0xe7,0xe0,0x42,0x60,0xc0,0xf2,0xa0,0x41,0x2f,0x93,0x08,0x08,0x3c,0xbf,0xd0,0xf9,0xfc,0x40,0x1e,0x78,0x08,0x41,0xb8,0x45,0x83,0x9f,0xff,0xff,0x7e,0xeb,0x12,0x53,0x08,0x3c,0x4d,0xe7,0x0c,0xde,0x7f,0xd1,0x82,0x0f,0x28,0xe8,0x2c,0xb8,0x2a,0x43,0xfc,0x33,0xcf,0xff,0x3f,0x0f,0x97,0xe3,0x06,0x25,0x26,0xa0,0x83,0xd3,0x9e,0x09,0x1c,0x01,0x8c,0x7f,0xf0,0x7c,0x02,0xe5,0x00,0x03,0xf0,0x07,0x8d,0xc0,0x0a,0x3f,0xc8,0x08,0x3c,0x83,0xe9,0xf3,0x07,0x8c,0x38,0x2e,0x74,0x00,0x7b,0x7d,0x27,0xff,0x0e,0x08,0x3d,0x7f,0x80,0xe3,0xbf,0xfd,0xfb,0xf0,0xfd,0x31,0x88,0xc1,0xe2,0x1e,0x4c,0xff,0xde,0x3f,0xb0,0xbc,0xdf,0x96,0x67,0x80,0xc3,0x83,0xcf,0xde,0x0f,0x1a,0x7d,0x27,0x25,0x01,0x07,0x97,0x03,0x02,0x4e,0x4f,0xba,0x98,0x40,0x04,0x0f,0x2f,0x01,0x84,0x40,0x05,0xfc,0x07,0x88,0x14,0xbf,0x00,0xf2,0xb0,0x60,0x03,0x06,0xc2,0x18,0xf8,0xb0,0xbf,0x80,0xf2,0x98,0x03,0xde,0x04,0x0c,0x12,0x81,0x58,0x01,0xf1,0x04,0x06,0x0d,0xfc,0x04,0x37,0x08,0xc6,0x03,0xce,0x0f,0x58,0xc4,0x03,0x80,0x4f,0x2d,0xe0,0x3c,0x78,0x70,0xf2,0x40,0x83,0xca,0xc0,0xc3,0x1f,0xfb,0xbc,0x67,0xf0,0xf0,0x78,0xeb,0xe6,0x5f,0xb0,0x78,0xa5,0x91,0xee,0x4e,0x61,0xf3,0x87,0xd5,0xcc,0x90,0x09,0xc0,0x3c,0x49,0xec,0x0f,0x59,0x00,0x3f,0xc5,0xe4,0x0f,0xe0,}; +const uint8_t _A_Tv_128x52_2[] = {0x01,0x00,0xc9,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0xf0,0x07,0xc2,0x00,0x43,0x02,0x05,0xbf,0xc2,0x0e,0x0f,0xd8,0x74,0xe0,0x06,0x31,0x00,0x10,0xc0,0x41,0xcd,0x80,0x80,0xf0,0x01,0xf9,0x40,0x05,0x1c,0x80,0x2c,0x20,0xb3,0x19,0x98,0x28,0x40,0xc4,0x0f,0x68,0x28,0x0c,0x85,0x45,0x04,0x12,0x10,0x98,0xa0,0x1c,0x00,0x40,0x96,0x90,0x04,0x20,0xf5,0x9c,0x03,0xe0,0x5a,0x23,0x62,0x3c,0x08,0x3c,0xc0,0x64,0x32,0x10,0x7a,0x43,0x01,0x66,0x0f,0x53,0x10,0xf4,0x20,0x10,0xf2,0xb0,0x83,0xea,0xa1,0xe1,0x98,0x1d,0x84,0xde,0x70,0x2c,0x04,0x3c,0xe4,0x74,0x88,0xf2,0x58,0x81,0xe8,0x82,0x5a,0x41,0xfc,0xd4,0x67,0x02,0xf0,0x4f,0xc1,0xe3,0xff,0xff,0xdf,0xd7,0x46,0x06,0x10,0x00,0xc0,0xfc,0x12,0x7f,0x04,0x7c,0x8a,0x38,0x40,0x79,0x58,0x04,0x67,0x1e,0xb0,0x49,0xbc,0x12,0x34,0x10,0xe0,0x81,0x46,0x0f,0x38,0x1f,0x02,0x27,0xc0,0xa0,0x83,0xc6,0x05,0x03,0x80,0x78,0x07,0xc6,0x55,0x12,0xf8,0xf0,0x11,0xc3,0x10,0x80,0xa3,0x44,0xec,0x40,0x01,0x98,0x04,0xcc,0x1e,0x7f,0x09,0xfa,0xe4,0xa0,0x1f,0x88,0x48,0x3d,0x74,0x00,0x51,0xa0,0x03,0xce,0x0f,0x06,0x07,0xe0,0xf4,0x7e,0x80,0xf5,0xf8,0x12,0xc4,0x1e,0x68,0x91,0xfe,0x17,0xc4,0x1e,0x7f,0xc8,0x38,0x3c,0x49,0xe4,0x02,0x1f,0x05,0xfd,0x8e,0x20,0xf2,0xff,0x43,0xc1,0xed,0xc0,0xf0,0x82,0x47,0xe1,0x83,0xff,0xff,0x7e,0xea,0xa2,0x53,0x08,0xc8,0x67,0x1f,0x00,0xa8,0xc3,0x33,0x9f,0xf1,0x38,0x83,0xca,0x3a,0x0f,0x18,0x47,0xf0,0x3c,0x2d,0x21,0xdc,0x32,0x0f,0xff,0x3f,0x0f,0x97,0xe2,0x27,0x00,0x87,0x39,0x87,0xe0,0x0f,0x4e,0x78,0x3c,0xa2,0x1e,0x0e,0x04,0x0c,0x9a,0x3e,0x05,0x49,0x91,0x84,0x1e,0x6f,0xa1,0x07,0x98,0x7d,0x3e,0x60,0xf1,0x8f,0x20,0x04,0x9e,0x34,0x00,0x7b,0x7d,0x27,0xff,0x09,0xcc,0x98,0x4e,0x40,0xf1,0xfe,0x03,0x8e,0xff,0xf7,0xef,0xc3,0xfe,0xd3,0xf0,0x7a,0x70,0xc1,0xe7,0x9f,0xfb,0xc7,0xf6,0x17,0x9b,0xf0,0x3c,0xa4,0x18,0x0c,0x00,0x3c,0xfd,0xe0,0xf1,0xa7,0xd2,0x73,0x4c,0x71,0x07,0x8d,0x00,0x1e,0x9f,0x3f,0xbe,0x7c,0x0a,0x48,0xe2,0x90,0x08,0x04,0xdc,0x7f,0xc0,0x78,0x81,0x4a,0x30,0x0f,0x40,0xf9,0xb0,0x86,0x3e,0x2c,0x28,0xe0,0x3c,0xa2,0x00,0xf7,0x81,0x03,0x06,0x3c,0x02,0x1b,0x00,0x3e,0x20,0x80,0xc1,0x1f,0x95,0xc2,0x11,0x80,0xf3,0x83,0xd4,0x78,0x3c,0x05,0x18,0xc0,0x37,0x80,0xf1,0xe1,0x85,0x87,0xf0,0x0f,0x2b,0x02,0xb4,0x6f,0xe0,0xf1,0x9f,0xc1,0xc1,0xe3,0xaf,0x99,0x7e,0xc1,0xe2,0xb5,0x47,0xb9,0x40,0x05,0xe2,0x1f,0x57,0x32,0x40,0x27,0x00,0xf1,0x27,0xb0,0x3d,0x5c,0x62,0x0f,0xf2,0xfb,0x83,0xe0,}; +const uint8_t _A_Tv_128x52_3[] = {0x01,0x00,0xc8,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0xf0,0x07,0xc2,0x00,0x43,0x02,0x05,0xbf,0xc2,0x0e,0x0f,0xd8,0x74,0xe0,0x06,0x31,0x00,0x10,0xc0,0x41,0xcd,0x80,0x80,0xf0,0x01,0xf9,0x40,0x05,0x1c,0x80,0x2c,0x20,0xa2,0x83,0x03,0xcc,0x14,0x23,0xa2,0x07,0xac,0x24,0x1e,0x62,0xa2,0x82,0x09,0x08,0x4c,0x40,0xf5,0x2d,0x10,0x08,0x41,0xe9,0xc0,0x05,0x10,0x3d,0x85,0xa2,0x36,0x29,0xc0,0x3d,0x05,0x82,0x32,0x20,0x7a,0x41,0xc1,0xf2,0x62,0x10,0x18,0x9d,0x84,0x1f,0xa2,0x11,0x05,0x11,0xb0,0xb0,0x10,0xf3,0x91,0x86,0xc4,0x22,0x20,0xf5,0x41,0x28,0x3c,0x40,0x22,0xc2,0x48,0x17,0x82,0x7e,0x0f,0x1f,0xf8,0x00,0xa1,0xf0,0x0f,0xf0,0x18,0xe0,0x7e,0x09,0x3f,0x82,0x3e,0x2a,0x18,0x27,0x81,0xcc,0x21,0x11,0x00,0x14,0x7a,0x40,0x0f,0x19,0xf8,0xb0,0x60,0xd1,0xc3,0xa0,0xc0,0xc1,0xe7,0x03,0xe0,0x44,0xf8,0x14,0x70,0x78,0xc6,0x81,0x83,0xe0,0x07,0x19,0xd4,0x4b,0xe3,0xc0,0xc1,0x97,0x07,0xca,0x0a,0x1b,0xc0,0x3c,0xe6,0x01,0x33,0x07,0x94,0x14,0x72,0x4b,0xe6,0x07,0x9e,0x80,0xf6,0x45,0x01,0x4f,0x21,0xb4,0x41,0xe6,0x17,0x22,0x72,0x79,0x17,0x26,0x0f,0x1f,0x84,0x46,0x01,0x0e,0x0f,0x9c,0xf2,0xf9,0x06,0x8c,0x03,0xcf,0xf9,0xe7,0xe0,0x42,0x60,0xc0,0xf2,0xe1,0x43,0xf9,0x88,0xc1,0x07,0x97,0xfa,0x1f,0x3f,0x88,0x03,0xce,0x02,0x21,0x11,0x78,0xfc,0x33,0xff,0xff,0xef,0xdd,0x54,0x41,0x91,0xc0,0x04,0x46,0x1c,0x4f,0x18,0x66,0xf3,0xfe,0x8c,0x10,0x79,0x47,0x41,0xe6,0x45,0x28,0x17,0xe1,0x90,0x7f,0xf9,0xf8,0x7c,0xf0,0x02,0x52,0x80,0xfc,0x01,0xe9,0xcf,0x07,0x98,0x9c,0x60,0xe0,0x42,0x3c,0x99,0x18,0x41,0xe3,0x70,0x80,0xff,0x3f,0x90,0x10,0xa1,0x80,0x0f,0xe6,0x0f,0x18,0x77,0xf9,0xd4,0x30,0x0a,0x00,0x3d,0xbe,0x93,0xff,0x87,0x04,0x4e,0x60,0xf1,0xfe,0x03,0x8e,0xff,0xf7,0xef,0xc3,0xf4,0xc6,0x21,0x07,0x98,0x79,0x33,0xff,0x78,0xfe,0xc2,0xf3,0x7e,0x07,0x94,0x83,0x01,0x87,0x07,0x9f,0xbc,0x1e,0x34,0xfa,0x4e,0x49,0x40,0x20,0xf1,0xe0,0x60,0x49,0xc9,0xf7,0x53,0x08,0x00,0x81,0xe5,0xe0,0x4b,0x10,0x00,0x7f,0x80,0xf1,0x02,0x97,0xe0,0x1e,0x56,0x04,0xa0,0x80,0x09,0x84,0x31,0xf1,0x61,0x7f,0x01,0xe5,0x30,0x07,0xbc,0x08,0x18,0x25,0x02,0xb0,0x03,0xe2,0x08,0x0c,0x1b,0xf8,0x08,0x6e,0x11,0x8c,0x07,0x9c,0x1e,0xb1,0x88,0x07,0x00,0x9e,0x5b,0xc0,0x78,0xf0,0xe1,0xe4,0x81,0x07,0x95,0x81,0x86,0x3f,0xf8,0x1c,0x02,0x7f,0x0f,0x07,0x8e,0xbe,0x65,0xfb,0x07,0x8a,0x59,0x1e,0xe4,0xe6,0x1f,0x38,0x7d,0x5c,0xc9,0x00,0x9c,0x03,0xc4,0x9e,0xc0,0xf5,0x90,0x03,0xfc,0x5e,0x40,0xfe,}; +const uint8_t _A_Tv_128x52_4[] = {0x01,0x00,0xd3,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0xf0,0x07,0xc2,0x00,0x43,0x02,0x05,0xbf,0xc2,0x0e,0x0f,0xd8,0x74,0xe0,0x06,0x31,0x00,0x10,0xc0,0x41,0xcd,0x80,0x80,0xf0,0x01,0xf9,0x40,0x05,0x1c,0x80,0x2c,0x20,0xa2,0x83,0x03,0xcc,0x14,0x23,0xa2,0x07,0xac,0x24,0x1e,0x62,0xa2,0x82,0x09,0x08,0x4c,0x40,0xf5,0x2d,0x10,0x08,0x41,0xe9,0xc0,0x05,0x10,0x3d,0x85,0xa2,0x36,0x29,0xc0,0x3d,0x05,0x82,0x32,0x20,0x7a,0x41,0xc1,0xf2,0x62,0x10,0x18,0x9d,0x84,0x4e,0x57,0xf0,0x7c,0x88,0x44,0x14,0x36,0x04,0x68,0xc0,0xb0,0x10,0xf3,0x91,0x86,0xc4,0x22,0x20,0xf1,0x98,0x20,0xc5,0x6e,0x40,0xf5,0x00,0x88,0x28,0x7f,0x00,0x51,0x81,0x78,0x27,0xe0,0xf1,0xff,0x80,0x0a,0x1f,0x00,0xff,0x01,0x06,0x03,0xf0,0x81,0xf8,0x24,0xfe,0x08,0xf8,0xa8,0x60,0x9e,0x07,0x30,0xb0,0x88,0x3a,0x31,0xfb,0x04,0x9b,0xc1,0x23,0x13,0x0c,0x1a,0x38,0xb2,0x48,0x17,0x02,0x07,0xc0,0x89,0xf0,0x28,0x20,0xf1,0x8d,0x40,0xcb,0x82,0x7d,0x33,0xa8,0x97,0xc7,0x80,0x19,0x18,0x87,0x94,0x16,0x31,0x85,0x69,0x98,0x45,0x70,0x40,0xf2,0x82,0xbb,0x96,0x10,0x65,0x12,0xe8,0x83,0xcb,0x40,0x96,0x22,0x71,0x05,0xc4,0x0e,0x2a,0x92,0x07,0x92,0xec,0x81,0xe7,0x20,0xfa,0x0d,0x88,0x1e,0x5f,0x08,0x8c,0x02,0x1c,0x0f,0x48,0x64,0x3e,0x2c,0x0f,0x3f,0xe7,0x9f,0x81,0x09,0x54,0x94,0x02,0x81,0x04,0x0c,0x90,0x3c,0xbf,0xd0,0xf9,0xfc,0x40,0x1e,0x78,0x02,0x79,0xfc,0x30,0x7f,0xff,0xef,0xdd,0x62,0x4a,0x61,0x07,0x89,0xbc,0xe1,0x99,0xcf,0xfc,0x03,0xc0,0x0f,0x28,0xe8,0x2c,0xb8,0x29,0x71,0x52,0x0e,0xe1,0x9e,0x7f,0xf9,0xf8,0x7c,0xbf,0x02,0xa1,0x6b,0x8b,0x50,0x41,0xe9,0xcf,0x07,0x8e,0x01,0xa8,0x3f,0xf8,0x19,0x34,0x7c,0x02,0x82,0x00,0x0f,0xc0,0x1e,0x37,0x00,0x28,0xff,0x20,0x20,0xf2,0x0f,0xa7,0xcc,0x1e,0x30,0xe0,0xb9,0xd0,0x01,0xed,0xf4,0x9f,0xfc,0x38,0x20,0xf5,0xfe,0x03,0x8e,0xff,0xf7,0xef,0xc3,0xf4,0xc6,0x23,0x07,0x8f,0x0c,0x1e,0x79,0xff,0xbc,0x7f,0x61,0x79,0xbf,0x2c,0xcf,0x01,0x80,0x07,0x9f,0xbc,0x1e,0x34,0xfa,0x4e,0x49,0x88,0x52,0x0a,0x00,0x3d,0x3e,0x7f,0x7c,0xf8,0x14,0x8f,0xa2,0x0f,0x11,0x00,0x91,0x8f,0xf8,0x0f,0x10,0x29,0x3b,0x44,0x1e,0x61,0xf3,0x61,0x0c,0x7c,0x58,0x51,0xc0,0x79,0x44,0x01,0xee,0xe1,0x28,0xf0,0x08,0x6c,0x00,0xf8,0x82,0x03,0x04,0x7e,0x57,0x08,0x46,0x03,0xce,0x0f,0x51,0xe0,0xf0,0x1a,0x65,0xbc,0x07,0x8f,0x0c,0x2c,0x3f,0x80,0x79,0x58,0x18,0x63,0x7f,0x07,0x8c,0xfe,0x0e,0x0f,0x1d,0x7c,0xcb,0xf6,0x0f,0x15,0xaa,0x3d,0xc9,0xcc,0x3e,0x70,0xfa,0xb9,0x92,0x01,0x38,0x07,0x89,0x3d,0x81,0xeb,0x20,0x07,0xf8,0xbc,0x81,0xfc,}; +const uint8_t _A_Tv_128x52_5[] = {0x01,0x00,0xd9,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0xf0,0x07,0xc2,0x00,0x43,0x02,0x05,0xbf,0xc2,0x0e,0x0f,0xd8,0x74,0xe0,0x06,0x31,0x00,0x10,0xc0,0x41,0xcd,0x80,0x80,0xf0,0x01,0xf9,0x40,0x05,0x1c,0x80,0x2c,0x20,0xa2,0x83,0x03,0xcc,0x14,0x23,0xa2,0x07,0xac,0x24,0x1e,0x62,0xa2,0x82,0x09,0x08,0x4c,0x40,0xf5,0x2d,0x10,0x08,0x41,0xe9,0xc0,0x05,0x10,0x3d,0x85,0xa2,0x36,0x29,0xc0,0x3d,0x05,0x82,0x32,0x20,0x7a,0x41,0xc1,0xf2,0x62,0x10,0x18,0x9d,0x84,0x4e,0x57,0xf0,0x7c,0x88,0x44,0x14,0x36,0x04,0x68,0xc0,0xb0,0x10,0xf3,0x91,0x86,0xc4,0x22,0x20,0xf1,0x98,0x20,0xc5,0x6e,0x40,0xf5,0x00,0x88,0x28,0x7f,0x00,0x51,0x81,0x78,0x27,0xe0,0xf1,0xff,0x80,0x0a,0x1f,0x00,0xff,0x01,0x06,0x03,0xf0,0x81,0xf8,0x24,0xfe,0x08,0xf8,0xa8,0x60,0x9e,0x07,0x30,0x84,0x44,0x44,0x20,0xb1,0x90,0x03,0xc6,0x7e,0x26,0x18,0x34,0x70,0xb8,0x30,0x30,0x79,0x70,0x20,0x7c,0x08,0x9f,0x02,0x8e,0x0f,0x18,0xd0,0x30,0x7c,0x07,0xd3,0x3a,0x89,0x7c,0x78,0x18,0x32,0xe0,0xf9,0x41,0x63,0x78,0x56,0x99,0x84,0x57,0x04,0x0f,0x28,0x28,0x18,0x63,0xc0,0xf3,0x51,0x98,0x3c,0xb4,0x09,0x62,0x28,0x0a,0x68,0x80,0xe4,0x0f,0x40,0xb9,0x13,0x89,0x14,0x3f,0x4f,0x81,0xf4,0x41,0xe5,0xf0,0x88,0xc0,0x21,0xc1,0xf3,0x90,0x43,0x21,0xf1,0x30,0x79,0xff,0x3c,0xfc,0x08,0x4c,0x18,0x1e,0x54,0x01,0x78,0x9e,0x04,0x1e,0x5f,0xe8,0x7c,0xfe,0x20,0x0f,0x3c,0x03,0x1c,0xfe,0x19,0xff,0xff,0xf7,0xee,0xb1,0x25,0x30,0x83,0xc4,0xde,0x20,0xf1,0x86,0x6f,0x3f,0xe8,0xc1,0x07,0x94,0x74,0x40,0x5c,0x18,0x19,0x3c,0x60,0x5f,0x86,0x79,0xff,0xe7,0xe1,0xf2,0xfc,0x60,0xc4,0xa4,0xd4,0x10,0x7a,0x73,0xc1,0x23,0x80,0x31,0x8f,0xfe,0x0f,0x80,0x5c,0xa0,0x00,0x7e,0x00,0xf1,0xb8,0x01,0x47,0xf9,0x01,0x07,0x90,0x7d,0x3e,0x60,0xf1,0x87,0x05,0xce,0x80,0x0f,0x6f,0xa4,0xff,0xe1,0xc1,0x07,0xaf,0xf0,0x1c,0x77,0xff,0xbf,0x7e,0x1f,0xa6,0x31,0x18,0x3c,0x43,0xc9,0x9f,0xfb,0xc7,0xf6,0x17,0x9b,0xf2,0xcc,0xf0,0x18,0x70,0x79,0xfb,0xc1,0xe3,0x4f,0xa4,0xe4,0xa0,0x20,0xf2,0xe0,0x60,0x49,0xc9,0xf7,0x53,0x08,0x00,0x81,0xe5,0xe0,0x30,0x88,0x00,0xbf,0x80,0xf1,0x02,0x97,0xe0,0x1e,0x56,0x0c,0x00,0x60,0xd8,0x43,0x1f,0x16,0x17,0xf0,0x1e,0x53,0x00,0x7b,0xc0,0x81,0x82,0x50,0x2b,0x00,0x3e,0x1f,0x83,0x00,0xbf,0x80,0x86,0xe1,0x18,0xc0,0x79,0xc1,0xeb,0x18,0x80,0x70,0x09,0xe5,0xbc,0x07,0x8f,0x0e,0x1e,0x48,0x10,0x79,0x58,0x18,0x63,0xff,0x81,0xc0,0x27,0xf0,0xf0,0x78,0xeb,0xe6,0x5f,0xb0,0x78,0xa5,0x91,0xee,0x4e,0x61,0xf3,0x87,0xd5,0xcc,0x90,0x09,0xc0,0x3c,0x49,0xec,0x0f,0x59,0x00,0x3f,0xc5,0xe4,0x0f,0xe0,}; +const uint8_t *_A_Tv_128x52[] = {_A_Tv_128x52_0,_A_Tv_128x52_1,_A_Tv_128x52_2,_A_Tv_128x52_3,_A_Tv_128x52_4,_A_Tv_128x52_5}; -const uint8_t _A_WavesActive_128x51_0[] = {0x01,0x00,0xef,0x01,0x00,0x14,0x7c,0x04,0x3f,0xe9,0xf8,0x3e,0xa0,0x60,0x21,0xf3,0xc3,0xc1,0xd3,0x80,0x0d,0x97,0x02,0x0e,0x0f,0x9f,0xe5,0xfc,0x06,0x3f,0x01,0x99,0x00,0x1f,0xff,0xe3,0x01,0x8c,0xf0,0x7e,0xf1,0xc1,0x70,0xf8,0xf0,0xe0,0x61,0x8f,0x4c,0xc1,0xed,0x22,0xff,0x7f,0xc0,0x09,0x73,0x07,0xb5,0x06,0x02,0x07,0x5a,0x19,0x5c,0xbf,0xe0,0xb2,0x07,0xd7,0xc3,0xfe,0x74,0x20,0x7b,0xf0,0xc1,0x63,0x7c,0x80,0x4f,0x87,0xe4,0x0f,0x6b,0x1d,0xe2,0x00,0x11,0x1f,0x81,0x7c,0xa2,0x32,0x4c,0x00,0x38,0xa2,0x97,0x3e,0x06,0x05,0x4c,0x3c,0x05,0x49,0x44,0x62,0x01,0xe3,0x8a,0x7c,0xe0,0x3c,0x71,0x49,0x29,0x4a,0x23,0x14,0xc1,0xc3,0x39,0xd1,0x88,0xbf,0xfe,0x07,0xfc,0x46,0xa0,0x3c,0x76,0x98,0x48,0x14,0xa7,0x4b,0x14,0xfd,0xc1,0xc8,0x02,0x00,0x19,0xc1,0xd0,0x62,0x39,0x4c,0x3c,0x10,0x1e,0x5f,0x58,0x7d,0x80,0x1e,0x5e,0x08,0xff,0xc0,0x1e,0x38,0x08,0x40,0x3c,0x60,0x9e,0xa8,0xff,0x00,0x1e,0x5c,0x0f,0x57,0xff,0xe3,0x15,0xc1,0xc1,0x87,0xe5,0xd4,0x9f,0xe0,0x09,0xe5,0x80,0xaa,0xff,0x4f,0xe7,0x08,0x01,0x0e,0xa1,0xe8,0x30,0x20,0x49,0x6a,0xf5,0x40,0xf3,0x83,0x00,0x86,0xbf,0xff,0x80,0x41,0x01,0x25,0x56,0xaa,0xa7,0xdb,0x57,0xfe,0x12,0x9c,0x03,0x5d,0xaa,0x77,0x2f,0xfc,0x70,0x49,0x83,0xae,0x55,0x7f,0xf7,0xfd,0x56,0xab,0xb4,0x02,0x1d,0x57,0xea,0x07,0x20,0x07,0x96,0xb3,0x54,0x63,0x1a,0xbd,0x56,0x0b,0x55,0xea,0xff,0xfe,0xf0,0x3a,0x00,0x3c,0xab,0x1d,0x50,0x18,0xee,0x03,0xe5,0x7a,0x80,0x7f,0x20,0xf8,0x0e,0x02,0xf8,0x77,0x17,0xe4,0x21,0x08,0x06,0xab,0x0f,0xbf,0x70,0x1d,0xc3,0xe1,0x8f,0xbc,0x44,0xbc,0x7f,0x8d,0x51,0x70,0x7f,0xf8,0x10,0x60,0xf8,0xa7,0xf0,0x05,0xa1,0xa5,0x45,0xb8,0x30,0x0c,0x4f,0xfc,0x18,0x30,0x01,0x60,0x83,0xd0,0x00,0x73,0x1f,0xe2,0x80,0x60,0x0e,0x21,0x07,0xc7,0x0e,0x01,0xf4,0x1c,0x11,0x2c,0x41,0xef,0x03,0x80,0xfa,0x09,0x43,0xf0,0x07,0xcc,0x1a,0x0d,0xd0,0x22,0x08,0x3c,0x5c,0x86,0x00,0x48,0x64,0x63,0x40,0x7d,0x1f,0xd0,0x3e,0x63,0x16,0x0e,0x82,0x00,0x6e,0x80,0xf1,0x12,0x08,0x00,0x7f,0x8e,0xb1,0x80,0x4c,0x30,0x1a,0xf4,0x00,0xca,0x81,0xe8,0x03,0x20,0xd0,0xf8,0x07,0x83,0x3f,0x88,0x55,0x0a,0xe4,0x75,0x38,0x05,0xc0,0x70,0x6b,0x11,0x6e,0x0c,0x00,0x48,0x30,0x02,0x38,0x88,0x8c,0x70,0x61,0xf2,0xf3,0x93,0x96,0x39,0x00,0x87,0x01,0x4b,0x50,0x1f,0x40,0x02,0xce,0x00,0xcb,0x79,0x07,0xb9,0x08,0x40,0x09,0xe1,0x07,0xbf,0x81,0x12,0xb8,0x10,0x7b,0xf0,0x0a,0x06,0x00,0x14,0xfb,0x98,0x84,0xcc,0x40,0xfb,0x49,0x90,0x03,0x67,0xc2,0x54,0x26,0x37,0xfc,0x00,0x33,0xf0,0x7c,0xff,0x10,0xa7,0xfc,0x07,0x1f,0xfc,0x7e,0x38,0x08,0x7f,0x80,0x94,0xa0,0x52,0xbf,0x0d,0x4f,0xe0,0xa3,0x6f,0xc4,0x0f,0xf8,0xd4,0x22,0x8d,0x7f,0x10,0x46,}; -const uint8_t _A_WavesActive_128x51_1[] = {0x01,0x00,0xd4,0x01,0x00,0x0e,0x02,0x1e,0x03,0x1f,0xfc,0x7c,0x1f,0x50,0x10,0x10,0xfc,0xe0,0xe0,0xf9,0xe0,0x06,0xcb,0xc1,0x03,0x07,0xcf,0xfa,0x7e,0x03,0x1f,0xc0,0xcc,0x85,0xcf,0xff,0xb8,0x81,0x07,0x3c,0x3f,0x78,0x70,0xb8,0x7e,0x34,0x30,0x30,0xe3,0xe3,0x20,0xf6,0x88,0xff,0xbf,0xe0,0x04,0x9c,0x8a,0x0c,0xb0,0x52,0x00,0x18,0x80,0x12,0x42,0x02,0x1f,0x87,0xfc,0x88,0x20,0xfb,0xbe,0x40,0x27,0xc0,0xf9,0x03,0x10,0x74,0x7e,0x03,0xf2,0x07,0xc6,0x01,0x04,0x3c,0x00,0x10,0xc3,0xa2,0x32,0x4c,0x00,0x38,0xa2,0x80,0xf1,0xe0,0x06,0x49,0x4a,0x51,0x18,0x80,0x78,0xe2,0x9e,0x19,0xff,0x80,0x0c,0x51,0xc0,0x79,0x45,0x30,0x70,0xce,0x74,0x62,0x2e,0x71,0x1b,0xf8,0x3c,0xa7,0x00,0xf2,0xda,0x61,0x20,0x52,0x9d,0x2c,0x52,0x7b,0xc0,0x9b,0x83,0xca,0xc0,0x35,0x18,0x8e,0x53,0x0f,0x04,0x07,0x92,0xbc,0x56,0x27,0xc0,0x87,0xfe,0x01,0xe3,0x80,0x84,0x03,0xc6,0x08,0xb7,0x11,0xd9,0x18,0xc7,0xeb,0xff,0xf8,0xc5,0x70,0x70,0x61,0xf9,0x41,0x20,0x17,0x02,0xb9,0xea,0xff,0xc7,0xf3,0x84,0x00,0x8c,0xde,0x70,0x0a,0xb5,0x54,0x0a,0x70,0x64,0xe1,0xc0,0x11,0x82,0x00,0x1d,0x76,0xa9,0x3e,0xd3,0xd0,0xaa,0x40,0x2b,0x95,0x57,0x7b,0x7f,0x86,0xa9,0x00,0xd6,0x6a,0x81,0x43,0x55,0xaa,0xdb,0x40,0x43,0xc7,0x16,0x8a,0xa0,0xeb,0x15,0x50,0x18,0xef,0xf5,0x58,0x2d,0x56,0xaa,0x0c,0x70,0x19,0x07,0x01,0x7c,0x3b,0x8d,0x50,0x3c,0x7c,0x01,0xf2,0xea,0xc1,0xd5,0x43,0x40,0xf0,0x24,0x86,0xe1,0xfd,0x12,0x10,0x80,0x75,0x53,0xe8,0x32,0xa8,0x43,0x03,0x3f,0x01,0x0b,0x84,0x84,0x05,0xf5,0x81,0xc3,0x0f,0xc7,0x7e,0x60,0x10,0x00,0xff,0xc7,0xd1,0x56,0x89,0xf8,0xaf,0x00,0xf6,0x74,0xa4,0x30,0x08,0x3f,0x85,0x20,0x83,0xdd,0x7a,0x31,0x80,0x20,0xfc,0x01,0xf3,0xe0,0x15,0x18,0x3c,0x70,0x0a,0xe6,0x66,0x96,0x00,0x08,0x3f,0xa0,0x7c,0xc0,0x0d,0x02,0x50,0x1b,0xa0,0x3c,0x5a,0x86,0x00,0x44,0xf8,0x94,0x06,0x54,0x0f,0x5f,0x87,0xfc,0x0a,0x47,0x01,0x98,0x44,0x2a,0x8f,0x45,0x0d,0x0c,0xf0,0xe0,0x7c,0x08,0x7a,0xf0,0x93,0xe5,0xe0,0x21,0x8a,0x70,0x8b,0x62,0x00,0x10,0xf9,0x59,0xc1,0x22,0x29,0x11,0x11,0x85,0x4a,0x01,0xa8,0x01,0x0e,0x7d,0x1c,0xfc,0x02,0xca,0xde,0x4b,0xef,0x80,0x6c,0x98,0x00,0x7c,0x20,0xf7,0x80,0x34,0xc4,0x00,0x78,0x10,0x7c,0x47,0xc0,0xa8,0x9f,0x88,0x04,0x78,0x1f,0xd3,0xe0,0x4c,0x03,0xe9,0xa8,0x40,0x07,0x51,0x90,0x3e,0x3f,0x9f,0xff,0xfd,0xfe,0xf8,0x3f,0x8c,0x03,0x3c,0xf0,0x17,0xf6,0xc9,0xcf,0xd7,0x05,0x01,0xfe,0x06,0x53,0xc0,0x02,0x16,0x88,0xf0,0x12,0xa5,0xfe,0x54,0xac,0x02,0xff,0x80,0x9f,0x81,0x07,0xf0,0x50,0x91,0x8a,0x40,0x00,}; -const uint8_t *_A_WavesActive_128x51[] = {_A_WavesActive_128x51_0,_A_WavesActive_128x51_1}; +const uint8_t _A_WavesActive_128x52_0[] = {0x01,0x00,0xc8,0x01,0x00,0x78,0x03,0xc0,0x0f,0xe0,0xf3,0xc0,0xc0,0x83,0xf8,0x07,0xce,0x03,0xff,0x0f,0x0a,0x10,0x4c,0x80,0x0f,0xfe,0x8e,0x01,0x08,0x1f,0x57,0xc0,0x19,0x7c,0x20,0xe0,0xf9,0xff,0xc0,0x47,0xe5,0xff,0x1f,0xce,0x7c,0x36,0x51,0xcf,0xf8,0xc2,0x30,0x11,0x92,0x79,0x61,0x23,0xe3,0x08,0xe0,0x46,0x61,0x00,0x42,0x9e,0x8b,0xe2,0x81,0x18,0x42,0x1c,0xe0,0x08,0x62,0x34,0x07,0xa7,0xc2,0xe0,0x04,0x2c,0x81,0x60,0x80,0x04,0x0f,0x3b,0x87,0x00,0x32,0x60,0xf5,0x15,0x1d,0xe3,0x00,0x0f,0xbf,0xe4,0x3e,0xf0,0x86,0x20,0x02,0x9b,0x06,0x70,0xc1,0x1b,0xf8,0x3c,0x83,0x8a,0x49,0x10,0x99,0x40,0xfe,0x1f,0x90,0x7c,0x54,0x2a,0xb5,0x5b,0xeb,0x8c,0x81,0xf1,0xb0,0xff,0xea,0xa3,0xc0,0x51,0xdf,0x43,0xfc,0x12,0x18,0x10,0x74,0xe0,0x5d,0x0e,0x1d,0x4d,0x5e,0x57,0x8f,0xad,0x7c,0x1e,0x91,0x08,0x0f,0xc2,0x01,0xae,0x4b,0x17,0x83,0x55,0xaa,0x90,0xcc,0xb9,0x3e,0x09,0x35,0x46,0x63,0x50,0x75,0x8b,0x68,0xb8,0x04,0x51,0x90,0xd2,0xa5,0x32,0x19,0x4d,0x46,0x96,0x1f,0x1f,0x01,0x24,0xf5,0x61,0xf1,0xa5,0x7a,0x41,0xe5,0x79,0xe8,0x41,0xf0,0x00,0xf3,0xab,0x07,0xce,0x40,0x0f,0x18,0x4f,0xc2,0x3f,0x00,0x17,0x94,0x03,0x58,0x3f,0x2e,0x34,0x83,0x92,0x3f,0x1f,0x85,0xfe,0x01,0x04,0x07,0x95,0x62,0xa2,0x7f,0x40,0x20,0xe4,0x3f,0xf0,0x17,0x01,0xec,0x35,0x40,0xf3,0x72,0x94,0x81,0x5a,0x32,0x05,0xb1,0xd5,0xd3,0xed,0x40,0xff,0x41,0xe8,0x00,0x62,0xb0,0x6f,0x01,0xed,0x80,0x76,0x0b,0xec,0xec,0x1c,0x0f,0xf3,0xc1,0xbe,0x26,0x01,0x0d,0x10,0xe4,0x9d,0xed,0xcf,0x9f,0xc0,0x20,0x53,0xe0,0x7c,0xfe,0x3f,0xe7,0x02,0x77,0x0a,0x51,0x00,0x07,0x18,0x18,0x88,0x10,0x4e,0x62,0x94,0x40,0x7a,0x11,0xc4,0x18,0x3f,0x00,0x68,0x83,0xde,0x60,0x30,0x10,0x50,0xf0,0x01,0xf5,0x60,0xd0,0x3f,0xc7,0x80,0x02,0x18,0x30,0x3d,0xac,0x18,0x0a,0x0c,0x3c,0x9a,0x20,0xf2,0xe0,0x11,0xc9,0x64,0x98,0x68,0xf0,0x3c,0xe1,0x93,0x88,0x01,0xe0,0x53,0xe6,0xce,0x19,0xec,0x03,0xa0,0x0f,0x21,0xaa,0x40,0x00,0x43,0x03,0xf0,0x5f,0xa0,0x1a,0x02,0x68,0xc7,0x11,0x67,0x07,0xf8,0x01,0x06,0x1c,0x7d,0x18,0x05,0x40,0xe4,0x20,0xf3,0x08,0x09,0x28,0x41,0x05,0xf0,0xc0,0xe8,0x20,0x48,0x71,0x58,0x3d,0xc0,0x04,0x37,0xea,0x84,0x16,0x00,0x4e,0x10,0x03,0x78,0x00,0x64,0x1f,0x20,0x7c,0x70,0x19,0x25,0x40,0x0f,0x8f,0xe0,0x1e,0xe7,0xb2,0x00,0x1f,0x20,0x1e,0xe5,0xe1,0x00,0x10,0x8c,0x61,0x00,0xe7,0xff,0x18,0xc8,0xa2,0x20,0xf6,0x49,0x0b,0xa8,0x86,0x87,0x03,0x0f,0xb2,0x04,0xc0,0x07,0xfc,0x84,0x8f,0xe0,0x6c,0xc0,}; +const uint8_t _A_WavesActive_128x52_1[] = {0x01,0x00,0xca,0x01,0x00,0x78,0x03,0xc0,0x0f,0xe0,0xf3,0xc0,0xc0,0x83,0xf8,0x07,0xce,0x03,0xff,0x0f,0x0a,0x10,0x4c,0x80,0x0f,0xfe,0x8e,0x01,0x08,0x1f,0x57,0xc0,0x19,0x7c,0x20,0xe0,0xf9,0xff,0xc0,0x47,0xe5,0xff,0x1f,0xce,0x7c,0x36,0x51,0xcf,0xf8,0xc2,0x30,0x11,0x92,0x79,0x61,0x23,0xe3,0x08,0xe0,0x46,0x61,0x00,0x42,0x9e,0x8b,0xe2,0x81,0x18,0x42,0x1c,0xe0,0x08,0x62,0x34,0x07,0x97,0xf2,0x1f,0xf0,0xb8,0x02,0x4b,0x20,0x58,0x20,0x01,0x46,0x12,0x23,0x7f,0xb8,0x70,0x03,0x26,0x0f,0x4b,0xf4,0xe1,0x38,0x3f,0x0b,0xce,0x00,0x1f,0x1c,0x39,0xdd,0xe0,0xc6,0x37,0xf4,0x31,0x00,0x17,0x1f,0x01,0x9f,0x2b,0xca,0xfc,0x02,0x11,0xe2,0xaa,0x45,0x36,0x27,0xf2,0x6f,0x90,0x3d,0xba,0x10,0x7b,0x01,0x98,0xbc,0x00,0xf8,0xd8,0x47,0xf8,0x0a,0xa2,0xe0,0x43,0xfc,0x12,0x18,0x10,0x34,0xaa,0x10,0x2a,0x85,0xff,0x00,0xba,0x3f,0xbd,0x7c,0x1e,0x91,0x08,0x0c,0xc1,0xb2,0x20,0x83,0xd7,0x6a,0xa4,0x33,0x2e,0x4f,0x82,0x4d,0x51,0x98,0xd4,0x1d,0xc3,0x04,0x07,0x95,0x72,0xab,0x21,0xa5,0x4a,0x64,0x32,0x9a,0x8d,0x2f,0x61,0xfe,0x81,0xb3,0xca,0x01,0xb8,0x0f,0x8d,0x2b,0xd2,0x0f,0x2b,0xcd,0x43,0xfb,0x07,0x88,0x12,0x0c,0x3e,0x72,0x00,0x78,0xc2,0x76,0x1f,0xa8,0x7c,0x80,0xcc,0x63,0xf2,0xe3,0x48,0x39,0x23,0xf2,0xfa,0xc7,0xe8,0x00,0xf2,0xb0,0x54,0x4f,0xe8,0x04,0x1d,0x87,0xaa,0x7e,0xcb,0x3f,0x06,0xa8,0x1e,0x6e,0x52,0xb0,0x6f,0x59,0x62,0x0a,0x2e,0x05,0x55,0x3e,0xdc,0x08,0x3a,0x00,0x60,0x13,0xe0,0x30,0x87,0xd0,0x00,0x42,0xc1,0xff,0x02,0x44,0x24,0x38,0x0a,0xaf,0xf9,0xe0,0xd0,0x0f,0xe0,0x3c,0x80,0x43,0xfb,0x0f,0x28,0x00,0xbf,0x0b,0xf1,0xf8,0x00,0x85,0xe8,0x40,0xf7,0x77,0x8b,0x88,0x9a,0x86,0x00,0x3f,0x85,0xff,0xe0,0x0f,0x20,0x10,0xc1,0x81,0xed,0xd8,0xe0,0x7f,0xc5,0x43,0x80,0x07,0xcc,0x22,0x07,0xa0,0x8f,0x83,0xce,0x18,0x0f,0x79,0xe5,0x00,0x1e,0x3d,0x00,0x7b,0xff,0xaf,0xf0,0x8e,0x06,0x8d,0x1a,0x3a,0x02,0x68,0xc7,0x13,0x89,0x01,0xc0,0x07,0x07,0xf8,0xb0,0x1a,0x81,0xfc,0x41,0xe9,0x3c,0x01,0x0c,0xe0,0x28,0x3f,0xfc,0x0e,0x82,0x05,0x00,0x8c,0x02,0x4b,0x00,0x74,0x2b,0x00,0x58,0xaf,0xd5,0x08,0x28,0x34,0x4a,0x64,0x32,0x50,0x21,0x07,0xcb,0xf0,0x35,0x10,0x02,0x85,0x8e,0x80,0x1f,0x1f,0xc2,0xb9,0xc8,0x64,0x00,0x3e,0x40,0x3d,0xfc,0x0f,0x85,0x84,0x03,0xdc,0xa8,0x60,0xfb,0x80,0x43,0x81,0xfb,0xf0,0xff,0x80,0x04,0x64,0x40,0xf7,0xff,0x37,0x45,0x00,0x40,0xc6,0x7b,0x8f,0xc0,0x7a,0x84,0x32,0x82,0x04,0x13,0xf0,0x1d,0x30,0x01,0x7f,0x20,0x3f,0xe2,0x7c,0x0d,0x96,0x02,}; +const uint8_t _A_WavesActive_128x52_2[] = {0x01,0x00,0xc8,0x01,0x00,0x78,0x03,0xc0,0x0f,0xe0,0xf3,0xc0,0xc0,0x83,0xf8,0x07,0xce,0x03,0xff,0x0f,0x0a,0x10,0x4c,0x80,0x0f,0xfe,0x8e,0x01,0x08,0x1f,0x57,0xc0,0x19,0x7c,0x20,0xe0,0xf9,0xff,0xc0,0x47,0xe5,0xff,0x1f,0xce,0x7c,0x36,0x51,0xcf,0xf8,0xc2,0x30,0x11,0x92,0x79,0x61,0x23,0xe3,0x08,0xe0,0x46,0x61,0x00,0x42,0x9e,0x8b,0xe2,0x81,0x18,0x42,0x1c,0xe0,0x08,0x62,0x34,0x07,0xa7,0xc2,0xe0,0x04,0x2c,0x81,0x60,0x80,0x04,0x0f,0x3b,0x87,0x00,0x32,0x60,0xf5,0x15,0x1d,0xe3,0x00,0x0f,0xbf,0xe4,0x3e,0xf0,0x86,0x20,0x02,0x9b,0x06,0x70,0xc1,0x1b,0xf8,0x3c,0x83,0x8a,0x49,0x10,0x99,0x40,0xfe,0x1f,0x90,0x7c,0x54,0x2a,0xb5,0x5b,0xeb,0x8c,0x81,0xf1,0xb0,0xff,0xea,0xa3,0xc0,0x51,0xdf,0x43,0xfc,0x12,0x18,0x10,0x74,0xe0,0x5d,0x0e,0x1d,0x4d,0x5e,0x57,0x8f,0xad,0x7c,0x1e,0x91,0x08,0x0f,0xc2,0x01,0xae,0x4b,0x17,0x83,0x55,0xaa,0x90,0xcc,0xb9,0x3e,0x09,0x35,0x46,0x63,0x50,0x75,0x8b,0x68,0xb8,0x04,0x51,0x90,0xd2,0xa5,0x32,0x19,0x4d,0x46,0x96,0x1f,0x1f,0x01,0x24,0xf5,0x61,0xf1,0xa5,0x7a,0x41,0xe5,0x79,0xe8,0x41,0xf0,0x00,0xf3,0xab,0x07,0xce,0x40,0x0f,0x18,0x4f,0xc2,0x3f,0x00,0x17,0x94,0x03,0x58,0x3f,0x2e,0x34,0x83,0x92,0x3f,0x1f,0x85,0xfe,0x01,0x04,0x07,0x95,0x62,0xa2,0x7f,0x40,0x20,0xe4,0x3f,0xf0,0x17,0x01,0xec,0x35,0x40,0xf3,0x72,0x94,0x81,0x5a,0x32,0x05,0xb1,0xd5,0xd3,0xed,0x40,0xff,0x41,0xe8,0x00,0x62,0xb0,0x6f,0x01,0xed,0x80,0x76,0x0b,0xec,0xec,0x1c,0x0f,0xf3,0xc1,0xbe,0x26,0x01,0x0d,0x10,0xe4,0x9d,0xed,0xcf,0x9f,0xc0,0x20,0x53,0xe0,0x7c,0xfe,0x3f,0xe7,0x02,0x77,0x0a,0x51,0x00,0x07,0x18,0x18,0x88,0x10,0x4e,0x62,0x94,0x40,0x7a,0x11,0xc4,0x18,0x3f,0x00,0x68,0x83,0xde,0x60,0x30,0x10,0x50,0xf0,0x01,0xf5,0x60,0xd0,0x3f,0xc7,0x80,0x02,0x18,0x30,0x3d,0xac,0x18,0x0a,0x0c,0x3c,0x9a,0x20,0xf2,0xe0,0x11,0xc9,0x64,0x98,0x68,0xf0,0x3c,0xe1,0x93,0x88,0x01,0xe0,0x53,0xe6,0xce,0x19,0xec,0x03,0xa0,0x0f,0x21,0xaa,0x40,0x00,0x43,0x03,0xf0,0x5f,0xa0,0x1a,0x02,0x68,0xc7,0x11,0x67,0x07,0xf8,0x01,0x06,0x1c,0x7d,0x18,0x05,0x40,0xe4,0x20,0xf3,0x08,0x09,0x28,0x41,0x05,0xf0,0xc0,0xe8,0x20,0x48,0x71,0x58,0x3d,0xc0,0x04,0x37,0xea,0x84,0x16,0x00,0x4e,0x10,0x03,0x78,0x00,0x64,0x1f,0x20,0x7c,0x70,0x19,0x25,0x40,0x0f,0x8f,0xe0,0x1e,0xe7,0xb2,0x00,0x1f,0x20,0x1e,0xe5,0xe1,0x00,0x10,0x8c,0x61,0x00,0xe7,0xff,0x18,0xc8,0xa2,0x20,0xf6,0x49,0x0b,0xa8,0x86,0x87,0x03,0x0f,0xb2,0x04,0xc0,0x07,0xfc,0x84,0x8f,0xe0,0x6c,0xc0,}; +const uint8_t _A_WavesActive_128x52_3[] = {0x01,0x00,0xfb,0x01,0x00,0x78,0x03,0xc0,0x0f,0xe0,0xf3,0xc0,0xc0,0x83,0xf8,0x07,0xce,0x03,0xff,0x0f,0x0a,0x10,0x4c,0x80,0x0f,0xfe,0x8e,0x01,0x08,0x1e,0x3f,0xef,0xf8,0x01,0x03,0x83,0x7c,0x07,0x17,0xc2,0x0f,0x00,0x80,0x87,0x56,0x21,0x00,0xff,0x82,0x4b,0xf1,0xff,0x07,0xc6,0x03,0x3e,0x1b,0x18,0x04,0x73,0xff,0x03,0x07,0xc4,0x64,0x9e,0x58,0x48,0xfc,0x1e,0x02,0x10,0x11,0x58,0x83,0xcb,0x81,0x19,0x84,0x01,0x47,0x81,0x3d,0x17,0x88,0x3d,0xa8,0x11,0x84,0x21,0xce,0x01,0xe3,0xe1,0xb7,0x5c,0x3b,0x93,0x98,0x48,0x3c,0xff,0x90,0xff,0x85,0xc0,0x1e,0x39,0x1c,0x96,0x42,0xa5,0x4a,0x07,0x8c,0x02,0x30,0x91,0x1b,0xfd,0xc3,0x80,0x0f,0x8b,0xf4,0xe1,0x38,0x3f,0x0b,0xce,0x00,0x1e,0xd4,0x98,0x87,0x0e,0x77,0x78,0x59,0x8d,0xfc,0x84,0x23,0xf1,0x07,0x88,0xfc,0x69,0xd9,0x08,0x0c,0xf9,0x5e,0x57,0xe0,0x79,0x15,0x8a,0x81,0x08,0x94,0x7c,0x13,0x62,0x7f,0x26,0xf9,0x03,0xd6,0x0d,0xd0,0x83,0xd8,0x13,0xe5,0xe0,0x07,0xa8,0x00,0xb6,0x11,0xfe,0x03,0xac,0xb8,0x10,0xff,0x00,0x3d,0xaa,0x17,0xfc,0x03,0xec,0xfe,0xf5,0xf0,0x79,0x50,0x60,0x1a,0x08,0x04,0xc1,0xb2,0x30,0x20,0x79,0x6b,0xb5,0x40,0xf1,0x39,0x88,0x3c,0xaa,0x0e,0xe1,0x82,0x03,0xca,0xb9,0x55,0x80,0xcd,0xf1,0x35,0xcf,0x36,0xe0,0x7e,0x3f,0xe8,0x1b,0x3c,0xa0,0x1b,0x80,0xf8,0xd2,0x71,0x34,0x59,0x4e,0x94,0x3e,0x3f,0xd8,0x3b,0x58,0xea,0x01,0xf1,0x07,0x8d,0x12,0x5e,0x0f,0x1d,0x87,0xea,0x1f,0x20,0x33,0x18,0x7c,0xe8,0x92,0x19,0x28,0x60,0x7e,0xb1,0xfa,0x00,0x3c,0xac,0x15,0x10,0x78,0xe3,0xa8,0x92,0x6d,0xc8,0x60,0x7d,0x53,0xf2,0xb9,0x24,0x04,0xbe,0x44,0x73,0x80,0x5c,0x37,0xac,0xb1,0x3d,0x17,0x00,0x7e,0x30,0x08,0x30,0x3c,0xfc,0x10,0x74,0x00,0xc0,0x27,0xc0,0xf1,0x0f,0x90,0x01,0x38,0x10,0x0f,0xf0,0x24,0x42,0x43,0x80,0x0f,0x90,0x01,0x07,0x83,0xfc,0x07,0x90,0x08,0x7f,0x7f,0xef,0xf8,0x01,0x60,0x3f,0x85,0xf8,0xfc,0x00,0x42,0xf4,0x20,0x03,0x7e,0x1d,0xe2,0xe2,0x26,0xa1,0x80,0x0f,0xe1,0x7f,0xf8,0x03,0xc8,0x04,0x25,0xc4,0x00,0x17,0x63,0x81,0xff,0x15,0x0e,0x00,0x1f,0x30,0x88,0x1e,0x82,0x3e,0x0f,0x38,0x60,0x3d,0xe7,0x94,0x00,0x78,0xf4,0x01,0xef,0xfe,0xbf,0xc2,0x38,0x1a,0x34,0x68,0xe8,0x09,0xa3,0x1c,0x46,0x24,0x07,0x00,0x1c,0x1f,0xe2,0xc0,0x6a,0x07,0xf1,0x07,0xa4,0xf0,0x04,0x33,0x80,0xa0,0xff,0xf0,0x3a,0x08,0x14,0x02,0x30,0x09,0x2c,0x01,0xd0,0xac,0x01,0x62,0xbf,0x54,0x20,0xa0,0xd1,0x29,0x90,0xc9,0x40,0x84,0x1f,0x2f,0xc0,0xd4,0x40,0x0a,0x16,0x3a,0x00,0x7c,0x7f,0x0a,0xe7,0x21,0x90,0x00,0xf9,0x00,0xf7,0xf0,0x3a,0x16,0x10,0x0f,0x72,0xa1,0x83,0xee,0x01,0x0e,0x07,0xef,0xc3,0xfe,0x00,0x11,0x91,0x03,0xdf,0xfc,0xdd,0x14,0x01,0x03,0x19,0xee,0x3f,0x01,0xea,0x10,0xca,0x08,0x10,0x4f,0xc0,0x74,0xc0,0x05,0xfc,0x80,0xff,0x89,0xf0,0x36,0x58,0x08,}; +const uint8_t _A_WavesActive_128x52_4[] = {0x01,0x00,0xf9,0x01,0x00,0x78,0x03,0xc0,0x0f,0xe0,0xf3,0xc0,0xc0,0x83,0xf8,0x07,0xce,0x03,0xff,0x0f,0x0a,0x10,0x4c,0x80,0x0f,0xfe,0x8e,0x01,0x08,0x1e,0x3f,0xef,0xf8,0x01,0x03,0x83,0x7c,0x07,0x17,0xc2,0x0f,0x00,0x80,0x87,0x56,0x21,0x00,0xff,0x82,0x4b,0xf1,0xff,0x07,0xc6,0x03,0x3e,0x1b,0x18,0x04,0x73,0xff,0x03,0x07,0xc4,0x64,0x9e,0x58,0x48,0xfc,0x1e,0x02,0x10,0x11,0x58,0x83,0xcb,0x81,0x19,0x84,0x01,0x47,0x81,0x3d,0x17,0x88,0x3d,0xa8,0x11,0x84,0x21,0xce,0x01,0xe3,0xe1,0xb7,0x5c,0x3b,0x93,0x98,0x48,0x3d,0x7e,0x17,0x00,0x78,0xe4,0x72,0x59,0x0a,0x95,0x28,0x1e,0x30,0x00,0x79,0xdc,0x38,0x00,0xf9,0x15,0x08,0x00,0x6f,0x18,0x00,0x7b,0x52,0x41,0xe7,0xfc,0x87,0xde,0x02,0x42,0x3f,0x10,0x78,0x8f,0xc6,0x9c,0x0f,0x26,0x08,0xdf,0xc1,0xe6,0x26,0x2a,0x04,0x22,0x51,0xf0,0x59,0x94,0x0f,0xe1,0xf9,0x07,0xbc,0x1a,0xa1,0x55,0xaa,0xdf,0x5c,0x64,0x0f,0x50,0x01,0x6c,0x3f,0xfa,0xa8,0xf0,0x14,0x77,0xd0,0xff,0x00,0x3d,0xba,0x1c,0x3a,0x9a,0xbc,0xaf,0x1f,0x5a,0xf8,0x3c,0xa8,0x30,0x0d,0x02,0x24,0x60,0x1a,0xe6,0x79,0x78,0x35,0x5a,0xa0,0x78,0x9c,0xc4,0x1e,0x55,0x07,0x58,0xc0,0xd7,0xe4,0x45,0x18,0x0c,0xdf,0x13,0x5c,0xf3,0x6e,0x03,0xe4,0x39,0x4d,0x58,0x7c,0x69,0x38,0x9a,0x2c,0xa7,0x4a,0x3f,0x18,0x3e,0x00,0x1e,0x75,0x60,0xf8,0x83,0xc6,0x89,0x2f,0x07,0x8f,0xc2,0x3f,0x00,0x17,0x94,0x03,0x58,0x1f,0x3a,0x24,0x86,0x4a,0x1f,0x1b,0xfc,0x02,0x08,0x0f,0x2a,0xc5,0x44,0x1e,0x38,0xea,0x24,0x9b,0x72,0x1f,0x1f,0xfc,0x05,0xc0,0x7b,0x0f,0xf0,0xd4,0x61,0x07,0xf3,0x98,0x2b,0x46,0x40,0x06,0x2f,0x84,0x0c,0x1e,0x30,0x60,0x79,0xd8,0x3f,0xd0,0x7a,0x00,0x18,0xd5,0xef,0xc0,0x76,0x0a,0x1c,0x81,0xf3,0x80,0xf8,0x98,0x04,0x14,0x5c,0x08,0x07,0xf9,0xd0,0x40,0x03,0xe7,0xcf,0xe0,0x10,0x29,0xf0,0x3c,0x80,0x0d,0xf8,0xff,0x9c,0x09,0xdc,0x29,0x44,0x00,0x1c,0x60,0x42,0x20,0x41,0x39,0x8a,0x51,0x01,0xe8,0x37,0x10,0x60,0x9b,0x44,0x1f,0x13,0x01,0x80,0x82,0x87,0x80,0x0f,0xab,0x06,0x81,0xfe,0x3c,0x00,0x10,0xa3,0x10,0xf0,0x78,0x0a,0x0c,0x3c,0x9a,0x20,0xf4,0xf0,0x16,0x44,0xf0,0x78,0x68,0xf0,0x3c,0xe1,0x80,0xa1,0x8e,0x60,0x11,0x42,0x68,0x28,0xc4,0xf5,0xc8,0x20,0xf3,0xc0,0x10,0x87,0xc0,0x02,0x10,0x28,0xf8,0x2f,0xd0,0x0d,0x00,0x1c,0x63,0x90,0x0b,0x80,0xb4,0xbf,0x90,0x3b,0xc4,0x38,0xfa,0x30,0x0a,0x81,0xc8,0x41,0xe2,0x00,0x4f,0xe4,0x1c,0x10,0x3f,0x0c,0x0e,0x82,0x04,0x87,0x15,0x83,0x89,0x8a,0xfd,0x50,0x82,0xc0,0x27,0x00,0xf7,0xf0,0x00,0xc8,0x3e,0x40,0xf8,0xe0,0x32,0x4a,0x80,0x1f,0x1f,0xc0,0x3d,0xcf,0x64,0x00,0x3e,0x40,0x3d,0xcb,0xc2,0x00,0x14,0x39,0x42,0x07,0xce,0xee,0x20,0x20,0x88,0xc4,0x1e,0xb7,0xc8,0x04,0xfc,0x0e,0x84,0xd1,0x07,0xae,0x00,0x3a,0x65,0x43,0x8f,0xfa,0x07,0xf0,0x36,0x58,0xf8,}; +const uint8_t _A_WavesActive_128x52_5[] = {0x01,0x00,0xfb,0x01,0x00,0x78,0x03,0xc0,0x0f,0xe0,0xf3,0xc0,0xc0,0x83,0xf8,0x07,0xce,0x03,0xff,0x0f,0x0a,0x10,0x4c,0x80,0x0f,0xfe,0x8e,0x01,0x08,0x1e,0x3f,0xef,0xf8,0x01,0x03,0x83,0x7c,0x07,0x17,0xc2,0x0f,0x00,0x80,0x87,0x56,0x21,0x00,0xff,0x82,0x4b,0xf1,0xff,0x07,0xc6,0x03,0x3e,0x1b,0x18,0x04,0x73,0xff,0x03,0x07,0xc4,0x64,0x9e,0x58,0x48,0xfc,0x1e,0x02,0x10,0x11,0x58,0x83,0xcb,0x81,0x19,0x84,0x01,0x47,0x81,0x3d,0x17,0x88,0x3d,0xa8,0x11,0x84,0x21,0xce,0x01,0xe3,0xe1,0xb7,0x5c,0x3b,0x93,0x98,0x48,0x3c,0xff,0x90,0xff,0x85,0xc0,0x1e,0x39,0x1c,0x96,0x42,0xa5,0x4a,0x07,0x8c,0x02,0x30,0x91,0x1b,0xfd,0xc3,0x80,0x0f,0x8b,0xf4,0xe1,0x38,0x3f,0x0b,0xce,0x00,0x1e,0xd4,0x98,0x87,0x0e,0x77,0x78,0x59,0x8d,0xfc,0x84,0x23,0xf1,0x07,0x88,0xfc,0x69,0xd9,0x08,0x0c,0xf9,0x5e,0x57,0xe0,0x79,0x15,0x8a,0x81,0x08,0x94,0x7c,0x13,0x62,0x7f,0x26,0xf9,0x03,0xd6,0x0d,0xd0,0x83,0xd8,0x13,0xe5,0xe0,0x07,0xa8,0x00,0xb6,0x11,0xfe,0x03,0xac,0xb8,0x10,0xff,0x00,0x3d,0xaa,0x17,0xfc,0x03,0xec,0xfe,0xf5,0xf0,0x79,0x50,0x60,0x1a,0x08,0x04,0xc1,0xb2,0x30,0x20,0x79,0x6b,0xb5,0x40,0xf1,0x39,0x88,0x3c,0xaa,0x0e,0xe1,0x82,0x03,0xca,0xb9,0x55,0x80,0xcd,0xf1,0x35,0xcf,0x36,0xe0,0x7e,0x3f,0xe8,0x1b,0x3c,0xa0,0x1b,0x80,0xf8,0xd2,0x71,0x34,0x59,0x4e,0x94,0x3e,0x3f,0xd8,0x3b,0x58,0xea,0x01,0xf1,0x07,0x8d,0x12,0x5e,0x0f,0x1d,0x87,0xea,0x1f,0x20,0x33,0x18,0x7c,0xe8,0x92,0x19,0x28,0x60,0x7e,0xb1,0xfa,0x00,0x3c,0xac,0x15,0x10,0x78,0xe3,0xa8,0x92,0x6d,0xc8,0x60,0x7d,0x53,0xf2,0xb9,0x24,0x04,0xbe,0x44,0x73,0x80,0x5c,0x37,0xac,0xb1,0x3d,0x17,0x00,0x7e,0x30,0x08,0x30,0x3c,0xfc,0x10,0x74,0x00,0xc0,0x27,0xc0,0xf1,0x0f,0x90,0x01,0x38,0x10,0x0f,0xf0,0x24,0x42,0x43,0x80,0x0f,0x90,0x01,0x07,0x83,0xfc,0x07,0x90,0x08,0x7f,0x7f,0xef,0xf8,0x01,0x60,0x3f,0x85,0xf8,0xfc,0x00,0x42,0xf4,0x20,0x03,0x7e,0x1d,0xe2,0xe2,0x26,0xa1,0x80,0x0f,0xe1,0x7f,0xf8,0x03,0xc8,0x04,0x25,0xc4,0x00,0x17,0x63,0x81,0xff,0x15,0x0e,0x00,0x1f,0x30,0x88,0x1e,0x82,0x3e,0x0f,0x38,0x60,0x3d,0xe7,0x94,0x00,0x78,0xf4,0x01,0xef,0xfe,0xbf,0xc2,0x38,0x1a,0x34,0x68,0xe8,0x09,0xa3,0x1c,0x46,0x24,0x07,0x00,0x1c,0x1f,0xe2,0xc0,0x6a,0x07,0xf1,0x07,0xa4,0xf0,0x04,0x33,0x80,0xa0,0xff,0xf0,0x3a,0x08,0x14,0x02,0x30,0x09,0x2c,0x01,0xd0,0xac,0x01,0x62,0xbf,0x54,0x20,0xa0,0xd1,0x29,0x90,0xc9,0x40,0x84,0x1f,0x2f,0xc0,0xd4,0x40,0x0a,0x16,0x3a,0x00,0x7c,0x7f,0x0a,0xe7,0x21,0x90,0x00,0xf9,0x00,0xf7,0xf0,0x3a,0x16,0x10,0x0f,0x72,0xa1,0x83,0xee,0x01,0x0e,0x07,0xef,0xc3,0xfe,0x00,0x11,0x91,0x03,0xdf,0xfc,0xdd,0x14,0x01,0x03,0x19,0xee,0x3f,0x01,0xea,0x10,0xca,0x08,0x10,0x4f,0xc0,0x74,0xc0,0x05,0xfc,0x80,0xff,0x89,0xf0,0x36,0x58,0x08,}; +const uint8_t _A_WavesActive_128x52_6[] = {0x01,0x00,0xf9,0x01,0x00,0x78,0x03,0xc0,0x0f,0xe0,0xf3,0xc0,0xc0,0x83,0xf8,0x07,0xce,0x03,0xff,0x0f,0x0a,0x10,0x4c,0x80,0x0f,0xfe,0x8e,0x01,0x08,0x1e,0x3f,0xef,0xf8,0x01,0x03,0x83,0x7c,0x07,0x17,0xc2,0x0f,0x00,0x80,0x87,0x56,0x21,0x00,0xff,0x82,0x4b,0xf1,0xff,0x07,0xc6,0x03,0x3e,0x1b,0x18,0x04,0x73,0xff,0x03,0x07,0xc4,0x64,0x9e,0x58,0x48,0xfc,0x1e,0x02,0x10,0x11,0x58,0x83,0xcb,0x81,0x19,0x84,0x01,0x47,0x81,0x3d,0x17,0x88,0x3d,0xa8,0x11,0x84,0x21,0xce,0x01,0xe3,0xe1,0xb7,0x5c,0x3b,0x93,0x98,0x48,0x3d,0x7e,0x17,0x00,0x78,0xe4,0x72,0x59,0x0a,0x95,0x28,0x1e,0x30,0x00,0x79,0xdc,0x38,0x00,0xf9,0x15,0x08,0x00,0x6f,0x18,0x00,0x7b,0x52,0x41,0xe7,0xfc,0x87,0xde,0x02,0x42,0x3f,0x10,0x78,0x8f,0xc6,0x9c,0x0f,0x26,0x08,0xdf,0xc1,0xe6,0x26,0x2a,0x04,0x22,0x51,0xf0,0x59,0x94,0x0f,0xe1,0xf9,0x07,0xbc,0x1a,0xa1,0x55,0xaa,0xdf,0x5c,0x64,0x0f,0x50,0x01,0x6c,0x3f,0xfa,0xa8,0xf0,0x14,0x77,0xd0,0xff,0x00,0x3d,0xba,0x1c,0x3a,0x9a,0xbc,0xaf,0x1f,0x5a,0xf8,0x3c,0xa8,0x30,0x0d,0x02,0x24,0x60,0x1a,0xe6,0x79,0x78,0x35,0x5a,0xa0,0x78,0x9c,0xc4,0x1e,0x55,0x07,0x58,0xc0,0xd7,0xe4,0x45,0x18,0x0c,0xdf,0x13,0x5c,0xf3,0x6e,0x03,0xe4,0x39,0x4d,0x58,0x7c,0x69,0x38,0x9a,0x2c,0xa7,0x4a,0x3f,0x18,0x3e,0x00,0x1e,0x75,0x60,0xf8,0x83,0xc6,0x89,0x2f,0x07,0x8f,0xc2,0x3f,0x00,0x17,0x94,0x03,0x58,0x1f,0x3a,0x24,0x86,0x4a,0x1f,0x1b,0xfc,0x02,0x08,0x0f,0x2a,0xc5,0x44,0x1e,0x38,0xea,0x24,0x9b,0x72,0x1f,0x1f,0xfc,0x05,0xc0,0x7b,0x0f,0xf0,0xd4,0x61,0x07,0xf3,0x98,0x2b,0x46,0x40,0x06,0x2f,0x84,0x0c,0x1e,0x30,0x60,0x79,0xd8,0x3f,0xd0,0x7a,0x00,0x18,0xd5,0xef,0xc0,0x76,0x0a,0x1c,0x81,0xf3,0x80,0xf8,0x98,0x04,0x14,0x5c,0x08,0x07,0xf9,0xd0,0x40,0x03,0xe7,0xcf,0xe0,0x10,0x29,0xf0,0x3c,0x80,0x0d,0xf8,0xff,0x9c,0x09,0xdc,0x29,0x44,0x00,0x1c,0x60,0x42,0x20,0x41,0x39,0x8a,0x51,0x01,0xe8,0x37,0x10,0x60,0x9b,0x44,0x1f,0x13,0x01,0x80,0x82,0x87,0x80,0x0f,0xab,0x06,0x81,0xfe,0x3c,0x00,0x10,0xa3,0x10,0xf0,0x78,0x0a,0x0c,0x3c,0x9a,0x20,0xf4,0xf0,0x16,0x44,0xf0,0x78,0x68,0xf0,0x3c,0xe1,0x80,0xa1,0x8e,0x60,0x11,0x42,0x68,0x28,0xc4,0xf5,0xc8,0x20,0xf3,0xc0,0x10,0x87,0xc0,0x02,0x10,0x28,0xf8,0x2f,0xd0,0x0d,0x00,0x1c,0x63,0x90,0x0b,0x80,0xb4,0xbf,0x90,0x3b,0xc4,0x38,0xfa,0x30,0x0a,0x81,0xc8,0x41,0xe2,0x00,0x4f,0xe4,0x1c,0x10,0x3f,0x0c,0x0e,0x82,0x04,0x87,0x15,0x83,0x89,0x8a,0xfd,0x50,0x82,0xc0,0x27,0x00,0xf7,0xf0,0x00,0xc8,0x3e,0x40,0xf8,0xe0,0x32,0x4a,0x80,0x1f,0x1f,0xc0,0x3d,0xcf,0x64,0x00,0x3e,0x40,0x3d,0xcb,0xc2,0x00,0x14,0x39,0x42,0x07,0xce,0xee,0x20,0x20,0x88,0xc4,0x1e,0xb7,0xc8,0x04,0xfc,0x0e,0x84,0xd1,0x07,0xae,0x00,0x3a,0x65,0x43,0x8f,0xfa,0x07,0xf0,0x36,0x58,0xf8,}; +const uint8_t *_A_WavesActive_128x52[] = {_A_WavesActive_128x52_0,_A_WavesActive_128x52_1,_A_WavesActive_128x52_2,_A_WavesActive_128x52_3,_A_WavesActive_128x52_4,_A_WavesActive_128x52_5,_A_WavesActive_128x52_6}; -const uint8_t _A_Waves_128x51_0[] = {0x01,0x00,0xc8,0x01,0x00,0x17,0xc2,0x03,0x00,0xf0,0x7f,0xe0,0x60,0xf9,0x98,0x00,0x86,0xe1,0xfe,0x0f,0xd7,0xe0,0x36,0x57,0xc0,0x74,0xf0,0x3f,0xf0,0x70,0x20,0xff,0xc6,0x62,0x3e,0x89,0xfc,0x38,0x26,0x3f,0x31,0xfb,0x70,0x00,0x43,0x38,0xbf,0x42,0x09,0xe3,0x31,0x07,0xb4,0x80,0x06,0x5e,0xf0,0x31,0x4c,0x06,0x64,0x00,0x38,0x80,0x0c,0xb8,0xe3,0xb2,0x98,0x41,0x01,0xf1,0x80,0xe1,0x8a,0xc8,0x1f,0x5c,0x0c,0x00,0x3c,0xcb,0x8c,0x3f,0x2a,0x06,0x00,0x76,0x53,0x83,0xe3,0x80,0xc8,0x1f,0x60,0x03,0x07,0xff,0x02,0x0f,0xff,0x00,0x2c,0x7c,0x18,0x46,0xb2,0x58,0x0e,0xa8,0x00,0x7e,0xa0,0x80,0xcf,0xc1,0x83,0x7f,0x65,0x95,0x54,0x00,0x9f,0x58,0x0f,0xe3,0xaa,0xc6,0x10,0xa9,0x6a,0xc3,0xa7,0xa2,0xd5,0x4f,0x85,0x02,0x09,0x1f,0xf0,0x48,0x6b,0xe1,0xc3,0xa2,0xd5,0x62,0xb0,0xf1,0x48,0x82,0x87,0xaa,0x11,0x10,0xf2,0x00,0x08,0xca,0x5b,0xc0,0x28,0xfd,0x47,0x8a,0x26,0x1e,0xb2,0x94,0xae,0x00,0x81,0xdf,0x0e,0xd0,0xb8,0x5e,0xf3,0x49,0x78,0x01,0x02,0x1e,0x5a,0xa7,0xd6,0x01,0xdf,0x4c,0x98,0x24,0x4e,0xc7,0xaa,0xd6,0xea,0xaf,0x47,0x51,0x4d,0x19,0x2c,0x6a,0xb1,0xd0,0xa8,0xd7,0xea,0x15,0x59,0xe8,0xec,0x41,0xe7,0x56,0x0f,0x89,0x58,0xbe,0x01,0xf1,0x8d,0x1f,0x04,0x7e,0x50,0x0d,0x66,0xab,0xca,0x36,0x33,0xb8,0x89,0x46,0x00,0x18,0x28,0x05,0x62,0xab,0x1e,0x13,0x1f,0xc3,0x55,0x3a,0x02,0x0c,0x30,0x10,0x5b,0x8d,0x51,0xd4,0x80,0x05,0xff,0xfb,0x80,0xc6,0x30,0x07,0x2b,0x87,0x55,0xe6,0xdf,0x80,0xb8,0xc8,0x05,0x06,0xe1,0x20,0x02,0x46,0x17,0xa3,0x40,0x03,0x15,0x80,0x1c,0xc0,0xf1,0x9c,0x15,0x46,0x01,0x1f,0x07,0xd7,0x80,0x06,0x38,0x1b,0xf9,0xd0,0x41,0xf1,0x80,0x3f,0x0e,0x03,0xfe,0x02,0x14,0x21,0x80,0x0e,0x60,0x7e,0x3f,0xc4,0x04,0x1e,0xdf,0x8f,0xfd,0xc4,0xfc,0x7e,0x00,0x7b,0x86,0xc7,0xfc,0x21,0x20,0x78,0x9d,0x05,0x1c,0x9f,0x00,0xd1,0x96,0x8b,0x80,0x0d,0x10,0xc8,0x96,0x0a,0x1c,0xc2,0x28,0x18,0xa8,0x81,0xe5,0x3e,0x80,0x30,0x10,0x64,0x70,0x28,0x07,0xa0,0x1e,0x3c,0x6f,0xf9,0x85,0xa3,0x85,0x02,0xe8,0x02,0xc4,0x54,0x40,0x05,0x4f,0x89,0x40,0x75,0x03,0xa4,0x00,0x2d,0xc0,0x7a,0x34,0x0a,0x80,0x7c,0x5e,0x86,0x00,0x42,0xb1,0x4f,0xf5,0x04,0x21,0x1b,0x08,0x01,0x8b,0x65,0x00,0x0f,0x90,0x3e,0x30,0x0a,0xf2,0xd0,0x07,0xc6,0xf8,0x0f,0x78,0x04,0x3c,0x0a,0x9e,0x41,0x73,0xff,0xc0,0x02,0x21,0x28,0x06,0x10,0x1c,0xbf,0x89,0xf8,0x10,0xd1,0x45,0x04,0x06,0x9c,0x7f,0x80,0x2c,0x53,0xe1,0x7f,0x0d,0x68,0x1d,0x36,0xb9,0xc1,0xff,0x0d,0xf4,0x00,0x47,0xe0,0x84,0x20,}; -const uint8_t _A_Waves_128x51_1[] = {0x01,0x00,0xd1,0x01,0x00,0x17,0xe0,0x04,0x3f,0x0f,0xfc,0x04,0x1f,0x31,0x80,0x10,0xce,0x2f,0xe1,0xfa,0xfe,0x06,0xca,0x7c,0x0e,0x9f,0x07,0xfe,0x07,0x00,0xc0,0x7f,0xc7,0xd5,0x1f,0x83,0x84,0xc7,0xf2,0x3f,0x6f,0x00,0x08,0x63,0x93,0xf8,0x21,0x3c,0x73,0x00,0xf6,0x88,0x00,0x87,0x01,0x77,0x03,0x16,0x60,0x66,0x20,0x04,0x84,0x03,0xcb,0xc6,0x63,0x38,0x10,0x3e,0x38,0x1e,0x11,0x59,0x03,0xea,0xc1,0xc0,0x07,0x99,0x71,0x87,0xe5,0x20,0xe0,0x0e,0xca,0x38,0x7c,0x70,0x19,0x03,0xec,0x00,0x60,0xf7,0xff,0x21,0xc4,0x46,0xb8,0x3f,0xf8,0x01,0x67,0xe0,0xf6,0xbf,0xd5,0x40,0x07,0xf5,0x80,0xaa,0x44,0x18,0x21,0x32,0xdf,0x6a,0x80,0x08,0xd2,0x1e,0x07,0xaf,0xff,0x80,0xfa,0x89,0x84,0x3a,0x95,0x1a,0xac,0x3c,0x32,0x35,0xfa,0xaf,0xff,0xd5,0xff,0xd7,0x87,0x0f,0x45,0xaa,0xc5,0x13,0x4b,0x79,0xaa,0xf5,0x04,0x44,0x3c,0x9d,0x5f,0xff,0x54,0xca,0x57,0x00,0x40,0xfe,0x87,0x8a,0x26,0x1f,0x7a,0x94,0xbc,0x00,0x81,0x19,0x08,0xec,0xcb,0x83,0x00,0xef,0x9a,0x4b,0x00,0x08,0x10,0xea,0x4a,0xb5,0x57,0xa8,0x05,0xf0,0xf4,0x7a,0xbd,0x50,0xfc,0x7f,0xf5,0xfe,0xad,0x5a,0xab,0x3d,0x1d,0x88,0x3c,0xc1,0x03,0xaa,0x1b,0x0f,0xe2,0x55,0xa8,0xd5,0x46,0x8f,0x82,0x3f,0x28,0x06,0xb3,0x55,0x75,0x02,0x97,0x5c,0x2c,0x31,0xd0,0x28,0xaf,0x4e,0xb1,0x55,0x87,0x01,0x4b,0xf0,0x41,0x19,0xd0,0x14,0x61,0x80,0x92,0xdc,0x0b,0x88,0x00,0x44,0x11,0xff,0x81,0x06,0x30,0x08,0x2b,0x87,0x55,0xa2,0x9f,0x0b,0xff,0xe1,0x1a,0x32,0x00,0x41,0x6c,0x18,0x82,0x00,0x58,0xc2,0xf4,0x68,0x0e,0xa3,0x52,0x10,0x3d,0x67,0x08,0xc1,0x80,0x3b,0x86,0xc0,0x0e,0x60,0x78,0xf8,0x00,0x63,0x81,0xbf,0x9d,0x04,0x1f,0x18,0x02,0xc0,0xe0,0x0a,0x82,0x05,0x20,0x02,0xcc,0x0f,0xc7,0xf8,0x80,0x83,0xe1,0x5a,0x27,0xe2,0xf0,0x03,0xd8,0x50,0x31,0xf1,0xf0,0x88,0x44,0xba,0x65,0xf4,0x0e,0x0f,0x83,0x83,0x01,0x2d,0x17,0x00,0x1e,0xc7,0xb1,0x80,0x63,0xa0,0x62,0xa2,0x07,0x94,0x1a,0x00,0xc0,0x13,0x51,0x08,0x84,0x9c,0x30,0x28,0x07,0xa0,0x1e,0x44,0x31,0x27,0xa6,0x01,0x16,0x25,0x01,0xe8,0x02,0xc6,0x7c,0x07,0x10,0x02,0xa7,0xc4,0xa0,0x3a,0x80,0x30,0xbb,0x8c,0xe0,0xdc,0x0a,0x05,0x40,0x3e,0x2f,0x43,0x00,0x21,0x10,0xa7,0xfa,0x82,0x10,0xc7,0x01,0xee,0x5b,0x28,0x00,0x7c,0x81,0xf1,0x80,0x57,0x96,0x80,0x3e,0x37,0xc0,0x7b,0xa1,0x0c,0x00,0x5e,0x40,0x7c,0x47,0x80,0xa9,0x84,0x06,0xb7,0xe3,0xfe,0x00,0x10,0x39,0xc1,0x01,0xcb,0xff,0x1e,0x91,0x7c,0x45,0xec,0xd6,0x17,0xc0,0x98,0x90,0x0a,0x2a,0x62,0x00,0x17,0xf0,0x3a,0x60,0x02,0xff,0x40,0x2f,0xe4,0xe8,0x1b,0x28,0x08,0x40,}; -const uint8_t *_A_Waves_128x51[] = {_A_Waves_128x51_0,_A_Waves_128x51_1}; - -const uint8_t _I_ble_10px_0[] = {0x00,0x04,0x00,0x8C,0x00,0x15,0x01,0x56,0x02,0x8C,0x02,0x8C,0x02,0x56,0x02,0x15,0x01,0x8C,0x00,0x04,0x00,}; -const uint8_t *_I_ble_10px[] = {_I_ble_10px_0}; - -const uint8_t _I_ibutt_10px_0[] = {0x00,0x80,0x03,0x40,0x02,0x20,0x02,0x10,0x01,0x8E,0x00,0x41,0x00,0x2D,0x00,0x2D,0x00,0x21,0x00,0x1E,0x00,}; -const uint8_t *_I_ibutt_10px[] = {_I_ibutt_10px_0}; - -const uint8_t _I_125_10px_0[] = {0x00,0xE0,0x00,0x00,0x01,0x0E,0x02,0x31,0x02,0x45,0x02,0x91,0x00,0xAA,0x00,0x92,0x00,0x44,0x00,0x38,0x00,}; -const uint8_t *_I_125_10px[] = {_I_125_10px_0}; +const uint8_t _A_Waves_128x52_0[] = {0x01,0x00,0xba,0x01,0x00,0x78,0x03,0xc0,0x0f,0xe0,0xf3,0xc0,0xc0,0x83,0xf8,0x07,0xce,0x03,0xff,0x0f,0x0a,0x10,0x4c,0x80,0x0f,0xfe,0x8e,0x01,0x08,0x1f,0x57,0xc0,0x19,0x7c,0x20,0xe0,0xf9,0xff,0xc0,0x47,0xe5,0xff,0x1f,0xce,0x7c,0x36,0x51,0xcf,0xf8,0xc2,0x30,0x11,0x92,0x79,0x61,0x23,0xe3,0x08,0xe0,0x46,0x61,0x00,0x42,0x9e,0x8b,0xe2,0x81,0x18,0x42,0x1c,0xe0,0x08,0x62,0x34,0x07,0xa7,0xc2,0xe0,0x04,0x2c,0x81,0x60,0x80,0x04,0x0f,0x3b,0x87,0x00,0x32,0x60,0xf5,0x15,0x1d,0xe3,0x00,0x0f,0xe0,0x10,0x8f,0x0a,0x04,0x0f,0x6f,0xe4,0xfc,0x1e,0x57,0xa0,0x79,0xff,0xbf,0xe0,0x05,0xfc,0x83,0x07,0xaa,0x20,0x18,0x17,0xfe,0xaa,0x00,0x3f,0xac,0x1f,0xc0,0xae,0x2d,0x54,0xfc,0x0a,0x3a,0xa0,0x02,0x7e,0x81,0x83,0xbf,0x87,0xf8,0x2a,0xbf,0xfa,0xf8,0x70,0xea,0x95,0x5a,0x8a,0x6c,0xaf,0x9f,0x5a,0xff,0xa8,0x3a,0x78,0xad,0x54,0xa8,0x08,0x2f,0xf2,0xf8,0x01,0x44,0x74,0x80,0x02,0xfe,0xd5,0xd9,0xe5,0xc0,0xab,0xd5,0x47,0x6a,0x00,0x1f,0xf6,0xbc,0xf2,0x58,0x0d,0x78,0x7d,0x3a,0xb5,0x60,0x18,0xc1,0xef,0xcf,0xa3,0xaf,0x07,0xd2,0x55,0xa8,0x01,0x8c,0x0f,0xf0,0x0f,0x3d,0xe6,0xab,0xeb,0x7f,0x0f,0xa7,0x56,0x03,0xe0,0x5b,0x1d,0xe2,0xa3,0x1e,0xe0,0x6b,0xcb,0xa2,0x00,0x1f,0x50,0xec,0x41,0xe7,0xf0,0xff,0x09,0x47,0xe0,0x42,0x3e,0xe8,0x2c,0x45,0xe7,0xe0,0x02,0x19,0x50,0x40,0x03,0xc3,0x04,0x0c,0x10,0x14,0x4f,0xf3,0x80,0x7e,0x03,0xc3,0x75,0xe0,0x1f,0x46,0x30,0x0f,0x37,0xda,0x36,0x05,0x6e,0x20,0xd1,0xb0,0x02,0x48,0x88,0x80,0x03,0xb0,0x03,0x47,0x00,0x0f,0x31,0xf9,0x83,0xd0,0x32,0x77,0xc2,0xa2,0x83,0xd2,0x01,0x02,0x02,0x0f,0xf8,0x26,0x2b,0x42,0x00,0x27,0x80,0xbc,0x67,0xc2,0x83,0x03,0xd8,0xb0,0x30,0x80,0xa1,0x07,0x46,0x1c,0x0f,0x62,0x40,0xcc,0x00,0x84,0x0f,0x18,0x60,0x3d,0x87,0x03,0x40,0x07,0x92,0x10,0x41,0xe5,0xe0,0xbf,0x83,0xce,0x1c,0x60,0x30,0x7a,0x47,0x30,0x11,0xf0,0x79,0x47,0x09,0x46,0xa4,0x34,0x11,0x31,0x4b,0x01,0x3b,0x80,0x14,0x08,0x1e,0x77,0x00,0xe1,0x7f,0x20,0x77,0x80,0x30,0x94,0x08,0x9e,0x33,0x82,0x6a,0xff,0x20,0xe8,0x01,0x6d,0x8e,0x02,0x14,0x0f,0x76,0xca,0x40,0xe8,0x31,0x51,0x21,0xa0,0x1c,0x48,0x21,0xf2,0x1e,0x98,0x01,0x49,0x63,0x00,0xa0,0x07,0xc4,0x1f,0x27,0x01,0x1f,0x9f,0xc0,0x1f,0x1f,0xf0,0x00,0xa1,0xcb,0x20,0xdf,0x7f,0xf8,0x10,0xcd,0xe3,0x10,0x06,0xa5,0xf2,0x01,0x3f,0x03,0xa1,0xb4,0x41,0xeb,0x80,0x0e,0x99,0xd0,0xe3,0xe3,0xf9,0x1b,0x2c,0x7c,}; +const uint8_t _A_Waves_128x52_1[] = {0x01,0x00,0xbf,0x01,0x00,0x78,0x03,0xc0,0x0f,0xe0,0xf3,0xc0,0xc0,0x83,0xf8,0x07,0xce,0x03,0xff,0x0f,0x0a,0x10,0x4c,0x80,0x0f,0xfe,0x8e,0x01,0x08,0x1f,0x57,0xc0,0x19,0x7c,0x20,0xe0,0xf9,0xff,0xc0,0x47,0xe5,0xff,0x1f,0xce,0x7c,0x36,0x51,0xcf,0xf8,0xc2,0x30,0x11,0x92,0x79,0x61,0x23,0xe3,0x08,0xe0,0x46,0x61,0x00,0x42,0x9e,0x8b,0xe2,0x81,0x18,0x42,0x1c,0xe0,0x08,0x62,0x34,0x07,0xa7,0xc2,0xe0,0x04,0x2c,0x81,0x60,0x80,0x04,0x0f,0x3b,0x87,0x00,0x32,0x60,0xf5,0x15,0x1d,0xe3,0x00,0x0f,0xbf,0xf4,0x7e,0xf0,0x06,0x11,0xe1,0x40,0x81,0xeb,0xc0,0xff,0xff,0xc1,0xe5,0x7a,0x07,0x9f,0xf8,0x14,0x20,0x02,0x81,0xfc,0x3f,0x60,0xc1,0xea,0x88,0x06,0x05,0xff,0xaa,0x80,0x0e,0xfa,0xe3,0x20,0x78,0xea,0xa7,0xfe,0x0f,0xfe,0xa8,0x00,0x91,0xe0,0x60,0xef,0xa1,0xfe,0x0a,0xaf,0xfe,0xbe,0x1c,0x3a,0xa5,0x56,0xa2,0xaf,0x2b,0xc7,0xd6,0xbf,0xea,0x0e,0x9e,0x2b,0x55,0x2a,0xff,0x6a,0xcb,0x25,0xe0,0xd5,0xea,0x87,0x48,0x00,0x2f,0xff,0x5d,0xb4,0x5c,0x0a,0xbd,0x54,0x76,0xa0,0x01,0x81,0xef,0xd0,0xc7,0xaf,0x0f,0xa7,0x56,0xac,0x02,0x18,0x0f,0xf0,0x1e,0x75,0xe0,0xfa,0x4a,0xb5,0x1a,0xaf,0x53,0x2c,0x52,0x87,0xbc,0x0f,0x9f,0xd7,0xff,0x7f,0xaa,0xdd,0x47,0x62,0x0f,0x3b,0xc5,0x44,0x3c,0x50,0xe0,0x58,0xeb,0xed,0x48,0xc1,0x17,0x9f,0xc0,0x3e,0x34,0x5e,0xa9,0x60,0x8f,0x02,0x0d,0x16,0x31,0xd8,0x07,0xe4,0xc1,0x21,0x00,0xfb,0xcf,0xa3,0x0c,0x03,0x97,0x80,0x7e,0x49,0x72,0x10,0x10,0x34,0x66,0x01,0x73,0x43,0x8f,0xfd,0xfc,0x93,0x00,0x68,0xd0,0x01,0xe7,0xab,0x7d,0xa0,0x3c,0x8b,0xc7,0x3e,0x2a,0x0d,0x54,0x1e,0xf0,0x01,0x31,0x3b,0x85,0xe2,0x60,0x04,0xb8,0x17,0x8c,0x74,0x46,0xb2,0x00,0x27,0x82,0x01,0x04,0x3e,0x90,0x34,0x5c,0x84,0x00,0x4e,0x04,0x06,0x30,0x04,0x20,0x78,0xc1,0x81,0xed,0x80,0x81,0xc8,0x01,0xe4,0x1d,0x10,0x7b,0xff,0x20,0xe6,0x02,0xc0,0x03,0xc7,0xfc,0x1e,0x76,0x20,0x8b,0x04,0x1e,0x50,0xc2,0x82,0xde,0x20,0x11,0xc2,0x81,0x03,0xce,0xf8,0x6b,0x32,0xb1,0x4e,0x20,0x05,0x01,0x12,0x88,0x58,0x70,0x17,0xf8,0x03,0x01,0x02,0x83,0x60,0x58,0x8c,0x14,0x4c,0x49,0x26,0x40,0x0e,0x03,0x03,0xa0,0x85,0x09,0x09,0x01,0x10,0x0b,0xf0,0x7c,0x86,0xc2,0x80,0x74,0xc9,0x07,0xc8,0x1f,0x10,0x03,0x80,0x8f,0xcf,0xf0,0x0f,0x89,0xe0,0x15,0x39,0x00,0xf8,0xfe,0x7f,0xff,0xe6,0xa1,0x80,0x42,0x07,0xcf,0xff,0x4c,0x16,0x02,0x3e,0x0f,0x6f,0x84,0x07,0xf8,0x74,0x60,0xfb,0x7f,0x96,0xcb,0x00,0xbf,0xe2,0x07,0xf0,0x36,0x5b,0xf8,}; +const uint8_t *_A_Waves_128x52[] = {_A_Waves_128x52_0,_A_Waves_128x52_1}; const uint8_t _I_sub1_10px_0[] = {0x01,0x00,0x12,0x00,0x81,0x40,0x69,0x30,0x2c,0x2c,0x0b,0x6a,0x01,0x28,0x0c,0x0a,0x65,0x01,0x98,0x40,0x00,0x26,}; const uint8_t *_I_sub1_10px[] = {_I_sub1_10px_0}; -const uint8_t _I_dir_10px_0[] = {0x01,0x00,0x11,0x00,0x00,0x0c,0xfe,0x01,0x41,0x80,0x7f,0xe0,0x70,0x18,0x10,0x05,0x7f,0xd0,0x10,0x88,0x80,}; -const uint8_t *_I_dir_10px[] = {_I_dir_10px_0}; - const uint8_t _I_ir_10px_0[] = {0x00,0xFC,0x00,0x02,0x01,0x79,0x02,0x84,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x58,0x00,0x78,0x00,0xFF,0x03,}; const uint8_t *_I_ir_10px[] = {_I_ir_10px_0}; -const uint8_t _I_Nfc_10px_0[] = {0x00,0x80,0x00,0x00,0x01,0x22,0x02,0x43,0x02,0x45,0x02,0x49,0x02,0x31,0x02,0x22,0x02,0x00,0x01,0x80,0x00,}; -const uint8_t *_I_Nfc_10px[] = {_I_Nfc_10px_0}; - const uint8_t _I_unknown_10px_0[] = {0x01,0x00,0x12,0x00,0xbc,0x40,0x39,0x90,0x0c,0x24,0x03,0x81,0x00,0xb0,0x40,0x26,0x00,0x12,0x00,0x08,0x14,0xc0,}; const uint8_t *_I_unknown_10px[] = {_I_unknown_10px_0}; +const uint8_t _I_ibutt_10px_0[] = {0x00,0x80,0x03,0x40,0x02,0x20,0x02,0x10,0x01,0x8E,0x00,0x41,0x00,0x2D,0x00,0x2D,0x00,0x21,0x00,0x1E,0x00,}; +const uint8_t *_I_ibutt_10px[] = {_I_ibutt_10px_0}; + +const uint8_t _I_Nfc_10px_0[] = {0x00,0x80,0x00,0x00,0x01,0x22,0x02,0x43,0x02,0x45,0x02,0x49,0x02,0x31,0x02,0x22,0x02,0x00,0x01,0x80,0x00,}; +const uint8_t *_I_Nfc_10px[] = {_I_Nfc_10px_0}; + +const uint8_t _I_ble_10px_0[] = {0x00,0x04,0x00,0x8C,0x00,0x15,0x01,0x56,0x02,0x8C,0x02,0x8C,0x02,0x56,0x02,0x15,0x01,0x8C,0x00,0x04,0x00,}; +const uint8_t *_I_ble_10px[] = {_I_ble_10px_0}; + +const uint8_t _I_125_10px_0[] = {0x00,0xE0,0x00,0x00,0x01,0x0E,0x02,0x31,0x02,0x45,0x02,0x91,0x00,0xAA,0x00,0x92,0x00,0x44,0x00,0x38,0x00,}; +const uint8_t *_I_125_10px[] = {_I_125_10px_0}; + +const uint8_t _I_dir_10px_0[] = {0x01,0x00,0x11,0x00,0x00,0x0c,0xfe,0x01,0x41,0x80,0x7f,0xe0,0x70,0x18,0x10,0x05,0x7f,0xd0,0x10,0x88,0x80,}; +const uint8_t *_I_dir_10px[] = {_I_dir_10px_0}; + const uint8_t _I_BLE_Pairing_128x64_0[] = {0x01,0x00,0xb7,0x01,0x00,0x6c,0x38,0x1f,0xd0,0x10,0x76,0xe0,0x03,0xdd,0x40,0x07,0xf4,0x82,0x01,0x08,0x07,0xf4,0xc0,0x1f,0x91,0x08,0x07,0x00,0x1f,0xc0,0x0d,0x1e,0xe8,0x3f,0xc0,0x03,0x58,0x80,0xcf,0x11,0xd9,0xaf,0x85,0x77,0x01,0xf7,0x60,0xf8,0x45,0xff,0x05,0xed,0x9e,0x7c,0x09,0xdb,0xe0,0x2f,0x78,0x03,0x3c,0x8e,0xee,0x8a,0x43,0x81,0xfb,0x0c,0x66,0xe8,0xfc,0x59,0xba,0x6f,0x28,0x1b,0xfb,0xa3,0x80,0xfc,0xa0,0x1f,0xc6,0x86,0xbf,0xc3,0x78,0xce,0x04,0x19,0x26,0x77,0xfa,0x43,0xbe,0x12,0xa0,0x7e,0xf8,0x2a,0xa2,0x02,0xff,0x89,0x27,0x01,0xbf,0x99,0x38,0x8a,0xfc,0x0f,0x8e,0x07,0xfe,0x0e,0x94,0x2c,0x07,0xfc,0x7f,0x1f,0xf5,0x00,0xc3,0x00,0xe4,0x31,0x13,0xd1,0x00,0x0a,0xb8,0x19,0x25,0x91,0xc0,0x81,0xe2,0xb9,0x4d,0x5d,0x78,0x64,0x2e,0x84,0x80,0x61,0x07,0x02,0x3e,0x2a,0xa4,0xa2,0x00,0xf2,0x40,0x20,0xe3,0x21,0xa0,0x62,0x9f,0x60,0x05,0x02,0x3e,0x36,0x41,0x66,0x23,0x20,0x51,0xfc,0x40,0x68,0x0f,0x15,0x90,0x60,0x20,0x1b,0x09,0x89,0x70,0x46,0x42,0x07,0x14,0x99,0x41,0xe8,0x1f,0x18,0x0c,0x07,0xc1,0x19,0xff,0xc3,0xce,0x6b,0x54,0x8f,0xe0,0x3f,0x90,0x78,0x17,0x02,0x1a,0x70,0x39,0x01,0xa0,0xb1,0x53,0xb5,0x88,0xc7,0xe0,0x98,0x08,0x3a,0xd5,0xe8,0x97,0xd0,0x78,0xcf,0xe1,0x07,0xf1,0x0d,0x08,0x00,0x74,0x10,0x80,0x18,0xe8,0x97,0xc3,0xf2,0xff,0xc4,0x03,0xe3,0x04,0x8c,0x19,0xcc,0x00,0x35,0x0c,0x3c,0x03,0xf9,0x3f,0xb0,0x8f,0xc6,0x31,0x0e,0x0f,0x90,0x90,0xb5,0x45,0xc1,0xf8,0x4f,0xf0,0xde,0x18,0xcc,0x82,0x08,0x1f,0x22,0x20,0xd0,0x3a,0xab,0xd1,0xe0,0x5f,0xa1,0x1b,0x19,0x8d,0x02,0x04,0x9a,0x1d,0x04,0x28,0x26,0x36,0xa8,0x05,0xf0,0xe0,0x3f,0x04,0xf8,0xd0,0x30,0x55,0xfa,0xad,0x54,0x3e,0x35,0x09,0xab,0xac,0xbf,0x2b,0xf2,0x0a,0x0e,0xfb,0x55,0xaa,0x0f,0x94,0x68,0x04,0x30,0x6f,0xd3,0x7c,0xb0,0x15,0x0f,0xfd,0x7f,0xeb,0x05,0x4f,0x0b,0x60,0xa3,0x1f,0x28,0x0b,0xfc,0xbc,0x30,0x1f,0xf7,0xfe,0x54,0x2c,0x18,0x30,0x3c,0x6f,0x00,0xf2,0x1c,0x8c,0xf8,0x10,0x3c,0x00,0xf8,0xd5,0x5c,0x05,0xb8,0xb0,0xaa,0xdb,0x01,0x2b,0x31,0x0a,0xdc,0xa7,0x00,0xe6,0x00,0x0c,0x56,0x00,0x7e,0x10,0x00,0xcc,0x01,0xf0,0x1f,0x1b,0x40,0x2e,0x00,0x07,0x16,0x10,0x90,0x02,0xe5,0x90,0x06,0x29,0x00,0x2a,0xa9,0x00,0x2f,0x10,0x02,0xa5,0x10,0x02,0xf1,0x00,0x2a,0xa0,0x0d,0xc0,0x00,0xec,0x01,0xfd,0x60,0x17,0x6a,0xc0,0x60,0x40,0xfd,0xc0,0x30,0x04,0x01,0xb0,0xb0,0x7f,0x45,0x80,}; const uint8_t *_I_BLE_Pairing_128x64[] = {_I_BLE_Pairing_128x64_0}; -const uint8_t _I_EviSmile2_18x21_0[] = {0x01,0x00,0x37,0x00,0x00,0x14,0x3b,0x81,0x01,0x83,0xe0,0x20,0x7c,0xfe,0x7c,0x0f,0xff,0xff,0x01,0x1f,0xfb,0xff,0x01,0x01,0x2f,0x9f,0x3f,0x03,0xe3,0xe3,0xe0,0x78,0x7c,0x3c,0x0f,0x1f,0xc7,0x0d,0x37,0x3b,0x99,0x01,0xcf,0x79,0x20,0x33,0xcf,0x84,0x03,0xf1,0x7f,0x80,0x7c,0x27,0xf0,0x0e,0x04,0x3e,0x00,}; -const uint8_t *_I_EviSmile2_18x21[] = {_I_EviSmile2_18x21_0}; - -const uint8_t _I_EviSmile1_18x21_0[] = {0x01,0x00,0x39,0x00,0x86,0x70,0x20,0x10,0x6c,0x04,0x06,0x0f,0x80,0x81,0xf3,0xf9,0xf0,0x3f,0xff,0xfc,0x04,0x7f,0xef,0xfc,0x04,0x04,0xbf,0x7d,0xfc,0x0f,0xcf,0x9f,0x81,0xf1,0xf1,0xf0,0x3c,0x3e,0x1e,0x07,0x8f,0xe3,0x86,0x9b,0xbd,0xef,0x80,0xef,0x3e,0x90,0x0b,0xc5,0xe2,0x01,0xf0,0x9f,0xc0,0x38,0x10,0xf8,0x00,}; -const uint8_t *_I_EviSmile1_18x21[] = {_I_EviSmile1_18x21_0}; - -const uint8_t _I_UsbTree_48x22_0[] = {0x01,0x00,0x3c,0x00,0x00,0x14,0x3c,0x08,0x78,0x08,0xf8,0x10,0xff,0xe0,0x59,0xb0,0x04,0x52,0xc0,0x1d,0x48,0xc0,0x9d,0x00,0xa7,0x02,0x80,0x41,0x80,0xa5,0x0e,0x02,0xa4,0xfb,0xfe,0x00,0xa1,0x49,0x04,0x48,0x0a,0x81,0xd1,0xc0,0x40,0x45,0x26,0x05,0x30,0x01,0x41,0xbe,0x10,0x30,0x2c,0x7e,0x3f,0xe0,0x59,0x80,0x04,0x50,0x0a,0x60,}; -const uint8_t *_I_UsbTree_48x22[] = {_I_UsbTree_48x22_0}; - const uint8_t _I_EviWaiting1_18x21_0[] = {0x01,0x00,0x34,0x00,0x86,0x70,0x20,0x10,0x6c,0x04,0x06,0x0f,0x80,0x81,0xf3,0xf9,0xf0,0x3f,0xff,0xfc,0x04,0x7f,0xef,0xfc,0x04,0x04,0xa0,0xb2,0xdb,0xeb,0xe0,0x7b,0xfd,0xfc,0x0f,0x3f,0x9f,0x81,0xf1,0xf8,0xe1,0xa9,0xfe,0x7f,0xe0,0x1f,0x8b,0xfc,0x03,0xe1,0x3f,0x80,0x70,0x21,0xf0,0x00,}; const uint8_t *_I_EviWaiting1_18x21[] = {_I_EviWaiting1_18x21_0}; -const uint8_t _I_EviWaiting2_18x21_0[] = {0x01,0x00,0x31,0x00,0x86,0x70,0x20,0x10,0x6c,0x04,0x06,0x0f,0x80,0x81,0xf3,0xf9,0xf0,0x3f,0xff,0xfc,0x04,0x7f,0xef,0xfc,0x04,0x04,0xa0,0xb2,0xeb,0xed,0xe0,0x7f,0x7f,0xb8,0x08,0xf1,0xf8,0xf0,0xd4,0xff,0x3f,0xf0,0x0f,0xc5,0xfe,0x01,0xf0,0x9f,0xc0,0x38,0x10,0xf8,0x00,}; -const uint8_t *_I_EviWaiting2_18x21[] = {_I_EviWaiting2_18x21_0}; - -const uint8_t _I_Percent_10x14_0[] = {0x00,0x0C,0x03,0x1E,0x03,0x33,0x03,0xB3,0x03,0xDE,0x01,0xEC,0x00,0x70,0x00,0x38,0x00,0xDC,0x00,0xEE,0x01,0x37,0x03,0x33,0x03,0xE3,0x01,0xC3,0x00,}; -const uint8_t *_I_Percent_10x14[] = {_I_Percent_10x14_0}; - -const uint8_t _I_Smile_18x18_0[] = {0x01,0x00,0x2d,0x00,0xe0,0x43,0xe0,0x1f,0x09,0xfc,0x03,0xf1,0x7f,0x80,0x7f,0x3f,0xf0,0x0f,0xf7,0xfe,0x02,0x02,0x2f,0xff,0xfe,0x07,0xcf,0xe7,0xc0,0xf0,0xf8,0x70,0x11,0x82,0x08,0x1c,0x41,0x42,0xdf,0x7d,0xe0,0x37,0xcf,0xc0,0x98,0xc5,0x84,0x32,0x20,}; -const uint8_t *_I_Smile_18x18[] = {_I_Smile_18x18_0}; +const uint8_t _I_EviSmile2_18x21_0[] = {0x01,0x00,0x37,0x00,0x00,0x14,0x3b,0x81,0x01,0x83,0xe0,0x20,0x7c,0xfe,0x7c,0x0f,0xff,0xff,0x01,0x1f,0xfb,0xff,0x01,0x01,0x2f,0x9f,0x3f,0x03,0xe3,0xe3,0xe0,0x78,0x7c,0x3c,0x0f,0x1f,0xc7,0x0d,0x37,0x3b,0x99,0x01,0xcf,0x79,0x20,0x33,0xcf,0x84,0x03,0xf1,0x7f,0x80,0x7c,0x27,0xf0,0x0e,0x04,0x3e,0x00,}; +const uint8_t *_I_EviSmile2_18x21[] = {_I_EviSmile2_18x21_0}; const uint8_t _I_Error_18x18_0[] = {0x01,0x00,0x2c,0x00,0xe0,0x43,0xe0,0x1f,0x09,0xfc,0x03,0xf1,0x7f,0x80,0x7f,0x3f,0xf0,0x0e,0x77,0x3e,0x03,0x8e,0xe3,0xc0,0x63,0xfe,0x38,0x1c,0xff,0xe1,0x03,0xbf,0xfe,0x00,0x46,0x08,0x20,0x71,0x05,0x08,0x34,0x42,0x02,0x13,0x10,0xb0,0x86,0x44,}; const uint8_t *_I_Error_18x18[] = {_I_Error_18x18_0}; +const uint8_t _I_Percent_10x14_0[] = {0x00,0x0C,0x03,0x1E,0x03,0x33,0x03,0xB3,0x03,0xDE,0x01,0xEC,0x00,0x70,0x00,0x38,0x00,0xDC,0x00,0xEE,0x01,0x37,0x03,0x33,0x03,0xE3,0x01,0xC3,0x00,}; +const uint8_t *_I_Percent_10x14[] = {_I_Percent_10x14_0}; + +const uint8_t _I_EviSmile1_18x21_0[] = {0x01,0x00,0x39,0x00,0x86,0x70,0x20,0x10,0x6c,0x04,0x06,0x0f,0x80,0x81,0xf3,0xf9,0xf0,0x3f,0xff,0xfc,0x04,0x7f,0xef,0xfc,0x04,0x04,0xbf,0x7d,0xfc,0x0f,0xcf,0x9f,0x81,0xf1,0xf1,0xf0,0x3c,0x3e,0x1e,0x07,0x8f,0xe3,0x86,0x9b,0xbd,0xef,0x80,0xef,0x3e,0x90,0x0b,0xc5,0xe2,0x01,0xf0,0x9f,0xc0,0x38,0x10,0xf8,0x00,}; +const uint8_t *_I_EviSmile1_18x21[] = {_I_EviSmile1_18x21_0}; + +const uint8_t _I_EviWaiting2_18x21_0[] = {0x01,0x00,0x31,0x00,0x86,0x70,0x20,0x10,0x6c,0x04,0x06,0x0f,0x80,0x81,0xf3,0xf9,0xf0,0x3f,0xff,0xfc,0x04,0x7f,0xef,0xfc,0x04,0x04,0xa0,0xb2,0xeb,0xed,0xe0,0x7f,0x7f,0xb8,0x08,0xf1,0xf8,0xf0,0xd4,0xff,0x3f,0xf0,0x0f,0xc5,0xfe,0x01,0xf0,0x9f,0xc0,0x38,0x10,0xf8,0x00,}; +const uint8_t *_I_EviWaiting2_18x21[] = {_I_EviWaiting2_18x21_0}; + +const uint8_t _I_UsbTree_48x22_0[] = {0x01,0x00,0x3c,0x00,0x00,0x14,0x3c,0x08,0x78,0x08,0xf8,0x10,0xff,0xe0,0x59,0xb0,0x04,0x52,0xc0,0x1d,0x48,0xc0,0x9d,0x00,0xa7,0x02,0x80,0x41,0x80,0xa5,0x0e,0x02,0xa4,0xfb,0xfe,0x00,0xa1,0x49,0x04,0x48,0x0a,0x81,0xd1,0xc0,0x40,0x45,0x26,0x05,0x30,0x01,0x41,0xbe,0x10,0x30,0x2c,0x7e,0x3f,0xe0,0x59,0x80,0x04,0x50,0x0a,0x60,}; +const uint8_t *_I_UsbTree_48x22[] = {_I_UsbTree_48x22_0}; + +const uint8_t _I_Smile_18x18_0[] = {0x01,0x00,0x2d,0x00,0xe0,0x43,0xe0,0x1f,0x09,0xfc,0x03,0xf1,0x7f,0x80,0x7f,0x3f,0xf0,0x0f,0xf7,0xfe,0x02,0x02,0x2f,0xff,0xfe,0x07,0xcf,0xe7,0xc0,0xf0,0xf8,0x70,0x11,0x82,0x08,0x1c,0x41,0x42,0xdf,0x7d,0xe0,0x37,0xcf,0xc0,0x98,0xc5,0x84,0x32,0x20,}; +const uint8_t *_I_Smile_18x18[] = {_I_Smile_18x18_0}; + const uint8_t _I_Clock_18x18_0[] = {0x01,0x00,0x31,0x00,0xe0,0x43,0xe0,0x1f,0x09,0xfc,0x03,0xf1,0x7f,0x80,0x47,0x3c,0x10,0x0d,0xf7,0xde,0x02,0x02,0x2d,0xff,0xde,0x07,0x7f,0xfd,0xc0,0xff,0xff,0xc0,0x11,0xdf,0xff,0x30,0x3d,0xff,0xca,0x07,0x3e,0xfa,0x85,0xc7,0xe5,0x01,0x10,0x10,0x98,0x85,0x84,0x32,0x20,}; const uint8_t *_I_Clock_18x18[] = {_I_Clock_18x18_0}; -const uint8_t _I_ButtonRightSmall_3x5_0[] = {0x00,0x01,0x03,0x07,0x03,0x01,}; -const uint8_t *_I_ButtonRightSmall_3x5[] = {_I_ButtonRightSmall_3x5_0}; - -const uint8_t _I_ButtonLeftSmall_3x5_0[] = {0x00,0x04,0x06,0x07,0x06,0x04,}; -const uint8_t *_I_ButtonLeftSmall_3x5[] = {_I_ButtonLeftSmall_3x5_0}; - -const uint8_t _I_ButtonCenter_7x7_0[] = {0x00,0x1C,0x22,0x5D,0x5D,0x5D,0x22,0x1C,}; -const uint8_t *_I_ButtonCenter_7x7[] = {_I_ButtonCenter_7x7_0}; - const uint8_t _I_ButtonDown_7x4_0[] = {0x00,0x7F,0x3E,0x1C,0x08,}; const uint8_t *_I_ButtonDown_7x4[] = {_I_ButtonDown_7x4_0}; -const uint8_t _I_ButtonRight_4x7_0[] = {0x00,0x01,0x03,0x07,0x0F,0x07,0x03,0x01,}; -const uint8_t *_I_ButtonRight_4x7[] = {_I_ButtonRight_4x7_0}; - -const uint8_t _I_DFU_128x50_0[] = {0x01,0x00,0x2e,0x02,0x00,0x57,0xfe,0x0e,0x0e,0xcf,0x84,0x02,0x70,0x0f,0xc8,0x74,0x03,0x80,0x0e,0xbc,0x7c,0x04,0x06,0x30,0x30,0x74,0xe0,0x2f,0xe0,0x42,0x82,0x03,0xe7,0x81,0xff,0x02,0x14,0x20,0x1f,0x3e,0x00,0x79,0xc4,0x01,0xfd,0x20,0x07,0xd5,0xd4,0xe2,0x53,0xf2,0x74,0xff,0xe1,0x40,0x41,0x87,0xd8,0x01,0xf1,0x60,0xf0,0x43,0xca,0x43,0xe0,0xa7,0x83,0xe2,0x30,0x01,0x29,0x84,0x7b,0x20,0x0f,0x88,0x30,0x3c,0xb1,0x90,0x1d,0x00,0xfa,0x30,0x3f,0xf8,0xcc,0x02,0xc6,0x31,0x1f,0x83,0x49,0xa8,0x16,0x0a,0xf4,0x7f,0x00,0x21,0x1f,0x04,0x38,0x06,0x20,0x04,0x90,0x46,0x35,0xf0,0xfa,0x00,0xcc,0x7f,0x10,0x14,0x0b,0x46,0x20,0xd5,0x70,0x50,0xb4,0x06,0xf1,0x00,0x9f,0x03,0xd7,0x09,0x81,0xd7,0xc0,0x8b,0x85,0x38,0xc0,0x50,0x41,0xeb,0x63,0xc0,0x07,0xc6,0x90,0xbf,0x2b,0x05,0x01,0xb8,0xb1,0x0c,0x06,0xae,0x01,0x24,0x6f,0x94,0x42,0x80,0xb2,0x49,0xc4,0x33,0x80,0x1f,0x18,0x93,0xfc,0xa1,0x14,0x0e,0x02,0x9c,0x43,0xc3,0x07,0x81,0xfc,0x03,0xe2,0xc0,0x28,0x14,0x10,0x5e,0x3f,0x03,0xc0,0xcf,0xf8,0x10,0x0f,0xe5,0x56,0x03,0x05,0xf0,0x40,0x20,0x20,0xf2,0x42,0x0d,0xfd,0x72,0x30,0x0f,0xf8,0x7c,0x41,0xe3,0x80,0x10,0x0d,0x00,0x5c,0x4a,0xd1,0x87,0xf8,0x39,0xf5,0x5c,0x0c,0x0b,0xe0,0x1c,0x10,0x78,0xfc,0x02,0x04,0x20,0x1f,0xf7,0x0f,0x57,0x80,0x81,0x5e,0x13,0x83,0x01,0x1f,0x97,0xff,0xfe,0x03,0x2e,0x07,0x57,0x03,0x01,0xbf,0x1d,0x45,0x70,0x27,0xe4,0xff,0x8c,0x07,0xf5,0x83,0xe0,0xcf,0xe1,0x00,0xf6,0x10,0x8c,0x07,0xb1,0x07,0xc1,0xfc,0x63,0xe5,0xd2,0x07,0x8f,0x80,0x1a,0x21,0xe1,0xc0,0x71,0xe0,0x20,0xf1,0x24,0x88,0x34,0x62,0x00,0xe3,0x3f,0x8d,0xfe,0x81,0x80,0xc1,0xf8,0x5b,0xe2,0x0f,0x18,0xc7,0xf0,0x1e,0x50,0x35,0xa0,0xc8,0x3f,0x98,0x30,0x70,0x87,0x44,0x1e,0x21,0xe3,0xf8,0x02,0x4b,0xaf,0x01,0x81,0xb3,0xca,0x01,0x1c,0x25,0x94,0x01,0x04,0x58,0x8d,0x5c,0x0b,0xc6,0x08,0x10,0x78,0xc3,0x3f,0xf0,0x72,0x88,0x98,0x8b,0x89,0x55,0x82,0xc7,0x9b,0xe5,0x00,0x87,0x26,0xc4,0x46,0x20,0xf2,0xd1,0x87,0xc6,0x0c,0xdf,0x21,0x50,0x8a,0xc7,0x00,0x38,0x2e,0x04,0x42,0xaf,0x05,0x06,0x0a,0xb8,0x70,0x0f,0x91,0x80,0x5c,0x03,0xc5,0x30,0x84,0x6a,0xe1,0x40,0xf1,0x7b,0x0f,0x00,0x7a,0x24,0x21,0x07,0x94,0x33,0x09,0x57,0x8a,0x93,0x85,0xec,0x3e,0x00,0x79,0x0b,0x88,0x06,0x3c,0x3f,0xfc,0xa8,0x1e,0x21,0x91,0x76,0x90,0x90,0x40,0x03,0xe0,0xe0,0x78,0x3f,0xd5,0x58,0x0e,0x08,0x32,0x3f,0x88,0xa8,0x90,0x8c,0x25,0x30,0xbc,0x7f,0xb5,0x50,0x1b,0xe0,0x20,0x7f,0x92,0x33,0x88,0x97,0x4a,0x07,0x0c,0x9e,0x5f,0xeb,0xaa,0xf2,0x74,0x8d,0x17,0x80,0x06,0x29,0xf1,0xe0,0x71,0xfb,0xfd,0x71,0xd8,0xff,0xf8,0x21,0x71,0x04,0x87,0x01,0xc1,0xa1,0xff,0x83,0xe7,0xf0,0xff,0xc1,0x51,0xe4,0xdd,0x1b,0x07,0xc2,0x63,0xf6,0x0f,0x9f,0xeb,0x5f,0x02,0x77,0x8a,0xc4,0xa3,0x17,0xc8,0x44,0x8c,0x34,0x20,0x71,0xfe,0x99,0x04,0x88,0x40,0x01,0xc3,0x47,0xf0,0x93,0x0f,0xf4,0x28,0x0e,0x3a,0xad,0x50,0x39,0x30,0x1f,0x18,0x3d,0x0e,0x31,0xff,0x3d,0x0c,0x02,0xa8,0x03,0x20,0x01,0x7e,0x3f,0xf8,0x09,0x06,0x33,0xfe,0x1b,0x50,}; -const uint8_t *_I_DFU_128x50[] = {_I_DFU_128x50_0}; - -const uint8_t _I_ButtonUp_7x4_0[] = {0x00,0x08,0x1C,0x3E,0x7F,}; -const uint8_t *_I_ButtonUp_7x4[] = {_I_ButtonUp_7x4_0}; - -const uint8_t _I_Warning_30x23_0[] = {0x01,0x00,0x47,0x00,0x80,0x70,0x00,0x65,0xe0,0x80,0x80,0xc7,0xe1,0x03,0x01,0xaf,0xe2,0x0e,0x03,0x19,0xe4,0x3c,0x06,0xb3,0xe8,0xf8,0x0c,0x67,0xf3,0xf0,0x1a,0x60,0x27,0xf7,0xf1,0x50,0xcf,0xff,0xe0,0x34,0xf0,0x00,0xc6,0x03,0xf0,0x01,0x8c,0x0c,0x06,0x7f,0x80,0x18,0xc1,0xff,0x9f,0xff,0xfc,0x3c,0x06,0x7f,0xe0,0x58,0xc7,0xff,0xe0,0x31,0x00,0x88,0x00,0x67,0xff,0xe0,0x18,0xc7,0xc0,}; -const uint8_t *_I_Warning_30x23[] = {_I_Warning_30x23_0}; +const uint8_t _I_ButtonCenter_7x7_0[] = {0x00,0x1C,0x22,0x5D,0x5D,0x5D,0x22,0x1C,}; +const uint8_t *_I_ButtonCenter_7x7[] = {_I_ButtonCenter_7x7_0}; const uint8_t _I_ButtonLeft_4x7_0[] = {0x00,0x08,0x0C,0x0E,0x0F,0x0E,0x0C,0x08,}; const uint8_t *_I_ButtonLeft_4x7[] = {_I_ButtonLeft_4x7_0}; -const uint8_t _I_DolphinFirstStart7_61x51_0[] = {0x01,0x00,0x13,0x01,0x00,0x17,0x03,0xff,0x01,0x03,0xa4,0xe2,0x01,0x0e,0x03,0xa4,0x1a,0x01,0x30,0x03,0x1e,0x00,0x2a,0x3c,0x00,0x39,0xd0,0x00,0x65,0x03,0x01,0x94,0x80,0x06,0x50,0x40,0x19,0x44,0x00,0x65,0x08,0x01,0xb0,0x2c,0xe2,0x81,0xb6,0x86,0x0a,0xd8,0x7c,0x20,0x75,0x85,0x10,0xcc,0x06,0x50,0x50,0x3b,0x10,0xce,0x00,0x69,0x20,0x79,0x7c,0x20,0x20,0x71,0xc0,0x07,0xca,0xf1,0x02,0x81,0x01,0xc6,0x3a,0x07,0x1f,0xe4,0x10,0x0e,0x53,0xe0,0x38,0xe7,0xa0,0xa0,0x72,0xbb,0x81,0xca,0x12,0x68,0x1c,0x05,0x5c,0x0e,0x3f,0xe8,0xc8,0x1c,0xab,0xe0,0x72,0x94,0x81,0xda,0xb2,0x07,0x5f,0xe0,0x3d,0xbf,0x95,0x44,0x20,0x81,0xce,0xf1,0x2f,0x03,0x94,0xb8,0xae,0x51,0x00,0x39,0x47,0x60,0xd0,0x84,0x70,0x81,0xcb,0x44,0x9d,0x10,0x3a,0x58,0xce,0xe6,0x07,0x29,0x10,0x18,0xa0,0x50,0x88,0x76,0x02,0x22,0x07,0x49,0x8e,0x02,0x24,0x07,0x4e,0x0e,0x02,0x12,0x96,0x38,0x44,0x07,0x02,0x8f,0x1c,0x07,0x1c,0x4e,0x30,0x1c,0x10,0x3c,0x6c,0x13,0x80,0x38,0xc0,0xb0,0x80,0xf1,0x6e,0x90,0x1c,0x71,0x10,0xd7,0x49,0x81,0xc7,0x20,0x0f,0x17,0xe9,0x42,0x20,0x91,0x09,0xeb,0x24,0xe2,0x10,0x49,0x07,0x6f,0xff,0x80,0x56,0x88,0x1c,0xa2,0xae,0xd1,0x66,0x89,0xe0,0x68,0x11,0xb8,0x06,0xc0,0x2e,0x40,0x71,0x9a,0xc0,0x2b,0x00,0x73,0xc0,0x7a,0xe0,0x09,0x12,0x03,0x95,0x57,0xff,0x17,0x03,0x9c,0x03,0x57,0xaa,0x78,0x94,0x40,0xa6,0x35,0x5a,0xac,0x14,0x0e,0x9a,0xad,0x50,0xf8,0x41,0x05,0x00,0x83,0x55,0x14,0x06,0x07,0x18,0x54,0xa0,0x0e,0xb0,0x60,0x31,0xc0,0x00,}; -const uint8_t *_I_DolphinFirstStart7_61x51[] = {_I_DolphinFirstStart7_61x51_0}; +const uint8_t _I_ButtonUp_7x4_0[] = {0x00,0x08,0x1C,0x3E,0x7F,}; +const uint8_t *_I_ButtonUp_7x4[] = {_I_ButtonUp_7x4_0}; -const uint8_t _I_DolphinOkay_41x43_0[] = {0x01,0x00,0xa0,0x00,0x00,0x0f,0x82,0x3e,0x05,0x38,0xf7,0x80,0x08,0x58,0x08,0x0c,0x02,0x0e,0x05,0x1b,0x00,0x08,0x63,0x00,0x21,0x88,0x00,0x86,0x40,0x02,0x18,0x40,0x08,0x68,0x00,0x21,0x82,0x06,0x88,0x0a,0xf0,0x21,0x39,0x09,0x84,0x02,0x20,0x57,0x09,0x98,0x15,0x67,0xc0,0x54,0xbe,0x81,0x4f,0x01,0xfe,0x02,0x9d,0x03,0xc4,0x20,0x10,0x29,0x7c,0x80,0xa9,0xfe,0x02,0xac,0x14,0x0a,0x77,0xc8,0x58,0x8c,0xf0,0x11,0x51,0x79,0xff,0x61,0x44,0x93,0x81,0x02,0xc4,0x9e,0x60,0xb2,0xf0,0xa0,0x46,0x0c,0x17,0x14,0x99,0x1a,0x07,0x80,0x59,0x49,0x82,0x21,0xc0,0xa4,0x82,0x24,0xb9,0x20,0x88,0x1c,0x47,0xc2,0x07,0x11,0x54,0xa0,0x60,0x53,0xb8,0x0a,0x4b,0xf3,0x03,0x87,0x81,0x4a,0x0d,0xfc,0x1a,0x98,0x68,0xb8,0x01,0x51,0x13,0x15,0xe0,0x82,0x7f,0x8d,0x78,0x38,0xbf,0xff,0xfa,0xb8,0x60,0xbf,0x1b,0xf9,0x50,0x14,0xea,0xe7,0x02,0x02,0x8e,0xac,0x94,0x40,}; -const uint8_t *_I_DolphinOkay_41x43[] = {_I_DolphinOkay_41x43_0}; +const uint8_t _I_DFU_128x50_0[] = {0x01,0x00,0x2e,0x02,0x00,0x57,0xfe,0x0e,0x0e,0xcf,0x84,0x02,0x70,0x0f,0xc8,0x74,0x03,0x80,0x0e,0xbc,0x7c,0x04,0x06,0x30,0x30,0x74,0xe0,0x2f,0xe0,0x42,0x82,0x03,0xe7,0x81,0xff,0x02,0x14,0x20,0x1f,0x3e,0x00,0x79,0xc4,0x01,0xfd,0x20,0x07,0xd5,0xd4,0xe2,0x53,0xf2,0x74,0xff,0xe1,0x40,0x41,0x87,0xd8,0x01,0xf1,0x60,0xf0,0x43,0xca,0x43,0xe0,0xa7,0x83,0xe2,0x30,0x01,0x29,0x84,0x7b,0x20,0x0f,0x88,0x30,0x3c,0xb1,0x90,0x1d,0x00,0xfa,0x30,0x3f,0xf8,0xcc,0x02,0xc6,0x31,0x1f,0x83,0x49,0xa8,0x16,0x0a,0xf4,0x7f,0x00,0x21,0x1f,0x04,0x38,0x06,0x20,0x04,0x90,0x46,0x35,0xf0,0xfa,0x00,0xcc,0x7f,0x10,0x14,0x0b,0x46,0x20,0xd5,0x70,0x50,0xb4,0x06,0xf1,0x00,0x9f,0x03,0xd7,0x09,0x81,0xd7,0xc0,0x8b,0x85,0x38,0xc0,0x50,0x41,0xeb,0x63,0xc0,0x07,0xc6,0x90,0xbf,0x2b,0x05,0x01,0xb8,0xb1,0x0c,0x06,0xae,0x01,0x24,0x6f,0x94,0x42,0x80,0xb2,0x49,0xc4,0x33,0x80,0x1f,0x18,0x93,0xfc,0xa1,0x14,0x0e,0x02,0x9c,0x43,0xc3,0x07,0x81,0xfc,0x03,0xe2,0xc0,0x28,0x14,0x10,0x5e,0x3f,0x03,0xc0,0xcf,0xf8,0x10,0x0f,0xe5,0x56,0x03,0x05,0xf0,0x40,0x20,0x20,0xf2,0x42,0x0d,0xfd,0x72,0x30,0x0f,0xf8,0x7c,0x41,0xe3,0x80,0x10,0x0d,0x00,0x5c,0x4a,0xd1,0x87,0xf8,0x39,0xf5,0x5c,0x0c,0x0b,0xe0,0x1c,0x10,0x78,0xfc,0x02,0x04,0x20,0x1f,0xf7,0x0f,0x57,0x80,0x81,0x5e,0x13,0x83,0x01,0x1f,0x97,0xff,0xfe,0x03,0x2e,0x07,0x57,0x03,0x01,0xbf,0x1d,0x45,0x70,0x27,0xe4,0xff,0x8c,0x07,0xf5,0x83,0xe0,0xcf,0xe1,0x00,0xf6,0x10,0x8c,0x07,0xb1,0x07,0xc1,0xfc,0x63,0xe5,0xd2,0x07,0x8f,0x80,0x1a,0x21,0xe1,0xc0,0x71,0xe0,0x20,0xf1,0x24,0x88,0x34,0x62,0x00,0xe3,0x3f,0x8d,0xfe,0x81,0x80,0xc1,0xf8,0x5b,0xe2,0x0f,0x18,0xc7,0xf0,0x1e,0x50,0x35,0xa0,0xc8,0x3f,0x98,0x30,0x70,0x87,0x44,0x1e,0x21,0xe3,0xf8,0x02,0x4b,0xaf,0x01,0x81,0xb3,0xca,0x01,0x1c,0x25,0x94,0x01,0x04,0x58,0x8d,0x5c,0x0b,0xc6,0x08,0x10,0x78,0xc3,0x3f,0xf0,0x72,0x88,0x98,0x8b,0x89,0x55,0x82,0xc7,0x9b,0xe5,0x00,0x87,0x26,0xc4,0x46,0x20,0xf2,0xd1,0x87,0xc6,0x0c,0xdf,0x21,0x50,0x8a,0xc7,0x00,0x38,0x2e,0x04,0x42,0xaf,0x05,0x06,0x0a,0xb8,0x70,0x0f,0x91,0x80,0x5c,0x03,0xc5,0x30,0x84,0x6a,0xe1,0x40,0xf1,0x7b,0x0f,0x00,0x7a,0x24,0x21,0x07,0x94,0x33,0x09,0x57,0x8a,0x93,0x85,0xec,0x3e,0x00,0x79,0x0b,0x88,0x06,0x3c,0x3f,0xfc,0xa8,0x1e,0x21,0x91,0x76,0x90,0x90,0x40,0x03,0xe0,0xe0,0x78,0x3f,0xd5,0x58,0x0e,0x08,0x32,0x3f,0x88,0xa8,0x90,0x8c,0x25,0x30,0xbc,0x7f,0xb5,0x50,0x1b,0xe0,0x20,0x7f,0x92,0x33,0x88,0x97,0x4a,0x07,0x0c,0x9e,0x5f,0xeb,0xaa,0xf2,0x74,0x8d,0x17,0x80,0x06,0x29,0xf1,0xe0,0x71,0xfb,0xfd,0x71,0xd8,0xff,0xf8,0x21,0x71,0x04,0x87,0x01,0xc1,0xa1,0xff,0x83,0xe7,0xf0,0xff,0xc1,0x51,0xe4,0xdd,0x1b,0x07,0xc2,0x63,0xf6,0x0f,0x9f,0xeb,0x5f,0x02,0x77,0x8a,0xc4,0xa3,0x17,0xc8,0x44,0x8c,0x34,0x20,0x71,0xfe,0x99,0x04,0x88,0x40,0x01,0xc3,0x47,0xf0,0x93,0x0f,0xf4,0x28,0x0e,0x3a,0xad,0x50,0x39,0x30,0x1f,0x18,0x3d,0x0e,0x31,0xff,0x3d,0x0c,0x02,0xa8,0x03,0x20,0x01,0x7e,0x3f,0xf8,0x09,0x06,0x33,0xfe,0x1b,0x50,}; +const uint8_t *_I_DFU_128x50[] = {_I_DFU_128x50_0}; -const uint8_t _I_DolphinFirstStart5_54x49_0[] = {0x01,0x00,0x0b,0x01,0x00,0x0f,0xf2,0xfe,0x06,0x48,0x1e,0x02,0x06,0x05,0x2e,0x00,0x08,0x61,0x80,0x62,0x98,0x00,0x86,0x20,0x06,0x28,0x40,0x08,0x64,0x00,0x62,0x82,0x00,0x86,0x80,0x06,0x28,0x14,0x72,0x01,0x80,0x03,0x14,0x06,0x44,0x03,0x20,0x49,0x00,0xc4,0x0c,0x61,0x13,0x81,0x07,0x90,0x0c,0xff,0xa8,0x18,0xcc,0xe0,0x10,0x78,0x60,0x18,0xc9,0xe3,0x10,0x03,0x0e,0x02,0x02,0x4f,0x19,0x00,0x18,0x78,0x10,0x12,0x78,0xc8,0x0a,0xc3,0xf8,0x80,0xc1,0x80,0xc5,0xe0,0xff,0x8f,0x47,0xe1,0x27,0x03,0x0d,0xfc,0x80,0x3b,0xc9,0x74,0x43,0x81,0x0f,0xb0,0x40,0x2b,0xd2,0xd3,0x71,0x07,0x87,0x5f,0x16,0x84,0x54,0x23,0xe3,0x21,0xab,0xc5,0x61,0x1a,0x82,0xf0,0xf0,0x35,0x70,0xa8,0x45,0x50,0x2a,0x3e,0x0a,0xac,0x1e,0x11,0x28,0x03,0x0f,0xc3,0xfe,0x06,0x19,0xa0,0x18,0x6f,0x9f,0x08,0x7c,0x22,0x30,0x06,0x1d,0xfc,0x3e,0x21,0x08,0x00,0x8f,0x01,0x7a,0x31,0x08,0x24,0x42,0x21,0xf0,0x5e,0x08,0x18,0x44,0xe3,0x0f,0x59,0x92,0xb4,0x96,0x66,0x06,0x58,0x10,0x19,0x60,0x20,0x64,0x46,0x08,0x19,0x27,0x00,0x65,0x9f,0x81,0x93,0xd1,0x2b,0x03,0x17,0x82,0x3f,0x50,0x9a,0x81,0x87,0x51,0x1e,0xf0,0x68,0x69,0x40,0x61,0xea,0x9d,0x86,0x1d,0x45,0x80,0x61,0x2d,0x48,0xc2,0x67,0x8d,0x12,0x3a,0x06,0x19,0x02,0x88,0x74,0x4b,0x21,0x03,0x1d,0x08,0xca,0x21,0x41,0x06,0x93,0xe8,0xa1,0x85,0x31,0xe9,0x24,0x48,0x20,0x30,0x1b,0x10,0x18,0x77,0x8f,0xa1,0x80,0xcc,0x40,0xc3,0x56,0x0b,0x8c,0x0a,0x22,0xba,0x12,0x88,0x81,0x84,}; -const uint8_t *_I_DolphinFirstStart5_54x49[] = {_I_DolphinFirstStart5_54x49_0}; +const uint8_t _I_ButtonLeftSmall_3x5_0[] = {0x00,0x04,0x06,0x07,0x06,0x04,}; +const uint8_t *_I_ButtonLeftSmall_3x5[] = {_I_ButtonLeftSmall_3x5_0}; -const uint8_t _I_Flipper_young_80x60_0[] = {0x01,0x00,0xa3,0x01,0x00,0x1e,0x03,0xff,0xff,0x87,0x82,0x57,0xf1,0x83,0x90,0xde,0x01,0x2b,0x0e,0x83,0x70,0xfb,0x10,0x10,0x41,0xf8,0x27,0x70,0xcc,0x34,0xc6,0x0e,0x09,0x3e,0x04,0x86,0x21,0x0c,0x90,0xc3,0x03,0xa9,0xe7,0xb0,0x46,0x2c,0x51,0x40,0x4a,0x63,0x38,0x31,0x0a,0x34,0x90,0x12,0x91,0x8e,0x3c,0xff,0x89,0x4c,0x04,0xa4,0x43,0xfd,0xf3,0xc3,0xf2,0x01,0x29,0xe0,0x2b,0x8e,0x72,0xa0,0x46,0x4b,0xe0,0x30,0xba,0x10,0x22,0xca,0x1c,0x0b,0x26,0x09,0x3c,0x04,0x0c,0x08,0x59,0xc8,0x21,0x64,0xc4,0x47,0x98,0x82,0x81,0x0a,0xe0,0x21,0x39,0x04,0x34,0x88,0x60,0x93,0xa0,0x45,0x4b,0x06,0xa3,0x40,0x48,0xfc,0x20,0xf0,0x82,0xa2,0x4d,0x60,0x11,0xe9,0xc2,0x19,0x64,0xd0,0x08,0x1f,0x80,0x7e,0x60,0x01,0x92,0x60,0x20,0x38,0x05,0x21,0x7c,0x3f,0xf0,0x1a,0xe6,0x00,0xe6,0x21,0x32,0x1a,0x0c,0x0e,0x91,0x80,0x8f,0xc0,0x06,0x25,0xcc,0xbf,0xc1,0xaa,0x10,0x0b,0xfc,0x02,0x60,0x2e,0x2c,0x04,0x32,0xc1,0x00,0xff,0x40,0x68,0x00,0x91,0x89,0xc0,0x21,0x20,0x51,0xfe,0x41,0xf0,0x00,0x91,0xc4,0xcf,0xe2,0x40,0x51,0xfc,0x0c,0x86,0x07,0x80,0xe2,0xdf,0xda,0x25,0xf0,0x9f,0xc0,0x21,0x98,0x0f,0x27,0xfd,0xa2,0x5e,0x01,0x90,0xc4,0x30,0x1e,0x2f,0xfc,0xa1,0x3a,0x45,0x41,0xb0,0x60,0x3e,0x5e,0x79,0x4a,0x10,0xbf,0xe2,0x61,0xc0,0x82,0x52,0x01,0xff,0x36,0x8e,0x3b,0xe5,0xff,0x04,0x9f,0xf8,0x78,0x3b,0x8f,0x97,0xf8,0x12,0x7f,0xc3,0x78,0xf8,0x3e,0x5f,0xc0,0x49,0xfe,0x08,0xc2,0x17,0x1f,0xcd,0xa5,0xac,0x5f,0x02,0x30,0xc0,0x30,0x5f,0xfd,0x23,0xbc,0xbc,0x1f,0xf0,0xc1,0x5f,0xaa,0x8e,0x52,0x28,0x10,0x10,0x6f,0x1b,0x28,0x57,0x81,0x66,0x25,0x01,0x80,0x4e,0x28,0x15,0x98,0xad,0xc3,0xfd,0xff,0xff,0x91,0x87,0xc1,0x80,0xd4,0xc2,0xb2,0x03,0xb1,0x5b,0x13,0x34,0x6a,0xf1,0x58,0x84,0x0e,0x1d,0x00,0x23,0x14,0x0f,0x55,0x0a,0x88,0x67,0x0d,0x83,0x7c,0x04,0x8c,0x0a,0xa9,0x15,0x90,0x7c,0x07,0x23,0xf8,0x80,0xc1,0xa0,0xda,0x88,0x54,0x82,0x00,0x2f,0x1f,0xe4,0x3c,0x7a,0x35,0x08,0xab,0x20,0x7f,0x03,0xc1,0x2d,0x96,0x82,0x14,0xce,0x20,0x02,0x04,0xc6,0x00,0x60,0x20,0x01,0x84,0xc4,0x6a,0x21,0x36,0x3b,0x8c,0xf0,0x3c,0xc8,0x02,0x1b,0x88,0x01,0xe1,0x80,0x98,0x2d,0x10,0x01,0xb0,0x05,0xa1,0x00,0x3d,0xf8,0x13,0x17,0x81,0x47,0x80,0x0b,0xc0,0x28,0x8e,0x02,0xa4,0x81,0x2c,0xf0,0x20,0x01,0x00,}; -const uint8_t *_I_Flipper_young_80x60[] = {_I_Flipper_young_80x60_0}; +const uint8_t _I_ButtonRightSmall_3x5_0[] = {0x00,0x01,0x03,0x07,0x03,0x01,}; +const uint8_t *_I_ButtonRightSmall_3x5[] = {_I_ButtonRightSmall_3x5_0}; + +const uint8_t _I_ButtonRight_4x7_0[] = {0x00,0x01,0x03,0x07,0x0F,0x07,0x03,0x01,}; +const uint8_t *_I_ButtonRight_4x7[] = {_I_ButtonRight_4x7_0}; + +const uint8_t _I_Warning_30x23_0[] = {0x01,0x00,0x47,0x00,0x80,0x70,0x00,0x65,0xe0,0x80,0x80,0xc7,0xe1,0x03,0x01,0xaf,0xe2,0x0e,0x03,0x19,0xe4,0x3c,0x06,0xb3,0xe8,0xf8,0x0c,0x67,0xf3,0xf0,0x1a,0x60,0x27,0xf7,0xf1,0x50,0xcf,0xff,0xe0,0x34,0xf0,0x00,0xc6,0x03,0xf0,0x01,0x8c,0x0c,0x06,0x7f,0x80,0x18,0xc1,0xff,0x9f,0xff,0xfc,0x3c,0x06,0x7f,0xe0,0x58,0xc7,0xff,0xe0,0x31,0x00,0x88,0x00,0x67,0xff,0xe0,0x18,0xc7,0xc0,}; +const uint8_t *_I_Warning_30x23[] = {_I_Warning_30x23_0}; const uint8_t _I_DolphinFirstStart2_59x51_0[] = {0x01,0x00,0x2e,0x01,0x00,0x1f,0xfe,0x06,0x05,0x3f,0xc7,0xfe,0x01,0x1c,0x03,0x16,0x02,0xaf,0x0f,0x80,0x58,0x01,0xc7,0xaa,0x80,0x82,0xc4,0x0e,0x55,0x6b,0x28,0x10,0x81,0x45,0xab,0x8d,0x01,0xca,0x04,0x1a,0x1a,0xac,0x1c,0x0e,0x50,0x48,0x06,0xc0,0x3c,0x40,0x01,0x84,0x40,0x2b,0x15,0x51,0xd9,0xc4,0x20,0x1a,0xc9,0x50,0x1c,0xe4,0x02,0xe1,0x8a,0x81,0xd7,0x55,0x0a,0x03,0x9d,0x02,0x01,0x5c,0x82,0x81,0xd7,0xc0,0x3a,0x10,0x3a,0x12,0x88,0xc8,0x60,0x11,0x07,0xa0,0x1c,0x68,0x00,0xf6,0xe0,0x22,0x50,0x0e,0x36,0x00,0x7b,0x68,0x00,0x83,0xa0,0x11,0x08,0x1c,0x6a,0x03,0x42,0x44,0x1e,0xc0,0x28,0x50,0x61,0xf9,0x56,0x00,0xe3,0x60,0x40,0x88,0x1c,0x75,0x01,0x42,0x07,0x9d,0x50,0x5e,0x4b,0x01,0x37,0x8e,0xb0,0x0e,0x51,0xd8,0x04,0xc2,0x01,0xd4,0x5d,0x1c,0x02,0x30,0x7f,0x14,0x99,0x5c,0x20,0x11,0x48,0x07,0x58,0x0e,0x20,0x81,0xd0,0x23,0x04,0x1e,0x30,0x80,0x38,0xd4,0x11,0x82,0x0f,0x18,0x40,0xb0,0xb0,0x50,0x3d,0x58,0x1c,0x52,0x85,0xf1,0x83,0x75,0x58,0x64,0x49,0x1a,0xfc,0x17,0x57,0x01,0x88,0x25,0x0b,0x55,0x02,0xaa,0xc0,0x64,0x14,0x08,0x1e,0x02,0xaa,0x1f,0x18,0x0f,0x00,0xbe,0x20,0xf1,0x80,0x82,0x46,0x01,0x03,0x82,0xe0,0x04,0xa3,0xab,0x46,0x0e,0x32,0x15,0x80,0xb5,0x40,0x2a,0xa4,0x21,0x98,0x43,0x70,0x13,0x58,0x04,0xac,0xa4,0x3c,0x08,0xd6,0x02,0x35,0x00,0x8a,0xcd,0x06,0xa3,0x1d,0xa0,0x24,0x46,0x57,0xe8,0x26,0x8c,0xdb,0x80,0x84,0x18,0xad,0x42,0x07,0x5f,0xbf,0xb9,0x8a,0x17,0x80,0xff,0x6a,0xb0,0x46,0x91,0x07,0x88,0xc4,0x4a,0x43,0x1f,0x07,0x92,0xc4,0x49,0x82,0x9b,0x25,0x98,0xc0,0x28,0xa0,0x73,0x1f,0x0b,0x50,0x81,0xea,0x07,0x40,0x7b,0xac,0x44,0x0e,0xa0,}; const uint8_t *_I_DolphinFirstStart2_59x51[] = {_I_DolphinFirstStart2_59x51_0}; +const uint8_t _I_DolphinFirstStart5_54x49_0[] = {0x01,0x00,0x0b,0x01,0x00,0x0f,0xf2,0xfe,0x06,0x48,0x1e,0x02,0x06,0x05,0x2e,0x00,0x08,0x61,0x80,0x62,0x98,0x00,0x86,0x20,0x06,0x28,0x40,0x08,0x64,0x00,0x62,0x82,0x00,0x86,0x80,0x06,0x28,0x14,0x72,0x01,0x80,0x03,0x14,0x06,0x44,0x03,0x20,0x49,0x00,0xc4,0x0c,0x61,0x13,0x81,0x07,0x90,0x0c,0xff,0xa8,0x18,0xcc,0xe0,0x10,0x78,0x60,0x18,0xc9,0xe3,0x10,0x03,0x0e,0x02,0x02,0x4f,0x19,0x00,0x18,0x78,0x10,0x12,0x78,0xc8,0x0a,0xc3,0xf8,0x80,0xc1,0x80,0xc5,0xe0,0xff,0x8f,0x47,0xe1,0x27,0x03,0x0d,0xfc,0x80,0x3b,0xc9,0x74,0x43,0x81,0x0f,0xb0,0x40,0x2b,0xd2,0xd3,0x71,0x07,0x87,0x5f,0x16,0x84,0x54,0x23,0xe3,0x21,0xab,0xc5,0x61,0x1a,0x82,0xf0,0xf0,0x35,0x70,0xa8,0x45,0x50,0x2a,0x3e,0x0a,0xac,0x1e,0x11,0x28,0x03,0x0f,0xc3,0xfe,0x06,0x19,0xa0,0x18,0x6f,0x9f,0x08,0x7c,0x22,0x30,0x06,0x1d,0xfc,0x3e,0x21,0x08,0x00,0x8f,0x01,0x7a,0x31,0x08,0x24,0x42,0x21,0xf0,0x5e,0x08,0x18,0x44,0xe3,0x0f,0x59,0x92,0xb4,0x96,0x66,0x06,0x58,0x10,0x19,0x60,0x20,0x64,0x46,0x08,0x19,0x27,0x00,0x65,0x9f,0x81,0x93,0xd1,0x2b,0x03,0x17,0x82,0x3f,0x50,0x9a,0x81,0x87,0x51,0x1e,0xf0,0x68,0x69,0x40,0x61,0xea,0x9d,0x86,0x1d,0x45,0x80,0x61,0x2d,0x48,0xc2,0x67,0x8d,0x12,0x3a,0x06,0x19,0x02,0x88,0x74,0x4b,0x21,0x03,0x1d,0x08,0xca,0x21,0x41,0x06,0x93,0xe8,0xa1,0x85,0x31,0xe9,0x24,0x48,0x20,0x30,0x1b,0x10,0x18,0x77,0x8f,0xa1,0x80,0xcc,0x40,0xc3,0x56,0x0b,0x8c,0x0a,0x22,0xba,0x12,0x88,0x81,0x84,}; +const uint8_t *_I_DolphinFirstStart5_54x49[] = {_I_DolphinFirstStart5_54x49_0}; + +const uint8_t _I_DolphinFirstStart6_58x54_0[] = {0x01,0x00,0x21,0x01,0x00,0x0f,0xf2,0x7e,0x06,0x4c,0x04,0x0f,0x81,0x03,0x03,0x9d,0x80,0x04,0x30,0xc0,0x39,0xc6,0x00,0x43,0x30,0x03,0x9c,0x10,0x04,0x34,0x00,0x39,0xc0,0x84,0x44,0x07,0x38,0x08,0x0d,0x41,0x68,0x13,0x70,0x39,0x08,0xd0,0x56,0xa1,0xd1,0x03,0x94,0x80,0x04,0x30,0x68,0x04,0x20,0x0e,0x84,0x91,0x03,0xa9,0x64,0x62,0x80,0x41,0x88,0x40,0x3f,0xc6,0xf1,0xfe,0x43,0xc0,0xe3,0x80,0xff,0xff,0xe0,0x3f,0xf8,0xf8,0x1c,0x78,0x18,0x1f,0xfe,0x0f,0x02,0x12,0x18,0x47,0x03,0x82,0x10,0x1e,0x08,0x1c,0xf5,0x60,0x71,0xd4,0x81,0xcf,0xab,0xff,0xd5,0xf5,0xc0,0xe3,0x04,0xe0,0x03,0x86,0xae,0x27,0x28,0x27,0x40,0x0e,0x21,0x91,0x03,0x96,0x80,0x0e,0x34,0x18,0x79,0x28,0x60,0x95,0x00,0x38,0xf8,0x20,0x27,0xd1,0x82,0x6a,0x03,0xc3,0x1c,0x39,0x94,0x0a,0xa1,0xc0,0xc5,0x2f,0xca,0x05,0x02,0x90,0x24,0x56,0x04,0x68,0x10,0x01,0x4f,0x80,0xea,0x5b,0x10,0x38,0x83,0x8d,0xa0,0x30,0x30,0x38,0xa3,0x09,0xc0,0x20,0xf2,0x03,0x90,0xc0,0x46,0xe2,0x91,0x2f,0x80,0xfc,0xe0,0x1e,0x08,0x02,0x54,0x47,0x62,0x27,0x2f,0xfb,0x14,0xdc,0xc6,0xb5,0x30,0x38,0x8b,0x05,0x6a,0x60,0x01,0x89,0x00,0xc8,0x16,0x50,0x29,0x10,0x1c,0x8d,0x25,0x05,0xa1,0x15,0xc9,0xfe,0x50,0xaa,0x08,0x10,0x67,0x01,0x22,0x8a,0xe0,0x60,0xe5,0xf2,0x07,0x8e,0xa8,0xb0,0x49,0xe1,0x00,0x0d,0xd4,0x68,0x5a,0x00,0x39,0x46,0x88,0x84,0x07,0x30,0xe8,0x81,0xc6,0x40,0x4d,0x11,0x91,0x17,0x06,0x40,0x65,0x11,0x51,0x01,0xc6,0x81,0x04,0x32,0x18,0x1e,0x92,0x64,0x00,0x11,0x68,0x81,0xd6,0xa0,0x07,0x16,0x22,0x6b,0x0a,0x82,0x07,0x3f,0x05,0x4d,0xdc,0x24,0x21,}; +const uint8_t *_I_DolphinFirstStart6_58x54[] = {_I_DolphinFirstStart6_58x54_0}; + +const uint8_t _I_Flipper_young_80x60_0[] = {0x01,0x00,0xa3,0x01,0x00,0x1e,0x03,0xff,0xff,0x87,0x82,0x57,0xf1,0x83,0x90,0xde,0x01,0x2b,0x0e,0x83,0x70,0xfb,0x10,0x10,0x41,0xf8,0x27,0x70,0xcc,0x34,0xc6,0x0e,0x09,0x3e,0x04,0x86,0x21,0x0c,0x90,0xc3,0x03,0xa9,0xe7,0xb0,0x46,0x2c,0x51,0x40,0x4a,0x63,0x38,0x31,0x0a,0x34,0x90,0x12,0x91,0x8e,0x3c,0xff,0x89,0x4c,0x04,0xa4,0x43,0xfd,0xf3,0xc3,0xf2,0x01,0x29,0xe0,0x2b,0x8e,0x72,0xa0,0x46,0x4b,0xe0,0x30,0xba,0x10,0x22,0xca,0x1c,0x0b,0x26,0x09,0x3c,0x04,0x0c,0x08,0x59,0xc8,0x21,0x64,0xc4,0x47,0x98,0x82,0x81,0x0a,0xe0,0x21,0x39,0x04,0x34,0x88,0x60,0x93,0xa0,0x45,0x4b,0x06,0xa3,0x40,0x48,0xfc,0x20,0xf0,0x82,0xa2,0x4d,0x60,0x11,0xe9,0xc2,0x19,0x64,0xd0,0x08,0x1f,0x80,0x7e,0x60,0x01,0x92,0x60,0x20,0x38,0x05,0x21,0x7c,0x3f,0xf0,0x1a,0xe6,0x00,0xe6,0x21,0x32,0x1a,0x0c,0x0e,0x91,0x80,0x8f,0xc0,0x06,0x25,0xcc,0xbf,0xc1,0xaa,0x10,0x0b,0xfc,0x02,0x60,0x2e,0x2c,0x04,0x32,0xc1,0x00,0xff,0x40,0x68,0x00,0x91,0x89,0xc0,0x21,0x20,0x51,0xfe,0x41,0xf0,0x00,0x91,0xc4,0xcf,0xe2,0x40,0x51,0xfc,0x0c,0x86,0x07,0x80,0xe2,0xdf,0xda,0x25,0xf0,0x9f,0xc0,0x21,0x98,0x0f,0x27,0xfd,0xa2,0x5e,0x01,0x90,0xc4,0x30,0x1e,0x2f,0xfc,0xa1,0x3a,0x45,0x41,0xb0,0x60,0x3e,0x5e,0x79,0x4a,0x10,0xbf,0xe2,0x61,0xc0,0x82,0x52,0x01,0xff,0x36,0x8e,0x3b,0xe5,0xff,0x04,0x9f,0xf8,0x78,0x3b,0x8f,0x97,0xf8,0x12,0x7f,0xc3,0x78,0xf8,0x3e,0x5f,0xc0,0x49,0xfe,0x08,0xc2,0x17,0x1f,0xcd,0xa5,0xac,0x5f,0x02,0x30,0xc0,0x30,0x5f,0xfd,0x23,0xbc,0xbc,0x1f,0xf0,0xc1,0x5f,0xaa,0x8e,0x52,0x28,0x10,0x10,0x6f,0x1b,0x28,0x57,0x81,0x66,0x25,0x01,0x80,0x4e,0x28,0x15,0x98,0xad,0xc3,0xfd,0xff,0xff,0x91,0x87,0xc1,0x80,0xd4,0xc2,0xb2,0x03,0xb1,0x5b,0x13,0x34,0x6a,0xf1,0x58,0x84,0x0e,0x1d,0x00,0x23,0x14,0x0f,0x55,0x0a,0x88,0x67,0x0d,0x83,0x7c,0x04,0x8c,0x0a,0xa9,0x15,0x90,0x7c,0x07,0x23,0xf8,0x80,0xc1,0xa0,0xda,0x88,0x54,0x82,0x00,0x2f,0x1f,0xe4,0x3c,0x7a,0x35,0x08,0xab,0x20,0x7f,0x03,0xc1,0x2d,0x96,0x82,0x14,0xce,0x20,0x02,0x04,0xc6,0x00,0x60,0x20,0x01,0x84,0xc4,0x6a,0x21,0x36,0x3b,0x8c,0xf0,0x3c,0xc8,0x02,0x1b,0x88,0x01,0xe1,0x80,0x98,0x2d,0x10,0x01,0xb0,0x05,0xa1,0x00,0x3d,0xf8,0x13,0x17,0x81,0x47,0x80,0x0b,0xc0,0x28,0x8e,0x02,0xa4,0x81,0x2c,0xf0,0x20,0x01,0x00,}; +const uint8_t *_I_Flipper_young_80x60[] = {_I_Flipper_young_80x60_0}; + const uint8_t _I_DolphinFirstStart8_56x51_0[] = {0x01,0x00,0xfd,0x00,0x00,0x17,0x83,0xff,0x01,0x03,0x1c,0x72,0x01,0x06,0x03,0x1c,0x0e,0x01,0x18,0x02,0x96,0x00,0x04,0x36,0x00,0x31,0x50,0x01,0x24,0x1c,0x29,0x00,0x28,0xa0,0x40,0x21,0x88,0x01,0x8a,0x08,0x02,0x18,0x40,0x18,0x80,0x64,0x09,0x20,0x89,0x81,0x98,0x3c,0x42,0x63,0x03,0x30,0xcc,0x70,0x10,0x71,0xd9,0x01,0x86,0xc1,0x1c,0x03,0x24,0x42,0x7e,0x50,0x12,0x91,0x62,0x2f,0xf8,0x0e,0x00,0x18,0xb9,0x17,0x1c,0x04,0x83,0x02,0x06,0x1e,0x27,0xc4,0x54,0x20,0x62,0xf2,0x7c,0xe0,0x52,0x0c,0x10,0x88,0x7c,0x9f,0xf8,0x28,0x18,0x41,0xa5,0xff,0x85,0x48,0x30,0x80,0xd1,0xe4,0x5f,0xc1,0xa3,0x84,0x26,0x0f,0x23,0xfe,0x1b,0x18,0x44,0x16,0x01,0x90,0x81,0xc1,0x62,0x10,0x84,0xc0,0xf8,0x20,0x30,0x28,0x84,0x40,0x1a,0x25,0x11,0x82,0x42,0x22,0x11,0xf4,0xd9,0xc1,0x02,0x22,0xb2,0x38,0x14,0xc1,0x8e,0x90,0x14,0xc1,0xa2,0x86,0x02,0xc6,0x30,0x31,0x06,0x8c,0x0c,0x26,0x02,0x56,0x9d,0x04,0x0c,0x6a,0xa1,0x03,0x21,0x20,0x68,0x5f,0xe7,0xa9,0x00,0x86,0x85,0x01,0x8f,0xe0,0x08,0xe3,0x00,0xe1,0x02,0xc6,0xfe,0x16,0x23,0xe1,0x13,0x10,0xa4,0x82,0xb1,0x12,0x88,0x00,0xf0,0x91,0xe0,0x6a,0xfd,0x63,0xfc,0x08,0x78,0x18,0xb5,0x5e,0xad,0xfb,0x84,0xa0,0x95,0x48,0xad,0x54,0x4a,0x50,0x4d,0x44,0x6b,0x56,0x0d,0x28,0x45,0x42,0x6a,0x0d,0x38,0x46,0x02,0x55,0xaa,0x35,0x25,0x52,0xac,0x06,0x4b,0x04,0xa8,0x0c,0x94,0x03,0xa0,0x80,0x04,}; const uint8_t *_I_DolphinFirstStart8_56x51[] = {_I_DolphinFirstStart8_56x51_0}; +const uint8_t _I_DolphinFirstStart1_59x53_0[] = {0x01,0x00,0x1e,0x01,0x00,0x0e,0x03,0xfe,0x07,0x5b,0x84,0x02,0x06,0x07,0x48,0x64,0x02,0x08,0x07,0x48,0x14,0x02,0x10,0x07,0x48,0x0c,0x03,0x21,0x3f,0x13,0x18,0x84,0xa8,0x00,0x75,0x8c,0x00,0xca,0x00,0x0b,0x28,0x20,0x1d,0xa0,0x59,0xe0,0x39,0x48,0x07,0x03,0x81,0xd5,0x81,0xd6,0x81,0x55,0x8c,0x01,0xc6,0x21,0x00,0x87,0x68,0x25,0x52,0x40,0x39,0x7c,0x21,0xf5,0x08,0xa8,0x1d,0x20,0xfa,0x88,0x70,0x1c,0xfd,0x10,0x3a,0xa4,0x1f,0x88,0x54,0x18,0x85,0x52,0x09,0xbe,0x81,0xc1,0x0c,0x83,0x10,0x94,0x40,0x39,0xf0,0x19,0x21,0xc8,0x62,0x12,0x0c,0x04,0x0e,0x0c,0x07,0x38,0x07,0x86,0x07,0x18,0x03,0x94,0xc2,0x01,0x9e,0x81,0xca,0x38,0x89,0x21,0x0f,0x0c,0x03,0xf9,0x27,0x13,0x94,0xd0,0xb6,0x70,0x20,0x38,0xda,0x80,0xe5,0x10,0x03,0x95,0x59,0x54,0x70,0x10,0x38,0xda,0xc0,0xc3,0xfe,0xc1,0xab,0x0b,0xaa,0x2a,0x1c,0x05,0x81,0x58,0x38,0x09,0xd0,0x5c,0xa3,0xe0,0x72,0x86,0xae,0x8d,0x40,0x34,0x06,0xa1,0xc0,0xc0,0xe3,0xc0,0x65,0x1c,0x19,0x58,0x29,0xe1,0x00,0x14,0x28,0x0a,0x26,0x61,0x00,0x15,0x58,0x0a,0x2e,0x34,0xd6,0x42,0x9e,0x6b,0x54,0x82,0x92,0x08,0x1e,0x63,0x41,0x1d,0x0a,0x88,0x60,0x1d,0x42,0x11,0x5c,0x01,0xe5,0x3c,0x03,0x97,0x30,0x0e,0x42,0x42,0x80,0xd0,0x82,0xe4,0x07,0x28,0x17,0x10,0x1e,0xb0,0x4a,0x20,0x3d,0x61,0x1a,0x80,0x79,0x0f,0x0a,0x21,0x70,0x07,0x90,0x1c,0xa4,0x1a,0x00,0x7a,0xd0,0x0e,0x42,0x34,0x20,0x10,0xe0,0x00,0xed,0x00,0xa1,0x82,0xc8,0xc6,0x74,0x40,0xd9,0x01,0xce,0x84,0x07,0x69,0x10,0xcc,0x80,0xe7,0x5c,0x03,0xb4,0xa8,0x96,0x40,0x73,0x8a,0x96,0xc8,0x0c,0x40,}; +const uint8_t *_I_DolphinFirstStart1_59x53[] = {_I_DolphinFirstStart1_59x53_0}; + +const uint8_t _I_DolphinOkay_41x43_0[] = {0x01,0x00,0xa0,0x00,0x00,0x0f,0x82,0x3e,0x05,0x38,0xf7,0x80,0x08,0x58,0x08,0x0c,0x02,0x0e,0x05,0x1b,0x00,0x08,0x63,0x00,0x21,0x88,0x00,0x86,0x40,0x02,0x18,0x40,0x08,0x68,0x00,0x21,0x82,0x06,0x88,0x0a,0xf0,0x21,0x39,0x09,0x84,0x02,0x20,0x57,0x09,0x98,0x15,0x67,0xc0,0x54,0xbe,0x81,0x4f,0x01,0xfe,0x02,0x9d,0x03,0xc4,0x20,0x10,0x29,0x7c,0x80,0xa9,0xfe,0x02,0xac,0x14,0x0a,0x77,0xc8,0x58,0x8c,0xf0,0x11,0x51,0x79,0xff,0x61,0x44,0x93,0x81,0x02,0xc4,0x9e,0x60,0xb2,0xf0,0xa0,0x46,0x0c,0x17,0x14,0x99,0x1a,0x07,0x80,0x59,0x49,0x82,0x21,0xc0,0xa4,0x82,0x24,0xb9,0x20,0x88,0x1c,0x47,0xc2,0x07,0x11,0x54,0xa0,0x60,0x53,0xb8,0x0a,0x4b,0xf3,0x03,0x87,0x81,0x4a,0x0d,0xfc,0x1a,0x98,0x68,0xb8,0x01,0x51,0x13,0x15,0xe0,0x82,0x7f,0x8d,0x78,0x38,0xbf,0xff,0xfa,0xb8,0x60,0xbf,0x1b,0xf9,0x50,0x14,0xea,0xe7,0x02,0x02,0x8e,0xac,0x94,0x40,}; +const uint8_t *_I_DolphinOkay_41x43[] = {_I_DolphinOkay_41x43_0}; + const uint8_t _I_DolphinFirstStart3_57x48_0[] = {0x01,0x00,0x12,0x01,0x00,0x16,0x03,0xff,0x07,0x03,0xa5,0x82,0x01,0x38,0x03,0xa4,0x62,0x01,0xc0,0x03,0xa4,0x10,0x04,0x30,0x10,0x39,0xc0,0x80,0x48,0x0c,0x40,0x91,0x7e,0x20,0x60,0x72,0x84,0x02,0x8b,0x78,0x12,0x28,0x80,0x68,0x85,0x87,0x20,0x11,0x18,0x5c,0x80,0xe8,0x01,0x19,0xc5,0x00,0x0e,0x62,0xc1,0x9f,0x01,0xcb,0xe9,0x03,0x84,0x60,0x20,0xf8,0x00,0x38,0xd7,0x21,0xb1,0x0f,0x04,0x04,0x0e,0x5a,0x89,0xd4,0x83,0xc0,0x4b,0x3a,0xc5,0x54,0xcc,0x20,0x51,0x00,0x8e,0xc3,0x54,0x80,0x13,0xf8,0x81,0xc6,0xc1,0x55,0x01,0x8c,0x78,0x0e,0x30,0xee,0x06,0xaa,0x05,0xe0,0xae,0x01,0xc6,0x23,0x80,0xaa,0xc1,0x60,0x1a,0x90,0x38,0xc8,0x60,0x1a,0xb8,0x54,0x02,0xad,0x07,0x80,0xd0,0x40,0x83,0x15,0x80,0x7b,0x21,0x10,0x1c,0x0c,0x03,0x7f,0x2a,0x80,0x4d,0x00,0xe3,0x01,0xf8,0xf0,0x2a,0xf0,0x08,0x60,0x1c,0x60,0x41,0xd1,0xdf,0x1a,0x44,0x0e,0x50,0x68,0x05,0xe3,0x07,0x02,0x82,0x01,0xc6,0x19,0x00,0xf8,0x5f,0xe0,0x20,0x72,0xfa,0x40,0x7f,0xc2,0xb1,0x03,0x88,0x68,0x7f,0xf6,0xb4,0x28,0xc0,0x80,0xe3,0x88,0xaa,0xc7,0x40,0xe9,0x50,0xd5,0x41,0x94,0xa2,0x07,0x29,0x87,0x52,0x02,0x07,0x12,0x30,0xc1,0x22,0x16,0x86,0x29,0x01,0xca,0x30,0xf6,0x10,0x39,0xc2,0x23,0x10,0x6c,0x00,0x1d,0x3d,0x10,0x1b,0x02,0xe0,0x41,0x03,0x08,0x75,0x0c,0x60,0x0e,0x4f,0x11,0x0a,0x0c,0x18,0x0e,0x96,0x06,0x28,0x81,0xd3,0x01,0x1f,0x01,0x90,0x1c,0xdc,0xc2,0x01,0x15,0xd0,0x81,0xdc,0x4c,0x30,0x30,0x3f,0x00,0xc4,0x0e,0x30,0x20,0x3c,0x8c,0xc8,0x0f,0x2b,0x41,}; const uint8_t *_I_DolphinFirstStart3_57x48[] = {_I_DolphinFirstStart3_57x48_0}; +const uint8_t _I_DolphinFirstStart7_61x51_0[] = {0x01,0x00,0x13,0x01,0x00,0x17,0x03,0xff,0x01,0x03,0xa4,0xe2,0x01,0x0e,0x03,0xa4,0x1a,0x01,0x30,0x03,0x1e,0x00,0x2a,0x3c,0x00,0x39,0xd0,0x00,0x65,0x03,0x01,0x94,0x80,0x06,0x50,0x40,0x19,0x44,0x00,0x65,0x08,0x01,0xb0,0x2c,0xe2,0x81,0xb6,0x86,0x0a,0xd8,0x7c,0x20,0x75,0x85,0x10,0xcc,0x06,0x50,0x50,0x3b,0x10,0xce,0x00,0x69,0x20,0x79,0x7c,0x20,0x20,0x71,0xc0,0x07,0xca,0xf1,0x02,0x81,0x01,0xc6,0x3a,0x07,0x1f,0xe4,0x10,0x0e,0x53,0xe0,0x38,0xe7,0xa0,0xa0,0x72,0xbb,0x81,0xca,0x12,0x68,0x1c,0x05,0x5c,0x0e,0x3f,0xe8,0xc8,0x1c,0xab,0xe0,0x72,0x94,0x81,0xda,0xb2,0x07,0x5f,0xe0,0x3d,0xbf,0x95,0x44,0x20,0x81,0xce,0xf1,0x2f,0x03,0x94,0xb8,0xae,0x51,0x00,0x39,0x47,0x60,0xd0,0x84,0x70,0x81,0xcb,0x44,0x9d,0x10,0x3a,0x58,0xce,0xe6,0x07,0x29,0x10,0x18,0xa0,0x50,0x88,0x76,0x02,0x22,0x07,0x49,0x8e,0x02,0x24,0x07,0x4e,0x0e,0x02,0x12,0x96,0x38,0x44,0x07,0x02,0x8f,0x1c,0x07,0x1c,0x4e,0x30,0x1c,0x10,0x3c,0x6c,0x13,0x80,0x38,0xc0,0xb0,0x80,0xf1,0x6e,0x90,0x1c,0x71,0x10,0xd7,0x49,0x81,0xc7,0x20,0x0f,0x17,0xe9,0x42,0x20,0x91,0x09,0xeb,0x24,0xe2,0x10,0x49,0x07,0x6f,0xff,0x80,0x56,0x88,0x1c,0xa2,0xae,0xd1,0x66,0x89,0xe0,0x68,0x11,0xb8,0x06,0xc0,0x2e,0x40,0x71,0x9a,0xc0,0x2b,0x00,0x73,0xc0,0x7a,0xe0,0x09,0x12,0x03,0x95,0x57,0xff,0x17,0x03,0x9c,0x03,0x57,0xaa,0x78,0x94,0x40,0xa6,0x35,0x5a,0xac,0x14,0x0e,0x9a,0xad,0x50,0xf8,0x41,0x05,0x00,0x83,0x55,0x14,0x06,0x07,0x18,0x54,0xa0,0x0e,0xb0,0x60,0x31,0xc0,0x00,}; +const uint8_t *_I_DolphinFirstStart7_61x51[] = {_I_DolphinFirstStart7_61x51_0}; + const uint8_t _I_DolphinFirstStart0_70x53_0[] = {0x01,0x00,0x5a,0x01,0x80,0x60,0x3f,0xf7,0xf0,0x42,0xf8,0x01,0x43,0x07,0x04,0x24,0x72,0x01,0xc0,0x9d,0x82,0x13,0xff,0xff,0xbd,0x70,0x20,0x20,0x72,0xe0,0x40,0x2a,0x11,0xdb,0x00,0x6c,0xec,0x10,0x0d,0x44,0x3a,0x71,0x0e,0x04,0x14,0x42,0x01,0x54,0x86,0xd3,0x27,0x02,0x44,0xd4,0x41,0xb0,0xf2,0x10,0x42,0x55,0x38,0x71,0x1b,0x10,0x18,0xa0,0x41,0x11,0xb1,0xc8,0x28,0x98,0x09,0xfc,0x00,0x72,0x35,0x49,0x8d,0x0b,0xc1,0x70,0xf0,0x10,0x4b,0x51,0x11,0xc2,0x6c,0x0a,0xa3,0x03,0x80,0x7f,0xbf,0xf3,0x08,0x46,0x60,0x90,0x30,0x60,0x50,0xd8,0x2c,0x11,0x0c,0x71,0x5c,0x60,0xf8,0x0f,0xcf,0x3f,0x81,0x80,0xa1,0x9e,0x86,0x0f,0xc0,0x82,0x64,0x30,0x3e,0x09,0x84,0x03,0xf1,0x03,0xa0,0x40,0xa4,0x18,0x39,0xfc,0x20,0x52,0x30,0x19,0x07,0xc6,0x8e,0x4a,0x18,0x22,0x74,0x60,0x1a,0x0f,0xc6,0x3c,0x60,0x5c,0x05,0x28,0xe4,0x3f,0x99,0xf8,0x22,0x28,0x7e,0x05,0x91,0xa8,0x7f,0x23,0xf0,0x59,0x00,0xac,0x63,0xe0,0x81,0xcf,0x4f,0xe0,0xb1,0x81,0x58,0xc3,0xc1,0x08,0x24,0x1f,0xf9,0x68,0x6a,0x1f,0xe9,0xff,0x16,0x02,0x34,0x13,0x50,0x82,0x0a,0xea,0x60,0x1f,0xf9,0xf0,0x41,0x05,0x1d,0x30,0x09,0x18,0x60,0x15,0xa3,0xe8,0x83,0x47,0xe0,0xec,0x2c,0xaf,0xf2,0x0e,0x08,0x1f,0xc1,0x18,0x60,0x1a,0xaf,0xc2,0x6c,0x89,0x62,0x03,0x19,0xad,0xe5,0x70,0x44,0x62,0x80,0x5a,0xa1,0x4f,0x63,0x23,0x0c,0x7a,0xaa,0x4d,0x11,0xe9,0x00,0x06,0x73,0xaa,0x25,0x0a,0x78,0xaf,0x90,0x09,0x25,0x54,0x56,0x5f,0x04,0x30,0xc0,0x64,0x7a,0xa1,0x11,0x7e,0x20,0x18,0x0f,0x3c,0x82,0xaa,0x04,0x18,0x0d,0xf8,0x16,0x33,0xe8,0x84,0xa8,0x08,0x3c,0x33,0x00,0xf0,0x20,0x71,0x08,0xa9,0x38,0x86,0x62,0x62,0x18,0x40,0x44,0x80,0x09,0x04,0x08,0x90,0x01,0x20,0x41,0x17,0x22,0x90,0x01,0x3e,0x00,0x76,0x80,0x1d,0x48,0x00,0x8d,0x91,0x00,0x34,0xf8,0x20,0xe2,0xa7,0x9c,0x06,0x5c,0x11,0x02,0x28,0x5d,0x91,0x35,0x48,0xaf,0xf8,0x04,0x3f,0xf9,0x88,0x20,0x01,}; const uint8_t *_I_DolphinFirstStart0_70x53[] = {_I_DolphinFirstStart0_70x53_0}; const uint8_t _I_DolphinFirstStart4_67x53_0[] = {0x01,0x00,0x1f,0x01,0x00,0x17,0xc3,0xfe,0x08,0x68,0x74,0x02,0x0e,0x07,0x4c,0x04,0x06,0x01,0x18,0x04,0x25,0x00,0x04,0x36,0x00,0x42,0x48,0x02,0x88,0x00,0x28,0x80,0x0c,0xa0,0x40,0x83,0x84,0x00,0xca,0x08,0x08,0x30,0x21,0x83,0x0c,0x2c,0x81,0xe3,0x04,0x20,0xc0,0x80,0x02,0x31,0x32,0x11,0x02,0x27,0x00,0x5d,0x40,0x45,0x87,0x90,0x3e,0x7c,0x00,0x43,0x84,0x4e,0x60,0x43,0x30,0x89,0x82,0x12,0x80,0x15,0x20,0x40,0x99,0xc8,0x22,0x7b,0x88,0x10,0x20,0x82,0x27,0x7c,0x82,0x9d,0x48,0x22,0x5f,0x0d,0xfc,0x08,0x10,0x41,0x12,0xf8,0x57,0xc2,0x28,0x30,0x1e,0x07,0x9e,0x06,0x87,0x25,0x79,0xc4,0x20,0x40,0x83,0x21,0x14,0x22,0x08,0x08,0x38,0x2a,0xb8,0xd9,0x47,0x0a,0x14,0x09,0xf0,0x54,0x47,0x1f,0x81,0x82,0x1a,0xde,0x8e,0x33,0xd1,0xc7,0x81,0x0f,0x0e,0x45,0x18,0x20,0xa1,0xe6,0xf2,0x10,0x89,0xa0,0x70,0x11,0x00,0x41,0x46,0x03,0x86,0x55,0x10,0x40,0xc1,0x82,0x25,0x20,0x04,0x11,0x94,0x80,0x43,0x10,0x84,0x01,0x46,0xc0,0xbd,0x38,0x40,0x20,0x8f,0x49,0x08,0xc4,0x1c,0xc8,0x22,0x50,0x38,0x20,0x20,0x86,0xe4,0x83,0x10,0x41,0x8b,0x87,0xf9,0x03,0x81,0xc0,0x81,0x05,0x81,0xc0,0x40,0xf3,0x90,0x60,0x41,0x70,0x2c,0x17,0x01,0xc0,0xc1,0x41,0x05,0x30,0x98,0x43,0x04,0x65,0x01,0x04,0x0c,0x32,0x38,0x91,0x18,0x04,0x14,0x10,0x38,0x18,0x1e,0xac,0x7c,0x41,0x11,0x88,0x5f,0xfc,0x17,0x55,0xa9,0x82,0x06,0x05,0xbc,0x85,0x02,0x08,0xc6,0x32,0x0f,0xe5,0x5e,0x1a,0x08,0x5c,0x06,0xaa,0x34,0x08,0x4a,0x06,0x02,0xab,0x75,0xf0,0x4f,0xc1,0x05,0x80,0x08,0x8e,0xab,0x7f,0xea,0x04,0x11,0x80,0x6a,0xa0,0x02,0x03,0x08,}; const uint8_t *_I_DolphinFirstStart4_67x53[] = {_I_DolphinFirstStart4_67x53_0}; -const uint8_t _I_DolphinFirstStart6_58x54_0[] = {0x01,0x00,0x21,0x01,0x00,0x0f,0xf2,0x7e,0x06,0x4c,0x04,0x0f,0x81,0x03,0x03,0x9d,0x80,0x04,0x30,0xc0,0x39,0xc6,0x00,0x43,0x30,0x03,0x9c,0x10,0x04,0x34,0x00,0x39,0xc0,0x84,0x44,0x07,0x38,0x08,0x0d,0x41,0x68,0x13,0x70,0x39,0x08,0xd0,0x56,0xa1,0xd1,0x03,0x94,0x80,0x04,0x30,0x68,0x04,0x20,0x0e,0x84,0x91,0x03,0xa9,0x64,0x62,0x80,0x41,0x88,0x40,0x3f,0xc6,0xf1,0xfe,0x43,0xc0,0xe3,0x80,0xff,0xff,0xe0,0x3f,0xf8,0xf8,0x1c,0x78,0x18,0x1f,0xfe,0x0f,0x02,0x12,0x18,0x47,0x03,0x82,0x10,0x1e,0x08,0x1c,0xf5,0x60,0x71,0xd4,0x81,0xcf,0xab,0xff,0xd5,0xf5,0xc0,0xe3,0x04,0xe0,0x03,0x86,0xae,0x27,0x28,0x27,0x40,0x0e,0x21,0x91,0x03,0x96,0x80,0x0e,0x34,0x18,0x79,0x28,0x60,0x95,0x00,0x38,0xf8,0x20,0x27,0xd1,0x82,0x6a,0x03,0xc3,0x1c,0x39,0x94,0x0a,0xa1,0xc0,0xc5,0x2f,0xca,0x05,0x02,0x90,0x24,0x56,0x04,0x68,0x10,0x01,0x4f,0x80,0xea,0x5b,0x10,0x38,0x83,0x8d,0xa0,0x30,0x30,0x38,0xa3,0x09,0xc0,0x20,0xf2,0x03,0x90,0xc0,0x46,0xe2,0x91,0x2f,0x80,0xfc,0xe0,0x1e,0x08,0x02,0x54,0x47,0x62,0x27,0x2f,0xfb,0x14,0xdc,0xc6,0xb5,0x30,0x38,0x8b,0x05,0x6a,0x60,0x01,0x89,0x00,0xc8,0x16,0x50,0x29,0x10,0x1c,0x8d,0x25,0x05,0xa1,0x15,0xc9,0xfe,0x50,0xaa,0x08,0x10,0x67,0x01,0x22,0x8a,0xe0,0x60,0xe5,0xf2,0x07,0x8e,0xa8,0xb0,0x49,0xe1,0x00,0x0d,0xd4,0x68,0x5a,0x00,0x39,0x46,0x88,0x84,0x07,0x30,0xe8,0x81,0xc6,0x40,0x4d,0x11,0x91,0x17,0x06,0x40,0x65,0x11,0x51,0x01,0xc6,0x81,0x04,0x32,0x18,0x1e,0x92,0x64,0x00,0x11,0x68,0x81,0xd6,0xa0,0x07,0x16,0x22,0x6b,0x0a,0x82,0x07,0x3f,0x05,0x4d,0xdc,0x24,0x21,}; -const uint8_t *_I_DolphinFirstStart6_58x54[] = {_I_DolphinFirstStart6_58x54_0}; - -const uint8_t _I_DolphinFirstStart1_59x53_0[] = {0x01,0x00,0x1e,0x01,0x00,0x0e,0x03,0xfe,0x07,0x5b,0x84,0x02,0x06,0x07,0x48,0x64,0x02,0x08,0x07,0x48,0x14,0x02,0x10,0x07,0x48,0x0c,0x03,0x21,0x3f,0x13,0x18,0x84,0xa8,0x00,0x75,0x8c,0x00,0xca,0x00,0x0b,0x28,0x20,0x1d,0xa0,0x59,0xe0,0x39,0x48,0x07,0x03,0x81,0xd5,0x81,0xd6,0x81,0x55,0x8c,0x01,0xc6,0x21,0x00,0x87,0x68,0x25,0x52,0x40,0x39,0x7c,0x21,0xf5,0x08,0xa8,0x1d,0x20,0xfa,0x88,0x70,0x1c,0xfd,0x10,0x3a,0xa4,0x1f,0x88,0x54,0x18,0x85,0x52,0x09,0xbe,0x81,0xc1,0x0c,0x83,0x10,0x94,0x40,0x39,0xf0,0x19,0x21,0xc8,0x62,0x12,0x0c,0x04,0x0e,0x0c,0x07,0x38,0x07,0x86,0x07,0x18,0x03,0x94,0xc2,0x01,0x9e,0x81,0xca,0x38,0x89,0x21,0x0f,0x0c,0x03,0xf9,0x27,0x13,0x94,0xd0,0xb6,0x70,0x20,0x38,0xda,0x80,0xe5,0x10,0x03,0x95,0x59,0x54,0x70,0x10,0x38,0xda,0xc0,0xc3,0xfe,0xc1,0xab,0x0b,0xaa,0x2a,0x1c,0x05,0x81,0x58,0x38,0x09,0xd0,0x5c,0xa3,0xe0,0x72,0x86,0xae,0x8d,0x40,0x34,0x06,0xa1,0xc0,0xc0,0xe3,0xc0,0x65,0x1c,0x19,0x58,0x29,0xe1,0x00,0x14,0x28,0x0a,0x26,0x61,0x00,0x15,0x58,0x0a,0x2e,0x34,0xd6,0x42,0x9e,0x6b,0x54,0x82,0x92,0x08,0x1e,0x63,0x41,0x1d,0x0a,0x88,0x60,0x1d,0x42,0x11,0x5c,0x01,0xe5,0x3c,0x03,0x97,0x30,0x0e,0x42,0x42,0x80,0xd0,0x82,0xe4,0x07,0x28,0x17,0x10,0x1e,0xb0,0x4a,0x20,0x3d,0x61,0x1a,0x80,0x79,0x0f,0x0a,0x21,0x70,0x07,0x90,0x1c,0xa4,0x1a,0x00,0x7a,0xd0,0x0e,0x42,0x34,0x20,0x10,0xe0,0x00,0xed,0x00,0xa1,0x82,0xc8,0xc6,0x74,0x40,0xd9,0x01,0xce,0x84,0x07,0x69,0x10,0xcc,0x80,0xe7,0x5c,0x03,0xb4,0xa8,0x96,0x40,0x73,0x8a,0x96,0xc8,0x0c,0x40,}; -const uint8_t *_I_DolphinFirstStart1_59x53[] = {_I_DolphinFirstStart1_59x53_0}; - -const uint8_t _I_ArrowDownFilled_14x15_0[] = {0x00,0xF8,0x07,0x08,0x04,0xE8,0x05,0x68,0x05,0xA8,0x05,0x68,0x05,0xA8,0x05,0x6F,0x3D,0xA1,0x21,0xFA,0x17,0xF4,0x0B,0xE8,0x05,0xD0,0x02,0x20,0x01,0xC0,0x00,}; -const uint8_t *_I_ArrowDownFilled_14x15[] = {_I_ArrowDownFilled_14x15_0}; - const uint8_t _I_ArrowUpEmpty_14x15_0[] = {0x01,0x00,0x18,0x00,0xe0,0x40,0x24,0x10,0x18,0x84,0x0a,0x11,0x04,0x82,0x42,0x20,0x51,0x08,0x0c,0x82,0x1f,0x3c,0x04,0x88,0x06,0x7f,0x10,0x70,}; const uint8_t *_I_ArrowUpEmpty_14x15[] = {_I_ArrowUpEmpty_14x15_0}; const uint8_t _I_ArrowUpFilled_14x15_0[] = {0x00,0xC0,0x00,0x20,0x01,0xD0,0x02,0xE8,0x05,0xF4,0x0B,0xFA,0x17,0x61,0x21,0xAF,0x3D,0x68,0x05,0xA8,0x05,0x68,0x05,0xA8,0x05,0xE8,0x05,0x08,0x04,0xF8,0x07,}; const uint8_t *_I_ArrowUpFilled_14x15[] = {_I_ArrowUpFilled_14x15_0}; +const uint8_t _I_ArrowDownFilled_14x15_0[] = {0x00,0xF8,0x07,0x08,0x04,0xE8,0x05,0x68,0x05,0xA8,0x05,0x68,0x05,0xA8,0x05,0x6F,0x3D,0xA1,0x21,0xFA,0x17,0xF4,0x0B,0xE8,0x05,0xD0,0x02,0x20,0x01,0xC0,0x00,}; +const uint8_t *_I_ArrowDownFilled_14x15[] = {_I_ArrowDownFilled_14x15_0}; + const uint8_t _I_ArrowDownEmpty_14x15_0[] = {0x01,0x00,0x17,0x00,0xfc,0x41,0xe1,0x10,0x40,0x0c,0xc3,0xe7,0x90,0x19,0x04,0x0a,0x20,0x08,0x10,0x48,0xc4,0x20,0x52,0x08,0x0f,0x02,0x00,}; const uint8_t *_I_ArrowDownEmpty_14x15[] = {_I_ArrowDownEmpty_14x15_0}; -const uint8_t _I_DoorLocked_10x56_0[] = {0x01,0x00,0x4e,0x00,0x86,0x40,0x25,0xb0,0x0b,0x6c,0x03,0x9b,0x00,0xc6,0xc0,0x65,0x90,0x10,0x3a,0xc3,0x20,0x31,0xc8,0x04,0xe2,0x01,0x70,0x80,0x78,0x20,0x1c,0x48,0x07,0x22,0x01,0xd0,0x00,0xf0,0x44,0x68,0x90,0x09,0x04,0x02,0x21,0x00,0x84,0x40,0x25,0x80,0x12,0x1e,0x88,0x14,0xc0,0x2e,0x0d,0x11,0xca,0xf8,0x60,0x1c,0x38,0x07,0x1a,0x05,0xcc,0x80,0x72,0x60,0x5c,0x38,0x10,0x1c,0xf9,0x10,0x2e,0x00,0x05,0x60,0x00,0x11,}; -const uint8_t *_I_DoorLocked_10x56[] = {_I_DoorLocked_10x56_0}; - const uint8_t _I_PassportBottom_128x17_0[] = {0x01,0x00,0x5e,0x00,0x96,0x01,0x97,0xe1,0xff,0x00,0x2e,0x3e,0x68,0x0f,0x5a,0xc5,0x54,0x00,0xb9,0x50,0xfb,0x6a,0x35,0x40,0x05,0xcd,0x4e,0x03,0xfd,0x30,0x0f,0xf8,0x7f,0xa0,0x81,0xfe,0xf9,0x1b,0xfb,0xf3,0x01,0x47,0x66,0x02,0x1b,0x03,0x07,0xe7,0x02,0x0b,0x02,0x07,0xe5,0x82,0x0b,0xf2,0x1c,0xb0,0x01,0x67,0xf0,0x5f,0xd0,0x3f,0x23,0xf0,0x9b,0xc9,0xe5,0x80,0x03,0xd5,0xc0,0x00,0x86,0x01,0xf3,0xe6,0x1e,0x58,0x00,0x36,0xa8,0x06,0xac,0x04,0x30,0x6c,0x30,0xee,0x60,0x1f,0xe0,0x10,0xff,0x0d,0xfb,0x00,}; const uint8_t *_I_PassportBottom_128x17[] = {_I_PassportBottom_128x17_0}; -const uint8_t _I_PassportLeft_6x47_0[] = {0x01,0x00,0x1c,0x00,0x9e,0x40,0xa3,0x32,0x59,0x2c,0x66,0x03,0x01,0x82,0xc2,0x62,0x32,0x50,0x16,0xc8,0x60,0x30,0x28,0x24,0x32,0x39,0x3c,0x9e,0x4d,0x25,0x80,0x1a,}; -const uint8_t *_I_PassportLeft_6x47[] = {_I_PassportLeft_6x47_0}; - const uint8_t _I_DoorLeft_70x55_0[] = {0x01,0x00,0x19,0x01,0x00,0x2c,0x32,0x01,0x03,0x04,0x2c,0x18,0x10,0xf0,0x40,0x47,0x82,0x06,0x81,0x03,0xff,0x80,0x08,0x1a,0x20,0x82,0x15,0x28,0x21,0x87,0x82,0x08,0x6f,0xc0,0xb1,0xe6,0x10,0x10,0x8b,0x46,0x20,0x43,0x55,0x8f,0x82,0x10,0x32,0x73,0x0a,0x09,0x89,0x6c,0x1e,0x09,0x00,0x18,0x60,0xf0,0x0c,0x84,0x93,0x82,0x03,0x18,0x0c,0x02,0x1d,0x00,0x90,0x52,0x70,0x50,0x1e,0x00,0x58,0x63,0x90,0x0a,0x06,0x4a,0x09,0x03,0xb0,0x02,0x06,0x70,0x62,0x49,0xf8,0x0c,0x66,0x3f,0xf0,0x41,0x63,0x04,0x43,0x00,0x99,0x60,0x00,0x85,0xc8,0x06,0x14,0xd0,0x80,0x3f,0xc8,0x0d,0xb8,0x10,0x70,0xf8,0x34,0x13,0x03,0x39,0x04,0x1c,0x42,0x19,0xf8,0xa0,0xc2,0x01,0x07,0xef,0x02,0x8c,0x80,0x10,0x9d,0x00,0x43,0xec,0x00,0xa3,0x10,0x04,0x25,0xce,0x19,0xfc,0x88,0x82,0x12,0x0c,0x35,0x10,0x42,0x4c,0xa1,0x90,0x3f,0xc0,0x21,0x22,0x39,0x82,0xc8,0x88,0xd2,0x11,0xf0,0x01,0x88,0xd5,0x18,0xe2,0x08,0x68,0x10,0x0c,0xa8,0x00,0x83,0x81,0xcc,0xd5,0xc3,0x80,0x84,0x82,0x0e,0xcc,0xc0,0x15,0x79,0x02,0x0b,0x98,0xf8,0x11,0x88,0x82,0x0f,0x31,0x19,0x02,0x08,0x2c,0x9f,0x6a,0x1d,0x20,0x41,0x31,0x4c,0x10,0x8d,0x73,0x04,0x23,0xa4,0xc4,0x6c,0xde,0x20,0x42,0xcc,0x01,0x07,0x07,0xff,0x80,0x06,0x3e,0x08,0x38,0x70,0x20,0xa1,0xe0,0x83,0x8e,0x01,0x0c,0xf0,0x73,0x80,0x43,0x70,0x05,0x08,0x00,0x2c,0x04,0xc4,0x46,0x53,0x09,0x98,0x24,0x80,0x65,0x80,0xb0,0xd9,0x84,0x65,0x32,0x06,0x17,0x0f,0x98,0x23,0x63,0xe1,0x88,0xc4,0x08,0x5f,0xc1,0x30,0x9d,0x84,0x4e,0x66,0x94,0x11,0x98,0x75,0x26,0x00,}; const uint8_t *_I_DoorLeft_70x55[] = {_I_DoorLeft_70x55_0}; -const uint8_t _I_LockPopup_100x49_0[] = {0x01,0x00,0x37,0x01,0xfc,0x7f,0xc0,0x13,0x01,0xfe,0x03,0x2a,0x07,0x06,0x12,0xd4,0x1a,0x06,0x0c,0xa8,0x60,0x33,0xe0,0x12,0x08,0x40,0x32,0x3f,0xd0,0x70,0x64,0xe0,0x20,0x31,0x8a,0x00,0x32,0x2c,0x10,0x0b,0x00,0x32,0x62,0x10,0x0c,0x06,0x00,0x19,0x00,0x82,0xc0,0x83,0x22,0x08,0x04,0x18,0x11,0x6a,0x01,0x25,0x02,0x84,0x83,0x1e,0x02,0x04,0x10,0xe1,0x03,0x1e,0x3c,0x0c,0x9c,0x1c,0x02,0x43,0x00,0x84,0x4f,0xc1,0x8f,0x80,0xaf,0x40,0x39,0x14,0x00,0x63,0xd0,0x36,0xf0,0x09,0xc6,0x00,0x18,0xd4,0x3a,0x06,0x9c,0x08,0x20,0xc9,0xdf,0xc0,0x20,0x7f,0x00,0x65,0x40,0x3f,0x80,0xc7,0xd0,0x10,0x06,0x01,0x7f,0x06,0x34,0x8e,0xa1,0x3d,0x80,0x70,0x0b,0x4f,0x23,0xd0,0x50,0xa0,0x1f,0x08,0x78,0x66,0x11,0xe3,0xfc,0x83,0x83,0x1e,0x40,0x0c,0x1f,0xfb,0xec,0x41,0x8c,0x03,0x1e,0x07,0x00,0x4d,0x10,0x0a,0x04,0xc0,0x9b,0x30,0x0c,0x1f,0xff,0xff,0x9f,0x06,0x3e,0x01,0x80,0x48,0xe7,0x99,0x83,0x0d,0x6a,0xe0,0xc4,0x90,0x03,0x1a,0x76,0x0c,0x38,0xe0,0x34,0x45,0x25,0x02,0x06,0x0d,0xe0,0x18,0x3c,0x08,0x19,0x40,0x78,0x00,0xc1,0x81,0xc3,0x27,0xf8,0x48,0x26,0x82,0x7d,0x00,0xfc,0x40,0xfc,0x10,0xfc,0x04,0xfc,0x18,0x30,0x28,0x7d,0x02,0x3f,0x00,0x98,0x41,0x38,0x31,0x08,0x25,0x0e,0x19,0x1f,0x81,0x42,0x70,0x11,0xa2,0x08,0xe2,0x30,0x72,0x08,0x76,0x0a,0x19,0x0f,0x85,0x42,0x60,0x11,0x51,0x78,0xc2,0x20,0x32,0x08,0x26,0x00,0x18,0x91,0x00,0x60,0x91,0x44,0x08,0x34,0x08,0x64,0x1f,0xe4,0x07,0x3f,0x84,0x0d,0x58,0x44,0x01,0x83,0xdc,0x60,0x43,0xe1,0x39,0xa9,0xd0,0x60,0x70,0x16,0x78,0xca,0x01,0x8f,0x83,0x3d,0x10,0x33,0x29,0x00,0xc7,0xa1,0x83,0x3f,0x10,0x0c,0x79,0x30,0x32,0xa0,0xdf,0xc7,0xa0,0x80,0x22,0x07,0xf8,0x06,0x54,0x04,}; -const uint8_t *_I_LockPopup_100x49[] = {_I_LockPopup_100x49_0}; - const uint8_t _I_DoorRight_70x55_0[] = {0x01,0x00,0x16,0x01,0x81,0xcc,0x01,0x0f,0x60,0x04,0x3f,0x00,0x10,0xf8,0x08,0x0c,0x02,0x05,0x01,0x84,0x02,0x06,0x26,0x0a,0x10,0x8a,0xcc,0xe0,0x1d,0x68,0xe0,0x18,0xab,0xd0,0x0b,0x18,0x10,0x46,0xe6,0x16,0x1e,0x18,0x10,0x46,0xe4,0x28,0x2c,0x98,0x14,0x68,0x00,0x21,0x1d,0x10,0x8c,0x40,0x02,0x0e,0x10,0xa1,0x08,0xc8,0x40,0x42,0x62,0x11,0x94,0x03,0xfd,0xff,0x00,0x0c,0xff,0x0c,0x08,0x28,0x60,0xe4,0xc0,0x85,0x00,0x83,0x00,0x87,0xf1,0x00,0x8c,0x02,0x0b,0x07,0x24,0x84,0xff,0x04,0xc7,0x80,0xa0,0xe4,0xa0,0x81,0x41,0x04,0x17,0x02,0x41,0x49,0x81,0x0e,0x10,0xb2,0xa0,0x82,0x0e,0x9f,0xfc,0x0a,0x62,0xf2,0xc0,0x03,0x92,0xf0,0x08,0x2d,0x78,0x20,0xff,0x02,0x01,0x08,0xae,0x60,0x64,0x38,0x0d,0xb0,0x8d,0x08,0x82,0x11,0x58,0xc4,0x13,0xc0,0x35,0x68,0x62,0x68,0x81,0x09,0x08,0x84,0x40,0x81,0x0d,0x18,0x69,0x10,0x47,0x44,0x66,0x5f,0x21,0xa9,0x29,0x94,0x10,0x2f,0x23,0x53,0x14,0x60,0x42,0x3c,0x08,0xfc,0x02,0x2c,0x62,0x23,0x58,0xd0,0x22,0x00,0x83,0x3e,0x98,0x44,0x43,0x46,0x22,0x30,0x89,0xce,0x01,0x0f,0x70,0x04,0x3f,0x81,0x8a,0x3c,0x21,0xaa,0x70,0x1a,0xe3,0x44,0x1a,0xa6,0x01,0xd2,0x38,0x90,0x8a,0x40,0x20,0xe5,0x96,0x80,0x43,0x81,0x06,0x6b,0x28,0x07,0xf3,0xfe,0x00,0x19,0xf9,0x34,0xc1,0x08,0x8f,0x20,0xf1,0x3e,0x16,0x00,0xa8,0x19,0x00,0x10,0x76,0x03,0xe2,0x3e,0x90,0x45,0x38,0x01,0x42,0x05,0x88,0x44,0x67,0x15,0x70,0x41,0x38,0x04,0x10,0x24,0x03,0x00,0x10,0x20,0x4a,0x46,0xe9,0x46,0xe1,0x04,0x50,0x66,0x40,0x85,0x19,0x98,0x00,0xc0,}; const uint8_t *_I_DoorRight_70x55[] = {_I_DoorRight_70x55_0}; -const uint8_t _I_IrdaArrowDown_4x8_0[] = {0x00,0xFF,0x7E,0x3C,0x18,}; -const uint8_t *_I_IrdaArrowDown_4x8[] = {_I_IrdaArrowDown_4x8_0}; +const uint8_t _I_DoorLocked_10x56_0[] = {0x01,0x00,0x4e,0x00,0x86,0x40,0x25,0xb0,0x0b,0x6c,0x03,0x9b,0x00,0xc6,0xc0,0x65,0x90,0x10,0x3a,0xc3,0x20,0x31,0xc8,0x04,0xe2,0x01,0x70,0x80,0x78,0x20,0x1c,0x48,0x07,0x22,0x01,0xd0,0x00,0xf0,0x44,0x68,0x90,0x09,0x04,0x02,0x21,0x00,0x84,0x40,0x25,0x80,0x12,0x1e,0x88,0x14,0xc0,0x2e,0x0d,0x11,0xca,0xf8,0x60,0x1c,0x38,0x07,0x1a,0x05,0xcc,0x80,0x72,0x60,0x5c,0x38,0x10,0x1c,0xf9,0x10,0x2e,0x00,0x05,0x60,0x00,0x11,}; +const uint8_t *_I_DoorLocked_10x56[] = {_I_DoorLocked_10x56_0}; -const uint8_t _I_Power_25x27_0[] = {0x01,0x00,0x54,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x30,0x18,0x80,0x0c,0xa7,0x00,0x35,0xc0,0xce,0x60,0x70,0x1e,0x0c,0xe6,0x0f,0x01,0xf0,0xce,0x21,0xd0,0x1b,0x0c,0xe2,0x18,0x03,0x58,0x80,0x0c,0xa0,0x00,0x39,0xf0,0xc0,0x03,0x63,0xc1,0x80,0x88,0xc7,0x03,0x83,0x15,0x8c,0x07,0xfe,0x02,0x18,0x0d,0xf0,0x76,0x44,0x73,0x01,0x94,0x0c,0xa6,0x30,0x18,0x34,0x03,0x81,0x00,0xfe,0x7f,0xef,0xe6,0x74,}; -const uint8_t *_I_Power_25x27[] = {_I_Power_25x27_0}; +const uint8_t _I_PassportLeft_6x47_0[] = {0x01,0x00,0x1c,0x00,0x9e,0x40,0xa3,0x32,0x59,0x2c,0x66,0x03,0x01,0x82,0xc2,0x62,0x32,0x50,0x16,0xc8,0x60,0x30,0x28,0x24,0x32,0x39,0x3c,0x9e,0x4d,0x25,0x80,0x1a,}; +const uint8_t *_I_PassportLeft_6x47[] = {_I_PassportLeft_6x47_0}; -const uint8_t _I_Mute_25x27_0[] = {0x01,0x00,0x51,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x20,0x31,0x81,0xc0,0x64,0x38,0x08,0xa4,0x06,0x83,0x40,0x86,0x40,0x70,0x32,0x08,0x20,0x3c,0x63,0xf0,0x60,0x38,0xc0,0xa0,0xa0,0x31,0xc2,0x02,0xc7,0x03,0x48,0x01,0x94,0xc0,0x06,0xc0,0xb3,0x09,0x98,0x6c,0x84,0x68,0x2b,0x21,0x99,0x8e,0xcc,0x86,0x64,0xb3,0x81,0x94,0xc6,0x03,0x06,0x80,0x70,0x20,0x1f,0xcf,0xfd,0xfc,0xce,0x80,}; -const uint8_t *_I_Mute_25x27[] = {_I_Mute_25x27_0}; +const uint8_t _I_LockPopup_100x49_0[] = {0x01,0x00,0x37,0x01,0xfc,0x7f,0xc0,0x13,0x01,0xfe,0x03,0x2a,0x07,0x06,0x12,0xd4,0x1a,0x06,0x0c,0xa8,0x60,0x33,0xe0,0x12,0x08,0x40,0x32,0x3f,0xd0,0x70,0x64,0xe0,0x20,0x31,0x8a,0x00,0x32,0x2c,0x10,0x0b,0x00,0x32,0x62,0x10,0x0c,0x06,0x00,0x19,0x00,0x82,0xc0,0x83,0x22,0x08,0x04,0x18,0x11,0x6a,0x01,0x25,0x02,0x84,0x83,0x1e,0x02,0x04,0x10,0xe1,0x03,0x1e,0x3c,0x0c,0x9c,0x1c,0x02,0x43,0x00,0x84,0x4f,0xc1,0x8f,0x80,0xaf,0x40,0x39,0x14,0x00,0x63,0xd0,0x36,0xf0,0x09,0xc6,0x00,0x18,0xd4,0x3a,0x06,0x9c,0x08,0x20,0xc9,0xdf,0xc0,0x20,0x7f,0x00,0x65,0x40,0x3f,0x80,0xc7,0xd0,0x10,0x06,0x01,0x7f,0x06,0x34,0x8e,0xa1,0x3d,0x80,0x70,0x0b,0x4f,0x23,0xd0,0x50,0xa0,0x1f,0x08,0x78,0x66,0x11,0xe3,0xfc,0x83,0x83,0x1e,0x40,0x0c,0x1f,0xfb,0xec,0x41,0x8c,0x03,0x1e,0x07,0x00,0x4d,0x10,0x0a,0x04,0xc0,0x9b,0x30,0x0c,0x1f,0xff,0xff,0x9f,0x06,0x3e,0x01,0x80,0x48,0xe7,0x99,0x83,0x0d,0x6a,0xe0,0xc4,0x90,0x03,0x1a,0x76,0x0c,0x38,0xe0,0x34,0x45,0x25,0x02,0x06,0x0d,0xe0,0x18,0x3c,0x08,0x19,0x40,0x78,0x00,0xc1,0x81,0xc3,0x27,0xf8,0x48,0x26,0x82,0x7d,0x00,0xfc,0x40,0xfc,0x10,0xfc,0x04,0xfc,0x18,0x30,0x28,0x7d,0x02,0x3f,0x00,0x98,0x41,0x38,0x31,0x08,0x25,0x0e,0x19,0x1f,0x81,0x42,0x70,0x11,0xa2,0x08,0xe2,0x30,0x72,0x08,0x76,0x0a,0x19,0x0f,0x85,0x42,0x60,0x11,0x51,0x78,0xc2,0x20,0x32,0x08,0x26,0x00,0x18,0x91,0x00,0x60,0x91,0x44,0x08,0x34,0x08,0x64,0x1f,0xe4,0x07,0x3f,0x84,0x0d,0x58,0x44,0x01,0x83,0xdc,0x60,0x43,0xe1,0x39,0xa9,0xd0,0x60,0x70,0x16,0x78,0xca,0x01,0x8f,0x83,0x3d,0x10,0x33,0x29,0x00,0xc7,0xa1,0x83,0x3f,0x10,0x0c,0x79,0x30,0x32,0xa0,0xdf,0xc7,0xa0,0x80,0x22,0x07,0xf8,0x06,0x54,0x04,}; +const uint8_t *_I_LockPopup_100x49[] = {_I_LockPopup_100x49_0}; const uint8_t _I_Down_hvr_25x27_0[] = {0x01,0x00,0x3a,0x00,0xfc,0x7f,0xe7,0xf0,0x0f,0xe7,0xfe,0xff,0x00,0xff,0x7f,0xff,0xf0,0x00,0x10,0xff,0xe0,0x20,0x3f,0x01,0x9c,0x3e,0x01,0xe0,0x01,0xa4,0x7e,0x01,0xf0,0x80,0x8b,0x47,0xf1,0x01,0x16,0x8f,0xf0,0x2e,0x23,0x11,0x01,0x88,0x04,0xf0,0x60,0x32,0xe3,0x80,0xcb,0xde,0x37,0xf0,0x1a,0x95,0xcc,0xbe,0x66,0x73,}; const uint8_t *_I_Down_hvr_25x27[] = {_I_Down_hvr_25x27_0}; -const uint8_t _I_Vol_up_25x27_0[] = {0x01,0x00,0x2f,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x20,0x38,0x88,0x00,0xfc,0x06,0xbc,0x1f,0xfc,0x1c,0x06,0x81,0x7f,0x01,0xc1,0x0e,0xa0,0x65,0x31,0x80,0xc1,0xa0,0x1c,0x08,0x07,0xf3,0xff,0x7f,0x33,0xa0,}; -const uint8_t *_I_Vol_up_25x27[] = {_I_Vol_up_25x27_0}; - -const uint8_t _I_IrdaLearnShort_128x31_0[] = {0x01,0x00,0x10,0x01,0x00,0x47,0xfb,0xfe,0x00,0x38,0x38,0x3e,0x20,0x20,0x54,0x84,0x03,0x9f,0xc0,0x06,0x58,0x80,0x3d,0xf2,0x00,0x65,0x90,0x03,0xde,0x90,0x06,0x5a,0x07,0xc0,0x8a,0x70,0x1a,0x04,0x02,0x51,0x80,0x03,0x94,0x02,0x3f,0x40,0x20,0x24,0x0b,0x01,0x00,0x92,0x70,0x35,0x40,0x01,0xe0,0xdf,0xf0,0x10,0x40,0x71,0x58,0x20,0x90,0x88,0x0c,0x4a,0x81,0x55,0x00,0x0f,0x87,0xf7,0x00,0x82,0x43,0x36,0x16,0xdc,0x9c,0x12,0x21,0x01,0x85,0x70,0x3f,0xc1,0xf1,0xf8,0xfc,0x60,0x20,0xf5,0x90,0x40,0xa1,0x34,0x08,0x18,0x7c,0x7e,0x24,0x91,0x07,0x8c,0xc0,0x5e,0x52,0x28,0x14,0x17,0x81,0x01,0x0f,0x8f,0xe7,0xe3,0x03,0x1f,0x8e,0x02,0xdb,0x03,0x8e,0x49,0x20,0x50,0x2e,0x04,0x72,0xbd,0x55,0xdc,0xeb,0xa0,0x7c,0x4f,0x68,0xbc,0x60,0x72,0x40,0x79,0x50,0x23,0x9a,0x6d,0x56,0x66,0x5c,0x0f,0x21,0x78,0x9b,0x04,0x1e,0x28,0x21,0x8e,0x5c,0x43,0xe6,0x2f,0x10,0xf9,0x0b,0xc7,0x04,0x99,0x18,0x06,0xe0,0x7e,0x56,0x32,0x78,0x8f,0xc4,0x08,0x32,0x20,0x79,0x48,0x2b,0x85,0xf2,0xf8,0x83,0xc4,0x5c,0x3f,0x03,0x78,0xd0,0x81,0xe3,0xc0,0xdf,0x9f,0xcb,0xf3,0x04,0xc6,0x7d,0xfb,0xdf,0x34,0x78,0xd0,0x45,0xe5,0x7e,0x4f,0x97,0xe2,0x09,0x80,0x07,0x88,0xbc,0x61,0x00,0xf3,0xd8,0x2f,0xcb,0xe0,0xcf,0x60,0x68,0xd0,0x30,0x15,0xfa,0xac,0x36,0x3f,0x60,0x77,0xb3,0x80,0x5d,0xe6,0x4b,0x20,0x03,0x03,0xc4,0x01,0xd0,0x10,0x7f,0x40,0x81,0xfc,0xa7,0x10,0x06,0x99,0xd0,0x01,0x51,0x00,0x7f,0x48,0x01,0xfd,0xc0,0x43,0x98,0x00,0x8e,0xfe,0x00,0xf0,}; -const uint8_t *_I_IrdaLearnShort_128x31[] = {_I_IrdaLearnShort_128x31_0}; - -const uint8_t _I_Up_25x27_0[] = {0x01,0x00,0x44,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x20,0x3c,0x88,0x00,0xca,0x70,0x03,0x2b,0xe0,0x0c,0xbf,0xc0,0x32,0xff,0x80,0x87,0x03,0xff,0x81,0xc0,0x78,0x3f,0xf8,0x3c,0x07,0xc3,0xff,0x87,0xc0,0x7e,0x3f,0xf8,0xf8,0x0d,0x06,0xfe,0x03,0x78,0x19,0x4c,0x60,0x30,0x68,0x07,0x02,0x01,0xfc,0xff,0xdf,0xcc,0xe8,}; -const uint8_t *_I_Up_25x27[] = {_I_Up_25x27_0}; - const uint8_t _I_Vol_down_hvr_25x27_0[] = {0x01,0x00,0x23,0x00,0xfc,0x7f,0xe7,0xf0,0x0f,0xe7,0xfe,0xff,0x00,0xff,0x7f,0xff,0xf0,0x00,0x10,0xff,0xe0,0x20,0x3f,0x01,0xf8,0xb4,0x7f,0x00,0x34,0x0b,0xf8,0x0f,0xc0,0x6e,0x57,0x32,0xf9,0x99,0xcc,}; const uint8_t *_I_Vol_down_hvr_25x27[] = {_I_Vol_down_hvr_25x27_0}; -const uint8_t _I_Vol_down_25x27_0[] = {0x01,0x00,0x2c,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x20,0x3f,0x01,0xff,0x07,0xff,0x07,0x01,0xa0,0x5f,0xc0,0x7e,0x03,0x38,0x19,0x4c,0x60,0x30,0x68,0x07,0x02,0x01,0xfc,0xff,0xdf,0xcc,0xe8,}; -const uint8_t *_I_Vol_down_25x27[] = {_I_Vol_down_25x27_0}; - -const uint8_t _I_Vol_up_hvr_25x27_0[] = {0x01,0x00,0x28,0x00,0xfc,0x7f,0xe7,0xf0,0x0f,0xe7,0xfe,0xff,0x00,0xff,0x7f,0xff,0xf0,0x00,0x10,0xff,0xe0,0x20,0x38,0xf7,0x80,0xfc,0x06,0xa2,0xd1,0xfc,0x00,0xd0,0x2f,0xe0,0x38,0x21,0xd8,0x0c,0x8a,0xe6,0x5f,0x33,0x39,0x80,}; -const uint8_t *_I_Vol_up_hvr_25x27[] = {_I_Vol_up_hvr_25x27_0}; - -const uint8_t _I_Fill_marker_7x7_0[] = {0x00,0x1C,0x32,0x6F,0x5F,0x7F,0x3E,0x1C,}; -const uint8_t *_I_Fill_marker_7x7[] = {_I_Fill_marker_7x7_0}; - -const uint8_t _I_Up_hvr_25x27_0[] = {0x01,0x00,0x39,0x00,0xfc,0x7f,0xe7,0xf0,0x0f,0xe7,0xfe,0xff,0x00,0xff,0x7f,0xff,0xf0,0x00,0x10,0xff,0xe0,0x20,0x3c,0xf7,0x80,0xcb,0x8e,0x03,0x2c,0x18,0x0c,0x80,0x26,0x25,0x18,0x08,0xa4,0x7f,0x90,0x11,0x88,0xfe,0x20,0x31,0xf8,0x07,0xc2,0x03,0x0f,0x80,0x78,0x00,0x68,0x37,0xf0,0x1d,0x95,0xcc,0xbe,0x66,0x73,}; -const uint8_t *_I_Up_hvr_25x27[] = {_I_Up_hvr_25x27_0}; - -const uint8_t _I_IrdaArrowUp_4x8_0[] = {0x00,0x18,0x3C,0x7E,0xFF,}; -const uint8_t *_I_IrdaArrowUp_4x8[] = {_I_IrdaArrowUp_4x8_0}; - const uint8_t _I_Down_25x27_0[] = {0x01,0x00,0x46,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x20,0x3f,0x01,0x9f,0xc7,0xff,0x1f,0x01,0xa7,0x87,0xff,0x0f,0x80,0xf0,0x7f,0xf0,0x78,0x0e,0x07,0xff,0x03,0x0b,0x8f,0xfc,0x04,0x30,0x1f,0xf0,0x7c,0xaf,0x80,0x32,0x9c,0x00,0xca,0x20,0x37,0xf0,0x18,0xc0,0xca,0x63,0x01,0x83,0x40,0x38,0x10,0x0f,0xe7,0xfe,0xfe,0x67,0x40,}; const uint8_t *_I_Down_25x27[] = {_I_Down_25x27_0}; -const uint8_t _I_DolphinReadingSuccess_59x63_0[] = {0x01,0x00,0x19,0x01,0x00,0x1d,0x00,0x0f,0xd2,0x00,0x21,0xe0,0x3f,0xf0,0xf9,0x00,0x40,0xee,0x00,0x11,0x88,0x04,0x0e,0x18,0x11,0x18,0x8c,0x40,0x0e,0x50,0x30,0x10,0xc0,0xa1,0x01,0xe2,0x05,0x14,0x12,0x08,0x33,0x58,0x44,0x08,0x66,0xa1,0xe3,0x01,0x9c,0x83,0x00,0x24,0x11,0x11,0x06,0xc4,0x76,0x20,0x75,0x15,0x99,0x48,0xc0,0xe9,0x0f,0x03,0x95,0xfc,0x86,0x3c,0x09,0x80,0x1c,0x7c,0x00,0x91,0x81,0x48,0x2f,0xc1,0x41,0x8c,0xc0,0x20,0x30,0x1c,0x87,0xfc,0x0e,0x30,0x70,0x70,0x81,0xc7,0xe6,0x07,0x18,0x08,0x1c,0xb9,0x1e,0x38,0x0f,0x02,0x01,0xf0,0x03,0xa0,0xa4,0x7f,0x90,0x30,0x38,0xff,0xe0,0x28,0x21,0xff,0x06,0x44,0x0e,0x46,0xe1,0x01,0x8c,0x03,0x34,0x2f,0x25,0x18,0x80,0xc7,0x2a,0x03,0x2e,0x01,0x3c,0x70,0x12,0xa2,0x39,0x78,0x27,0xe0,0x31,0xea,0x82,0xc4,0x6c,0x31,0xf0,0x78,0xea,0xb0,0x22,0x31,0xfc,0x1a,0xc6,0x01,0x55,0x25,0x88,0xf8,0x4b,0x02,0x1f,0x13,0xe1,0x7f,0x97,0x85,0x15,0x03,0x90,0xf8,0xa0,0x10,0xa1,0xb1,0x0e,0x88,0x00,0x7f,0x0f,0xc0,0x7c,0x57,0x27,0x3c,0xb0,0x7f,0x5f,0xa9,0x1f,0xc0,0x6a,0xc5,0x05,0xc0,0xf0,0x11,0x46,0xac,0x18,0x3f,0xf9,0x54,0x75,0x00,0x73,0x1f,0x0f,0xfe,0xfe,0xc6,0x30,0x01,0xbc,0x48,0x00,0x84,0x82,0x00,0x1b,0x64,0xc0,0x07,0x60,0x03,0xb4,0x70,0x0c,0xbf,0x82,0x31,0x01,0x8d,0x0c,0x40,0x02,0x37,0x08,0x1d,0x74,0x00,0x76,0xa0,0x01,0xdb,0x01,0xfe,0x85,0x8b,0x96,0xaa,0x9b,0x30,0x01,0x6a,0xa3,0x40,0x75,0xaa,0x03,0xdb,0x50,0xbb,0x30,0x01,0x54,0x24,0x25,0xe6,0x51,0x08,0x1f,0x68,0x00,0x7f,0x03,0xf2,0x79,0xc0,0xf4,}; -const uint8_t *_I_DolphinReadingSuccess_59x63[] = {_I_DolphinReadingSuccess_59x63_0}; +const uint8_t _I_Fill_marker_7x7_0[] = {0x00,0x1C,0x32,0x6F,0x5F,0x7F,0x3E,0x1C,}; +const uint8_t *_I_Fill_marker_7x7[] = {_I_Fill_marker_7x7_0}; -const uint8_t _I_IrdaSendShort_128x34_0[] = {0x01,0x00,0x42,0x01,0xfe,0x7f,0xc0,0x07,0x03,0x07,0xc4,0x10,0x0a,0x90,0x20,0x7f,0x83,0xfc,0x04,0x3c,0x01,0xc2,0x7f,0xf8,0x80,0x43,0x9f,0x83,0xca,0x40,0x1f,0x5e,0x27,0x7e,0xab,0x55,0xee,0x83,0xce,0x38,0x0f,0x6d,0x50,0x00,0xa5,0xc0,0xf2,0x89,0x03,0xda,0xfe,0x1f,0x1f,0xa8,0x7c,0x48,0xc3,0x09,0x07,0xb6,0xae,0x54,0x1f,0x19,0xd4,0x08,0x40,0x30,0x5f,0x81,0x1c,0x63,0xfe,0x08,0x1f,0x12,0xbe,0x3f,0x49,0x0e,0x02,0x09,0x58,0x04,0x0c,0xd7,0xf1,0x0f,0x1f,0x8e,0x2b,0x11,0xaa,0x95,0x40,0xa2,0x34,0x08,0x16,0xa0,0x4e,0x32,0xab,0xe4,0x7f,0x89,0x77,0x0b,0x0d,0xd6,0x7f,0x82,0x84,0x50,0x20,0x3d,0x81,0x48,0xcd,0x67,0xd3,0xe1,0xf8,0xc8,0xb4,0x43,0xf1,0xc1,0x62,0x24,0x10,0x1b,0x46,0x80,0x3e,0x3f,0xe9,0xf8,0xfc,0xfa,0xa1,0xf1,0xa4,0x68,0x20,0x13,0x8a,0x00,0x7c,0x67,0xf7,0xe3,0xfa,0x4a,0x81,0xe3,0x40,0x80,0x66,0x38,0x66,0xa1,0xeb,0xdd,0x47,0xec,0x0f,0x2c,0x47,0x0e,0xa9,0x35,0xe9,0xd9,0x47,0xe2,0x1f,0x21,0xf8,0xd2,0x17,0xc3,0x88,0x91,0xeb,0x83,0xe6,0xbf,0x42,0x78,0xc4,0x20,0x10,0x88,0x05,0x5c,0x7e,0x7a,0xe1,0xfa,0x42,0x01,0xe5,0x84,0x1f,0x89,0x7c,0xbf,0xf7,0x7b,0xaf,0xdd,0x3e,0x31,0x10,0xe8,0xc2,0x3f,0x01,0xf1,0x3f,0x98,0x7c,0xa7,0x6a,0xf1,0x07,0x97,0x03,0x5e,0x9f,0x36,0x28,0xf7,0x7f,0xa1,0xf1,0x81,0x03,0xca,0x01,0x56,0x5f,0x9f,0xb8,0x3c,0x3e,0xa7,0xf8,0xc1,0x01,0xe5,0xf0,0x15,0x0f,0x85,0xbe,0x21,0xf1,0x00,0x08,0x7c,0x60,0x04,0xf1,0x77,0x96,0x7e,0x02,0xff,0x10,0x7c,0x00,0x16,0x08,0x05,0x40,0x78,0xa3,0xc4,0x00,0xb2,0x40,0x7b,0x2b,0xc4,0x00,0xb5,0x48,0x78,0x3d,0x70,0x01,0xf7,0x07,0xb4,0x00,0x94,0x23,0xfc,0x01,0x18,0x00,0xff,0x85,0xf3,0xff,0xc0,0xc3,0x0f,0x00,0xf0,0x09,0xce,0xf0,0x03,0x2f,0xc0,0x61,0x3f,0xe0,0xf8,0x00,0x30,0x3f,0xc0,}; -const uint8_t *_I_IrdaSendShort_128x34[] = {_I_IrdaSendShort_128x34_0}; +const uint8_t _I_Vol_down_25x27_0[] = {0x01,0x00,0x2c,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x20,0x3f,0x01,0xff,0x07,0xff,0x07,0x01,0xa0,0x5f,0xc0,0x7e,0x03,0x38,0x19,0x4c,0x60,0x30,0x68,0x07,0x02,0x01,0xfc,0xff,0xdf,0xcc,0xe8,}; +const uint8_t *_I_Vol_down_25x27[] = {_I_Vol_down_25x27_0}; -const uint8_t _I_IrdaLearn_128x64_0[] = {0x01,0x00,0xcc,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0xf0,0x07,0x80,0x3f,0x01,0x07,0x82,0x41,0x21,0x20,0x73,0x00,0x8e,0x82,0x0f,0x00,0xa0,0x01,0x46,0x11,0x00,0x07,0xc0,0x28,0x41,0xe5,0xc8,0xba,0x63,0xa7,0x70,0x6b,0x3d,0xbb,0x99,0x19,0xee,0x68,0x71,0x16,0x3f,0x70,0x3c,0x64,0xf9,0x58,0x25,0x26,0x13,0x91,0xc9,0x64,0xa4,0x99,0x2d,0x06,0x1f,0x29,0x42,0x07,0x8c,0x80,0x1e,0x50,0xff,0x88,0x3c,0x67,0x80,0xf1,0xc1,0x03,0xde,0x03,0x11,0x07,0x8c,0x10,0x1e,0x38,0x40,0x79,0xf0,0x32,0x80,0xf1,0x83,0x58,0x72,0x58,0xc8,0xc6,0x73,0x40,0x3f,0x10,0x78,0x9e,0xf1,0x17,0xe9,0xcf,0x00,0x78,0x03,0xc0,0x1e,0x00,0xf0,0x02,0x44,0x18,0xa3,0x80,0x82,0x32,0x06,0x44,0x0f,0xf0,0x73,0x5d,0xe3,0x92,0x7e,0xcf,0x06,0x3b,0xc3,0xa4,0xdd,0xfc,0xc8,0x35,0xca,0x44,0xa5,0x34,0x5c,0x16,0x92,0x89,0x4a,0x91,0x4a,0x60,0x20,0xf7,0xa4,0x83,0xc6,0x8e,0x0f,0xba,0x88,0x3c,0x68,0x00,0xf7,0x80,0x65,0xe3,0x9c,0x7a,0x6e,0x0a,0x49,0xc3,0xb8,0xc8,0xa4,0xc0,0xf5,0x00,0x08,0x1d,0xc0,0x0e,0x0f,0xf0,0x07,0x80,0x3c,0x01,0xe0,0x0f,0x00,0x2f,0xfb,0xfe,0x00,0x38,0x39,0x97,0xa1,0x00,0xe7,0xf0,0x3b,0x1c,0x00,0xd9,0x00,0x32,0xc8,0x01,0xef,0x48,0x03,0x2d,0x03,0xe0,0x45,0x38,0x0d,0x02,0x01,0x28,0xc0,0x01,0xca,0x01,0x1f,0xa0,0x10,0x12,0x05,0x80,0x80,0x49,0x38,0x1a,0xa0,0x00,0xf0,0x6f,0xf8,0x08,0x20,0x38,0xac,0x10,0x48,0x44,0x06,0x25,0x40,0xaa,0x80,0x07,0xc3,0xfb,0x80,0x41,0x21,0x9b,0x0b,0x6e,0x4e,0x09,0x10,0x80,0xc2,0xb8,0x1f,0xe0,0xf8,0xfc,0x7e,0x30,0x10,0x7a,0xc8,0x20,0x50,0x9a,0x04,0x0c,0x3e,0x3f,0x12,0x48,0x83,0xc6,0x60,0x2f,0x29,0x14,0x0a,0x0b,0xc0,0x80,0x87,0xc7,0xf3,0xf1,0x81,0x8f,0xc7,0x01,0x6d,0x81,0xc7,0x24,0x90,0x28,0x17,0x02,0x39,0x5e,0xaa,0xee,0x75,0xd0,0x3e,0x27,0xb4,0x5e,0x30,0x39,0x20,0x3c,0xa8,0x11,0xcd,0x36,0xab,0x33,0x2e,0x07,0x90,0xbc,0x4d,0x82,0x0f,0x14,0x10,0xc7,0x2e,0x21,0xf3,0x17,0x88,0x7c,0x85,0xe3,0x82,0x4c,0x8c,0x03,0x70,0x3f,0x2b,0x19,0x3c,0x47,0xe2,0x04,0x19,0x10,0x3c,0xa4,0x15,0xc2,0xf9,0x7c,0x41,0xe2,0x2e,0x1f,0x81,0xbc,0x68,0x40,0xf1,0xe0,0x6f,0xcf,0xe5,0xf9,0x82,0x63,0x3e,0xfd,0xef,0x9a,0x3c,0x68,0x22,0xf2,0xbf,0x27,0xcb,0xf1,0x04,0xc0,0x03,0xc4,0x5e,0x30,0x80,0x79,0xec,0x17,0xe5,0xf0,0x67,0xb0,0x34,0x68,0x18,0x0a,0xfd,0x56,0x1b,0x1f,0xb0,0x3b,0xd9,0xc0,0x2e,0xf3,0x25,0x90,0x01,0x81,0xe2,0x00,0xe8,0x08,0x3f,0xa0,0x40,0xfe,0x53,0x88,0x03,0x4c,0xe8,0x00,0xa8,0x80,0x3f,0xa4,0x00,0xfe,0xe0,0x21,0xcc,0x00,0x47,0x7f,0x00,0x78,}; -const uint8_t *_I_IrdaLearn_128x64[] = {_I_IrdaLearn_128x64_0}; +const uint8_t _I_Vol_up_25x27_0[] = {0x01,0x00,0x2f,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x20,0x38,0x88,0x00,0xfc,0x06,0xbc,0x1f,0xfc,0x1c,0x06,0x81,0x7f,0x01,0xc1,0x0e,0xa0,0x65,0x31,0x80,0xc1,0xa0,0x1c,0x08,0x07,0xf3,0xff,0x7f,0x33,0xa0,}; +const uint8_t *_I_Vol_up_25x27[] = {_I_Vol_up_25x27_0}; -const uint8_t _I_Mute_hvr_25x27_0[] = {0x01,0x00,0x4a,0x00,0xfc,0x7f,0xe7,0xf0,0x0f,0xe7,0xfe,0xff,0x00,0xff,0x7f,0xff,0xf0,0x00,0x10,0xff,0xe0,0x20,0x21,0xfe,0x40,0x7b,0xf7,0xff,0x5c,0x07,0x7f,0xbf,0xf9,0xc0,0x6f,0xfd,0xff,0xd8,0x3c,0x7c,0x1f,0x90,0x38,0xff,0x7f,0x40,0x31,0xbd,0x82,0xc6,0xff,0xb7,0x01,0x97,0x3c,0x06,0xc0,0xb3,0x09,0x98,0x6c,0x84,0x68,0x2b,0x21,0x99,0x8e,0xcc,0x86,0x64,0xb5,0x01,0x89,0x5c,0xcb,0xe6,0x67,0x30,}; -const uint8_t *_I_Mute_hvr_25x27[] = {_I_Mute_hvr_25x27_0}; +const uint8_t _I_Up_hvr_25x27_0[] = {0x01,0x00,0x39,0x00,0xfc,0x7f,0xe7,0xf0,0x0f,0xe7,0xfe,0xff,0x00,0xff,0x7f,0xff,0xf0,0x00,0x10,0xff,0xe0,0x20,0x3c,0xf7,0x80,0xcb,0x8e,0x03,0x2c,0x18,0x0c,0x80,0x26,0x25,0x18,0x08,0xa4,0x7f,0x90,0x11,0x88,0xfe,0x20,0x31,0xf8,0x07,0xc2,0x03,0x0f,0x80,0x78,0x00,0x68,0x37,0xf0,0x1d,0x95,0xcc,0xbe,0x66,0x73,}; +const uint8_t *_I_Up_hvr_25x27[] = {_I_Up_hvr_25x27_0}; + +const uint8_t _I_Vol_up_hvr_25x27_0[] = {0x01,0x00,0x28,0x00,0xfc,0x7f,0xe7,0xf0,0x0f,0xe7,0xfe,0xff,0x00,0xff,0x7f,0xff,0xf0,0x00,0x10,0xff,0xe0,0x20,0x38,0xf7,0x80,0xfc,0x06,0xa2,0xd1,0xfc,0x00,0xd0,0x2f,0xe0,0x38,0x21,0xd8,0x0c,0x8a,0xe6,0x5f,0x33,0x39,0x80,}; +const uint8_t *_I_Vol_up_hvr_25x27[] = {_I_Vol_up_hvr_25x27_0}; + +const uint8_t _I_IrdaLearnShort_128x31_0[] = {0x01,0x00,0x10,0x01,0x00,0x47,0xfb,0xfe,0x00,0x38,0x38,0x3e,0x20,0x20,0x54,0x84,0x03,0x9f,0xc0,0x06,0x58,0x80,0x3d,0xf2,0x00,0x65,0x90,0x03,0xde,0x90,0x06,0x5a,0x07,0xc0,0x8a,0x70,0x1a,0x04,0x02,0x51,0x80,0x03,0x94,0x02,0x3f,0x40,0x20,0x24,0x0b,0x01,0x00,0x92,0x70,0x35,0x40,0x01,0xe0,0xdf,0xf0,0x10,0x40,0x71,0x58,0x20,0x90,0x88,0x0c,0x4a,0x81,0x55,0x00,0x0f,0x87,0xf7,0x00,0x82,0x43,0x36,0x16,0xdc,0x9c,0x12,0x21,0x01,0x85,0x70,0x3f,0xc1,0xf1,0xf8,0xfc,0x60,0x20,0xf5,0x90,0x40,0xa1,0x34,0x08,0x18,0x7c,0x7e,0x24,0x91,0x07,0x8c,0xc0,0x5e,0x52,0x28,0x14,0x17,0x81,0x01,0x0f,0x8f,0xe7,0xe3,0x03,0x1f,0x8e,0x02,0xdb,0x03,0x8e,0x49,0x20,0x50,0x2e,0x04,0x72,0xbd,0x55,0xdc,0xeb,0xa0,0x7c,0x4f,0x68,0xbc,0x60,0x72,0x40,0x79,0x50,0x23,0x9a,0x6d,0x56,0x66,0x5c,0x0f,0x21,0x78,0x9b,0x04,0x1e,0x28,0x21,0x8e,0x5c,0x43,0xe6,0x2f,0x10,0xf9,0x0b,0xc7,0x04,0x99,0x18,0x06,0xe0,0x7e,0x56,0x32,0x78,0x8f,0xc4,0x08,0x32,0x20,0x79,0x48,0x2b,0x85,0xf2,0xf8,0x83,0xc4,0x5c,0x3f,0x03,0x78,0xd0,0x81,0xe3,0xc0,0xdf,0x9f,0xcb,0xf3,0x04,0xc6,0x7d,0xfb,0xdf,0x34,0x78,0xd0,0x45,0xe5,0x7e,0x4f,0x97,0xe2,0x09,0x80,0x07,0x88,0xbc,0x61,0x00,0xf3,0xd8,0x2f,0xcb,0xe0,0xcf,0x60,0x68,0xd0,0x30,0x15,0xfa,0xac,0x36,0x3f,0x60,0x77,0xb3,0x80,0x5d,0xe6,0x4b,0x20,0x03,0x03,0xc4,0x01,0xd0,0x10,0x7f,0x40,0x81,0xfc,0xa7,0x10,0x06,0x99,0xd0,0x01,0x51,0x00,0x7f,0x48,0x01,0xfd,0xc0,0x43,0x98,0x00,0x8e,0xfe,0x00,0xf0,}; +const uint8_t *_I_IrdaLearnShort_128x31[] = {_I_IrdaLearnShort_128x31_0}; const uint8_t _I_IrdaSend_128x64_0[] = {0x01,0x00,0xe2,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0xfe,0x04,0x0e,0x05,0x82,0xd7,0x81,0xca,0x21,0x08,0x01,0x8c,0x10,0x0e,0x54,0x00,0x20,0xe0,0xa4,0x00,0xfb,0xb2,0x4e,0xb0,0xfa,0x0e,0x74,0xc7,0x0f,0x3b,0xce,0x4e,0xec,0xf0,0xe1,0x79,0xe4,0xe9,0x58,0x2d,0x3d,0x4a,0x95,0x41,0x89,0x52,0x31,0x59,0x40,0xfa,0x64,0x01,0xe3,0xa0,0xa9,0x5e,0x81,0xe7,0xf4,0x07,0xcc,0x28,0x1e,0x71,0x40,0x7a,0x58,0x01,0xe4,0x3f,0x1c,0x0c,0x4f,0x11,0x0b,0xb3,0x83,0xcc,0x00,0x94,0x20,0x2a,0x03,0xa0,0x1e,0xd0,0x34,0xdf,0x80,0x3c,0x01,0xe0,0x0f,0x00,0x4c,0xf0,0x17,0x4c,0x81,0xa0,0x18,0x18,0x1f,0x39,0x90,0x6c,0x60,0x27,0x70,0xe9,0x3f,0x67,0x03,0x3c,0x80,0x83,0xde,0x81,0x4a,0x84,0xca,0x68,0xb8,0x2b,0xf0,0x3f,0x29,0x20,0xfe,0xa8,0xe0,0x85,0xf3,0x80,0xa5,0xc3,0xb8,0xf4,0xd8,0x11,0x3e,0x40,0x04,0x1b,0x23,0x7d,0x83,0xcd,0x1f,0x60,0x0f,0x00,0x78,0x03,0x7f,0x9f,0xf0,0x01,0xc0,0xc1,0xf1,0x04,0x02,0xa4,0x08,0x1f,0xe0,0xff,0x01,0x0f,0x00,0x70,0x9f,0xfe,0x20,0x10,0xe7,0xe0,0xf2,0x90,0x07,0xd7,0x89,0xdf,0xaa,0xd5,0x7b,0xa0,0xf3,0x8e,0x03,0xdb,0x54,0x00,0x29,0x70,0x3c,0xa2,0x40,0xf6,0xbf,0x87,0xc7,0xea,0x1f,0x12,0x30,0xc2,0x41,0xed,0xab,0x95,0x07,0xc6,0x75,0x02,0x10,0x0c,0x17,0xe0,0x47,0x18,0xff,0x82,0x07,0xc4,0xaf,0x8f,0xd2,0x43,0x80,0x82,0x56,0x01,0x03,0x35,0xfc,0x43,0xc7,0xe3,0x8a,0xc4,0x6a,0xa5,0x50,0x28,0x8d,0x02,0x05,0xa8,0x13,0x8c,0xaa,0xf9,0x1f,0xe2,0x5d,0xc2,0xc3,0x75,0x9f,0xe0,0xa1,0x14,0x08,0x0f,0x60,0x52,0x33,0x59,0xf4,0xf8,0x7e,0x32,0x2d,0x10,0xfc,0x70,0x58,0x89,0x04,0x06,0xd1,0xa0,0x0f,0x8f,0xfa,0x7e,0x3f,0x3e,0xa8,0x7c,0x69,0x1a,0x08,0x04,0xe2,0x80,0x1f,0x19,0xfd,0xf8,0xfe,0x92,0xa0,0x78,0xd0,0x20,0x19,0x8e,0x19,0xa8,0x7a,0xf7,0x51,0xfb,0x03,0xcb,0x11,0xc3,0xaa,0x4d,0x7a,0x76,0x51,0xf8,0x87,0xc8,0x7e,0x34,0x85,0xf0,0xe2,0x24,0x7a,0xe0,0xf9,0xaf,0xd0,0x9e,0x31,0x08,0x04,0x22,0x01,0x57,0x1f,0x9e,0xb8,0x7e,0x90,0x80,0x79,0x61,0x07,0xe2,0x5f,0x2f,0xfd,0xde,0xeb,0xf7,0x4f,0x8c,0x44,0x3a,0x30,0x8f,0xc0,0x7c,0x4f,0xe6,0x1f,0x29,0xda,0xbc,0x41,0xe5,0xc0,0xd7,0xa7,0xcd,0x8a,0x3d,0xdf,0xe8,0x7c,0x60,0x40,0xf2,0x80,0x55,0x97,0xe7,0xee,0x0f,0x0f,0xa9,0xfe,0x30,0x40,0x79,0x7c,0x05,0x43,0xe1,0x6f,0x88,0x7c,0x40,0x02,0x1f,0x18,0x01,0x3c,0x5d,0xe5,0x9f,0x80,0xbf,0xc4,0x1f,0x00,0x05,0x82,0x01,0x50,0x1e,0x28,0xf1,0x00,0x2c,0x90,0x1e,0xca,0xf1,0x00,0x2d,0x52,0x1e,0x0f,0x5c,0x00,0x7d,0xc1,0xed,0x00,0x25,0x08,0xff,0x00,0x46,0x00,0x3f,0xe1,0x7c,0xff,0xf0,0x30,0xc3,0xc0,0x3c,0x02,0x73,0xbc,0x00,0xcb,0xf0,0x18,0x4f,0xf8,0x3e,0x00,0x0c,0x0f,0xf0,}; const uint8_t *_I_IrdaSend_128x64[] = {_I_IrdaSend_128x64_0}; -const uint8_t _I_Power_hvr_25x27_0[] = {0x01,0x00,0x4b,0x00,0xfc,0x7f,0xe7,0xf0,0x0f,0xe7,0xfe,0xff,0x00,0xff,0x7f,0xff,0xf0,0x00,0x10,0xff,0xe0,0x3f,0xff,0x78,0x0c,0xb8,0xe0,0x35,0xbf,0xf1,0xbf,0x90,0x19,0xff,0x1b,0xf1,0x01,0x8f,0xf1,0xfe,0x30,0x1c,0xff,0x1f,0xe6,0x03,0x5f,0x78,0x0c,0xbf,0xe0,0x39,0x8f,0xff,0xc3,0x63,0x3f,0xff,0x08,0xc6,0xff,0x7c,0x15,0x89,0x04,0x7f,0xc0,0x31,0xc1,0x8e,0xc8,0x8e,0x60,0x36,0x2b,0x99,0x7c,0xcc,0xe6,}; -const uint8_t *_I_Power_hvr_25x27[] = {_I_Power_hvr_25x27_0}; +const uint8_t _I_DolphinReadingSuccess_59x63_0[] = {0x01,0x00,0x19,0x01,0x00,0x1d,0x00,0x0f,0xd2,0x00,0x21,0xe0,0x3f,0xf0,0xf9,0x00,0x40,0xee,0x00,0x11,0x88,0x04,0x0e,0x18,0x11,0x18,0x8c,0x40,0x0e,0x50,0x30,0x10,0xc0,0xa1,0x01,0xe2,0x05,0x14,0x12,0x08,0x33,0x58,0x44,0x08,0x66,0xa1,0xe3,0x01,0x9c,0x83,0x00,0x24,0x11,0x11,0x06,0xc4,0x76,0x20,0x75,0x15,0x99,0x48,0xc0,0xe9,0x0f,0x03,0x95,0xfc,0x86,0x3c,0x09,0x80,0x1c,0x7c,0x00,0x91,0x81,0x48,0x2f,0xc1,0x41,0x8c,0xc0,0x20,0x30,0x1c,0x87,0xfc,0x0e,0x30,0x70,0x70,0x81,0xc7,0xe6,0x07,0x18,0x08,0x1c,0xb9,0x1e,0x38,0x0f,0x02,0x01,0xf0,0x03,0xa0,0xa4,0x7f,0x90,0x30,0x38,0xff,0xe0,0x28,0x21,0xff,0x06,0x44,0x0e,0x46,0xe1,0x01,0x8c,0x03,0x34,0x2f,0x25,0x18,0x80,0xc7,0x2a,0x03,0x2e,0x01,0x3c,0x70,0x12,0xa2,0x39,0x78,0x27,0xe0,0x31,0xea,0x82,0xc4,0x6c,0x31,0xf0,0x78,0xea,0xb0,0x22,0x31,0xfc,0x1a,0xc6,0x01,0x55,0x25,0x88,0xf8,0x4b,0x02,0x1f,0x13,0xe1,0x7f,0x97,0x85,0x15,0x03,0x90,0xf8,0xa0,0x10,0xa1,0xb1,0x0e,0x88,0x00,0x7f,0x0f,0xc0,0x7c,0x57,0x27,0x3c,0xb0,0x7f,0x5f,0xa9,0x1f,0xc0,0x6a,0xc5,0x05,0xc0,0xf0,0x11,0x46,0xac,0x18,0x3f,0xf9,0x54,0x75,0x00,0x73,0x1f,0x0f,0xfe,0xfe,0xc6,0x30,0x01,0xbc,0x48,0x00,0x84,0x82,0x00,0x1b,0x64,0xc0,0x07,0x60,0x03,0xb4,0x70,0x0c,0xbf,0x82,0x31,0x01,0x8d,0x0c,0x40,0x02,0x37,0x08,0x1d,0x74,0x00,0x76,0xa0,0x01,0xdb,0x01,0xfe,0x85,0x8b,0x96,0xaa,0x9b,0x30,0x01,0x6a,0xa3,0x40,0x75,0xaa,0x03,0xdb,0x50,0xbb,0x30,0x01,0x54,0x24,0x25,0xe6,0x51,0x08,0x1f,0x68,0x00,0x7f,0x03,0xf2,0x79,0xc0,0xf4,}; +const uint8_t *_I_DolphinReadingSuccess_59x63[] = {_I_DolphinReadingSuccess_59x63_0}; + +const uint8_t _I_Mute_hvr_25x27_0[] = {0x01,0x00,0x4a,0x00,0xfc,0x7f,0xe7,0xf0,0x0f,0xe7,0xfe,0xff,0x00,0xff,0x7f,0xff,0xf0,0x00,0x10,0xff,0xe0,0x20,0x21,0xfe,0x40,0x7b,0xf7,0xff,0x5c,0x07,0x7f,0xbf,0xf9,0xc0,0x6f,0xfd,0xff,0xd8,0x3c,0x7c,0x1f,0x90,0x38,0xff,0x7f,0x40,0x31,0xbd,0x82,0xc6,0xff,0xb7,0x01,0x97,0x3c,0x06,0xc0,0xb3,0x09,0x98,0x6c,0x84,0x68,0x2b,0x21,0x99,0x8e,0xcc,0x86,0x64,0xb5,0x01,0x89,0x5c,0xcb,0xe6,0x67,0x30,}; +const uint8_t *_I_Mute_hvr_25x27[] = {_I_Mute_hvr_25x27_0}; const uint8_t _I_Back_15x10_0[] = {0x00,0x04,0x00,0x06,0x00,0xFF,0x0F,0x06,0x10,0x04,0x20,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x10,0xFE,0x0F,}; const uint8_t *_I_Back_15x10[] = {_I_Back_15x10_0}; +const uint8_t _I_Up_25x27_0[] = {0x01,0x00,0x44,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x20,0x3c,0x88,0x00,0xca,0x70,0x03,0x2b,0xe0,0x0c,0xbf,0xc0,0x32,0xff,0x80,0x87,0x03,0xff,0x81,0xc0,0x78,0x3f,0xf8,0x3c,0x07,0xc3,0xff,0x87,0xc0,0x7e,0x3f,0xf8,0xf8,0x0d,0x06,0xfe,0x03,0x78,0x19,0x4c,0x60,0x30,0x68,0x07,0x02,0x01,0xfc,0xff,0xdf,0xcc,0xe8,}; +const uint8_t *_I_Up_25x27[] = {_I_Up_25x27_0}; + +const uint8_t _I_IrdaArrowUp_4x8_0[] = {0x00,0x18,0x3C,0x7E,0xFF,}; +const uint8_t *_I_IrdaArrowUp_4x8[] = {_I_IrdaArrowUp_4x8_0}; + +const uint8_t _I_Mute_25x27_0[] = {0x01,0x00,0x51,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x20,0x31,0x81,0xc0,0x64,0x38,0x08,0xa4,0x06,0x83,0x40,0x86,0x40,0x70,0x32,0x08,0x20,0x3c,0x63,0xf0,0x60,0x38,0xc0,0xa0,0xa0,0x31,0xc2,0x02,0xc7,0x03,0x48,0x01,0x94,0xc0,0x06,0xc0,0xb3,0x09,0x98,0x6c,0x84,0x68,0x2b,0x21,0x99,0x8e,0xcc,0x86,0x64,0xb3,0x81,0x94,0xc6,0x03,0x06,0x80,0x70,0x20,0x1f,0xcf,0xfd,0xfc,0xce,0x80,}; +const uint8_t *_I_Mute_25x27[] = {_I_Mute_25x27_0}; + +const uint8_t _I_Power_25x27_0[] = {0x01,0x00,0x54,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x30,0x18,0x80,0x0c,0xa7,0x00,0x35,0xc0,0xce,0x60,0x70,0x1e,0x0c,0xe6,0x0f,0x01,0xf0,0xce,0x21,0xd0,0x1b,0x0c,0xe2,0x18,0x03,0x58,0x80,0x0c,0xa0,0x00,0x39,0xf0,0xc0,0x03,0x63,0xc1,0x80,0x88,0xc7,0x03,0x83,0x15,0x8c,0x07,0xfe,0x02,0x18,0x0d,0xf0,0x76,0x44,0x73,0x01,0x94,0x0c,0xa6,0x30,0x18,0x34,0x03,0x81,0x00,0xfe,0x7f,0xef,0xe6,0x74,}; +const uint8_t *_I_Power_25x27[] = {_I_Power_25x27_0}; + +const uint8_t _I_IrdaSendShort_128x34_0[] = {0x01,0x00,0x42,0x01,0xfe,0x7f,0xc0,0x07,0x03,0x07,0xc4,0x10,0x0a,0x90,0x20,0x7f,0x83,0xfc,0x04,0x3c,0x01,0xc2,0x7f,0xf8,0x80,0x43,0x9f,0x83,0xca,0x40,0x1f,0x5e,0x27,0x7e,0xab,0x55,0xee,0x83,0xce,0x38,0x0f,0x6d,0x50,0x00,0xa5,0xc0,0xf2,0x89,0x03,0xda,0xfe,0x1f,0x1f,0xa8,0x7c,0x48,0xc3,0x09,0x07,0xb6,0xae,0x54,0x1f,0x19,0xd4,0x08,0x40,0x30,0x5f,0x81,0x1c,0x63,0xfe,0x08,0x1f,0x12,0xbe,0x3f,0x49,0x0e,0x02,0x09,0x58,0x04,0x0c,0xd7,0xf1,0x0f,0x1f,0x8e,0x2b,0x11,0xaa,0x95,0x40,0xa2,0x34,0x08,0x16,0xa0,0x4e,0x32,0xab,0xe4,0x7f,0x89,0x77,0x0b,0x0d,0xd6,0x7f,0x82,0x84,0x50,0x20,0x3d,0x81,0x48,0xcd,0x67,0xd3,0xe1,0xf8,0xc8,0xb4,0x43,0xf1,0xc1,0x62,0x24,0x10,0x1b,0x46,0x80,0x3e,0x3f,0xe9,0xf8,0xfc,0xfa,0xa1,0xf1,0xa4,0x68,0x20,0x13,0x8a,0x00,0x7c,0x67,0xf7,0xe3,0xfa,0x4a,0x81,0xe3,0x40,0x80,0x66,0x38,0x66,0xa1,0xeb,0xdd,0x47,0xec,0x0f,0x2c,0x47,0x0e,0xa9,0x35,0xe9,0xd9,0x47,0xe2,0x1f,0x21,0xf8,0xd2,0x17,0xc3,0x88,0x91,0xeb,0x83,0xe6,0xbf,0x42,0x78,0xc4,0x20,0x10,0x88,0x05,0x5c,0x7e,0x7a,0xe1,0xfa,0x42,0x01,0xe5,0x84,0x1f,0x89,0x7c,0xbf,0xf7,0x7b,0xaf,0xdd,0x3e,0x31,0x10,0xe8,0xc2,0x3f,0x01,0xf1,0x3f,0x98,0x7c,0xa7,0x6a,0xf1,0x07,0x97,0x03,0x5e,0x9f,0x36,0x28,0xf7,0x7f,0xa1,0xf1,0x81,0x03,0xca,0x01,0x56,0x5f,0x9f,0xb8,0x3c,0x3e,0xa7,0xf8,0xc1,0x01,0xe5,0xf0,0x15,0x0f,0x85,0xbe,0x21,0xf1,0x00,0x08,0x7c,0x60,0x04,0xf1,0x77,0x96,0x7e,0x02,0xff,0x10,0x7c,0x00,0x16,0x08,0x05,0x40,0x78,0xa3,0xc4,0x00,0xb2,0x40,0x7b,0x2b,0xc4,0x00,0xb5,0x48,0x78,0x3d,0x70,0x01,0xf7,0x07,0xb4,0x00,0x94,0x23,0xfc,0x01,0x18,0x00,0xff,0x85,0xf3,0xff,0xc0,0xc3,0x0f,0x00,0xf0,0x09,0xce,0xf0,0x03,0x2f,0xc0,0x61,0x3f,0xe0,0xf8,0x00,0x30,0x3f,0xc0,}; +const uint8_t *_I_IrdaSendShort_128x34[] = {_I_IrdaSendShort_128x34_0}; + +const uint8_t _I_IrdaArrowDown_4x8_0[] = {0x00,0xFF,0x7E,0x3C,0x18,}; +const uint8_t *_I_IrdaArrowDown_4x8[] = {_I_IrdaArrowDown_4x8_0}; + +const uint8_t _I_IrdaLearn_128x64_0[] = {0x01,0x00,0xcc,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0xf0,0x07,0x80,0x3f,0x01,0x07,0x82,0x41,0x21,0x20,0x73,0x00,0x8e,0x82,0x0f,0x00,0xa0,0x01,0x46,0x11,0x00,0x07,0xc0,0x28,0x41,0xe5,0xc8,0xba,0x63,0xa7,0x70,0x6b,0x3d,0xbb,0x99,0x19,0xee,0x68,0x71,0x16,0x3f,0x70,0x3c,0x64,0xf9,0x58,0x25,0x26,0x13,0x91,0xc9,0x64,0xa4,0x99,0x2d,0x06,0x1f,0x29,0x42,0x07,0x8c,0x80,0x1e,0x50,0xff,0x88,0x3c,0x67,0x80,0xf1,0xc1,0x03,0xde,0x03,0x11,0x07,0x8c,0x10,0x1e,0x38,0x40,0x79,0xf0,0x32,0x80,0xf1,0x83,0x58,0x72,0x58,0xc8,0xc6,0x73,0x40,0x3f,0x10,0x78,0x9e,0xf1,0x17,0xe9,0xcf,0x00,0x78,0x03,0xc0,0x1e,0x00,0xf0,0x02,0x44,0x18,0xa3,0x80,0x82,0x32,0x06,0x44,0x0f,0xf0,0x73,0x5d,0xe3,0x92,0x7e,0xcf,0x06,0x3b,0xc3,0xa4,0xdd,0xfc,0xc8,0x35,0xca,0x44,0xa5,0x34,0x5c,0x16,0x92,0x89,0x4a,0x91,0x4a,0x60,0x20,0xf7,0xa4,0x83,0xc6,0x8e,0x0f,0xba,0x88,0x3c,0x68,0x00,0xf7,0x80,0x65,0xe3,0x9c,0x7a,0x6e,0x0a,0x49,0xc3,0xb8,0xc8,0xa4,0xc0,0xf5,0x00,0x08,0x1d,0xc0,0x0e,0x0f,0xf0,0x07,0x80,0x3c,0x01,0xe0,0x0f,0x00,0x2f,0xfb,0xfe,0x00,0x38,0x39,0x97,0xa1,0x00,0xe7,0xf0,0x3b,0x1c,0x00,0xd9,0x00,0x32,0xc8,0x01,0xef,0x48,0x03,0x2d,0x03,0xe0,0x45,0x38,0x0d,0x02,0x01,0x28,0xc0,0x01,0xca,0x01,0x1f,0xa0,0x10,0x12,0x05,0x80,0x80,0x49,0x38,0x1a,0xa0,0x00,0xf0,0x6f,0xf8,0x08,0x20,0x38,0xac,0x10,0x48,0x44,0x06,0x25,0x40,0xaa,0x80,0x07,0xc3,0xfb,0x80,0x41,0x21,0x9b,0x0b,0x6e,0x4e,0x09,0x10,0x80,0xc2,0xb8,0x1f,0xe0,0xf8,0xfc,0x7e,0x30,0x10,0x7a,0xc8,0x20,0x50,0x9a,0x04,0x0c,0x3e,0x3f,0x12,0x48,0x83,0xc6,0x60,0x2f,0x29,0x14,0x0a,0x0b,0xc0,0x80,0x87,0xc7,0xf3,0xf1,0x81,0x8f,0xc7,0x01,0x6d,0x81,0xc7,0x24,0x90,0x28,0x17,0x02,0x39,0x5e,0xaa,0xee,0x75,0xd0,0x3e,0x27,0xb4,0x5e,0x30,0x39,0x20,0x3c,0xa8,0x11,0xcd,0x36,0xab,0x33,0x2e,0x07,0x90,0xbc,0x4d,0x82,0x0f,0x14,0x10,0xc7,0x2e,0x21,0xf3,0x17,0x88,0x7c,0x85,0xe3,0x82,0x4c,0x8c,0x03,0x70,0x3f,0x2b,0x19,0x3c,0x47,0xe2,0x04,0x19,0x10,0x3c,0xa4,0x15,0xc2,0xf9,0x7c,0x41,0xe2,0x2e,0x1f,0x81,0xbc,0x68,0x40,0xf1,0xe0,0x6f,0xcf,0xe5,0xf9,0x82,0x63,0x3e,0xfd,0xef,0x9a,0x3c,0x68,0x22,0xf2,0xbf,0x27,0xcb,0xf1,0x04,0xc0,0x03,0xc4,0x5e,0x30,0x80,0x79,0xec,0x17,0xe5,0xf0,0x67,0xb0,0x34,0x68,0x18,0x0a,0xfd,0x56,0x1b,0x1f,0xb0,0x3b,0xd9,0xc0,0x2e,0xf3,0x25,0x90,0x01,0x81,0xe2,0x00,0xe8,0x08,0x3f,0xa0,0x40,0xfe,0x53,0x88,0x03,0x4c,0xe8,0x00,0xa8,0x80,0x3f,0xa4,0x00,0xfe,0xe0,0x21,0xcc,0x00,0x47,0x7f,0x00,0x78,}; +const uint8_t *_I_IrdaLearn_128x64[] = {_I_IrdaLearn_128x64_0}; + +const uint8_t _I_Power_hvr_25x27_0[] = {0x01,0x00,0x4b,0x00,0xfc,0x7f,0xe7,0xf0,0x0f,0xe7,0xfe,0xff,0x00,0xff,0x7f,0xff,0xf0,0x00,0x10,0xff,0xe0,0x3f,0xff,0x78,0x0c,0xb8,0xe0,0x35,0xbf,0xf1,0xbf,0x90,0x19,0xff,0x1b,0xf1,0x01,0x8f,0xf1,0xfe,0x30,0x1c,0xff,0x1f,0xe6,0x03,0x5f,0x78,0x0c,0xbf,0xe0,0x39,0x8f,0xff,0xc3,0x63,0x3f,0xff,0x08,0xc6,0xff,0x7c,0x15,0x89,0x04,0x7f,0xc0,0x31,0xc1,0x8e,0xc8,0x8e,0x60,0x36,0x2b,0x99,0x7c,0xcc,0xe6,}; +const uint8_t *_I_Power_hvr_25x27[] = {_I_Power_hvr_25x27_0}; + const uint8_t _I_KeySaveSelected_24x11_0[] = {0x01,0x00,0x1a,0x00,0xff,0x7f,0xc0,0x0d,0xcf,0xb4,0x7c,0xee,0xf6,0xbf,0x6d,0xbe,0xd7,0xe1,0xaf,0xda,0xff,0xbe,0x7c,0xc7,0xcc,0x28,0xa1,0xd1,0xbf,0x80,}; const uint8_t *_I_KeySaveSelected_24x11[] = {_I_KeySaveSelected_24x11_0}; -const uint8_t _I_KeySave_24x11_0[] = {0x01,0x00,0x1e,0x00,0xff,0x7f,0xff,0xf0,0x18,0x06,0x00,0x04,0x53,0x1c,0xbe,0x33,0x13,0x94,0xc9,0x64,0x72,0x99,0xed,0x0e,0x53,0x05,0x19,0xb3,0xe3,0x02,0x8a,0x1d,0x1b,0xf8,}; -const uint8_t *_I_KeySave_24x11[] = {_I_KeySave_24x11_0}; +const uint8_t _I_KeyBackspace_16x9_0[] = {0x00,0xFE,0x7F,0x01,0x80,0x11,0x80,0x19,0x80,0xFD,0xBF,0x19,0x80,0x11,0x80,0x01,0x80,0xFE,0x7F,}; +const uint8_t *_I_KeyBackspace_16x9[] = {_I_KeyBackspace_16x9_0}; const uint8_t _I_KeyBackspaceSelected_16x9_0[] = {0x00,0xFE,0x7F,0xFF,0xFF,0xEF,0xFF,0xE7,0xFF,0x03,0xC0,0xE7,0xFF,0xEF,0xFF,0xFF,0xFF,0xFE,0x7F,}; const uint8_t *_I_KeyBackspaceSelected_16x9[] = {_I_KeyBackspaceSelected_16x9_0}; -const uint8_t _I_KeyBackspace_16x9_0[] = {0x00,0xFE,0x7F,0x01,0x80,0x11,0x80,0x19,0x80,0xFD,0xBF,0x19,0x80,0x11,0x80,0x01,0x80,0xFE,0x7F,}; -const uint8_t *_I_KeyBackspace_16x9[] = {_I_KeyBackspace_16x9_0}; +const uint8_t _I_KeySave_24x11_0[] = {0x01,0x00,0x1e,0x00,0xff,0x7f,0xff,0xf0,0x18,0x06,0x00,0x04,0x53,0x1c,0xbe,0x33,0x13,0x94,0xc9,0x64,0x72,0x99,0xed,0x0e,0x53,0x05,0x19,0xb3,0xe3,0x02,0x8a,0x1d,0x1b,0xf8,}; +const uint8_t *_I_KeySave_24x11[] = {_I_KeySave_24x11_0}; const uint8_t _A_125khz_14_0[] = {0x00,0x80,0x07,0x00,0x08,0x00,0x13,0x00,0x24,0x0E,0x28,0x71,0x28,0x85,0x21,0x01,0x02,0x62,0x02,0x92,0x02,0x92,0x02,0x64,0x02,0x04,0x01,0xF8,0x00,}; const uint8_t _A_125khz_14_1[] = {0x00,0x80,0x07,0x00,0x08,0x00,0x10,0x00,0x20,0x0E,0x20,0x71,0x20,0x85,0x21,0x01,0x02,0x62,0x02,0x92,0x02,0x92,0x02,0x64,0x02,0x04,0x01,0xF8,0x00,}; @@ -623,80 +644,74 @@ const uint8_t _A_iButton_14_5[] = {0x01,0x00,0x1a,0x00,0x00,0x14,0xe2,0x01,0x24, const uint8_t _A_iButton_14_6[] = {0x00,0x00,0x00,0x00,0x38,0x00,0x24,0x00,0x23,0x80,0x20,0xF0,0x10,0x0C,0x0D,0xE2,0x02,0x91,0x01,0x69,0x01,0x15,0x01,0x8D,0x00,0x4D,0x00,0x3E,0x00,}; const uint8_t *_A_iButton_14[] = {_A_iButton_14_0,_A_iButton_14_1,_A_iButton_14_2,_A_iButton_14_3,_A_iButton_14_4,_A_iButton_14_5,_A_iButton_14_6}; -const uint8_t _I_Medium_chip_22x21_0[] = {0x01,0x00,0x35,0x00,0xfe,0x7f,0xe1,0xf0,0x28,0x04,0x43,0xf3,0xff,0x93,0xe1,0x6a,0x52,0x8e,0x2f,0xfe,0x51,0x25,0x80,0x4a,0x72,0xb6,0x79,0x55,0x76,0xc1,0x2e,0xaa,0xc0,0x25,0x51,0xdc,0x00,0x14,0x70,0x00,0x56,0xae,0x81,0x47,0x2b,0x7d,0x95,0x07,0x48,0x46,0x42,0x92,0x17,0x90,0xd4,0x87,0x64,}; -const uint8_t *_I_Medium_chip_22x21[] = {_I_Medium_chip_22x21_0}; - const uint8_t _I_Detailed_chip_17x13_0[] = {0x01,0x00,0x1e,0x00,0xfe,0x5f,0xe0,0x10,0x2c,0x04,0x02,0x23,0x11,0x80,0xe4,0x62,0x50,0x1a,0xff,0xc2,0x03,0x21,0x84,0x00,0x9a,0xbf,0xf4,0x08,0x98,0x5c,0x83,0xa4,0x23,0x20,}; const uint8_t *_I_Detailed_chip_17x13[] = {_I_Detailed_chip_17x13_0}; -const uint8_t _I_Health_16x16_0[] = {0x01,0x00,0x12,0x00,0x00,0x2f,0x02,0x03,0x40,0x00,0x95,0xe2,0x1f,0x08,0x84,0x00,0xc4,0x12,0x60,0xf1,0x0c,0xb8,}; -const uint8_t *_I_Health_16x16[] = {_I_Health_16x16_0}; - -const uint8_t _I_Voltage_16x16_0[] = {0x01,0x00,0x1a,0x00,0x00,0x24,0x0a,0x01,0x03,0xc0,0x40,0x78,0x10,0x1f,0x04,0x03,0xe1,0x07,0xc0,0x40,0xc0,0xe3,0xc0,0x80,0x58,0x20,0x12,0x00,0xd3,0x00,}; -const uint8_t *_I_Voltage_16x16[] = {_I_Voltage_16x16_0}; +const uint8_t _I_Medium_chip_22x21_0[] = {0x01,0x00,0x35,0x00,0xfe,0x7f,0xe1,0xf0,0x28,0x04,0x43,0xf3,0xff,0x93,0xe1,0x6a,0x52,0x8e,0x2f,0xfe,0x51,0x25,0x80,0x4a,0x72,0xb6,0x79,0x55,0x76,0xc1,0x2e,0xaa,0xc0,0x25,0x51,0xdc,0x00,0x14,0x70,0x00,0x56,0xae,0x81,0x47,0x2b,0x7d,0x95,0x07,0x48,0x46,0x42,0x92,0x17,0x90,0xd4,0x87,0x64,}; +const uint8_t *_I_Medium_chip_22x21[] = {_I_Medium_chip_22x21_0}; const uint8_t _I_BatteryBody_52x28_0[] = {0x01,0x00,0x45,0x00,0xe0,0x7f,0x3f,0xe0,0x02,0x87,0xf0,0x21,0xe0,0xc3,0x84,0x50,0x39,0xbf,0xff,0x27,0xfe,0xf3,0x09,0xe0,0x42,0x81,0xab,0x0d,0x03,0x1c,0x2b,0xfc,0x0d,0x48,0x55,0xdc,0x1a,0x90,0x8f,0x18,0x6d,0x41,0xaa,0x1b,0x71,0x4b,0x0d,0xd4,0x1b,0xe0,0xdf,0x1b,0xd5,0xfc,0x1a,0xa5,0x36,0x06,0xac,0x20,0xa7,0xe0,0xdc,0xa5,0x7c,0x7c,0xb7,0xff,0xb4,0x21,0x5c,0xcb,0xc6,}; const uint8_t *_I_BatteryBody_52x28[] = {_I_BatteryBody_52x28_0}; -const uint8_t _I_FaceNormal_29x14_0[] = {0x01,0x00,0x1e,0x00,0x00,0x1c,0xf2,0x01,0x80,0x83,0xd7,0xa0,0x1c,0x08,0x5d,0xf8,0x06,0x30,0xf0,0x1b,0x84,0xcc,0x41,0x10,0x88,0x10,0x0e,0x62,0x10,0x10,0x18,0xf8,0x00,0x42,}; -const uint8_t *_I_FaceNormal_29x14[] = {_I_FaceNormal_29x14_0}; - const uint8_t _I_FaceCharging_29x14_0[] = {0x01,0x00,0x28,0x00,0xa0,0x00,0x86,0x05,0x60,0x01,0x8c,0x0e,0x61,0x00,0xc0,0x40,0x63,0x10,0x0e,0x04,0x03,0xf9,0x00,0xf0,0x41,0xc0,0x66,0x13,0xb8,0x40,0x94,0xc0,0x07,0x04,0x82,0x00,0xc6,0x11,0x02,0x01,0x8f,0xc2,0x03,0x00,}; const uint8_t *_I_FaceCharging_29x14[] = {_I_FaceCharging_29x14_0}; +const uint8_t _I_Health_16x16_0[] = {0x01,0x00,0x12,0x00,0x00,0x2f,0x02,0x03,0x40,0x00,0x95,0xe2,0x1f,0x08,0x84,0x00,0xc4,0x12,0x60,0xf1,0x0c,0xb8,}; +const uint8_t *_I_Health_16x16[] = {_I_Health_16x16_0}; + +const uint8_t _I_Temperature_16x16_0[] = {0x01,0x00,0x12,0x00,0x00,0x1e,0x02,0x01,0x40,0x80,0x80,0x66,0x41,0x02,0xf0,0x40,0xc0,0x23,0xc0,0x80,0x86,0xd4,}; +const uint8_t *_I_Temperature_16x16[] = {_I_Temperature_16x16_0}; + const uint8_t _I_Battery_16x16_0[] = {0x01,0x00,0x12,0x00,0x00,0x1e,0x02,0x03,0xc0,0x81,0xc8,0x20,0x80,0x11,0xd0,0x41,0x40,0x72,0x11,0x10,0xda,0x80,}; const uint8_t *_I_Battery_16x16[] = {_I_Battery_16x16_0}; const uint8_t _I_FaceConfused_29x14_0[] = {0x01,0x00,0x30,0x00,0xc0,0x00,0x46,0x1f,0x38,0x80,0xd0,0x22,0x14,0x48,0x0c,0x82,0x0f,0x52,0x80,0xe8,0x21,0x14,0xa0,0x18,0xc2,0xa6,0x59,0x19,0x24,0x27,0x09,0x48,0xa1,0x41,0x2f,0x12,0x4c,0x0c,0x0c,0x51,0x1f,0xc8,0x78,0x0c,0x7f,0xd1,0xf0,0x18,0xc3,0xa3,0x00,0x74,}; const uint8_t *_I_FaceConfused_29x14[] = {_I_FaceConfused_29x14_0}; -const uint8_t _I_Temperature_16x16_0[] = {0x01,0x00,0x12,0x00,0x00,0x1e,0x02,0x01,0x40,0x80,0x80,0x66,0x41,0x02,0xf0,0x40,0xc0,0x23,0xc0,0x80,0x86,0xd4,}; -const uint8_t *_I_Temperature_16x16[] = {_I_Temperature_16x16_0}; +const uint8_t _I_FaceNormal_29x14_0[] = {0x01,0x00,0x1e,0x00,0x00,0x1c,0xf2,0x01,0x80,0x83,0xd7,0xa0,0x1c,0x08,0x5d,0xf8,0x06,0x30,0xf0,0x1b,0x84,0xcc,0x41,0x10,0x88,0x10,0x0e,0x62,0x10,0x10,0x18,0xf8,0x00,0x42,}; +const uint8_t *_I_FaceNormal_29x14[] = {_I_FaceNormal_29x14_0}; + +const uint8_t _I_Voltage_16x16_0[] = {0x01,0x00,0x1a,0x00,0x00,0x24,0x0a,0x01,0x03,0xc0,0x40,0x78,0x10,0x1f,0x04,0x03,0xe1,0x07,0xc0,0x40,0xc0,0xe3,0xc0,0x80,0x58,0x20,0x12,0x00,0xd3,0x00,}; +const uint8_t *_I_Voltage_16x16[] = {_I_Voltage_16x16_0}; const uint8_t _I_FaceNopower_29x14_0[] = {0x01,0x00,0x24,0x00,0x00,0x1f,0x02,0x01,0x60,0x01,0xa7,0x80,0x02,0x57,0xe0,0x48,0xc3,0xe7,0xd0,0x0c,0x04,0x3c,0x39,0x1f,0x88,0x18,0x0c,0x61,0x90,0x60,0x18,0xff,0x82,0x44,0x03,0x38,0x74,0x38,0x2c,0x80,}; const uint8_t *_I_FaceNopower_29x14[] = {_I_FaceNopower_29x14_0}; +const uint8_t _I_RFIDDolphinSend_97x61_0[] = {0x01,0x00,0x8d,0x01,0x00,0x0f,0xfa,0x3e,0x04,0x2a,0x00,0x2d,0x78,0x10,0x1f,0x04,0x04,0x0a,0x38,0x00,0x62,0xcc,0x00,0x43,0x06,0x06,0x44,0x30,0x04,0x31,0x80,0x31,0x07,0x48,0x00,0x50,0x20,0x10,0xc8,0x01,0x64,0x0c,0x1d,0x04,0x28,0x24,0x83,0xd2,0x81,0x04,0xc4,0x18,0x42,0xc3,0x01,0x90,0x30,0xbe,0x05,0x51,0x29,0xa0,0x74,0x60,0x80,0xc1,0x84,0x0b,0x44,0x5e,0x43,0x73,0x82,0x41,0x20,0x1e,0x4a,0x68,0x31,0x27,0x90,0x48,0x84,0x20,0x18,0x31,0x7e,0x64,0x06,0x20,0x0c,0x2a,0x14,0x12,0x40,0x0c,0x28,0xa0,0xc4,0x41,0x87,0x81,0x17,0x08,0x30,0xa0,0xfd,0x08,0x0c,0x20,0xfc,0x38,0x08,0xc4,0x24,0x32,0x95,0x02,0x18,0xc2,0x61,0x18,0x09,0x20,0x31,0x03,0x25,0x84,0x1d,0x88,0x30,0x62,0x21,0x96,0xe2,0x44,0x22,0x00,0xc2,0x26,0xa0,0x64,0x68,0x80,0xc4,0x33,0x9e,0x92,0x9f,0x00,0xa3,0x48,0x24,0x00,0xc4,0x40,0xa4,0xa8,0x18,0xa9,0xb5,0x9b,0x48,0x28,0x05,0xa1,0x06,0x22,0xd4,0xa3,0x7e,0x05,0x98,0xe0,0x4f,0x22,0xcf,0x58,0x6f,0x80,0x10,0x34,0x24,0x31,0x3a,0x52,0x0f,0xe0,0x03,0x0c,0xf1,0xee,0x2d,0x63,0x00,0x0c,0x0f,0xe0,0x13,0x28,0xa0,0x31,0xa0,0x3f,0x08,0x18,0x10,0x45,0xa2,0xe3,0x40,0x00,0xf4,0x3f,0xe1,0xa1,0x84,0x02,0x94,0x18,0xb0,0xc0,0x63,0xc6,0x3f,0xe0,0x31,0x87,0x03,0x1e,0x11,0x3c,0x80,0x47,0xc1,0x90,0x56,0x1b,0x06,0x01,0xc0,0x20,0x06,0x17,0x88,0xf8,0x60,0xa0,0xc7,0x31,0x8a,0x58,0x60,0xe1,0x99,0x00,0x08,0x9a,0x01,0x06,0xd9,0x10,0x03,0x1f,0x44,0x19,0x43,0xc3,0x40,0xc4,0x2c,0x19,0x58,0x08,0x29,0xa0,0x60,0x0c,0xf2,0x00,0x27,0x02,0x05,0x20,0x06,0x4d,0x02,0x0b,0xc0,0x02,0x08,0x3c,0x80,0x09,0xa0,0x39,0x0a,0xd4,0x41,0x8f,0x50,0x05,0x09,0xa4,0x5b,0x4d,0x00,0xd8,0x23,0xc4,0x96,0x20,0xc7,0xac,0x40,0x2d,0x53,0x00,0x64,0x6b,0x20,0x1d,0x4a,0x08,0x32,0x2a,0x90,0x0d,0x46,0x0e,0x02,0x0c,0x79,0x51,0x08,0x61,0xf0,0x20,0x63,0xc5,0x4b,0x83,0x1e,0xfe,0x57,0xd3,0x51,0x40,0xbe,0xc0,0x08,0x42,0x00,0x53,0x30,0xe8,0x3f,0x50,0x14,0x73,0x80,0x0b,0xeb,0x07,0x61,0x40,0x00,0x7d,0x5f,0xf8,0x38,0x32,0x7a,0x03,0xf7,0x55,0xa6,0x78,0x19,0x54,0x0c,0xa8,0x32,0xa0,0x19,0xa0,0x65,0xc4,0x0b,0xe2,0x00,0x98,0x40,0x33,0xc1,0x92,0xfa,0x10,0x67,0x80,0x08,}; +const uint8_t *_I_RFIDDolphinSend_97x61[] = {_I_RFIDDolphinSend_97x61_0}; + const uint8_t _I_RFIDDolphinSuccess_108x57_0[] = {0x01,0x00,0xe7,0x01,0x00,0x0f,0x03,0xff,0x1f,0x06,0xd4,0xe2,0x01,0xe0,0x06,0xd4,0x18,0x04,0x30,0x30,0x64,0x60,0x20,0x20,0x31,0x86,0x03,0x62,0x80,0x03,0x28,0x80,0x36,0x24,0x00,0x36,0x00,0x28,0x5c,0xc3,0xe6,0x00,0x58,0x40,0xec,0xc1,0xb1,0x04,0x02,0x19,0x24,0x80,0x0b,0x02,0x02,0x40,0x37,0xc4,0x8c,0x2e,0x40,0x6f,0x93,0x8b,0x81,0x07,0x06,0xdc,0xc2,0x38,0x66,0x50,0x6a,0xe2,0x27,0xe0,0xd2,0xfc,0x08,0x09,0x0c,0x9c,0x4b,0x98,0x34,0xa0,0xe1,0xd5,0x06,0x8f,0x92,0xc2,0x05,0x1e,0x42,0xe1,0x81,0xa3,0xe2,0xf0,0xbc,0x4c,0x1a,0xff,0x2f,0x9b,0x80,0xd8,0xca,0x05,0x1f,0x97,0xfd,0xf8,0x60,0xd2,0x01,0x1e,0x00,0x1a,0x5c,0x00,0x08,0xc9,0xc1,0xab,0x40,0xf9,0x83,0x46,0x61,0x00,0xd8,0x4a,0x81,0xab,0xa0,0xf3,0x5f,0xc6,0x05,0x58,0x8a,0xa4,0x09,0x76,0x21,0xb1,0xf2,0x83,0x4f,0x5d,0x1a,0x01,0x8c,0x90,0x1a,0x31,0x0d,0x07,0xa9,0x16,0x50,0x0a,0xac,0x34,0xba,0x42,0xa1,0x88,0x50,0x23,0xaa,0x72,0xe0,0x6a,0xa1,0x4a,0x32,0x39,0x88,0x6c,0x60,0xc7,0x82,0xb0,0x55,0x60,0xa2,0x92,0x80,0xc0,0x43,0x63,0x03,0x25,0x96,0xe3,0x54,0x33,0x18,0xc4,0x90,0x22,0x21,0x81,0x81,0x03,0x4a,0xa9,0x55,0x7a,0x17,0xf3,0x82,0x9f,0x6d,0x5e,0xa9,0xb6,0x50,0x38,0x70,0x35,0x70,0x15,0x5a,0xa9,0xb8,0xa3,0x46,0x12,0x06,0x9f,0x83,0x54,0x8a,0x28,0x80,0x34,0xfc,0x08,0x93,0xaa,0xc7,0x40,0x83,0x83,0x81,0xd3,0xa1,0xd1,0x08,0x84,0x0c,0x24,0x3f,0xed,0x54,0x18,0x26,0x50,0x20,0xd9,0x42,0x21,0x90,0x4c,0x07,0xff,0xae,0x52,0x20,0x6a,0xc4,0x23,0x1f,0x88,0x3f,0xf0,0x1a,0x45,0x31,0xe7,0x03,0x4a,0x41,0xe0,0x69,0x0f,0xc2,0x1e,0x0d,0x19,0x80,0x48,0xa2,0x10,0xc5,0x68,0xdf,0x0a,0x82,0xb9,0x28,0x22,0x2c,0xe3,0x0a,0xd1,0x2b,0x0f,0x00,0x3c,0x22,0x91,0x53,0x9c,0x50,0x1a,0x30,0x08,0x39,0x1c,0x60,0x6d,0x12,0x3d,0x8c,0xc2,0x51,0x00,0x17,0x0c,0xe2,0x01,0xff,0x83,0x84,0xc6,0x40,0xb0,0x19,0x84,0xd0,0x1a,0x5c,0x08,0x1f,0xf8,0x8c,0x50,0x43,0x08,0xce,0x2d,0x06,0x71,0x5f,0x17,0xfe,0x12,0xdf,0x20,0x69,0x55,0x01,0xa6,0x00,0x18,0x40,0xa4,0x80,0x63,0x3c,0xb5,0x03,0x56,0x08,0x8b,0x20,0x10,0xcf,0x03,0x62,0x08,0x20,0x00,0x94,0xc6,0x01,0x70,0x01,0x0c,0xe8,0x36,0x20,0xd3,0xe0,0x00,0xcb,0x10,0x02,0x19,0xf3,0x9c,0x41,0xa3,0x15,0x31,0x90,0x00,0x70,0xc0,0x21,0xdd,0x86,0xc4,0x78,0x3e,0xa3,0x71,0xe0,0x30,0x20,0x31,0xbe,0x86,0xc4,0x1a,0x35,0x40,0x20,0x8d,0x89,0x28,0x5b,0xa0,0xd9,0xea,0x3d,0x44,0x42,0x87,0x83,0x48,0x36,0x49,0xe1,0xa0,0x75,0x67,0x8d,0x41,0x54,0x14,0x03,0xf5,0x2a,0x06,0x96,0x03,0x54,0xc4,0x14,0xd0,0x83,0x4a,0xfb,0x35,0x06,0x90,0x38,0x4e,0x46,0xb4,0x10,0xd9,0x81,0x49,0x72,0x40,0x01,0x0a,0x95,0xd4,0x36,0x20,0xd7,0x55,0x10,}; const uint8_t *_I_RFIDDolphinSuccess_108x57[] = {_I_RFIDDolphinSuccess_108x57_0}; -const uint8_t _I_RFIDBigChip_37x36_0[] = {0x01,0x00,0x6e,0x00,0x83,0x01,0x0f,0xcd,0xff,0x00,0x0c,0x1e,0x24,0x08,0x28,0x47,0x24,0x12,0x51,0x39,0x28,0x24,0xa2,0x91,0x5e,0x07,0xab,0xfe,0x04,0x1c,0x04,0xaa,0x01,0x15,0x02,0x28,0x4c,0x81,0x2c,0x04,0x4e,0x05,0xfc,0x08,0x35,0x59,0x06,0x02,0x81,0x15,0xca,0xe4,0x26,0xf2,0x10,0x70,0xd7,0x66,0x11,0x70,0x70,0xd4,0x20,0x14,0x10,0x70,0xc7,0x68,0x13,0x70,0x70,0xd4,0x28,0x10,0x10,0x4a,0x84,0xc6,0x80,0x13,0x10,0xe8,0xd0,0x03,0xa2,0x27,0x19,0xf0,0x9c,0x46,0x28,0x3b,0x42,0xcf,0x96,0x6a,0xd4,0x13,0x6f,0x2a,0x2c,0xa2,0x90,0x54,0x59,0xfe,0x52,0xa7,0x02,0x4f,0x9f,0xf1,0x52,0x60,}; -const uint8_t *_I_RFIDBigChip_37x36[] = {_I_RFIDBigChip_37x36_0}; - const uint8_t _I_RFIDDolphinReceive_97x61_0[] = {0x01,0x00,0x87,0x01,0x00,0x0f,0xfa,0x3e,0x04,0x28,0x08,0x2d,0x78,0x10,0x1f,0x00,0x24,0x70,0x01,0x86,0x98,0x00,0x86,0x0c,0x0c,0x88,0x60,0x08,0x63,0x10,0x0a,0x00,0x31,0xa0,0x40,0x21,0x90,0x03,0x04,0x1a,0x5a,0x08,0x50,0xe9,0x01,0x23,0x20,0x07,0x88,0x30,0xc5,0xa6,0x03,0x10,0x61,0xfc,0x0a,0xa2,0x2d,0x48,0x0c,0x82,0x20,0x04,0x18,0x40,0x40,0x42,0x44,0x37,0x28,0x80,0x30,0xbc,0x94,0xd0,0x62,0x4f,0x20,0x91,0x08,0x44,0x12,0x01,0x17,0xe6,0x40,0x42,0x45,0x00,0xa1,0x03,0x08,0xa8,0x31,0x41,0x88,0x83,0x0f,0x03,0x08,0x06,0x1c,0x1f,0xa1,0x01,0x84,0x1f,0x8a,0x31,0x09,0x0c,0xa5,0x40,0x86,0x30,0x98,0x46,0x02,0x48,0x0c,0x40,0xc9,0x61,0x00,0xe2,0x0c,0x18,0x88,0x65,0xb8,0x85,0x51,0x06,0x21,0x34,0x83,0x23,0x44,0x06,0x29,0x1c,0xb4,0x94,0xf8,0x05,0x19,0x12,0x20,0xc2,0x40,0xb4,0xa8,0x18,0xa9,0xb5,0x9b,0x48,0x28,0x05,0xa1,0x06,0x22,0xd4,0xa3,0x7e,0x05,0x98,0xe0,0x62,0x0c,0xf6,0x86,0xf8,0x16,0x63,0x42,0x06,0x0b,0xa1,0x60,0xfe,0x06,0xe8,0xcf,0x23,0x0d,0x53,0x00,0x14,0x0f,0xe0,0xea,0x28,0xa0,0x31,0xa0,0x3f,0x08,0x18,0x10,0x45,0xa2,0x11,0x20,0x01,0xf4,0x3f,0xe0,0x81,0x84,0x02,0x94,0x18,0xb0,0xc0,0x63,0xc6,0x3f,0xe0,0x31,0x87,0x03,0x1e,0x11,0x3c,0x80,0x47,0xc1,0x91,0x18,0x80,0x58,0x30,0x0e,0x01,0x00,0x30,0xbc,0x47,0xc3,0x05,0x06,0x3c,0x52,0x00,0xe4,0x20,0xcc,0x80,0x04,0x4d,0x00,0x83,0x73,0x08,0x01,0x8f,0xa2,0x0c,0xa1,0xe1,0xa0,0x62,0x16,0x0c,0xac,0x04,0x14,0xd0,0x30,0x08,0x80,0x31,0xb8,0x10,0x27,0x89,0x03,0x1e,0x81,0x05,0xe0,0x01,0x04,0x1e,0x40,0x04,0xd0,0x1c,0x85,0x6a,0x20,0xc7,0xa8,0x02,0x84,0xd2,0x34,0x00,0x63,0x6c,0x11,0xe2,0x4b,0x10,0x63,0xd6,0x20,0x16,0xa9,0x80,0x32,0x35,0x90,0x0e,0xa5,0x04,0x19,0x15,0x48,0x06,0xa3,0x07,0x01,0x06,0x3c,0xa8,0x84,0x30,0xf8,0x10,0x31,0xe2,0xa5,0xc1,0x8f,0x7f,0x2b,0xe9,0xa8,0xa0,0x5f,0x60,0x04,0x21,0x00,0x29,0x98,0x74,0x1f,0xa8,0x0a,0x39,0xc0,0x05,0xf5,0x83,0xb0,0xa0,0x00,0x3e,0xaf,0xfc,0x1c,0x19,0x3d,0x01,0xfb,0xaa,0xd3,0x3c,0x0c,0xaa,0x06,0x54,0x19,0x50,0x0c,0xd0,0x32,0xe2,0x05,0xf1,0x00,0x4c,0x20,0x19,0xe0,0xc9,0x7d,0x08,0x33,0xc0,0x04,}; const uint8_t *_I_RFIDDolphinReceive_97x61[] = {_I_RFIDDolphinReceive_97x61_0}; -const uint8_t _I_RFIDDolphinSend_97x61_0[] = {0x01,0x00,0x8d,0x01,0x00,0x0f,0xfa,0x3e,0x04,0x2a,0x00,0x2d,0x78,0x10,0x1f,0x04,0x04,0x0a,0x38,0x00,0x62,0xcc,0x00,0x43,0x06,0x06,0x44,0x30,0x04,0x31,0x80,0x31,0x07,0x48,0x00,0x50,0x20,0x10,0xc8,0x01,0x64,0x0c,0x1d,0x04,0x28,0x24,0x83,0xd2,0x81,0x04,0xc4,0x18,0x42,0xc3,0x01,0x90,0x30,0xbe,0x05,0x51,0x29,0xa0,0x74,0x60,0x80,0xc1,0x84,0x0b,0x44,0x5e,0x43,0x73,0x82,0x41,0x20,0x1e,0x4a,0x68,0x31,0x27,0x90,0x48,0x84,0x20,0x18,0x31,0x7e,0x64,0x06,0x20,0x0c,0x2a,0x14,0x12,0x40,0x0c,0x28,0xa0,0xc4,0x41,0x87,0x81,0x17,0x08,0x30,0xa0,0xfd,0x08,0x0c,0x20,0xfc,0x38,0x08,0xc4,0x24,0x32,0x95,0x02,0x18,0xc2,0x61,0x18,0x09,0x20,0x31,0x03,0x25,0x84,0x1d,0x88,0x30,0x62,0x21,0x96,0xe2,0x44,0x22,0x00,0xc2,0x26,0xa0,0x64,0x68,0x80,0xc4,0x33,0x9e,0x92,0x9f,0x00,0xa3,0x48,0x24,0x00,0xc4,0x40,0xa4,0xa8,0x18,0xa9,0xb5,0x9b,0x48,0x28,0x05,0xa1,0x06,0x22,0xd4,0xa3,0x7e,0x05,0x98,0xe0,0x4f,0x22,0xcf,0x58,0x6f,0x80,0x10,0x34,0x24,0x31,0x3a,0x52,0x0f,0xe0,0x03,0x0c,0xf1,0xee,0x2d,0x63,0x00,0x0c,0x0f,0xe0,0x13,0x28,0xa0,0x31,0xa0,0x3f,0x08,0x18,0x10,0x45,0xa2,0xe3,0x40,0x00,0xf4,0x3f,0xe1,0xa1,0x84,0x02,0x94,0x18,0xb0,0xc0,0x63,0xc6,0x3f,0xe0,0x31,0x87,0x03,0x1e,0x11,0x3c,0x80,0x47,0xc1,0x90,0x56,0x1b,0x06,0x01,0xc0,0x20,0x06,0x17,0x88,0xf8,0x60,0xa0,0xc7,0x31,0x8a,0x58,0x60,0xe1,0x99,0x00,0x08,0x9a,0x01,0x06,0xd9,0x10,0x03,0x1f,0x44,0x19,0x43,0xc3,0x40,0xc4,0x2c,0x19,0x58,0x08,0x29,0xa0,0x60,0x0c,0xf2,0x00,0x27,0x02,0x05,0x20,0x06,0x4d,0x02,0x0b,0xc0,0x02,0x08,0x3c,0x80,0x09,0xa0,0x39,0x0a,0xd4,0x41,0x8f,0x50,0x05,0x09,0xa4,0x5b,0x4d,0x00,0xd8,0x23,0xc4,0x96,0x20,0xc7,0xac,0x40,0x2d,0x53,0x00,0x64,0x6b,0x20,0x1d,0x4a,0x08,0x32,0x2a,0x90,0x0d,0x46,0x0e,0x02,0x0c,0x79,0x51,0x08,0x61,0xf0,0x20,0x63,0xc5,0x4b,0x83,0x1e,0xfe,0x57,0xd3,0x51,0x40,0xbe,0xc0,0x08,0x42,0x00,0x53,0x30,0xe8,0x3f,0x50,0x14,0x73,0x80,0x0b,0xeb,0x07,0x61,0x40,0x00,0x7d,0x5f,0xf8,0x38,0x32,0x7a,0x03,0xf7,0x55,0xa6,0x78,0x19,0x54,0x0c,0xa8,0x32,0xa0,0x19,0xa0,0x65,0xc4,0x0b,0xe2,0x00,0x98,0x40,0x33,0xc1,0x92,0xfa,0x10,0x67,0x80,0x08,}; -const uint8_t *_I_RFIDDolphinSend_97x61[] = {_I_RFIDDolphinSend_97x61_0}; - -const uint8_t _I_SDError_43x35_0[] = {0x01,0x00,0x6f,0x00,0xff,0x7f,0xc0,0x05,0x03,0x80,0x82,0x8e,0x08,0x05,0x59,0xe8,0x16,0x82,0x2d,0x30,0x8c,0x43,0x20,0xc0,0x51,0xb0,0x43,0x23,0x10,0x30,0x88,0xf0,0x20,0xdb,0x08,0x08,0x2c,0x70,0x10,0x3f,0x00,0x5c,0x80,0xa8,0x11,0x60,0xea,0x0a,0x54,0x8f,0xe5,0x99,0xfe,0x4f,0xc0,0xa6,0x70,0x10,0x89,0x60,0x23,0xff,0x91,0xa9,0x70,0x25,0xff,0x21,0xa9,0x70,0x2b,0xfe,0x42,0xc9,0x60,0x30,0x7e,0x40,0x89,0x42,0x30,0x12,0x08,0x80,0x14,0xa0,0x11,0x10,0x28,0xc0,0x66,0x10,0x08,0x74,0x30,0x8f,0xe0,0x58,0x5c,0x88,0x14,0xc0,0x43,0x01,0x8f,0x81,0x4f,0x05,0x20,0x02,0x9f,0xf3,0x80,0xcb,0x10,}; -const uint8_t *_I_SDError_43x35[] = {_I_SDError_43x35_0}; +const uint8_t _I_RFIDBigChip_37x36_0[] = {0x01,0x00,0x6e,0x00,0x83,0x01,0x0f,0xcd,0xff,0x00,0x0c,0x1e,0x24,0x08,0x28,0x47,0x24,0x12,0x51,0x39,0x28,0x24,0xa2,0x91,0x5e,0x07,0xab,0xfe,0x04,0x1c,0x04,0xaa,0x01,0x15,0x02,0x28,0x4c,0x81,0x2c,0x04,0x4e,0x05,0xfc,0x08,0x35,0x59,0x06,0x02,0x81,0x15,0xca,0xe4,0x26,0xf2,0x10,0x70,0xd7,0x66,0x11,0x70,0x70,0xd4,0x20,0x14,0x10,0x70,0xc7,0x68,0x13,0x70,0x70,0xd4,0x28,0x10,0x10,0x4a,0x84,0xc6,0x80,0x13,0x10,0xe8,0xd0,0x03,0xa2,0x27,0x19,0xf0,0x9c,0x46,0x28,0x3b,0x42,0xcf,0x96,0x6a,0xd4,0x13,0x6f,0x2a,0x2c,0xa2,0x90,0x54,0x59,0xfe,0x52,0xa7,0x02,0x4f,0x9f,0xf1,0x52,0x60,}; +const uint8_t *_I_RFIDBigChip_37x36[] = {_I_RFIDBigChip_37x36_0}; const uint8_t _I_SDQuestion_35x43_0[] = {0x01,0x00,0x67,0x00,0xf8,0x7f,0xc0,0x03,0x03,0xfc,0x01,0x0a,0x0f,0x38,0xa4,0xe4,0xa4,0x80,0x4f,0x0c,0x20,0x13,0xc0,0x9f,0x80,0x02,0x15,0xfe,0x00,0x04,0x29,0xfc,0x03,0xfd,0x07,0xfa,0x47,0xe7,0xdf,0xc8,0x3f,0xea,0x1f,0x7f,0xfc,0x41,0xff,0xb8,0xff,0xf8,0x10,0x7f,0xe0,0x4e,0xef,0x86,0x08,0x68,0x33,0xf1,0x10,0xff,0x3f,0xf1,0xf1,0x60,0x81,0x06,0x1e,0x36,0x10,0x20,0xe1,0xc0,0x87,0xc7,0x02,0x0f,0xd3,0xff,0xe3,0x02,0x0f,0xe8,0x08,0x7f,0xd0,0x21,0x89,0xc4,0x08,0x9f,0x70,0x21,0x9a,0x08,0x08,0xc1,0x89,0x02,0x20,0x62,0x40,0x8f,0xfe,0x68,0x98,}; const uint8_t *_I_SDQuestion_35x43[] = {_I_SDQuestion_35x43_0}; +const uint8_t _I_SDError_43x35_0[] = {0x01,0x00,0x6f,0x00,0xff,0x7f,0xc0,0x05,0x03,0x80,0x82,0x8e,0x08,0x05,0x59,0xe8,0x16,0x82,0x2d,0x30,0x8c,0x43,0x20,0xc0,0x51,0xb0,0x43,0x23,0x10,0x30,0x88,0xf0,0x20,0xdb,0x08,0x08,0x2c,0x70,0x10,0x3f,0x00,0x5c,0x80,0xa8,0x11,0x60,0xea,0x0a,0x54,0x8f,0xe5,0x99,0xfe,0x4f,0xc0,0xa6,0x70,0x10,0x89,0x60,0x23,0xff,0x91,0xa9,0x70,0x25,0xff,0x21,0xa9,0x70,0x2b,0xfe,0x42,0xc9,0x60,0x30,0x7e,0x40,0x89,0x42,0x30,0x12,0x08,0x80,0x14,0xa0,0x11,0x10,0x28,0xc0,0x66,0x10,0x08,0x74,0x30,0x8f,0xe0,0x58,0x5c,0x88,0x14,0xc0,0x43,0x01,0x8f,0x81,0x4f,0x05,0x20,0x02,0x9f,0xf3,0x80,0xcb,0x10,}; +const uint8_t *_I_SDError_43x35[] = {_I_SDError_43x35_0}; + const uint8_t _I_Cry_dolph_55x52_0[] = {0x01,0x00,0xe8,0x00,0x00,0x0f,0xe3,0xff,0x01,0x03,0x1f,0xfb,0xff,0x0f,0x02,0x96,0x02,0x0f,0x00,0x9f,0x01,0x8b,0xc0,0x12,0x1f,0x80,0x18,0xae,0x00,0x21,0xe0,0x07,0x0a,0x30,0x0a,0x28,0x18,0x08,0x61,0x80,0x62,0x83,0x00,0x90,0x14,0x61,0x02,0x0c,0x16,0x00,0x76,0x60,0x66,0x98,0x0b,0x04,0x90,0x60,0x66,0xb0,0x00,0x48,0x0d,0x21,0x21,0x03,0x30,0x74,0x40,0xd3,0x80,0x03,0x34,0x04,0xc0,0x52,0x00,0x32,0xc7,0xa0,0x18,0x80,0x31,0x80,0x07,0xe1,0x01,0x37,0x18,0x50,0x80,0xc2,0x92,0x10,0x31,0xe8,0x23,0xe9,0x63,0x86,0x54,0x3f,0xe0,0xe1,0x0d,0x96,0x83,0xfc,0x06,0x40,0x69,0x6c,0x3c,0x60,0xd2,0xfc,0xc0,0x60,0x58,0x48,0x0c,0x1b,0x81,0x08,0x14,0x9c,0x1a,0x81,0x04,0x03,0x46,0x80,0x0c,0x50,0x26,0x21,0xc1,0x94,0x26,0x14,0x27,0x8a,0x40,0xc0,0xc2,0xe7,0x26,0x40,0x81,0x86,0xc0,0x6b,0x28,0x64,0x0f,0x01,0x10,0x4e,0x14,0x60,0x0c,0x29,0x02,0x48,0x8b,0x5c,0x45,0x22,0x01,0x10,0x31,0x3a,0x4c,0x0c,0x34,0x06,0xf1,0xd8,0x00,0xc5,0x1a,0x64,0x94,0x0c,0xc0,0x37,0x52,0x20,0x81,0x84,0x26,0x3e,0x88,0x0c,0x38,0x28,0x54,0x0e,0xac,0x1f,0xe1,0x3f,0x06,0x96,0x82,0x7e,0x29,0x4a,0xaf,0xfd,0x76,0x30,0x3a,0x41,0x14,0x7f,0xd0,0xf8,0x78,0x18,0xaa,0x9f,0xd4,0xe0,0x83,0x4f,0xf5,0xf7,0x38,0x0b,0x9c,0x6a,0x1f,0x5b,0x5c,0x00,}; const uint8_t *_I_Cry_dolph_55x52[] = {_I_Cry_dolph_55x52_0}; -const uint8_t _I_Battery_19x8_0[] = {0x01,0x00,0x0f,0x00,0xff,0x7f,0xe0,0x30,0x18,0x04,0x08,0x04,0x90,0x60,0x12,0x02,0xcc,0x28,0x40,}; -const uint8_t *_I_Battery_19x8[] = {_I_Battery_19x8_0}; - -const uint8_t _I_SDcardFail_11x8_0[] = {0x00,0xFF,0x07,0xB7,0x07,0xFF,0x07,0x87,0x07,0x7B,0x07,0xFF,0x07,0xFF,0x07,0x67,0x00,}; -const uint8_t *_I_SDcardFail_11x8[] = {_I_SDcardFail_11x8_0}; - -const uint8_t _I_Bluetooth_5x8_0[] = {0x00,0x04,0x0D,0x16,0x0C,0x0C,0x16,0x0D,0x04,}; -const uint8_t *_I_Bluetooth_5x8[] = {_I_Bluetooth_5x8_0}; - -const uint8_t _I_PlaceholderR_30x13_0[] = {0x01,0x00,0x19,0x00,0xfe,0x7f,0xff,0xf0,0xf8,0x10,0x18,0x62,0x10,0x10,0x18,0xc8,0x00,0x7e,0x03,0xb8,0x18,0x0c,0x66,0x1f,0xe1,0x58,0xc7,0xc5,0xe6,}; -const uint8_t *_I_PlaceholderR_30x13[] = {_I_PlaceholderR_30x13_0}; - -const uint8_t _I_Battery_26x8_0[] = {0x01,0x00,0x13,0x00,0xff,0x7f,0xef,0xf0,0x08,0x0c,0x03,0x00,0x03,0x38,0x18,0x0c,0xa0,0x40,0x36,0x05,0x98,0x6d,0x00,}; -const uint8_t *_I_Battery_26x8[] = {_I_Battery_26x8_0}; +const uint8_t _I_Background_128x11_0[] = {0x01,0x00,0x70,0x00,0xff,0x40,0x40,0xc9,0xe0,0xff,0x80,0x06,0x1e,0x08,0x38,0x0c,0x0c,0x1e,0x93,0x00,0x19,0x46,0x01,0x07,0x7d,0x83,0x03,0xd2,0x31,0xff,0xdb,0xd5,0x66,0x20,0x83,0xc0,0xff,0x05,0x24,0x00,0x1c,0x78,0x28,0xbc,0x40,0x72,0xbf,0xcf,0x47,0xeb,0x40,0xdb,0x7a,0xbf,0xf0,0x40,0x39,0x60,0x28,0x3f,0xe0,0xa0,0xea,0x80,0x63,0x3f,0x0b,0x17,0xe4,0x3e,0x5a,0xbc,0xf9,0x99,0x70,0x1f,0x81,0x50,0xc0,0x80,0xe7,0x3e,0x1e,0x9d,0x57,0xfb,0x7f,0x23,0x15,0xb0,0x12,0x5b,0x5b,0x02,0x1d,0x8c,0xc3,0x80,0x24,0x9e,0x03,0x80,0x5e,0x40,0x00,0xa1,0x88,0x0e,0x98,0x00,0x7b,0x07,0x08,0xb2,0x44,0x41,}; +const uint8_t *_I_Background_128x11[] = {_I_Background_128x11_0}; const uint8_t _I_Lock_8x8_0[] = {0x00,0x3C,0x42,0x42,0xFF,0xFF,0xE7,0xFF,0xFF,}; const uint8_t *_I_Lock_8x8[] = {_I_Lock_8x8_0}; -const uint8_t _I_SDcardMounted_11x8_0[] = {0x01,0x00,0x09,0x00,0xff,0xc1,0xff,0xf0,0x40,0x1c,0xd9,0xe0,0x00,}; -const uint8_t *_I_SDcardMounted_11x8[] = {_I_SDcardMounted_11x8_0}; +const uint8_t _I_Battery_26x8_0[] = {0x01,0x00,0x13,0x00,0xff,0x7f,0xef,0xf0,0x08,0x0c,0x03,0x00,0x03,0x38,0x18,0x0c,0xa0,0x40,0x36,0x05,0x98,0x6d,0x00,}; +const uint8_t *_I_Battery_26x8[] = {_I_Battery_26x8_0}; + +const uint8_t _I_Battery_19x8_0[] = {0x01,0x00,0x0f,0x00,0xff,0x7f,0xe0,0x30,0x18,0x04,0x08,0x04,0x90,0x60,0x12,0x02,0xcc,0x28,0x40,}; +const uint8_t *_I_Battery_19x8[] = {_I_Battery_19x8_0}; + +const uint8_t _I_USBConnected_15x8_0[] = {0x00,0xF0,0x07,0x08,0x7C,0x04,0x44,0x07,0x54,0x07,0x54,0x04,0x44,0x08,0x7C,0xF0,0x07,}; +const uint8_t *_I_USBConnected_15x8[] = {_I_USBConnected_15x8_0}; const uint8_t _I_BadUsb_9x8_0[] = {0x00,0x01,0x01,0xBB,0x01,0xFE,0x00,0xFE,0x00,0xD6,0x00,0xD6,0x00,0x7C,0x00,0x38,0x00,}; const uint8_t *_I_BadUsb_9x8[] = {_I_BadUsb_9x8_0}; @@ -707,26 +722,47 @@ const uint8_t *_I_BT_Pair_9x8[] = {_I_BT_Pair_9x8_0}; const uint8_t _I_PlaceholderL_11x13_0[] = {0x01,0x00,0x10,0x00,0xfe,0x40,0x60,0x50,0x28,0x0c,0x10,0x03,0xb0,0x38,0x37,0xfe,0x07,0xfe,0x80,0x80,}; const uint8_t *_I_PlaceholderL_11x13[] = {_I_PlaceholderL_11x13_0}; -const uint8_t _I_Background_128x11_0[] = {0x01,0x00,0x70,0x00,0xff,0x40,0x40,0xc9,0xe0,0xff,0x80,0x06,0x1e,0x08,0x38,0x0c,0x0c,0x1e,0x93,0x00,0x19,0x46,0x01,0x07,0x7d,0x83,0x03,0xd2,0x31,0xff,0xdb,0xd5,0x66,0x20,0x83,0xc0,0xff,0x05,0x24,0x00,0x1c,0x78,0x28,0xbc,0x40,0x72,0xbf,0xcf,0x47,0xeb,0x40,0xdb,0x7a,0xbf,0xf0,0x40,0x39,0x60,0x28,0x3f,0xe0,0xa0,0xea,0x80,0x63,0x3f,0x0b,0x17,0xe4,0x3e,0x5a,0xbc,0xf9,0x99,0x70,0x1f,0x81,0x50,0xc0,0x80,0xe7,0x3e,0x1e,0x9d,0x57,0xfb,0x7f,0x23,0x15,0xb0,0x12,0x5b,0x5b,0x02,0x1d,0x8c,0xc3,0x80,0x24,0x9e,0x03,0x80,0x5e,0x40,0x00,0xa1,0x88,0x0e,0x98,0x00,0x7b,0x07,0x08,0xb2,0x44,0x41,}; -const uint8_t *_I_Background_128x11[] = {_I_Background_128x11_0}; +const uint8_t _I_SDcardFail_11x8_0[] = {0x00,0xFF,0x07,0xB7,0x07,0xFF,0x07,0x87,0x07,0x7B,0x07,0xFF,0x07,0xFF,0x07,0x67,0x00,}; +const uint8_t *_I_SDcardFail_11x8[] = {_I_SDcardFail_11x8_0}; -const uint8_t _I_USBConnected_15x8_0[] = {0x00,0xF0,0x07,0x08,0x7C,0x04,0x44,0x07,0x54,0x07,0x54,0x04,0x44,0x08,0x7C,0xF0,0x07,}; -const uint8_t *_I_USBConnected_15x8[] = {_I_USBConnected_15x8_0}; +const uint8_t _I_Bluetooth_5x8_0[] = {0x00,0x04,0x0D,0x16,0x0C,0x0C,0x16,0x0D,0x04,}; +const uint8_t *_I_Bluetooth_5x8[] = {_I_Bluetooth_5x8_0}; + +const uint8_t _I_PlaceholderR_30x13_0[] = {0x01,0x00,0x19,0x00,0xfe,0x7f,0xff,0xf0,0xf8,0x10,0x18,0x62,0x10,0x10,0x18,0xc8,0x00,0x7e,0x03,0xb8,0x18,0x0c,0x66,0x1f,0xe1,0x58,0xc7,0xc5,0xe6,}; +const uint8_t *_I_PlaceholderR_30x13[] = {_I_PlaceholderR_30x13_0}; + +const uint8_t _I_SDcardMounted_11x8_0[] = {0x01,0x00,0x09,0x00,0xff,0xc1,0xff,0xf0,0x40,0x1c,0xd9,0xe0,0x00,}; +const uint8_t *_I_SDcardMounted_11x8[] = {_I_SDcardMounted_11x8_0}; const uint8_t _I_Quest_7x8_0[] = {0x00,0x1E,0x33,0x33,0x30,0x18,0x0C,0x00,0x0C,}; const uint8_t *_I_Quest_7x8[] = {_I_Quest_7x8_0}; -const uint8_t _I_MHz_25x11_0[] = {0x01,0x00,0x21,0x00,0xe1,0xe1,0xa0,0x30,0x0f,0x38,0x0c,0xbf,0xe0,0x34,0xfe,0xc0,0x7b,0x7f,0xe0,0x19,0xf0,0x60,0x1d,0xbc,0x35,0x84,0x36,0x53,0x10,0x19,0x46,0x40,0x64,0x13,0x10,0x19,0x80,}; -const uint8_t *_I_MHz_25x11[] = {_I_MHz_25x11_0}; +const uint8_t _I_Lock_7x8_0[] = {0x00,0x1C,0x22,0x22,0x7F,0x7F,0x77,0x7F,0x3E,}; +const uint8_t *_I_Lock_7x8[] = {_I_Lock_7x8_0}; const uint8_t _I_Scanning_123x52_0[] = {0x01,0x00,0xd3,0x01,0x00,0x78,0x03,0xc0,0x1f,0x00,0xe0,0x7f,0xc1,0xfb,0xf0,0x80,0x41,0xc0,0xc7,0x03,0x07,0xbe,0xb2,0x07,0x18,0x07,0xc4,0x40,0x06,0x55,0x68,0x2d,0x80,0x0a,0x58,0x08,0x10,0x3c,0xe1,0x00,0x32,0xc0,0xc2,0xb0,0x00,0xf8,0x82,0x02,0x0a,0x01,0x15,0x80,0x40,0x40,0xc3,0x40,0x07,0xa0,0x10,0xa8,0x10,0x09,0xc0,0x19,0x01,0xe9,0x82,0x01,0x0c,0x82,0x01,0x74,0x13,0x1d,0x03,0x04,0x24,0x28,0x05,0x04,0x1e,0x76,0x80,0x79,0xc8,0x30,0x50,0x28,0x30,0x14,0x64,0x26,0x23,0xe8,0x78,0x21,0xe0,0xf4,0x85,0x43,0x30,0x12,0x03,0x00,0x83,0xc7,0x41,0x1c,0x3b,0x10,0x3c,0xe2,0x98,0x08,0x80,0xa4,0x61,0x1e,0x0e,0x9c,0x0c,0x1e,0x51,0x00,0x7a,0x95,0x46,0x11,0x90,0xd3,0xd0,0x24,0x80,0xfb,0xe4,0x5f,0xf0,0x92,0x80,0x79,0x61,0x01,0xe3,0xff,0x07,0x9e,0x22,0xcf,0x3e,0xc4,0x03,0xd3,0xf5,0xff,0x07,0xa5,0x12,0xc9,0x2e,0x07,0xa7,0xf3,0x5f,0xff,0x8a,0x93,0xce,0x89,0xe4,0x97,0xe2,0x25,0x40,0xf1,0x8c,0x75,0x3b,0xf1,0xf1,0xf8,0x9b,0xc8,0x1e,0x55,0x0f,0xfc,0x03,0xfd,0x1f,0xf6,0x4f,0xc9,0xe2,0x8f,0x3a,0x27,0x12,0x5f,0xea,0x68,0x0c,0x06,0x35,0xfc,0x2f,0x92,0xbc,0xf0,0x98,0x89,0x7c,0x75,0x8e,0x37,0xd8,0xf1,0x7c,0xa3,0x0c,0xf3,0xc3,0x47,0xf8,0xcb,0x81,0xc2,0x5f,0x62,0xc0,0xf2,0x77,0xa5,0x1b,0xeb,0xc3,0x6c,0x8d,0x12,0x03,0x22,0x07,0x8c,0x30,0x18,0x2d,0x82,0xc3,0xc2,0xaf,0x84,0x42,0x81,0xc8,0xb1,0x01,0xb2,0x4e,0x08,0x08,0x68,0xb0,0x50,0x20,0xdf,0xb4,0x90,0x3a,0x10,0x3d,0x19,0x05,0x86,0x1e,0x8f,0x03,0x03,0xa5,0x83,0xd0,0xa1,0x10,0x30,0x79,0x00,0x0a,0x0a,0x02,0x19,0x84,0x03,0xa5,0xff,0xc0,0x8a,0x88,0x00,0x81,0xe1,0x80,0x12,0x07,0xa5,0x1f,0xc0,0x03,0xde,0x0b,0x80,0x80,0x0a,0x47,0xa3,0x1f,0x80,0x42,0x43,0xf1,0xe1,0x80,0x60,0x3d,0x30,0xf8,0x04,0x48,0x3e,0xf0,0x08,0xf1,0x40,0x7d,0x00,0xf1,0x56,0x08,0xfe,0x20,0x17,0x0f,0x70,0x3c,0x55,0x82,0x00,0x58,0x38,0x0c,0xa7,0x9f,0x90,0x78,0x80,0x1c,0xec,0x5a,0xac,0xff,0xc0,0x1f,0x30,0x1a,0x05,0x57,0xfb,0x5f,0xf8,0x45,0xc3,0xf3,0x80,0xf5,0x7f,0xe7,0xfe,0x00,0x7c,0x87,0xc7,0xab,0xff,0x8f,0x83,0xea,0x05,0x80,0xd5,0x7f,0xe1,0xfe,0x08,0x98,0x7e,0x60,0x15,0x5a,0xac,0x0f,0xe1,0x15,0x0f,0xc9,0x78,0x75,0x50,0x0d,0x84,0x28,0x3f,0x55,0x4b,0xac,0x02,0xb1,0x0d,0x0f,0xd6,0xa0,0xf8,0x3a,0x85,0x29,0xaf,0xde,0xf8,0x04,0x1a,0xe2,0x54,0x83,0xf0,0x00,0x2d,0x70,0xd4,0x43,0xf2,0x00,0x2e,0xb8,0x3a,0x20,0x05,0x93,0xc0,0x5e,0xc1,0xf2,0x79,0x3e,0x04,0x7c,0x1f,0x32,0xa0,0x19,0x7c,0x1e,0x86,0x00,0x6a,0xa8,0x0c,0xbf,0x84,0xe9,0x4e,0x88,0x0c,0x85,0xd5,0x00,}; const uint8_t *_I_Scanning_123x52[] = {_I_Scanning_123x52_0}; +const uint8_t _I_MHz_25x11_0[] = {0x01,0x00,0x21,0x00,0xe1,0xe1,0xa0,0x30,0x0f,0x38,0x0c,0xbf,0xe0,0x34,0xfe,0xc0,0x7b,0x7f,0xe0,0x19,0xf0,0x60,0x1d,0xbc,0x35,0x84,0x36,0x53,0x10,0x19,0x46,0x40,0x64,0x13,0x10,0x19,0x80,}; +const uint8_t *_I_MHz_25x11[] = {_I_MHz_25x11_0}; + const uint8_t _I_Unlock_7x8_0[] = {0x00,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[] = {0x00,0x1C,0x22,0x22,0x7F,0x7F,0x77,0x7F,0x3E,}; -const uint8_t *_I_Lock_7x8[] = {_I_Lock_7x8_0}; +const uint8_t _I_iButtonKey_49x44_0[] = {0x01,0x00,0xb4,0x00,0x00,0x24,0xfc,0x0a,0x9c,0x0e,0x00,0x19,0x26,0x18,0x00,0x32,0x43,0x20,0x10,0x10,0x31,0xc0,0x80,0xc9,0x80,0x02,0x08,0x18,0xec,0x00,0x21,0x03,0x1c,0x40,0x1e,0x22,0x15,0xa0,0x08,0x56,0x40,0x06,0x30,0xc0,0x85,0x84,0x86,0x40,0x21,0x84,0x10,0xcc,0x04,0x30,0x40,0x31,0x02,0x88,0x3a,0x20,0x01,0x83,0x0d,0x94,0x06,0x26,0x03,0xf8,0x43,0xc5,0xe9,0x0c,0x11,0x08,0xbc,0xe0,0x64,0x21,0x23,0x09,0x38,0x80,0x22,0x28,0x20,0x58,0x99,0xc4,0x50,0x41,0xe1,0xc0,0x60,0xcc,0xab,0x47,0x21,0xa6,0x02,0x9e,0x06,0x22,0x70,0xf0,0x00,0xcb,0x40,0x03,0x18,0xb0,0x78,0x14,0xe0,0x32,0x58,0x28,0xa5,0x84,0xd0,0x51,0x80,0xc9,0x30,0x06,0xae,0x62,0x84,0x06,0x48,0x64,0x88,0x0c,0x90,0x29,0x08,0x19,0x30,0x31,0x13,0x71,0xb8,0xc4,0xea,0x70,0x6b,0xc5,0x01,0x4a,0x7f,0xc8,0x7c,0x81,0x4a,0x77,0x8a,0xac,0x45,0x4a,0x7f,0x08,0x54,0x39,0x4a,0x7e,0x0e,0xa9,0xf0,0xcb,0xe3,0x7f,0x6e,0x22,0x5c,0x59,0x44,0x00,0x28,0x7a,0xd4,0x40,0x07,0xf0,0x02,0xa0,}; +const uint8_t *_I_iButtonKey_49x44[] = {_I_iButtonKey_49x44_0}; + +const uint8_t _I_DolphinExcited_64x63_0[] = {0x01,0x00,0x36,0x01,0x00,0x25,0x00,0x0f,0xd2,0x00,0x3b,0xe0,0x00,0xeb,0x10,0x0c,0x34,0x40,0x30,0xd0,0x88,0x80,0x1d,0xa1,0x00,0x42,0xfc,0x7f,0xc0,0x63,0x04,0x01,0x0e,0x02,0x0f,0x00,0x00,0x8c,0x08,0x0e,0x37,0x00,0x10,0xc6,0x20,0x10,0x10,0xd9,0x11,0x92,0x1c,0x1a,0x3e,0x00,0x04,0x42,0x02,0x1a,0x20,0xb0,0xce,0x00,0x64,0x07,0x20,0x59,0x16,0x50,0x36,0x45,0x94,0x84,0x78,0x20,0x60,0x75,0x8e,0x43,0x06,0x63,0x3c,0x33,0x94,0x0c,0xd2,0x5c,0x30,0x38,0xe4,0x08,0x43,0x10,0xc0,0x5e,0x06,0x22,0x53,0x1a,0x02,0x08,0x7f,0xd0,0x32,0xc1,0x50,0x21,0x14,0x0e,0x70,0x1c,0x46,0xe2,0x07,0x19,0x06,0x3c,0xdc,0x20,0x91,0xae,0x01,0xcc,0xbe,0x30,0x09,0xfc,0x12,0x41,0xff,0x83,0xcc,0x0a,0xa3,0x1f,0x03,0x99,0xe8,0x7c,0x10,0xf8,0x25,0xa0,0x5e,0x50,0x0f,0x84,0x1e,0x09,0x54,0x03,0x9f,0xf2,0x07,0x02,0xd5,0x11,0xca,0x01,0xfe,0x80,0xc0,0xaa,0x9f,0xf0,0x39,0x5f,0xd0,0x43,0xaa,0x83,0x41,0x92,0xc3,0x1f,0x03,0x8d,0x52,0x02,0x2e,0x25,0xc9,0x6a,0x99,0x46,0xa6,0x2a,0xa0,0x1c,0xaf,0xca,0x62,0x94,0x28,0xcb,0x7e,0x0f,0x15,0x71,0xf8,0x3c,0x22,0x71,0x03,0x8a,0x84,0x67,0x18,0x0f,0xac,0x1c,0x0e,0x38,0x08,0x0c,0x3e,0x01,0xae,0xbd,0x13,0x0c,0x0e,0x35,0x8e,0xa8,0x1c,0xb0,0x1f,0xf8,0x06,0x83,0xf4,0x27,0x38,0x07,0xff,0xff,0x8f,0x03,0xa0,0x4c,0x80,0xed,0x60,0x03,0xb4,0x60,0x0e,0xd0,0x60,0x3a,0x87,0x84,0x0e,0xb7,0xc2,0xfa,0x18,0x05,0x44,0x20,0x73,0xff,0xf7,0xce,0xe4,0x07,0x2d,0x52,0x2c,0x80,0xe7,0x54,0xea,0x81,0xd7,0x50,0x0f,0x7a,0xaa,0x3d,0x41,0xe2,0x07,0x5a,0x80,0x3c,0xa0,0x40,0x72,0xd0,0x6a,0x80,0xa2,0x07,0x3a,0x05,0x54,0x8e,0x20,0x73,0xc0,0x03,0xd8,0x60,0x30,0x40,0x3a,0xc0,0x00,0xee,0xea,0x10,0x3b,0x80,}; +const uint8_t *_I_DolphinExcited_64x63[] = {_I_DolphinExcited_64x63_0}; + +const uint8_t _I_DolphinWait_61x59_0[] = {0x01,0x00,0x56,0x01,0x00,0x17,0xfa,0x1e,0x06,0x4f,0x84,0x06,0xe0,0x07,0x48,0x64,0x03,0x01,0x01,0x03,0x9c,0x0c,0x04,0x30,0x60,0x31,0x70,0x00,0x65,0x08,0x01,0x94,0xc0,0x06,0x51,0x00,0x5b,0x48,0x00,0x65,0x04,0x01,0x95,0x00,0x82,0xd8,0x00,0x19,0x40,0x7e,0x00,0x75,0x1f,0x88,0xe0,0x88,0x02,0x1a,0x1f,0x94,0x14,0x0e,0xbf,0x98,0x58,0x5c,0x42,0x45,0x00,0x9e,0x99,0x87,0x01,0x02,0x11,0x94,0xf2,0x2e,0x03,0x18,0x39,0x28,0x70,0x1f,0xc0,0x3e,0x42,0x00,0xe5,0x80,0xff,0xdf,0xc0,0xe5,0xf8,0x85,0xd8,0x10,0x27,0x40,0xf9,0xc2,0x63,0x88,0x12,0x82,0x6a,0x20,0x50,0x41,0xe9,0x42,0x20,0x95,0x48,0x6e,0x0c,0xfa,0x9a,0xaf,0xf9,0x90,0xe2,0x10,0x2e,0xac,0xe0,0x0e,0x98,0x29,0x52,0x11,0x13,0x23,0x15,0x3e,0x20,0x3c,0x61,0x40,0x52,0xfc,0x4f,0xe2,0x10,0x38,0x68,0x1c,0xa0,0xfc,0x08,0xbe,0x04,0x1e,0x5e,0x01,0xb9,0x03,0xc5,0x60,0x24,0xf2,0x84,0x60,0x63,0x40,0x71,0x27,0x9c,0x0e,0x2b,0x04,0x6c,0xa4,0x06,0x15,0x08,0x6c,0x99,0x8c,0xa6,0x0f,0x81,0x00,0x0c,0x08,0xf0,0x3c,0x05,0x61,0xc0,0x40,0x86,0xd0,0x30,0x78,0x80,0x0c,0xc6,0x2b,0x92,0x00,0x0d,0x51,0xf0,0x2d,0x42,0x0a,0x8e,0xaa,0x34,0x0f,0x4a,0x85,0x55,0x6e,0x20,0xf3,0xd5,0x6a,0x84,0xa2,0x66,0x2a,0x05,0xf7,0xaa,0x07,0x18,0xaf,0xfb,0x7f,0xea,0xc1,0xef,0xc0,0xe3,0xea,0x80,0xf8,0x27,0xf0,0x0a,0xc0,0x1c,0x67,0xa2,0xd1,0xb1,0xc0,0x34,0x00,0x71,0x14,0x8f,0x00,0x98,0x34,0x02,0x69,0xd0,0x37,0x90,0x16,0xf1,0x00,0x06,0xe1,0x84,0x31,0x89,0x14,0xe9,0xdc,0x40,0x38,0xa4,0xc4,0x4c,0x3c,0x1f,0x88,0x8c,0x5b,0xc3,0x01,0xbc,0x40,0x3f,0xf0,0xf6,0x71,0x0c,0x0b,0xe0,0x07,0x3c,0x0a,0xf8,0xa3,0xf0,0x03,0xb8,0xd8,0x80,0xe8,0x87,0x1b,0xa8,0x1c,0x78,0x1f,0xf8,0x0e,0x7e,0x01,0x6a,0x03,0x94,0x0f,0xfd,0xa0,0x80,0x7d,0x49,0x04,0x4d,0x12,0xc0,0xfa,0x83,0x83,0xbe,0x26,0x8d,0x02,0x05,0xd5,0xff,0xff,0xeb,0xe9,0x31,0x90,0x40,0x80,}; +const uint8_t *_I_DolphinWait_61x59[] = {_I_DolphinWait_61x59_0}; + +const uint8_t _I_iButtonDolphinVerySuccess_108x52_0[] = {0x01,0x00,0xc2,0x01,0x00,0x0f,0xe2,0xfe,0x0d,0xb8,0x3e,0x02,0x06,0x0c,0x9f,0x00,0x08,0x61,0x80,0xd9,0x8c,0x00,0x86,0x60,0x0d,0x98,0x30,0x08,0x6a,0x00,0xd9,0x80,0x80,0x87,0x40,0x0c,0x8c,0x00,0x0c,0xa8,0x01,0x12,0x00,0x2d,0x00,0x22,0x70,0x20,0x6b,0xc8,0x02,0x26,0x62,0x88,0x80,0x6c,0xc9,0x24,0x0d,0x9a,0x07,0x17,0xfe,0x1d,0x68,0x40,0x6c,0xe7,0x48,0x04,0x28,0x10,0x34,0xe8,0x10,0xd1,0x11,0xc4,0x01,0xa5,0x04,0x06,0x96,0xa0,0xa6,0x24,0xc2,0x88,0x17,0x88,0x1a,0x7d,0x43,0x78,0x82,0x4a,0x40,0x03,0x20,0xb0,0xff,0x20,0x16,0xa3,0xb2,0x48,0x03,0xe4,0x0d,0x1f,0xfc,0x06,0x3a,0x0d,0x4a,0x00,0x34,0xf8,0x00,0xd1,0x37,0x0f,0x82,0x9e,0x95,0x58,0x17,0x83,0xff,0x81,0x1b,0x0f,0xf1,0xfe,0x71,0xe0,0x69,0x7c,0x3f,0xe0,0x82,0xff,0xcf,0xc0,0x85,0x61,0x80,0x43,0xb0,0x5f,0xa8,0x79,0xdc,0x81,0xa5,0x70,0xc0,0x68,0x3c,0x10,0x1a,0x17,0xd5,0x28,0x42,0xd1,0x8f,0x84,0x46,0x83,0xb0,0x8e,0x40,0x34,0x5f,0xa8,0x38,0x34,0x45,0xa2,0x0d,0x18,0x04,0x9b,0x50,0x03,0x1a,0x14,0x35,0x36,0x5f,0x8f,0xf8,0xb8,0xa4,0x19,0x40,0x18,0xe8,0xa0,0xca,0x22,0xfe,0x7f,0xc4,0x05,0x20,0xa5,0x80,0xc6,0x82,0xcb,0x3f,0xf3,0x44,0xfc,0x12,0x40,0x18,0xe8,0x51,0x82,0x52,0x28,0xfc,0x38,0x0a,0x3e,0x48,0x98,0x6c,0x8f,0x43,0x00,0xe0,0x63,0xe0,0x62,0xe2,0x91,0x90,0x0a,0x02,0x0d,0x2f,0x82,0x50,0x41,0xa3,0x80,0x90,0x41,0x04,0xc3,0x01,0xc0,0x83,0x46,0x71,0x30,0x06,0x95,0x82,0x21,0x02,0x6e,0x88,0x6c,0x43,0x83,0x1f,0x2f,0x88,0x34,0x62,0x00,0xd1,0x15,0x08,0x2c,0x60,0xcc,0x51,0x0f,0x08,0xcc,0x81,0xa2,0x12,0x10,0x68,0xc6,0x3f,0x06,0xc2,0x06,0x8e,0x02,0x16,0x41,0x20,0x10,0xf8,0x01,0x85,0x00,0x19,0x0d,0x82,0x18,0x07,0x20,0x81,0x00,0x0c,0x9c,0x31,0x08,0x42,0x74,0x81,0xab,0x80,0x03,0x0c,0x32,0x11,0x0b,0x06,0xb9,0xc0,0x43,0xa3,0x10,0x8b,0x83,0x5c,0xe0,0x20,0x81,0xc8,0x26,0x49,0x4c,0x40,0x02,0x86,0x0a,0xc5,0x22,0x32,0x50,0x6b,0x93,0x86,0xc0,0x0d,0x19,0x18,0x35,0x8c,0x84,0x79,0x1a,0x84,0x84,0x1a,0xdf,0xc2,0xe0,0x8a,0xc7,0x51,0x22,0x06,0xb5,0x5e,0x3f,0x00,0x77,0x0d,0x60,0x36,0xfa,0xa9,0xd7,0x00,0x08,0x3a,0xc9,0x02,0x48,0xc0,0x05,0x54,0xba,0x98,0x8a,0xa8,0xf1,0x20,0x6a,0x6a,0x3d,0x43,0x61,0x80,0x4a,0x81,0xaf,0x40,0xea,0x8d,0x86,0x01,0x56,0x06,0x93,0x60,0x80,0x05,0xea,0x01,0x94,0xac,0x1b,0x11,0x80,0x19,0x45,0x41,0x44,0x0d,0x58,0x33,0x18,0xa1,0x4f,0xf3,0x06,0x1f,0x01,0x76,0x58,0x00,0xd9,0x83,0x52,0x7c,0x11,0x38,0x51,0x40,0x80,}; +const uint8_t *_I_iButtonDolphinVerySuccess_108x52[] = {_I_iButtonDolphinVerySuccess_108x52_0}; + +const uint8_t _I_DolphinMafia_115x62_0[] = {0x01,0x00,0x21,0x02,0x00,0x1e,0x02,0x06,0x0e,0xcb,0x04,0x10,0x1d,0x91,0x88,0x40,0x3b,0x20,0xc0,0xec,0xc0,0x40,0x62,0x03,0xac,0x80,0x03,0xb2,0x31,0x00,0x90,0x03,0xae,0x5e,0x0e,0xcf,0xc4,0x56,0x01,0x40,0x07,0x56,0xbe,0x14,0x0e,0x2f,0xf1,0x5e,0x2a,0xa1,0xd1,0xc0,0x7c,0x3f,0xf0,0x70,0x73,0x70,0x35,0x41,0xd1,0xc0,0x7f,0xff,0xf0,0xf0,0x73,0x50,0x03,0xa4,0x0d,0x10,0x74,0x07,0x46,0x55,0xe0,0x07,0x10,0xb1,0xc3,0xa3,0x55,0xfe,0x03,0x88,0x94,0xe1,0xd1,0xd5,0x03,0x4a,0x3e,0x59,0x9e,0xaf,0xfe,0xff,0x05,0x60,0x4e,0xab,0xf5,0xff,0x95,0xb4,0xa4,0x3a,0x3f,0xd0,0xe0,0xfa,0x20,0x20,0xf8,0xd5,0xff,0xb5,0xf0,0x0f,0x88,0x3a,0x6a,0xbf,0xf8,0xaf,0x82,0x6f,0x03,0x07,0x47,0xaf,0xff,0x0a,0xfe,0x5f,0xc1,0xd3,0xf6,0xbf,0xe0,0x7f,0xfe,0xf0,0x73,0x41,0x00,0x43,0xfa,0xd7,0xf8,0x27,0xfe,0xe0,0x73,0x40,0x80,0x43,0xfe,0xab,0xfe,0x21,0xfc,0xe5,0x9b,0x05,0x48,0xea,0x3f,0xc8,0xfa,0xc4,0x66,0x07,0x44,0x0e,0x8f,0x00,0xb0,0x2b,0x31,0x07,0x0f,0x00,0x1c,0x72,0x00,0x70,0xf8,0x37,0xe5,0x81,0xff,0x89,0x08,0xf2,0x71,0x80,0x20,0xfe,0x2b,0xf0,0x5f,0xc0,0x38,0xc8,0xa5,0x60,0xc3,0x00,0xc7,0xf9,0xaf,0x81,0x2d,0x04,0x34,0x40,0xe1,0x98,0x47,0x68,0x04,0x92,0xab,0xc0,0x7e,0xb7,0xf7,0x39,0x03,0x85,0x8e,0x24,0xf1,0xc0,0x7f,0xf5,0x78,0x0f,0x53,0xb4,0xbc,0x1f,0xb8,0x1a,0x0c,0x61,0xc5,0x82,0xab,0xc0,0x3e,0xa3,0xa2,0xfc,0x07,0x46,0x09,0x60,0x19,0x8f,0x80,0xec,0x38,0x08,0x52,0x6c,0xb8,0xdc,0x28,0x7c,0x10,0x2a,0x5f,0x0f,0xfc,0x5a,0x01,0x05,0x1a,0x8e,0x02,0x02,0x1d,0x1f,0x81,0xa8,0xbe,0x13,0xf8,0x52,0x2c,0x8c,0x62,0x77,0x42,0x11,0x40,0xe0,0xca,0x93,0x8e,0x03,0x8a,0x30,0x10,0x48,0x54,0x03,0x04,0xbb,0x2c,0x00,0x0c,0x64,0x80,0xe4,0x0e,0x88,0x38,0x7c,0x10,0x04,0x09,0x48,0x83,0xac,0x1b,0x18,0xf3,0x44,0xc1,0xca,0x1d,0x15,0x40,0x8e,0x05,0x02,0x20,0xe6,0x24,0x12,0x8c,0x8b,0x05,0x21,0x07,0x24,0x14,0x08,0x73,0x80,0x19,0x78,0x43,0xb2,0xff,0x15,0x30,0xc4,0x01,0x26,0x8f,0x14,0x61,0xa9,0x8a,0x09,0x10,0x02,0x12,0x1c,0x80,0x84,0xaf,0x10,0x71,0xaa,0xc4,0x00,0x3b,0x04,0xea,0x24,0x48,0x1c,0xbd,0x8f,0xf8,0x00,0x67,0xf0,0x09,0x40,0x20,0x61,0x00,0xe4,0xf6,0x07,0x4b,0xc1,0x1f,0x07,0x14,0x40,0x1c,0x9d,0x66,0x79,0x24,0xc6,0xa0,0x0e,0x32,0x51,0xfa,0xce,0xe7,0x50,0x07,0x1c,0x80,0x30,0x58,0x0e,0xa2,0xcc,0xa0,0x19,0x00,0x71,0x42,0x13,0x27,0x40,0xf5,0x45,0x41,0xc5,0x08,0xb0,0x80,0xc6,0x18,0xf2,0x28,0x04,0x83,0xe8,0x58,0x10,0x30,0xc2,0x2c,0x40,0x91,0x89,0x3c,0x88,0x62,0x21,0xd2,0xff,0x03,0x87,0xc8,0x12,0x19,0x08,0x39,0x3e,0x83,0xb2,0x4a,0x0e,0xa2,0x0d,0xc0,0xe0,0x50,0x06,0xa7,0xe8,0x2c,0x94,0xc2,0x09,0x50,0x8c,0xce,0x20,0x34,0x70,0x71,0x41,0x3e,0x85,0xe2,0xe0,0x41,0x38,0x1e,0x28,0x3c,0x19,0xc8,0x70,0x4f,0xc1,0xdc,0xe0,0x74,0x01,0xd8,0xc6,0x24,0x00,0x82,0x81,0x7c,0x12,0xa6,0x7e,0x10,0x28,0xd8,0x22,0x00,0xe3,0xfc,0x34,0x53,0x00,0x23,0x1c,0x04,0x44,0x0e,0x50,0x10,0xeb,0x17,0xca,0x1c,0x07,0x20,}; +const uint8_t *_I_DolphinMafia_115x62[] = {_I_DolphinMafia_115x62_0}; const uint8_t _I_DolphinNice_96x59_0[] = {0x01,0x00,0x8a,0x01,0x00,0x37,0xfa,0x3e,0x0a,0x8f,0x04,0x04,0x02,0x20,0xb7,0x8c,0x00,0x86,0x1c,0x0b,0x78,0x20,0x08,0x66,0x00,0xb7,0x81,0x00,0x86,0x80,0x0b,0x71,0x61,0x60,0x01,0x4c,0x07,0x41,0xe3,0x07,0xd0,0x4e,0x40,0xb8,0x1f,0x90,0x00,0xe4,0x00,0xba,0x88,0x01,0x0e,0x10,0x0a,0x48,0xf9,0x6c,0xbe,0x10,0x70,0x82,0x78,0x3c,0x15,0x82,0x18,0xc2,0x21,0x00,0xb4,0x02,0x0e,0xbc,0x86,0x30,0x48,0x80,0xd1,0x05,0x03,0x78,0x82,0xc0,0x3e,0x52,0x32,0x63,0x70,0x20,0x70,0x09,0xd4,0x98,0xb0,0xf0,0x60,0x58,0xc9,0xce,0x12,0x0b,0xbf,0xd4,0x9d,0x28,0x9e,0x24,0xa9,0x82,0xda,0x24,0x2d,0x10,0x00,0xfd,0x2a,0x60,0xb4,0x85,0x4e,0x00,0x85,0xf8,0xd4,0x82,0xd2,0x09,0xc0,0x12,0x14,0x12,0xad,0x81,0x29,0xa8,0x90,0xf5,0x01,0x75,0x80,0x46,0x00,0xa5,0x50,0x0b,0x90,0x1c,0x41,0x63,0x60,0x05,0x96,0xc0,0x2e,0x52,0x44,0x79,0x60,0x06,0x05,0x50,0x05,0x94,0x89,0x88,0x63,0x02,0x98,0x02,0xc7,0xc1,0x21,0x6a,0x98,0xa0,0x62,0x11,0x00,0x58,0xc6,0x02,0xe2,0xb8,0x21,0x80,0xc3,0x05,0x02,0x38,0x11,0x78,0xa5,0x0b,0x01,0x81,0x5a,0x88,0x2c,0x60,0x40,0xb1,0xc0,0x27,0x0a,0xfc,0x0f,0x28,0x04,0x06,0x50,0x05,0x18,0xa9,0x94,0xc1,0x67,0x48,0x02,0x8c,0xb8,0x16,0xf8,0x80,0x28,0xd6,0x16,0x86,0x0b,0x38,0x40,0xd4,0x76,0x0c,0xd4,0x05,0x94,0x10,0x9a,0x34,0x01,0x82,0x1f,0x06,0x05,0x02,0x98,0x01,0x47,0x54,0x18,0x35,0xc8,0xff,0x20,0x3c,0x00,0x58,0xd5,0x6a,0xa0,0xb3,0x81,0xa3,0x0a,0x0f,0x80,0xd5,0xea,0x81,0x67,0x07,0x46,0x14,0xe3,0xe1,0x55,0x18,0x18,0x2c,0x51,0x85,0xc0,0xef,0x85,0x8c,0x0c,0x30,0xf4,0x61,0x40,0x2d,0x46,0xb4,0x05,0x8b,0x04,0xb0,0x15,0x40,0x5a,0x50,0x23,0xe6,0x01,0x02,0x8c,0xa8,0x2e,0xb1,0xe5,0x40,0x81,0x46,0x6a,0x17,0x59,0xeb,0xe4,0xa8,0x11,0xa0,0x5a,0x68,0x27,0x4e,0xd3,0x59,0xad,0x82,0xfa,0xed,0x2a,0x04,0x28,0x2e,0xb7,0xa7,0x69,0xc3,0x42,0xeb,0xf5,0x1f,0x09,0x4c,0x42,0xed,0xea,0x01,0x8c,0x06,0x41,0x05,0x0b,0xbc,0x02,0x0d,0x80,0x83,0x05,0xe2,0x11,0x40,0x0b,0xb7,0x14,0x06,0x33,0x0c,0x83,0x89,0x02,0xe3,0xca,0x3d,0x95,0x01,0xe2,0x21,0x74,0xc2,0x81,0x0b,0x0e,0x17,0x6c,0x10,0x10,0xaf,0x09,0xe2,0x0b,0xbb,0xd0,0x42,0xeb,0x02,}; const uint8_t *_I_DolphinNice_96x59[] = {_I_DolphinNice_96x59_0}; @@ -734,21 +770,6 @@ const uint8_t *_I_DolphinNice_96x59[] = {_I_DolphinNice_96x59_0}; const uint8_t _I_iButtonDolphinSuccess_109x60_0[] = {0x01,0x00,0xac,0x01,0x00,0x17,0xfe,0x1e,0x0c,0xaf,0x04,0x02,0xe0,0x0d,0xa8,0xf4,0x03,0x01,0x03,0x06,0x46,0x02,0x02,0x03,0x18,0xe0,0x36,0x2c,0x00,0x36,0x00,0x2c,0x40,0x3e,0x60,0xd8,0x84,0x01,0x0c,0x5a,0x40,0x05,0x82,0x01,0x0e,0x04,0x0d,0x70,0x42,0x04,0x90,0x49,0x02,0xe4,0x20,0x41,0x28,0xc0,0x07,0x40,0x06,0xf8,0x00,0xa4,0x00,0xd6,0x03,0xa8,0x37,0x44,0x2a,0x31,0x74,0xd3,0x83,0x57,0x80,0x0d,0xc7,0x18,0xa9,0xa8,0x36,0x2a,0x86,0x06,0x8d,0xfc,0x36,0x60,0xd7,0xc0,0x3b,0x8c,0x36,0xf0,0x4a,0x05,0xf9,0x6e,0x5e,0x06,0x23,0x41,0x24,0x1f,0xf6,0x01,0x74,0x01,0xb1,0xe3,0x82,0x81,0x47,0x40,0x0d,0x7c,0x87,0x8e,0x12,0x05,0x1a,0x84,0x0d,0xb6,0xa0,0xd2,0x85,0x86,0xc8,0x1a,0x50,0x40,0x69,0x40,0xb2,0x1f,0xf0,0x69,0x50,0x01,0xa5,0x08,0xfc,0x03,0x5f,0x60,0x0d,0x28,0x84,0x1a,0x07,0x18,0x06,0xaf,0x00,0x1a,0x3c,0x03,0xb8,0xc3,0x20,0xd0,0x28,0x87,0xfc,0x8a,0x50,0x08,0x78,0x08,0x70,0x77,0x0c,0x44,0x06,0x05,0x30,0xff,0x18,0x4a,0x01,0x30,0x01,0x0d,0x33,0x19,0x11,0x1b,0x8c,0xa2,0xf8,0x7d,0x27,0x71,0xd0,0x20,0x51,0x20,0x68,0xd5,0x00,0x42,0x0d,0x2c,0x00,0x08,0x64,0x10,0x19,0x20,0x28,0x75,0x07,0x53,0x3d,0x18,0x35,0x2a,0x9f,0xf4,0x9a,0x41,0x90,0x23,0x00,0x94,0x43,0xe0,0x5e,0xae,0x03,0x9d,0xb4,0xe0,0xd1,0x0d,0x8c,0xd0,0x52,0xb1,0x00,0xd9,0x83,0x46,0x34,0x45,0x41,0xa8,0x9f,0x86,0x01,0x14,0x05,0x08,0x08,0x81,0xa6,0x62,0x10,0x68,0xe5,0x20,0x70,0x41,0x80,0x80,0x10,0xc4,0x34,0x48,0x04,0x2a,0x38,0x0d,0x99,0x16,0x02,0x1a,0xd5,0x10,0x6c,0x5e,0x2e,0x0b,0xa1,0x4b,0x0a,0x60,0xc1,0xa7,0x84,0xfc,0x58,0x01,0xb5,0x02,0x82,0xb4,0xc4,0x16,0x22,0xa5,0x06,0x96,0x19,0x20,0x20,0xd7,0x30,0x8c,0x0f,0x08,0x05,0x10,0x68,0xa1,0x44,0x1a,0x98,0x08,0x14,0x11,0x28,0x21,0x91,0x1d,0x8f,0x83,0xfe,0x07,0x1b,0x00,0x34,0x61,0x00,0xd3,0x1d,0x8c,0x7a,0x01,0x7e,0x80,0x56,0x30,0x06,0xb1,0x4a,0x08,0xd4,0xbf,0xc1,0x31,0xc0,0x7f,0xe8,0xf0,0x08,0x3c,0x40,0x1a,0x80,0x04,0x5a,0x8c,0x10,0x80,0x40,0xd7,0x05,0x08,0x36,0xc0,0xe2,0x0d,0xb8,0x30,0x34,0x45,0x82,0x0d,0x72,0x49,0x03,0x5a,0x41,0x55,0xf8,0x7f,0xff,0xe8,0x72,0x06,0xae,0x03,0xf4,0x0c,0x1d,0xf8,0x18,0x60,0x40,0xd2,0x4b,0x9f,0xd0,0x1a,0x35,0x71,0x48,0xc0,0x95,0x42,0x0d,0x4d,0x50,0x70,0x75,0x40,0xd1,0x80,0x83,0x5a,0xa1,0x55,0x00,0x0c,0x05,0xa4,0x20,0xd2,}; const uint8_t *_I_iButtonDolphinSuccess_109x60[] = {_I_iButtonDolphinSuccess_109x60_0}; -const uint8_t _I_DolphinExcited_64x63_0[] = {0x01,0x00,0x36,0x01,0x00,0x25,0x00,0x0f,0xd2,0x00,0x3b,0xe0,0x00,0xeb,0x10,0x0c,0x34,0x40,0x30,0xd0,0x88,0x80,0x1d,0xa1,0x00,0x42,0xfc,0x7f,0xc0,0x63,0x04,0x01,0x0e,0x02,0x0f,0x00,0x00,0x8c,0x08,0x0e,0x37,0x00,0x10,0xc6,0x20,0x10,0x10,0xd9,0x11,0x92,0x1c,0x1a,0x3e,0x00,0x04,0x42,0x02,0x1a,0x20,0xb0,0xce,0x00,0x64,0x07,0x20,0x59,0x16,0x50,0x36,0x45,0x94,0x84,0x78,0x20,0x60,0x75,0x8e,0x43,0x06,0x63,0x3c,0x33,0x94,0x0c,0xd2,0x5c,0x30,0x38,0xe4,0x08,0x43,0x10,0xc0,0x5e,0x06,0x22,0x53,0x1a,0x02,0x08,0x7f,0xd0,0x32,0xc1,0x50,0x21,0x14,0x0e,0x70,0x1c,0x46,0xe2,0x07,0x19,0x06,0x3c,0xdc,0x20,0x91,0xae,0x01,0xcc,0xbe,0x30,0x09,0xfc,0x12,0x41,0xff,0x83,0xcc,0x0a,0xa3,0x1f,0x03,0x99,0xe8,0x7c,0x10,0xf8,0x25,0xa0,0x5e,0x50,0x0f,0x84,0x1e,0x09,0x54,0x03,0x9f,0xf2,0x07,0x02,0xd5,0x11,0xca,0x01,0xfe,0x80,0xc0,0xaa,0x9f,0xf0,0x39,0x5f,0xd0,0x43,0xaa,0x83,0x41,0x92,0xc3,0x1f,0x03,0x8d,0x52,0x02,0x2e,0x25,0xc9,0x6a,0x99,0x46,0xa6,0x2a,0xa0,0x1c,0xaf,0xca,0x62,0x94,0x28,0xcb,0x7e,0x0f,0x15,0x71,0xf8,0x3c,0x22,0x71,0x03,0x8a,0x84,0x67,0x18,0x0f,0xac,0x1c,0x0e,0x38,0x08,0x0c,0x3e,0x01,0xae,0xbd,0x13,0x0c,0x0e,0x35,0x8e,0xa8,0x1c,0xb0,0x1f,0xf8,0x06,0x83,0xf4,0x27,0x38,0x07,0xff,0xff,0x8f,0x03,0xa0,0x4c,0x80,0xed,0x60,0x03,0xb4,0x60,0x0e,0xd0,0x60,0x3a,0x87,0x84,0x0e,0xb7,0xc2,0xfa,0x18,0x05,0x44,0x20,0x73,0xff,0xf7,0xce,0xe4,0x07,0x2d,0x52,0x2c,0x80,0xe7,0x54,0xea,0x81,0xd7,0x50,0x0f,0x7a,0xaa,0x3d,0x41,0xe2,0x07,0x5a,0x80,0x3c,0xa0,0x40,0x72,0xd0,0x6a,0x80,0xa2,0x07,0x3a,0x05,0x54,0x8e,0x20,0x73,0xc0,0x03,0xd8,0x60,0x30,0x40,0x3a,0xc0,0x00,0xee,0xea,0x10,0x3b,0x80,}; -const uint8_t *_I_DolphinExcited_64x63[] = {_I_DolphinExcited_64x63_0}; - -const uint8_t _I_iButtonKey_49x44_0[] = {0x01,0x00,0xb4,0x00,0x00,0x24,0xfc,0x0a,0x9c,0x0e,0x00,0x19,0x26,0x18,0x00,0x32,0x43,0x20,0x10,0x10,0x31,0xc0,0x80,0xc9,0x80,0x02,0x08,0x18,0xec,0x00,0x21,0x03,0x1c,0x40,0x1e,0x22,0x15,0xa0,0x08,0x56,0x40,0x06,0x30,0xc0,0x85,0x84,0x86,0x40,0x21,0x84,0x10,0xcc,0x04,0x30,0x40,0x31,0x02,0x88,0x3a,0x20,0x01,0x83,0x0d,0x94,0x06,0x26,0x03,0xf8,0x43,0xc5,0xe9,0x0c,0x11,0x08,0xbc,0xe0,0x64,0x21,0x23,0x09,0x38,0x80,0x22,0x28,0x20,0x58,0x99,0xc4,0x50,0x41,0xe1,0xc0,0x60,0xcc,0xab,0x47,0x21,0xa6,0x02,0x9e,0x06,0x22,0x70,0xf0,0x00,0xcb,0x40,0x03,0x18,0xb0,0x78,0x14,0xe0,0x32,0x58,0x28,0xa5,0x84,0xd0,0x51,0x80,0xc9,0x30,0x06,0xae,0x62,0x84,0x06,0x48,0x64,0x88,0x0c,0x90,0x29,0x08,0x19,0x30,0x31,0x13,0x71,0xb8,0xc4,0xea,0x70,0x6b,0xc5,0x01,0x4a,0x7f,0xc8,0x7c,0x81,0x4a,0x77,0x8a,0xac,0x45,0x4a,0x7f,0x08,0x54,0x39,0x4a,0x7e,0x0e,0xa9,0xf0,0xcb,0xe3,0x7f,0x6e,0x22,0x5c,0x59,0x44,0x00,0x28,0x7a,0xd4,0x40,0x07,0xf0,0x02,0xa0,}; -const uint8_t *_I_iButtonKey_49x44[] = {_I_iButtonKey_49x44_0}; - -const uint8_t _I_iButtonDolphinVerySuccess_108x52_0[] = {0x01,0x00,0xc2,0x01,0x00,0x0f,0xe2,0xfe,0x0d,0xb8,0x3e,0x02,0x06,0x0c,0x9f,0x00,0x08,0x61,0x80,0xd9,0x8c,0x00,0x86,0x60,0x0d,0x98,0x30,0x08,0x6a,0x00,0xd9,0x80,0x80,0x87,0x40,0x0c,0x8c,0x00,0x0c,0xa8,0x01,0x12,0x00,0x2d,0x00,0x22,0x70,0x20,0x6b,0xc8,0x02,0x26,0x62,0x88,0x80,0x6c,0xc9,0x24,0x0d,0x9a,0x07,0x17,0xfe,0x1d,0x68,0x40,0x6c,0xe7,0x48,0x04,0x28,0x10,0x34,0xe8,0x10,0xd1,0x11,0xc4,0x01,0xa5,0x04,0x06,0x96,0xa0,0xa6,0x24,0xc2,0x88,0x17,0x88,0x1a,0x7d,0x43,0x78,0x82,0x4a,0x40,0x03,0x20,0xb0,0xff,0x20,0x16,0xa3,0xb2,0x48,0x03,0xe4,0x0d,0x1f,0xfc,0x06,0x3a,0x0d,0x4a,0x00,0x34,0xf8,0x00,0xd1,0x37,0x0f,0x82,0x9e,0x95,0x58,0x17,0x83,0xff,0x81,0x1b,0x0f,0xf1,0xfe,0x71,0xe0,0x69,0x7c,0x3f,0xe0,0x82,0xff,0xcf,0xc0,0x85,0x61,0x80,0x43,0xb0,0x5f,0xa8,0x79,0xdc,0x81,0xa5,0x70,0xc0,0x68,0x3c,0x10,0x1a,0x17,0xd5,0x28,0x42,0xd1,0x8f,0x84,0x46,0x83,0xb0,0x8e,0x40,0x34,0x5f,0xa8,0x38,0x34,0x45,0xa2,0x0d,0x18,0x04,0x9b,0x50,0x03,0x1a,0x14,0x35,0x36,0x5f,0x8f,0xf8,0xb8,0xa4,0x19,0x40,0x18,0xe8,0xa0,0xca,0x22,0xfe,0x7f,0xc4,0x05,0x20,0xa5,0x80,0xc6,0x82,0xcb,0x3f,0xf3,0x44,0xfc,0x12,0x40,0x18,0xe8,0x51,0x82,0x52,0x28,0xfc,0x38,0x0a,0x3e,0x48,0x98,0x6c,0x8f,0x43,0x00,0xe0,0x63,0xe0,0x62,0xe2,0x91,0x90,0x0a,0x02,0x0d,0x2f,0x82,0x50,0x41,0xa3,0x80,0x90,0x41,0x04,0xc3,0x01,0xc0,0x83,0x46,0x71,0x30,0x06,0x95,0x82,0x21,0x02,0x6e,0x88,0x6c,0x43,0x83,0x1f,0x2f,0x88,0x34,0x62,0x00,0xd1,0x15,0x08,0x2c,0x60,0xcc,0x51,0x0f,0x08,0xcc,0x81,0xa2,0x12,0x10,0x68,0xc6,0x3f,0x06,0xc2,0x06,0x8e,0x02,0x16,0x41,0x20,0x10,0xf8,0x01,0x85,0x00,0x19,0x0d,0x82,0x18,0x07,0x20,0x81,0x00,0x0c,0x9c,0x31,0x08,0x42,0x74,0x81,0xab,0x80,0x03,0x0c,0x32,0x11,0x0b,0x06,0xb9,0xc0,0x43,0xa3,0x10,0x8b,0x83,0x5c,0xe0,0x20,0x81,0xc8,0x26,0x49,0x4c,0x40,0x02,0x86,0x0a,0xc5,0x22,0x32,0x50,0x6b,0x93,0x86,0xc0,0x0d,0x19,0x18,0x35,0x8c,0x84,0x79,0x1a,0x84,0x84,0x1a,0xdf,0xc2,0xe0,0x8a,0xc7,0x51,0x22,0x06,0xb5,0x5e,0x3f,0x00,0x77,0x0d,0x60,0x36,0xfa,0xa9,0xd7,0x00,0x08,0x3a,0xc9,0x02,0x48,0xc0,0x05,0x54,0xba,0x98,0x8a,0xa8,0xf1,0x20,0x6a,0x6a,0x3d,0x43,0x61,0x80,0x4a,0x81,0xaf,0x40,0xea,0x8d,0x86,0x01,0x56,0x06,0x93,0x60,0x80,0x05,0xea,0x01,0x94,0xac,0x1b,0x11,0x80,0x19,0x45,0x41,0x44,0x0d,0x58,0x33,0x18,0xa1,0x4f,0xf3,0x06,0x1f,0x01,0x76,0x58,0x00,0xd9,0x83,0x52,0x7c,0x11,0x38,0x51,0x40,0x80,}; -const uint8_t *_I_iButtonDolphinVerySuccess_108x52[] = {_I_iButtonDolphinVerySuccess_108x52_0}; - -const uint8_t _I_DolphinWait_61x59_0[] = {0x01,0x00,0x56,0x01,0x00,0x17,0xfa,0x1e,0x06,0x4f,0x84,0x06,0xe0,0x07,0x48,0x64,0x03,0x01,0x01,0x03,0x9c,0x0c,0x04,0x30,0x60,0x31,0x70,0x00,0x65,0x08,0x01,0x94,0xc0,0x06,0x51,0x00,0x5b,0x48,0x00,0x65,0x04,0x01,0x95,0x00,0x82,0xd8,0x00,0x19,0x40,0x7e,0x00,0x75,0x1f,0x88,0xe0,0x88,0x02,0x1a,0x1f,0x94,0x14,0x0e,0xbf,0x98,0x58,0x5c,0x42,0x45,0x00,0x9e,0x99,0x87,0x01,0x02,0x11,0x94,0xf2,0x2e,0x03,0x18,0x39,0x28,0x70,0x1f,0xc0,0x3e,0x42,0x00,0xe5,0x80,0xff,0xdf,0xc0,0xe5,0xf8,0x85,0xd8,0x10,0x27,0x40,0xf9,0xc2,0x63,0x88,0x12,0x82,0x6a,0x20,0x50,0x41,0xe9,0x42,0x20,0x95,0x48,0x6e,0x0c,0xfa,0x9a,0xaf,0xf9,0x90,0xe2,0x10,0x2e,0xac,0xe0,0x0e,0x98,0x29,0x52,0x11,0x13,0x23,0x15,0x3e,0x20,0x3c,0x61,0x40,0x52,0xfc,0x4f,0xe2,0x10,0x38,0x68,0x1c,0xa0,0xfc,0x08,0xbe,0x04,0x1e,0x5e,0x01,0xb9,0x03,0xc5,0x60,0x24,0xf2,0x84,0x60,0x63,0x40,0x71,0x27,0x9c,0x0e,0x2b,0x04,0x6c,0xa4,0x06,0x15,0x08,0x6c,0x99,0x8c,0xa6,0x0f,0x81,0x00,0x0c,0x08,0xf0,0x3c,0x05,0x61,0xc0,0x40,0x86,0xd0,0x30,0x78,0x80,0x0c,0xc6,0x2b,0x92,0x00,0x0d,0x51,0xf0,0x2d,0x42,0x0a,0x8e,0xaa,0x34,0x0f,0x4a,0x85,0x55,0x6e,0x20,0xf3,0xd5,0x6a,0x84,0xa2,0x66,0x2a,0x05,0xf7,0xaa,0x07,0x18,0xaf,0xfb,0x7f,0xea,0xc1,0xef,0xc0,0xe3,0xea,0x80,0xf8,0x27,0xf0,0x0a,0xc0,0x1c,0x67,0xa2,0xd1,0xb1,0xc0,0x34,0x00,0x71,0x14,0x8f,0x00,0x98,0x34,0x02,0x69,0xd0,0x37,0x90,0x16,0xf1,0x00,0x06,0xe1,0x84,0x31,0x89,0x14,0xe9,0xdc,0x40,0x38,0xa4,0xc4,0x4c,0x3c,0x1f,0x88,0x8c,0x5b,0xc3,0x01,0xbc,0x40,0x3f,0xf0,0xf6,0x71,0x0c,0x0b,0xe0,0x07,0x3c,0x0a,0xf8,0xa3,0xf0,0x03,0xb8,0xd8,0x80,0xe8,0x87,0x1b,0xa8,0x1c,0x78,0x1f,0xf8,0x0e,0x7e,0x01,0x6a,0x03,0x94,0x0f,0xfd,0xa0,0x80,0x7d,0x49,0x04,0x4d,0x12,0xc0,0xfa,0x83,0x83,0xbe,0x26,0x8d,0x02,0x05,0xd5,0xff,0xff,0xeb,0xe9,0x31,0x90,0x40,0x80,}; -const uint8_t *_I_DolphinWait_61x59[] = {_I_DolphinWait_61x59_0}; - -const uint8_t _I_DolphinMafia_115x62_0[] = {0x01,0x00,0x21,0x02,0x00,0x1e,0x02,0x06,0x0e,0xcb,0x04,0x10,0x1d,0x91,0x88,0x40,0x3b,0x20,0xc0,0xec,0xc0,0x40,0x62,0x03,0xac,0x80,0x03,0xb2,0x31,0x00,0x90,0x03,0xae,0x5e,0x0e,0xcf,0xc4,0x56,0x01,0x40,0x07,0x56,0xbe,0x14,0x0e,0x2f,0xf1,0x5e,0x2a,0xa1,0xd1,0xc0,0x7c,0x3f,0xf0,0x70,0x73,0x70,0x35,0x41,0xd1,0xc0,0x7f,0xff,0xf0,0xf0,0x73,0x50,0x03,0xa4,0x0d,0x10,0x74,0x07,0x46,0x55,0xe0,0x07,0x10,0xb1,0xc3,0xa3,0x55,0xfe,0x03,0x88,0x94,0xe1,0xd1,0xd5,0x03,0x4a,0x3e,0x59,0x9e,0xaf,0xfe,0xff,0x05,0x60,0x4e,0xab,0xf5,0xff,0x95,0xb4,0xa4,0x3a,0x3f,0xd0,0xe0,0xfa,0x20,0x20,0xf8,0xd5,0xff,0xb5,0xf0,0x0f,0x88,0x3a,0x6a,0xbf,0xf8,0xaf,0x82,0x6f,0x03,0x07,0x47,0xaf,0xff,0x0a,0xfe,0x5f,0xc1,0xd3,0xf6,0xbf,0xe0,0x7f,0xfe,0xf0,0x73,0x41,0x00,0x43,0xfa,0xd7,0xf8,0x27,0xfe,0xe0,0x73,0x40,0x80,0x43,0xfe,0xab,0xfe,0x21,0xfc,0xe5,0x9b,0x05,0x48,0xea,0x3f,0xc8,0xfa,0xc4,0x66,0x07,0x44,0x0e,0x8f,0x00,0xb0,0x2b,0x31,0x07,0x0f,0x00,0x1c,0x72,0x00,0x70,0xf8,0x37,0xe5,0x81,0xff,0x89,0x08,0xf2,0x71,0x80,0x20,0xfe,0x2b,0xf0,0x5f,0xc0,0x38,0xc8,0xa5,0x60,0xc3,0x00,0xc7,0xf9,0xaf,0x81,0x2d,0x04,0x34,0x40,0xe1,0x98,0x47,0x68,0x04,0x92,0xab,0xc0,0x7e,0xb7,0xf7,0x39,0x03,0x85,0x8e,0x24,0xf1,0xc0,0x7f,0xf5,0x78,0x0f,0x53,0xb4,0xbc,0x1f,0xb8,0x1a,0x0c,0x61,0xc5,0x82,0xab,0xc0,0x3e,0xa3,0xa2,0xfc,0x07,0x46,0x09,0x60,0x19,0x8f,0x80,0xec,0x38,0x08,0x52,0x6c,0xb8,0xdc,0x28,0x7c,0x10,0x2a,0x5f,0x0f,0xfc,0x5a,0x01,0x05,0x1a,0x8e,0x02,0x02,0x1d,0x1f,0x81,0xa8,0xbe,0x13,0xf8,0x52,0x2c,0x8c,0x62,0x77,0x42,0x11,0x40,0xe0,0xca,0x93,0x8e,0x03,0x8a,0x30,0x10,0x48,0x54,0x03,0x04,0xbb,0x2c,0x00,0x0c,0x64,0x80,0xe4,0x0e,0x88,0x38,0x7c,0x10,0x04,0x09,0x48,0x83,0xac,0x1b,0x18,0xf3,0x44,0xc1,0xca,0x1d,0x15,0x40,0x8e,0x05,0x02,0x20,0xe6,0x24,0x12,0x8c,0x8b,0x05,0x21,0x07,0x24,0x14,0x08,0x73,0x80,0x19,0x78,0x43,0xb2,0xff,0x15,0x30,0xc4,0x01,0x26,0x8f,0x14,0x61,0xa9,0x8a,0x09,0x10,0x02,0x12,0x1c,0x80,0x84,0xaf,0x10,0x71,0xaa,0xc4,0x00,0x3b,0x04,0xea,0x24,0x48,0x1c,0xbd,0x8f,0xf8,0x00,0x67,0xf0,0x09,0x40,0x20,0x61,0x00,0xe4,0xf6,0x07,0x4b,0xc1,0x1f,0x07,0x14,0x40,0x1c,0x9d,0x66,0x79,0x24,0xc6,0xa0,0x0e,0x32,0x51,0xfa,0xce,0xe7,0x50,0x07,0x1c,0x80,0x30,0x58,0x0e,0xa2,0xcc,0xa0,0x19,0x00,0x71,0x42,0x13,0x27,0x40,0xf5,0x45,0x41,0xc5,0x08,0xb0,0x80,0xc6,0x18,0xf2,0x28,0x04,0x83,0xe8,0x58,0x10,0x30,0xc2,0x2c,0x40,0x91,0x89,0x3c,0x88,0x62,0x21,0xd2,0xff,0x03,0x87,0xc8,0x12,0x19,0x08,0x39,0x3e,0x83,0xb2,0x4a,0x0e,0xa2,0x0d,0xc0,0xe0,0x50,0x06,0xa7,0xe8,0x2c,0x94,0xc2,0x09,0x50,0x8c,0xce,0x20,0x34,0x70,0x71,0x41,0x3e,0x85,0xe2,0xe0,0x41,0x38,0x1e,0x28,0x3c,0x19,0xc8,0x70,0x4f,0xc1,0xdc,0xe0,0x74,0x01,0xd8,0xc6,0x24,0x00,0x82,0x81,0x7c,0x12,0xa6,0x7e,0x10,0x28,0xd8,0x22,0x00,0xe3,0xfc,0x34,0x53,0x00,0x23,0x1c,0x04,0x44,0x0e,0x50,0x10,0xeb,0x17,0xca,0x1c,0x07,0x20,}; -const uint8_t *_I_DolphinMafia_115x62[] = {_I_DolphinMafia_115x62_0}; - const Icon I_Certification2_119x30 = {.width=119,.height=30,.frame_count=1,.frame_rate=0,.frames=_I_Certification2_119x30}; const Icon I_Certification1_103x23 = {.width=103,.height=23,.frame_count=1,.frame_rate=0,.frames=_I_Certification1_103x23}; const Icon A_BadBattery_128x51 = {.width=128,.height=51,.frame_count=2,.frame_rate=2,.frames=_A_BadBattery_128x51}; @@ -762,8 +783,8 @@ const Icon A_CryActive_128x51 = {.width=128,.height=51,.frame_count=3,.frame_rat const Icon A_Cry_128x51 = {.width=128,.height=51,.frame_count=4,.frame_rate=2,.frames=_A_Cry_128x51}; const Icon A_KnifeActive_128x51 = {.width=128,.height=51,.frame_count=2,.frame_rate=2,.frames=_A_KnifeActive_128x51}; const Icon A_Knife_128x51 = {.width=128,.height=51,.frame_count=2,.frame_rate=2,.frames=_A_Knife_128x51}; -const Icon A_LaptopActive_128x51 = {.width=128,.height=51,.frame_count=2,.frame_rate=2,.frames=_A_LaptopActive_128x51}; -const Icon A_Laptop_128x51 = {.width=128,.height=51,.frame_count=2,.frame_rate=2,.frames=_A_Laptop_128x51}; +const Icon A_LaptopActive_128x52 = {.width=128,.height=52,.frame_count=8,.frame_rate=2,.frames=_A_LaptopActive_128x52}; +const Icon A_Laptop_128x52 = {.width=128,.height=52,.frame_count=6,.frame_rate=2,.frames=_A_Laptop_128x52}; const Icon A_LeavingActive_128x51 = {.width=128,.height=51,.frame_count=2,.frame_rate=2,.frames=_A_LeavingActive_128x51}; const Icon A_Leaving_128x51 = {.width=128,.height=51,.frame_count=2,.frame_rate=2,.frames=_A_Leaving_128x51}; const Icon A_Level1FurippaActive_128x51 = {.width=128,.height=51,.frame_count=6,.frame_rate=2,.frames=_A_Level1FurippaActive_128x51}; @@ -784,101 +805,101 @@ const Icon A_Level3HijackActive_128x51 = {.width=128,.height=51,.frame_count=2,. const Icon A_Level3Hijack_128x51 = {.width=128,.height=51,.frame_count=3,.frame_rate=2,.frames=_A_Level3Hijack_128x51}; const Icon A_Level3LabActive_128x51 = {.width=128,.height=51,.frame_count=2,.frame_rate=2,.frames=_A_Level3LabActive_128x51}; const Icon A_Level3Lab_128x51 = {.width=128,.height=51,.frame_count=3,.frame_rate=2,.frames=_A_Level3Lab_128x51}; -const Icon I_LevelUp2_03 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_03}; -const Icon I_LevelUp2_02 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_02}; -const Icon I_LevelUp2_05 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_05}; const Icon I_LevelUp2_04 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_04}; -const Icon I_LevelUp2_01 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_01}; -const Icon I_LevelUp2_06 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_06}; +const Icon I_LevelUp2_03 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_03}; const Icon I_LevelUp2_07 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_07}; -const Icon I_LevelUp3_05 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_05}; -const Icon I_LevelUp3_06 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_06}; -const Icon I_LevelUp3_02 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_02}; +const Icon I_LevelUp2_05 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_05}; +const Icon I_LevelUp2_02 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_02}; +const Icon I_LevelUp2_06 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_06}; +const Icon I_LevelUp2_01 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_01}; const Icon I_LevelUp3_07 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_07}; +const Icon I_LevelUp3_02 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_02}; const Icon I_LevelUp3_04 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_04}; -const Icon I_LevelUp3_03 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_03}; +const Icon I_LevelUp3_05 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_05}; const Icon I_LevelUp3_01 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_01}; +const Icon I_LevelUp3_03 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_03}; +const Icon I_LevelUp3_06 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_06}; const Icon A_LevelUpPending_128x51 = {.width=128,.height=51,.frame_count=2,.frame_rate=2,.frames=_A_LevelUpPending_128x51}; const Icon A_NoSdCard_128x51 = {.width=128,.height=51,.frame_count=2,.frame_rate=2,.frames=_A_NoSdCard_128x51}; -const Icon A_SleepActive_128x51 = {.width=128,.height=51,.frame_count=2,.frame_rate=2,.frames=_A_SleepActive_128x51}; -const Icon A_Sleep_128x51 = {.width=128,.height=51,.frame_count=4,.frame_rate=2,.frames=_A_Sleep_128x51}; -const Icon A_TVActive_128x51 = {.width=128,.height=51,.frame_count=2,.frame_rate=2,.frames=_A_TVActive_128x51}; -const Icon A_TV_128x51 = {.width=128,.height=51,.frame_count=5,.frame_rate=2,.frames=_A_TV_128x51}; -const Icon A_WavesActive_128x51 = {.width=128,.height=51,.frame_count=2,.frame_rate=2,.frames=_A_WavesActive_128x51}; -const Icon A_Waves_128x51 = {.width=128,.height=51,.frame_count=2,.frame_rate=2,.frames=_A_Waves_128x51}; -const Icon I_ble_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_ble_10px}; -const Icon I_ibutt_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_ibutt_10px}; -const Icon I_125_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_125_10px}; +const Icon A_SleepActive_128x52 = {.width=128,.height=52,.frame_count=5,.frame_rate=2,.frames=_A_SleepActive_128x52}; +const Icon A_Sleep_128x52 = {.width=128,.height=52,.frame_count=2,.frame_rate=2,.frames=_A_Sleep_128x52}; +const Icon A_TvActive_128x52 = {.width=128,.height=52,.frame_count=6,.frame_rate=2,.frames=_A_TvActive_128x52}; +const Icon A_Tv_128x52 = {.width=128,.height=52,.frame_count=6,.frame_rate=2,.frames=_A_Tv_128x52}; +const Icon A_WavesActive_128x52 = {.width=128,.height=52,.frame_count=7,.frame_rate=2,.frames=_A_WavesActive_128x52}; +const Icon A_Waves_128x52 = {.width=128,.height=52,.frame_count=2,.frame_rate=2,.frames=_A_Waves_128x52}; const Icon I_sub1_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_sub1_10px}; -const Icon I_dir_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_dir_10px}; const Icon I_ir_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_ir_10px}; -const Icon I_Nfc_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_Nfc_10px}; const Icon I_unknown_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_unknown_10px}; +const Icon I_ibutt_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_ibutt_10px}; +const Icon I_Nfc_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_Nfc_10px}; +const Icon I_ble_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_ble_10px}; +const Icon I_125_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_125_10px}; +const Icon I_dir_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_dir_10px}; const Icon I_BLE_Pairing_128x64 = {.width=128,.height=64,.frame_count=1,.frame_rate=0,.frames=_I_BLE_Pairing_128x64}; -const Icon I_EviSmile2_18x21 = {.width=18,.height=21,.frame_count=1,.frame_rate=0,.frames=_I_EviSmile2_18x21}; -const Icon I_EviSmile1_18x21 = {.width=18,.height=21,.frame_count=1,.frame_rate=0,.frames=_I_EviSmile1_18x21}; -const Icon I_UsbTree_48x22 = {.width=48,.height=22,.frame_count=1,.frame_rate=0,.frames=_I_UsbTree_48x22}; const Icon I_EviWaiting1_18x21 = {.width=18,.height=21,.frame_count=1,.frame_rate=0,.frames=_I_EviWaiting1_18x21}; -const Icon I_EviWaiting2_18x21 = {.width=18,.height=21,.frame_count=1,.frame_rate=0,.frames=_I_EviWaiting2_18x21}; -const Icon I_Percent_10x14 = {.width=10,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_Percent_10x14}; -const Icon I_Smile_18x18 = {.width=18,.height=18,.frame_count=1,.frame_rate=0,.frames=_I_Smile_18x18}; +const Icon I_EviSmile2_18x21 = {.width=18,.height=21,.frame_count=1,.frame_rate=0,.frames=_I_EviSmile2_18x21}; const Icon I_Error_18x18 = {.width=18,.height=18,.frame_count=1,.frame_rate=0,.frames=_I_Error_18x18}; +const Icon I_Percent_10x14 = {.width=10,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_Percent_10x14}; +const Icon I_EviSmile1_18x21 = {.width=18,.height=21,.frame_count=1,.frame_rate=0,.frames=_I_EviSmile1_18x21}; +const Icon I_EviWaiting2_18x21 = {.width=18,.height=21,.frame_count=1,.frame_rate=0,.frames=_I_EviWaiting2_18x21}; +const Icon I_UsbTree_48x22 = {.width=48,.height=22,.frame_count=1,.frame_rate=0,.frames=_I_UsbTree_48x22}; +const Icon I_Smile_18x18 = {.width=18,.height=18,.frame_count=1,.frame_rate=0,.frames=_I_Smile_18x18}; const Icon I_Clock_18x18 = {.width=18,.height=18,.frame_count=1,.frame_rate=0,.frames=_I_Clock_18x18}; -const Icon I_ButtonRightSmall_3x5 = {.width=3,.height=5,.frame_count=1,.frame_rate=0,.frames=_I_ButtonRightSmall_3x5}; -const Icon I_ButtonLeftSmall_3x5 = {.width=3,.height=5,.frame_count=1,.frame_rate=0,.frames=_I_ButtonLeftSmall_3x5}; -const Icon I_ButtonCenter_7x7 = {.width=7,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_ButtonCenter_7x7}; const Icon I_ButtonDown_7x4 = {.width=7,.height=4,.frame_count=1,.frame_rate=0,.frames=_I_ButtonDown_7x4}; -const Icon I_ButtonRight_4x7 = {.width=4,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_ButtonRight_4x7}; -const Icon I_DFU_128x50 = {.width=128,.height=50,.frame_count=1,.frame_rate=0,.frames=_I_DFU_128x50}; -const Icon I_ButtonUp_7x4 = {.width=7,.height=4,.frame_count=1,.frame_rate=0,.frames=_I_ButtonUp_7x4}; -const Icon I_Warning_30x23 = {.width=30,.height=23,.frame_count=1,.frame_rate=0,.frames=_I_Warning_30x23}; +const Icon I_ButtonCenter_7x7 = {.width=7,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_ButtonCenter_7x7}; const Icon I_ButtonLeft_4x7 = {.width=4,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_ButtonLeft_4x7}; -const Icon I_DolphinFirstStart7_61x51 = {.width=61,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart7_61x51}; -const Icon I_DolphinOkay_41x43 = {.width=41,.height=43,.frame_count=1,.frame_rate=0,.frames=_I_DolphinOkay_41x43}; -const Icon I_DolphinFirstStart5_54x49 = {.width=54,.height=49,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart5_54x49}; -const Icon I_Flipper_young_80x60 = {.width=80,.height=60,.frame_count=1,.frame_rate=0,.frames=_I_Flipper_young_80x60}; +const Icon I_ButtonUp_7x4 = {.width=7,.height=4,.frame_count=1,.frame_rate=0,.frames=_I_ButtonUp_7x4}; +const Icon I_DFU_128x50 = {.width=128,.height=50,.frame_count=1,.frame_rate=0,.frames=_I_DFU_128x50}; +const Icon I_ButtonLeftSmall_3x5 = {.width=3,.height=5,.frame_count=1,.frame_rate=0,.frames=_I_ButtonLeftSmall_3x5}; +const Icon I_ButtonRightSmall_3x5 = {.width=3,.height=5,.frame_count=1,.frame_rate=0,.frames=_I_ButtonRightSmall_3x5}; +const Icon I_ButtonRight_4x7 = {.width=4,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_ButtonRight_4x7}; +const Icon I_Warning_30x23 = {.width=30,.height=23,.frame_count=1,.frame_rate=0,.frames=_I_Warning_30x23}; const Icon I_DolphinFirstStart2_59x51 = {.width=59,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart2_59x51}; +const Icon I_DolphinFirstStart5_54x49 = {.width=54,.height=49,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart5_54x49}; +const Icon I_DolphinFirstStart6_58x54 = {.width=58,.height=54,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart6_58x54}; +const Icon I_Flipper_young_80x60 = {.width=80,.height=60,.frame_count=1,.frame_rate=0,.frames=_I_Flipper_young_80x60}; const Icon I_DolphinFirstStart8_56x51 = {.width=56,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart8_56x51}; +const Icon I_DolphinFirstStart1_59x53 = {.width=59,.height=53,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart1_59x53}; +const Icon I_DolphinOkay_41x43 = {.width=41,.height=43,.frame_count=1,.frame_rate=0,.frames=_I_DolphinOkay_41x43}; const Icon I_DolphinFirstStart3_57x48 = {.width=57,.height=48,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart3_57x48}; +const Icon I_DolphinFirstStart7_61x51 = {.width=61,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart7_61x51}; const Icon I_DolphinFirstStart0_70x53 = {.width=70,.height=53,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart0_70x53}; const Icon I_DolphinFirstStart4_67x53 = {.width=67,.height=53,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart4_67x53}; -const Icon I_DolphinFirstStart6_58x54 = {.width=58,.height=54,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart6_58x54}; -const Icon I_DolphinFirstStart1_59x53 = {.width=59,.height=53,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart1_59x53}; -const Icon I_ArrowDownFilled_14x15 = {.width=14,.height=15,.frame_count=1,.frame_rate=0,.frames=_I_ArrowDownFilled_14x15}; const Icon I_ArrowUpEmpty_14x15 = {.width=14,.height=15,.frame_count=1,.frame_rate=0,.frames=_I_ArrowUpEmpty_14x15}; const Icon I_ArrowUpFilled_14x15 = {.width=14,.height=15,.frame_count=1,.frame_rate=0,.frames=_I_ArrowUpFilled_14x15}; +const Icon I_ArrowDownFilled_14x15 = {.width=14,.height=15,.frame_count=1,.frame_rate=0,.frames=_I_ArrowDownFilled_14x15}; const Icon I_ArrowDownEmpty_14x15 = {.width=14,.height=15,.frame_count=1,.frame_rate=0,.frames=_I_ArrowDownEmpty_14x15}; -const Icon I_DoorLocked_10x56 = {.width=10,.height=56,.frame_count=1,.frame_rate=0,.frames=_I_DoorLocked_10x56}; const Icon I_PassportBottom_128x17 = {.width=128,.height=17,.frame_count=1,.frame_rate=0,.frames=_I_PassportBottom_128x17}; -const Icon I_PassportLeft_6x47 = {.width=6,.height=47,.frame_count=1,.frame_rate=0,.frames=_I_PassportLeft_6x47}; const Icon I_DoorLeft_70x55 = {.width=70,.height=55,.frame_count=1,.frame_rate=0,.frames=_I_DoorLeft_70x55}; -const Icon I_LockPopup_100x49 = {.width=100,.height=49,.frame_count=1,.frame_rate=0,.frames=_I_LockPopup_100x49}; const Icon I_DoorRight_70x55 = {.width=70,.height=55,.frame_count=1,.frame_rate=0,.frames=_I_DoorRight_70x55}; -const Icon I_IrdaArrowDown_4x8 = {.width=8,.height=4,.frame_count=1,.frame_rate=0,.frames=_I_IrdaArrowDown_4x8}; -const Icon I_Power_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Power_25x27}; -const Icon I_Mute_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Mute_25x27}; +const Icon I_DoorLocked_10x56 = {.width=10,.height=56,.frame_count=1,.frame_rate=0,.frames=_I_DoorLocked_10x56}; +const Icon I_PassportLeft_6x47 = {.width=6,.height=47,.frame_count=1,.frame_rate=0,.frames=_I_PassportLeft_6x47}; +const Icon I_LockPopup_100x49 = {.width=100,.height=49,.frame_count=1,.frame_rate=0,.frames=_I_LockPopup_100x49}; const Icon I_Down_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Down_hvr_25x27}; -const Icon I_Vol_up_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_up_25x27}; -const Icon I_IrdaLearnShort_128x31 = {.width=128,.height=31,.frame_count=1,.frame_rate=0,.frames=_I_IrdaLearnShort_128x31}; -const Icon I_Up_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Up_25x27}; const Icon I_Vol_down_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_down_hvr_25x27}; -const Icon I_Vol_down_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_down_25x27}; -const Icon I_Vol_up_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_up_hvr_25x27}; -const Icon I_Fill_marker_7x7 = {.width=7,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_Fill_marker_7x7}; -const Icon I_Up_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Up_hvr_25x27}; -const Icon I_IrdaArrowUp_4x8 = {.width=8,.height=4,.frame_count=1,.frame_rate=0,.frames=_I_IrdaArrowUp_4x8}; const Icon I_Down_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Down_25x27}; -const Icon I_DolphinReadingSuccess_59x63 = {.width=59,.height=63,.frame_count=1,.frame_rate=0,.frames=_I_DolphinReadingSuccess_59x63}; -const Icon I_IrdaSendShort_128x34 = {.width=128,.height=34,.frame_count=1,.frame_rate=0,.frames=_I_IrdaSendShort_128x34}; -const Icon I_IrdaLearn_128x64 = {.width=128,.height=64,.frame_count=1,.frame_rate=0,.frames=_I_IrdaLearn_128x64}; -const Icon I_Mute_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Mute_hvr_25x27}; +const Icon I_Fill_marker_7x7 = {.width=7,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_Fill_marker_7x7}; +const Icon I_Vol_down_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_down_25x27}; +const Icon I_Vol_up_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_up_25x27}; +const Icon I_Up_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Up_hvr_25x27}; +const Icon I_Vol_up_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_up_hvr_25x27}; +const Icon I_IrdaLearnShort_128x31 = {.width=128,.height=31,.frame_count=1,.frame_rate=0,.frames=_I_IrdaLearnShort_128x31}; const Icon I_IrdaSend_128x64 = {.width=128,.height=64,.frame_count=1,.frame_rate=0,.frames=_I_IrdaSend_128x64}; -const Icon I_Power_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Power_hvr_25x27}; +const Icon I_DolphinReadingSuccess_59x63 = {.width=59,.height=63,.frame_count=1,.frame_rate=0,.frames=_I_DolphinReadingSuccess_59x63}; +const Icon I_Mute_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Mute_hvr_25x27}; const Icon I_Back_15x10 = {.width=15,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_Back_15x10}; +const Icon I_Up_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Up_25x27}; +const Icon I_IrdaArrowUp_4x8 = {.width=8,.height=4,.frame_count=1,.frame_rate=0,.frames=_I_IrdaArrowUp_4x8}; +const Icon I_Mute_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Mute_25x27}; +const Icon I_Power_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Power_25x27}; +const Icon I_IrdaSendShort_128x34 = {.width=128,.height=34,.frame_count=1,.frame_rate=0,.frames=_I_IrdaSendShort_128x34}; +const Icon I_IrdaArrowDown_4x8 = {.width=8,.height=4,.frame_count=1,.frame_rate=0,.frames=_I_IrdaArrowDown_4x8}; +const Icon I_IrdaLearn_128x64 = {.width=128,.height=64,.frame_count=1,.frame_rate=0,.frames=_I_IrdaLearn_128x64}; +const Icon I_Power_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Power_hvr_25x27}; const Icon I_KeySaveSelected_24x11 = {.width=24,.height=11,.frame_count=1,.frame_rate=0,.frames=_I_KeySaveSelected_24x11}; -const Icon I_KeySave_24x11 = {.width=24,.height=11,.frame_count=1,.frame_rate=0,.frames=_I_KeySave_24x11}; -const Icon I_KeyBackspaceSelected_16x9 = {.width=16,.height=9,.frame_count=1,.frame_rate=0,.frames=_I_KeyBackspaceSelected_16x9}; const Icon I_KeyBackspace_16x9 = {.width=16,.height=9,.frame_count=1,.frame_rate=0,.frames=_I_KeyBackspace_16x9}; +const Icon I_KeyBackspaceSelected_16x9 = {.width=16,.height=9,.frame_count=1,.frame_rate=0,.frames=_I_KeyBackspaceSelected_16x9}; +const Icon I_KeySave_24x11 = {.width=24,.height=11,.frame_count=1,.frame_rate=0,.frames=_I_KeySave_24x11}; const Icon A_125khz_14 = {.width=14,.height=14,.frame_count=4,.frame_rate=3,.frames=_A_125khz_14}; const Icon A_BadUsb_14 = {.width=14,.height=14,.frame_count=11,.frame_rate=3,.frames=_A_BadUsb_14}; const Icon A_Bluetooth_14 = {.width=14,.height=14,.frame_count=6,.frame_rate=3,.frames=_A_Bluetooth_14}; @@ -896,46 +917,46 @@ const Icon A_Sub1ghz_14 = {.width=14,.height=14,.frame_count=6,.frame_rate=3,.fr const Icon A_Tamagotchi_14 = {.width=14,.height=14,.frame_count=6,.frame_rate=3,.frames=_A_Tamagotchi_14}; const Icon A_U2F_14 = {.width=14,.height=14,.frame_count=4,.frame_rate=3,.frames=_A_U2F_14}; const Icon A_iButton_14 = {.width=14,.height=14,.frame_count=7,.frame_rate=3,.frames=_A_iButton_14}; -const Icon I_Medium_chip_22x21 = {.width=22,.height=21,.frame_count=1,.frame_rate=0,.frames=_I_Medium_chip_22x21}; const Icon I_Detailed_chip_17x13 = {.width=17,.height=13,.frame_count=1,.frame_rate=0,.frames=_I_Detailed_chip_17x13}; -const Icon I_Health_16x16 = {.width=16,.height=16,.frame_count=1,.frame_rate=0,.frames=_I_Health_16x16}; -const Icon I_Voltage_16x16 = {.width=16,.height=16,.frame_count=1,.frame_rate=0,.frames=_I_Voltage_16x16}; +const Icon I_Medium_chip_22x21 = {.width=22,.height=21,.frame_count=1,.frame_rate=0,.frames=_I_Medium_chip_22x21}; const Icon I_BatteryBody_52x28 = {.width=52,.height=28,.frame_count=1,.frame_rate=0,.frames=_I_BatteryBody_52x28}; -const Icon I_FaceNormal_29x14 = {.width=29,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_FaceNormal_29x14}; const Icon I_FaceCharging_29x14 = {.width=29,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_FaceCharging_29x14}; +const Icon I_Health_16x16 = {.width=16,.height=16,.frame_count=1,.frame_rate=0,.frames=_I_Health_16x16}; +const Icon I_Temperature_16x16 = {.width=16,.height=16,.frame_count=1,.frame_rate=0,.frames=_I_Temperature_16x16}; const Icon I_Battery_16x16 = {.width=16,.height=16,.frame_count=1,.frame_rate=0,.frames=_I_Battery_16x16}; const Icon I_FaceConfused_29x14 = {.width=29,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_FaceConfused_29x14}; -const Icon I_Temperature_16x16 = {.width=16,.height=16,.frame_count=1,.frame_rate=0,.frames=_I_Temperature_16x16}; +const Icon I_FaceNormal_29x14 = {.width=29,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_FaceNormal_29x14}; +const Icon I_Voltage_16x16 = {.width=16,.height=16,.frame_count=1,.frame_rate=0,.frames=_I_Voltage_16x16}; const Icon I_FaceNopower_29x14 = {.width=29,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_FaceNopower_29x14}; -const Icon I_RFIDDolphinSuccess_108x57 = {.width=108,.height=57,.frame_count=1,.frame_rate=0,.frames=_I_RFIDDolphinSuccess_108x57}; -const Icon I_RFIDBigChip_37x36 = {.width=37,.height=36,.frame_count=1,.frame_rate=0,.frames=_I_RFIDBigChip_37x36}; -const Icon I_RFIDDolphinReceive_97x61 = {.width=97,.height=61,.frame_count=1,.frame_rate=0,.frames=_I_RFIDDolphinReceive_97x61}; const Icon I_RFIDDolphinSend_97x61 = {.width=97,.height=61,.frame_count=1,.frame_rate=0,.frames=_I_RFIDDolphinSend_97x61}; -const Icon I_SDError_43x35 = {.width=43,.height=35,.frame_count=1,.frame_rate=0,.frames=_I_SDError_43x35}; +const Icon I_RFIDDolphinSuccess_108x57 = {.width=108,.height=57,.frame_count=1,.frame_rate=0,.frames=_I_RFIDDolphinSuccess_108x57}; +const Icon I_RFIDDolphinReceive_97x61 = {.width=97,.height=61,.frame_count=1,.frame_rate=0,.frames=_I_RFIDDolphinReceive_97x61}; +const Icon I_RFIDBigChip_37x36 = {.width=37,.height=36,.frame_count=1,.frame_rate=0,.frames=_I_RFIDBigChip_37x36}; const Icon I_SDQuestion_35x43 = {.width=35,.height=43,.frame_count=1,.frame_rate=0,.frames=_I_SDQuestion_35x43}; +const Icon I_SDError_43x35 = {.width=43,.height=35,.frame_count=1,.frame_rate=0,.frames=_I_SDError_43x35}; const Icon I_Cry_dolph_55x52 = {.width=55,.height=52,.frame_count=1,.frame_rate=0,.frames=_I_Cry_dolph_55x52}; -const Icon I_Battery_19x8 = {.width=19,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Battery_19x8}; -const Icon I_SDcardFail_11x8 = {.width=11,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_SDcardFail_11x8}; -const Icon I_Bluetooth_5x8 = {.width=5,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Bluetooth_5x8}; -const Icon I_PlaceholderR_30x13 = {.width=30,.height=13,.frame_count=1,.frame_rate=0,.frames=_I_PlaceholderR_30x13}; -const Icon I_Battery_26x8 = {.width=26,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Battery_26x8}; +const Icon I_Background_128x11 = {.width=128,.height=11,.frame_count=1,.frame_rate=0,.frames=_I_Background_128x11}; const Icon I_Lock_8x8 = {.width=8,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Lock_8x8}; -const Icon I_SDcardMounted_11x8 = {.width=11,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_SDcardMounted_11x8}; +const Icon I_Battery_26x8 = {.width=26,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Battery_26x8}; +const Icon I_Battery_19x8 = {.width=19,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Battery_19x8}; +const Icon I_USBConnected_15x8 = {.width=15,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_USBConnected_15x8}; const Icon I_BadUsb_9x8 = {.width=9,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_BadUsb_9x8}; const Icon I_BT_Pair_9x8 = {.width=9,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_BT_Pair_9x8}; const Icon I_PlaceholderL_11x13 = {.width=11,.height=13,.frame_count=1,.frame_rate=0,.frames=_I_PlaceholderL_11x13}; -const Icon I_Background_128x11 = {.width=128,.height=11,.frame_count=1,.frame_rate=0,.frames=_I_Background_128x11}; -const Icon I_USBConnected_15x8 = {.width=15,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_USBConnected_15x8}; +const Icon I_SDcardFail_11x8 = {.width=11,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_SDcardFail_11x8}; +const Icon I_Bluetooth_5x8 = {.width=5,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Bluetooth_5x8}; +const Icon I_PlaceholderR_30x13 = {.width=30,.height=13,.frame_count=1,.frame_rate=0,.frames=_I_PlaceholderR_30x13}; +const Icon I_SDcardMounted_11x8 = {.width=11,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_SDcardMounted_11x8}; const Icon I_Quest_7x8 = {.width=7,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Quest_7x8}; -const Icon I_MHz_25x11 = {.width=25,.height=11,.frame_count=1,.frame_rate=0,.frames=_I_MHz_25x11}; -const Icon I_Scanning_123x52 = {.width=123,.height=52,.frame_count=1,.frame_rate=0,.frames=_I_Scanning_123x52}; -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_Scanning_123x52 = {.width=123,.height=52,.frame_count=1,.frame_rate=0,.frames=_I_Scanning_123x52}; +const Icon I_MHz_25x11 = {.width=25,.height=11,.frame_count=1,.frame_rate=0,.frames=_I_MHz_25x11}; +const Icon I_Unlock_7x8 = {.width=7,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Unlock_7x8}; +const Icon I_iButtonKey_49x44 = {.width=49,.height=44,.frame_count=1,.frame_rate=0,.frames=_I_iButtonKey_49x44}; +const Icon I_DolphinExcited_64x63 = {.width=64,.height=63,.frame_count=1,.frame_rate=0,.frames=_I_DolphinExcited_64x63}; +const Icon I_DolphinWait_61x59 = {.width=61,.height=59,.frame_count=1,.frame_rate=0,.frames=_I_DolphinWait_61x59}; +const Icon I_iButtonDolphinVerySuccess_108x52 = {.width=108,.height=52,.frame_count=1,.frame_rate=0,.frames=_I_iButtonDolphinVerySuccess_108x52}; +const Icon I_DolphinMafia_115x62 = {.width=115,.height=62,.frame_count=1,.frame_rate=0,.frames=_I_DolphinMafia_115x62}; const Icon I_DolphinNice_96x59 = {.width=96,.height=59,.frame_count=1,.frame_rate=0,.frames=_I_DolphinNice_96x59}; const Icon I_iButtonDolphinSuccess_109x60 = {.width=109,.height=60,.frame_count=1,.frame_rate=0,.frames=_I_iButtonDolphinSuccess_109x60}; -const Icon I_DolphinExcited_64x63 = {.width=64,.height=63,.frame_count=1,.frame_rate=0,.frames=_I_DolphinExcited_64x63}; -const Icon I_iButtonKey_49x44 = {.width=49,.height=44,.frame_count=1,.frame_rate=0,.frames=_I_iButtonKey_49x44}; -const Icon I_iButtonDolphinVerySuccess_108x52 = {.width=108,.height=52,.frame_count=1,.frame_rate=0,.frames=_I_iButtonDolphinVerySuccess_108x52}; -const Icon I_DolphinWait_61x59 = {.width=61,.height=59,.frame_count=1,.frame_rate=0,.frames=_I_DolphinWait_61x59}; -const Icon I_DolphinMafia_115x62 = {.width=115,.height=62,.frame_count=1,.frame_rate=0,.frames=_I_DolphinMafia_115x62}; diff --git a/assets/compiled/assets_icons.h b/assets/compiled/assets_icons.h index b3217400..6d05a531 100644 --- a/assets/compiled/assets_icons.h +++ b/assets/compiled/assets_icons.h @@ -14,8 +14,8 @@ extern const Icon A_CryActive_128x51; extern const Icon A_Cry_128x51; extern const Icon A_KnifeActive_128x51; extern const Icon A_Knife_128x51; -extern const Icon A_LaptopActive_128x51; -extern const Icon A_Laptop_128x51; +extern const Icon A_LaptopActive_128x52; +extern const Icon A_Laptop_128x52; extern const Icon A_LeavingActive_128x51; extern const Icon A_Leaving_128x51; extern const Icon A_Level1FurippaActive_128x51; @@ -36,101 +36,101 @@ extern const Icon A_Level3HijackActive_128x51; extern const Icon A_Level3Hijack_128x51; extern const Icon A_Level3LabActive_128x51; extern const Icon A_Level3Lab_128x51; -extern const Icon I_LevelUp2_03; -extern const Icon I_LevelUp2_02; -extern const Icon I_LevelUp2_05; extern const Icon I_LevelUp2_04; -extern const Icon I_LevelUp2_01; -extern const Icon I_LevelUp2_06; +extern const Icon I_LevelUp2_03; extern const Icon I_LevelUp2_07; -extern const Icon I_LevelUp3_05; -extern const Icon I_LevelUp3_06; -extern const Icon I_LevelUp3_02; +extern const Icon I_LevelUp2_05; +extern const Icon I_LevelUp2_02; +extern const Icon I_LevelUp2_06; +extern const Icon I_LevelUp2_01; extern const Icon I_LevelUp3_07; +extern const Icon I_LevelUp3_02; extern const Icon I_LevelUp3_04; -extern const Icon I_LevelUp3_03; +extern const Icon I_LevelUp3_05; extern const Icon I_LevelUp3_01; +extern const Icon I_LevelUp3_03; +extern const Icon I_LevelUp3_06; extern const Icon A_LevelUpPending_128x51; extern const Icon A_NoSdCard_128x51; -extern const Icon A_SleepActive_128x51; -extern const Icon A_Sleep_128x51; -extern const Icon A_TVActive_128x51; -extern const Icon A_TV_128x51; -extern const Icon A_WavesActive_128x51; -extern const Icon A_Waves_128x51; -extern const Icon I_ble_10px; -extern const Icon I_ibutt_10px; -extern const Icon I_125_10px; +extern const Icon A_SleepActive_128x52; +extern const Icon A_Sleep_128x52; +extern const Icon A_TvActive_128x52; +extern const Icon A_Tv_128x52; +extern const Icon A_WavesActive_128x52; +extern const Icon A_Waves_128x52; extern const Icon I_sub1_10px; -extern const Icon I_dir_10px; extern const Icon I_ir_10px; -extern const Icon I_Nfc_10px; extern const Icon I_unknown_10px; +extern const Icon I_ibutt_10px; +extern const Icon I_Nfc_10px; +extern const Icon I_ble_10px; +extern const Icon I_125_10px; +extern const Icon I_dir_10px; extern const Icon I_BLE_Pairing_128x64; -extern const Icon I_EviSmile2_18x21; -extern const Icon I_EviSmile1_18x21; -extern const Icon I_UsbTree_48x22; extern const Icon I_EviWaiting1_18x21; -extern const Icon I_EviWaiting2_18x21; -extern const Icon I_Percent_10x14; -extern const Icon I_Smile_18x18; +extern const Icon I_EviSmile2_18x21; extern const Icon I_Error_18x18; +extern const Icon I_Percent_10x14; +extern const Icon I_EviSmile1_18x21; +extern const Icon I_EviWaiting2_18x21; +extern const Icon I_UsbTree_48x22; +extern const Icon I_Smile_18x18; extern const Icon I_Clock_18x18; -extern const Icon I_ButtonRightSmall_3x5; -extern const Icon I_ButtonLeftSmall_3x5; -extern const Icon I_ButtonCenter_7x7; extern const Icon I_ButtonDown_7x4; -extern const Icon I_ButtonRight_4x7; -extern const Icon I_DFU_128x50; -extern const Icon I_ButtonUp_7x4; -extern const Icon I_Warning_30x23; +extern const Icon I_ButtonCenter_7x7; extern const Icon I_ButtonLeft_4x7; -extern const Icon I_DolphinFirstStart7_61x51; -extern const Icon I_DolphinOkay_41x43; -extern const Icon I_DolphinFirstStart5_54x49; -extern const Icon I_Flipper_young_80x60; +extern const Icon I_ButtonUp_7x4; +extern const Icon I_DFU_128x50; +extern const Icon I_ButtonLeftSmall_3x5; +extern const Icon I_ButtonRightSmall_3x5; +extern const Icon I_ButtonRight_4x7; +extern const Icon I_Warning_30x23; extern const Icon I_DolphinFirstStart2_59x51; +extern const Icon I_DolphinFirstStart5_54x49; +extern const Icon I_DolphinFirstStart6_58x54; +extern const Icon I_Flipper_young_80x60; extern const Icon I_DolphinFirstStart8_56x51; +extern const Icon I_DolphinFirstStart1_59x53; +extern const Icon I_DolphinOkay_41x43; extern const Icon I_DolphinFirstStart3_57x48; +extern const Icon I_DolphinFirstStart7_61x51; extern const Icon I_DolphinFirstStart0_70x53; extern const Icon I_DolphinFirstStart4_67x53; -extern const Icon I_DolphinFirstStart6_58x54; -extern const Icon I_DolphinFirstStart1_59x53; -extern const Icon I_ArrowDownFilled_14x15; extern const Icon I_ArrowUpEmpty_14x15; extern const Icon I_ArrowUpFilled_14x15; +extern const Icon I_ArrowDownFilled_14x15; extern const Icon I_ArrowDownEmpty_14x15; -extern const Icon I_DoorLocked_10x56; extern const Icon I_PassportBottom_128x17; -extern const Icon I_PassportLeft_6x47; extern const Icon I_DoorLeft_70x55; -extern const Icon I_LockPopup_100x49; extern const Icon I_DoorRight_70x55; -extern const Icon I_IrdaArrowDown_4x8; -extern const Icon I_Power_25x27; -extern const Icon I_Mute_25x27; +extern const Icon I_DoorLocked_10x56; +extern const Icon I_PassportLeft_6x47; +extern const Icon I_LockPopup_100x49; extern const Icon I_Down_hvr_25x27; -extern const Icon I_Vol_up_25x27; -extern const Icon I_IrdaLearnShort_128x31; -extern const Icon I_Up_25x27; extern const Icon I_Vol_down_hvr_25x27; -extern const Icon I_Vol_down_25x27; -extern const Icon I_Vol_up_hvr_25x27; -extern const Icon I_Fill_marker_7x7; -extern const Icon I_Up_hvr_25x27; -extern const Icon I_IrdaArrowUp_4x8; extern const Icon I_Down_25x27; -extern const Icon I_DolphinReadingSuccess_59x63; -extern const Icon I_IrdaSendShort_128x34; -extern const Icon I_IrdaLearn_128x64; -extern const Icon I_Mute_hvr_25x27; +extern const Icon I_Fill_marker_7x7; +extern const Icon I_Vol_down_25x27; +extern const Icon I_Vol_up_25x27; +extern const Icon I_Up_hvr_25x27; +extern const Icon I_Vol_up_hvr_25x27; +extern const Icon I_IrdaLearnShort_128x31; extern const Icon I_IrdaSend_128x64; -extern const Icon I_Power_hvr_25x27; +extern const Icon I_DolphinReadingSuccess_59x63; +extern const Icon I_Mute_hvr_25x27; extern const Icon I_Back_15x10; +extern const Icon I_Up_25x27; +extern const Icon I_IrdaArrowUp_4x8; +extern const Icon I_Mute_25x27; +extern const Icon I_Power_25x27; +extern const Icon I_IrdaSendShort_128x34; +extern const Icon I_IrdaArrowDown_4x8; +extern const Icon I_IrdaLearn_128x64; +extern const Icon I_Power_hvr_25x27; extern const Icon I_KeySaveSelected_24x11; -extern const Icon I_KeySave_24x11; -extern const Icon I_KeyBackspaceSelected_16x9; extern const Icon I_KeyBackspace_16x9; +extern const Icon I_KeyBackspaceSelected_16x9; +extern const Icon I_KeySave_24x11; extern const Icon A_125khz_14; extern const Icon A_BadUsb_14; extern const Icon A_Bluetooth_14; @@ -148,45 +148,45 @@ extern const Icon A_Sub1ghz_14; extern const Icon A_Tamagotchi_14; extern const Icon A_U2F_14; extern const Icon A_iButton_14; -extern const Icon I_Medium_chip_22x21; extern const Icon I_Detailed_chip_17x13; -extern const Icon I_Health_16x16; -extern const Icon I_Voltage_16x16; +extern const Icon I_Medium_chip_22x21; extern const Icon I_BatteryBody_52x28; -extern const Icon I_FaceNormal_29x14; extern const Icon I_FaceCharging_29x14; +extern const Icon I_Health_16x16; +extern const Icon I_Temperature_16x16; extern const Icon I_Battery_16x16; extern const Icon I_FaceConfused_29x14; -extern const Icon I_Temperature_16x16; +extern const Icon I_FaceNormal_29x14; +extern const Icon I_Voltage_16x16; extern const Icon I_FaceNopower_29x14; -extern const Icon I_RFIDDolphinSuccess_108x57; -extern const Icon I_RFIDBigChip_37x36; -extern const Icon I_RFIDDolphinReceive_97x61; extern const Icon I_RFIDDolphinSend_97x61; -extern const Icon I_SDError_43x35; +extern const Icon I_RFIDDolphinSuccess_108x57; +extern const Icon I_RFIDDolphinReceive_97x61; +extern const Icon I_RFIDBigChip_37x36; extern const Icon I_SDQuestion_35x43; +extern const Icon I_SDError_43x35; extern const Icon I_Cry_dolph_55x52; -extern const Icon I_Battery_19x8; -extern const Icon I_SDcardFail_11x8; -extern const Icon I_Bluetooth_5x8; -extern const Icon I_PlaceholderR_30x13; -extern const Icon I_Battery_26x8; +extern const Icon I_Background_128x11; extern const Icon I_Lock_8x8; -extern const Icon I_SDcardMounted_11x8; +extern const Icon I_Battery_26x8; +extern const Icon I_Battery_19x8; +extern const Icon I_USBConnected_15x8; extern const Icon I_BadUsb_9x8; extern const Icon I_BT_Pair_9x8; extern const Icon I_PlaceholderL_11x13; -extern const Icon I_Background_128x11; -extern const Icon I_USBConnected_15x8; +extern const Icon I_SDcardFail_11x8; +extern const Icon I_Bluetooth_5x8; +extern const Icon I_PlaceholderR_30x13; +extern const Icon I_SDcardMounted_11x8; extern const Icon I_Quest_7x8; -extern const Icon I_MHz_25x11; -extern const Icon I_Scanning_123x52; -extern const Icon I_Unlock_7x8; extern const Icon I_Lock_7x8; +extern const Icon I_Scanning_123x52; +extern const Icon I_MHz_25x11; +extern const Icon I_Unlock_7x8; +extern const Icon I_iButtonKey_49x44; +extern const Icon I_DolphinExcited_64x63; +extern const Icon I_DolphinWait_61x59; +extern const Icon I_iButtonDolphinVerySuccess_108x52; +extern const Icon I_DolphinMafia_115x62; extern const Icon I_DolphinNice_96x59; extern const Icon I_iButtonDolphinSuccess_109x60; -extern const Icon I_DolphinExcited_64x63; -extern const Icon I_iButtonKey_49x44; -extern const Icon I_iButtonDolphinVerySuccess_108x52; -extern const Icon I_DolphinWait_61x59; -extern const Icon I_DolphinMafia_115x62; diff --git a/assets/icons/Animations/LaptopActive_128x51/frame_01.png b/assets/icons/Animations/LaptopActive_128x51/frame_01.png deleted file mode 100644 index d4446f42513c12f404c34e24b32c70c6cec0ecd8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2189 zcmbVO3rrJt7_a3aXjPo3h%Vet;zVfgt`DFmm6oMfrYHe^eh6W+R3Jt9DF97vyIo ztZbQ}fq~S32d6tk>*9lX0vSWRgd4$RsNd5N&}{y1sM8rj^Fk5*Oz*J7yrsfTBSkdN zmT@Ev;IoI8;ss+lkQg*OieO_o?Gi%a6d8(jmvN54G*Ki%J7_0>@xT=p(&@Id0?XUk z5t0yk9ZH28*K;%>u$+Zu9YbX<7-E6s3KjAscdqol2%btt5peB#H^`GrGloEsBKUeh&QlgnLmL;@f3*H z8MCo$y#iIpQ4GV3`t&p-W=J=x&@7`oOKngN#pZJi*k^>}|8Y6O7N2LrT$ZpR7Ize6=JPXNtu@ZoTRM^~}{smD$O%0R~r+eQHx z&)NhJ!O^->P~Oq>bRdkh6RuJk3{3>~8%6xnCEyGRRN$HE!FSJ1q9HgKZ~n{BU#$Hj5iE*}ePFeUZo{g|42O=3zoS>5qiwLInpo4ED(fo(NkJaU+3 zNW#CXn{~I{0`HOJULyF`DJc&Yq*v@m4sKpw;;Y+gitktwGrsR&#O^(xWF>8`>B?kd z`lr`b&N$h5wY{RbB}Qu>*tB zHRtPj=wphVYUrzB`58ntq)utmPK7D&wVnC&C+Am*po^w~meS zl`P+|z3cQ>FJ2Q}mME?+kKS2`e0%EVp(Wy4aZfqB4B7VaDOT4cx%w-#@L?D^)zbVu z^jFG)H{>gA+SebUHtj2QjvagJU+tU2pD1^HnQ{h>KFsJYH**P_6>)us3Eh#YjrVAC zN|d{JQrnfg%Ie#5Z4vgfht9+|w#+1?z<0AR|GGA^ss3w7yXDFG^xlYXByrRF#$L#L z*)T~Td9typ^Y_?W#5-H(^fmoF(6(;l>UO&(F@75NZpX@|hx_uFQ*A!&)11our6par xqVM?hN8Y}8^qgcOkb!|7~Z5Jm6k)QNI_v)kitN+yE$62Lnyg=SVA$a$T@Vg`!(It>@K@ol6EKr zC^rlaFjB+OQn5c20XYk8)*Gr5uy=fbgEyZnVCRA-N3`~X6)vHLm0}jX6#L)lW>YQP{3uB zN+73nd@fTulQFSa>KJsipMnBjpwOt_Tg1zh-;A~CQt&$T7{|~yh%(cRSwah8`LWk>g8i>%yCA>oWHM~5yUBM1yM&d+;6L>VFNV|n% z#f-sF!yde1RF;<`d4d_k{j`XaS|a4B9q4raH`MEmqGiPe9>?3Eu$)^W0^9{;p;%%7 zgb!|CN>&`RVTcj4ogh1A173;JStiOAi>0ErG_ed0ihviwWax^F#wivEiXayVPf0@b zbu<+sWs?A{2vV*f6t$OmLc0p8(`yNIn3HBWKBPN5WGO-cc3J^uEL3z2Noe$BE@`BU z21;)nLFg%h2t%C$%jK6m2_-c|axQ72bSacx_b(`HIhI!F&VZdxDwCHLnrA?!-HgGY zv>eA$dIK<;lJk=_0I;OSpws7TObl(*q%b-IsblkLmI=oN`F4RR4kfUi&qBVP7-h2> ztR}sVAW70;8YBlLRl?){Yd{K?W?2G&0SmC!g*h%w;=pAK~hr z%EhC>WNa1Z^f!K{>(yaPdQ}hYzv@QADvu>^ z{g7Ta-rK0x+`rg(AVz5HU7whRcpg4Tu5?|BEARO_-{&pYYr|VMrYujdycV-#?vw^g zz*_caP##eB^(VdW|1c#+Q=f)4jM`xz-Mvcvvb%ElvKzaNkEYKr$ztwiseUTWZM_!g zR&_Yh5E@z)s`gnpn7+u>bN?%V$CA{ z#L9>9Ilo=ox2VfAU+s0$t(!L7$+q#e>#oT5=HnF36xLkdkQ4Xw#FeT& zU8V`!OO|f>;_xtUUC&dXvNX{gSChBpcvF{E2ba$&|EOWt{b4K~)iKm;?cPlp69xS}N4M+5iuL?^qUAXtn)RM&St_--#Y$yzzG~c(* z8(3e7|9atG%h}qPpmu3xbMv9PTQAhj4UH%J}3Id^sh>NLj+%b`sl%!1oeX%Ybq8G+4uSFq^(HY^lg>!%y3H z8c<2J8RnS^iNcTr_@w-L1(enoxrO>F!73WEr=!zqIcOjNG#;%D_=74}YcquHa&WFM z;|4Sg(W-2Q9Ni&WR#=QWWCfsRBZ&zFL7--b(Iv6P!GrX1$;iQqk0|8xF7_Dk0;Oa51 zi&ourA%K?vRjyV90O6Te$*x7v^Pq+sAiEZUpcbXW*#9?q$d4#QaiMC(9}bf!;J^<8 z(4Go4kx@Y*pRCEMPyQFv(d}>`bO$h6+`WnftA_VGWuaO(S>Uu8;Eqw0M3_aV!$G=8 znj#32bU7?$7wNRPOoZJ<*{x1y$j0@!1Wh=s3`H{*t24}HOu0@v$LuiCxvpHwKEy2u zsu~{@z>r@F`t>qiQltqpMtUtCjImk>%xVTAdDd0lpI8pN!F~;K&Fvbi_ znAJ*?7(oG+w0KF1^}-ND_~JE%5$O%H*LE{TTY<^<>;wokaLGJ^)Qd z6aLREMqsM!)oOSJEYrjbGQ;U(A| z^=Y&(!;ffZ2SI3BfqlDb{eycDB=&&@WxJwPY&D`0V!`oINea4;0r3M4KwQ5Yh z@7&q6aVvI?h;cb9;u~jv{Xy(n;frTZjBqU1PJFrG-s)81j$d~4yi}2z^KI`*?BcGy zhdvzJ-Sqgjk?-u}5B%PouzFMa7GLq)6fypEdd%j1%Rb0M*R~>i?Jeurb7!fE@7a#M zTG8?D)c7Uumvyx}e#oqdi+e8d!t-y``SCnwx_C6>+W{jAFs9|9XQ z&n-BJo|bNDD1C-Q9(rp<@~M~^w+}xwXT!?hY?&#sBO4dTwPo$PcwtA%uru!@j_l}r zeafjx&$X1)Tlzbfl(l5EuWOw(_4)QGrMLe)zFXULzPac9l+|UY=Z!`tb~g3ZfBw;m z<@?*_aQo4i_65feU+x>fyl=;_#)HX7;>+FTYdX@}gD2*uF1~LRx4vBSk3j4z%Hq;r z+?LRI@$H4uzTfWOhE)8d^&aYPOG?Su7&EyO|0FcQ=`Na|MkA9S=&WDdaH{{x(&N+L zIK{q2w=JA;&*h1TzrDX4S)NC4*=n!0#1|h(`myJUnWk}BbW_E{(^_x&YSQ%DEM(lg zSx;sy>B-u6sH+tDd9JVe%?-vQW4xP3uif+P}y2_2hPXsy`#5d*f%fcb?g68kOEhcv(sL& F}BIegc>XA~;AUC_zv%0Y!<9@i#~aKmK6-uH6bMDow86ci;Cs@B2OP z`+jfkwX!J_vodosAqdLyO=8Ny*Z>~tp)~McvuFQWF!V2*9Pq~DaWI|s*@=Z<$cRpQ zPJ^HU*~Vjn*1k0Ypwi?(rC#ZuO!G?E!U_r}T4LcSKtoVraV*O6)uIk_VwD_mny>Ep z)C|jl(>%lK$NW)`7?dZ?Q^ksTQv&?FYThB3i;LjG7!3@BMV*CX;ZQ`QV@`9zE)C|! zGHQks5WU)Ib{P)gN`D#bQB)Bwu;2)fVHjNCum~*2@*FoFCNKg=F$%>g1jA_3K~ogm z^D_f?svyzjOlglZ@a8lJbv;U>XkA^MrH-^HY88q*91avCP=Y`J0@3OtIvYbG+UQ;j zjHvOd9Mxqd0vi@tPN~tIW^mM`hH%vHPZ^GAJ&^)2Lt|_d#Vr^b4jaM}XiYB{?;hj6 zXf04571450Q)*OR1n|*!$=+JvxktkTkiE5HL{HH{?EjnG>qp>IxM+QL!6dkpwUi-U1s*F|>MbSQyT-J$ONDEs3NN?YCus!y=7X~ z8wHpkEf_r3&+>A_h|9QpC?dn^qSI^?ErJsWMg?$!CP{Sb?p^nJJY}jP z$sw?zl}~iTKCj1yJ8U+Du;9l1NT!n!Rk>CaN>wEcCkmXF?-SqxiR4+*CLk2Y@d#BQ zS`mkX#1V`TZMa>+37Z5$kmL*Z6h^W`fEAFWyGO=sl0?~T5+V^Ii`c9bkFcy&KsYNw z2*8WYW-lf9wsxO0=RA(0>z_bebHvI^+1cLfFeT*wm*>$2NY+*=G#j{qUZLjzZU-Xqcbdu%k~!zv|Ac3)2RPu1)Y0%a<=&y4VT* z)Kqe0VqSXL2`Lk5Th}~x6)G*ez#K8nUbr>8Pd}*0UKTFx9645Pjw#??Q$*y9 zKUmmy*s|NZ-LH#u{C#`JDe`u+*6 zzNIa>eKMd8Y0d78r+*wbtnJlR(_IJaOP~B@;L>9k_tqafcRLfxInTzwKK@nn`x$`= z$L(|CU1XlnR4+Atvhs!Sg1i;!r=i1xOV(8Gy0xx*1hl&EO=yW4K9xJ4!njW_3Ju`|`rPD<7Q8Z^=Dk z>%6w$x074tg)2|DwS4esL+7wpZ%FGjvA96I=9+6ddsZ(7F$$Nqe3UtzxzW%2YG6GDUf4z5@LZJE6J%E;qq2f7Y@ zT)mxZW=np3e{NpK65pCRhiWd=4f*-Cos_+3)feCHnoIhp&Kg&w?WY6rOT$}ppDF4; U^gZiw-1vI%d8aU~?%9oh0syE2^#A|> literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/LaptopActive_128x52/frame_03.png b/assets/icons/Animations/LaptopActive_128x52/frame_03.png new file mode 100644 index 0000000000000000000000000000000000000000..2578dfca1be334cd7dba9f35d47bfd1dda188833 GIT binary patch literal 2213 zcma)8YjD(56iy$)3R4j%O0kug4l|%+^W3zFU1+=6(gn8EwhR>z$R^n~bT?U&w7V@* zvE^YIVdMvI7{NhB1g!Oe*m39-M4kguup=T=%K!s{4vJHB1aEfR1r?Q@$=;iLzwey; zopbJ)G!++3NEt9<00coPo)T;{%W=MI=oZSSZD!^5G% z=M4xNIMjL)p!FMv15}byR&JJiCv&0}v;x*}I1XpAc1iFFqR%%LCUKI$a2g|M6vsJ=m(SqvvJl0*RlHELB;h@h&G*=K>5 z4N+G@rlP5^Wl`{H)us~xM~!I+hP>XmVb$o36o?rX5keSY$FX405*9@pW{G_F823dR zWwjw0E0GPYS{G#i&%8@^*8tDG8Xkb`u8~zUP6x67Z*rd>NsQw{)p{TrCP~EPfE)z& z44{dK3kp?gre;)X|6)469Swx#07Q$MqAQ?kgaEIJ)s{&Q??k|kT~Z{FMc(Bi+yq79 zI6=5w*;#Ia&vrZTd^efT@^qh#`*DeU#?4bMoX%$XD3^8=@Kj!w%Rv>m3&{LFu17UY zK^5gbzY6f{APC7v(KITPxPa0En~e$%8q6eC5d9Lv60{WMb1q#LOieG-v_M~(7WYK~ zCMi1(kM;_pqFQkoa}P!41ygn+R?(saiQ;q_L2@L;QTQ`B#o>4i>eVF0U;8(xql_du zn&4>mFHmr0B*7H^7c7aKU(|v!RLEFJtw7*-Za9|~&~)I~I^DhN9+#_F*ZfKV zY#1dI@?nqL#SkpRproC!?nf-0ysRrVvQ(gJK{#6AoN}K4XZa~npco0IeLfMTvt$R# zvJ`>hq|6Z6eu8BDAOtbKbWdT#Is{k&NxFMvobmf$ zVVLYJ1dAWBP%%KtYI~bPsXVWD7EpjkaH}{$v@ST1DF7wbF|5V=$#}3jiSfggGB6oW z_&>84gBhCN3=6uPR{`$AgOpT^CRPe+g$#Nw78QzF%_*h~i{<66=;+=(jSQ%dE`jc7 zP2+tTyu>@ZtOC2bI&r#zN^wcG0tkw`?snuHIU`VPW0Dp24dcyvc)>j(h1O_M#a) z3!OpQUmnbF-s#);?!XyKUP!KhdTj9cLAg5{-f8&gM$s=%FKT(MxWRUCe_P>VCv+qC z#Ii57r1N9vo)KHo-oKTLo?SO(PGnGqRD$@^Yv?!S3Yefg3tPc%H|J?0Y_3(_jccdmAl<@ci|2y zGVmjuZ1N9HO($(M&D4lKjcH`iOrs_fi>ds;aMaPX#hKmP|>%W6T{0f~5P3g)%rUh7V&K0{?5H@3m{!;B;nZcOx8z zMT#FY5M=n>){}y)-*6v94N)p8%}W0?UedyLQPu*$9t%ex8bR_V$0DLs157jksub0Y z{m{M_LlxPL&2sulf5Zc-mEr~+lsA-ANDVa-Cu5T*p?NVL8VCbZL}THQYVa{P7Prg8 zxwTASXdGhJxUmAuAzJA#MLn7hP?w#;C6Xjj7iX8nfG7n552G|mQv}Hn6oZo_@8Ecb zK?i;qbf?QfzDy_@a0cJpShZ=#(gaQ85P=)@swu{B)yNsN zAOJ(sm58ZmDr#9216r-=#^6yC8p093KWSJs1|kJxM#RJjLD@+n9JYkT(S}(Dt{>y3 zXrrP&0*EqTXtlZoAUx+f*;@xa4`{drvbPSXW|9tL|KH?6KeCj>MQZg>JWR4gfDi~n zdj`}*B?U#QHB&RHwSO_4+>QsrasZ>nPuCS#HDXB6q*}|QPjF*!$1W=}%%b4&P+rPG zlO#oXJ-IF~CFFXYWTBTXQf&i&HdCG8Gif(@vh^CXx=GBok1-CM&`Ezd@Z9 zG|e*N;#d}^?UZ#t66q9xuG9g!NY}z>yuf+oCINN@9g^r^Wt<5FB%E;p zC(dyW3MXm6Qn^8jW`i&U3BG(oVI(>PT!Bfteq@pj1{szO;z1gSIO}92Toj!$9&pmM z485>yt_vfQM=Vwhn6mnTrce$R4a`Cc^ayViFG|)0hcZQ|#5#txcrzKdRwoI5v>HH@ z$%OwiiwT&a1!Ra(H#9P+KE4FI zqcu(TW%!cp>_CO4b=bGNYKEOckW|(u6jW61ySVn0n)aY=$<-6rw*J;vH!DB?*f(2z zHAi0k@ObygWs6ErzmZ;da`{^qs(xCPSI{`7<$pU1>3d>h#(1Rv^rq)CGl}Oi*0wPhdTgaj=(7in z4(v>357GX4ta0W8qCqzR+1yGxgIS?)^BgZ@c5rCpo<-+qbB; zoGYGUWLnmbqdQyr)^j_2qdV$WMpLRk3-IR)XY?KYb==}l_GWV}D~C7lcdnW}V%^ot zr@Q6VE!>%PK6c`)y=@Qng)+x=4{cqTvfyI+%qz+;UhxVODkR+F$C%AO-J@L zEJwa?IeB}>2in~A#>vmJk=CB<*jNYH_jK#+oAxwTF57&6>&(OFc0ZBXdUi+d@bllc zHIDrw@Kk~R@}YM>zm!@%Z&AN(%U4qLsrS03=B_+2bjQ9&5%=-KCk{lKJD2X>uyjhR zTC(~s`TF?R%%?B;9U>Kn>tZ;HH4CE$g;6B)(hMdF? zyLJ<}syK<+wo1A(?1qhM*+L!GES&C@7dFX)LQF2g3u7WO5QGN6W5GZuBF3CV!mfzs z<}yX#35e0;BuY$&cx`1B?$&gO+bs+!(=?6S1&acFK=%0xaF%8nismSWBWYT+3L?kh zeLn)Z(-ps1EtU2;LvK!^(J;ayMMa}gOVn!7^ahF%1c9Piie*WJAS10I1H{NsWJ13M z2}WdH4I8Q!!cB|7r!^Z+0v$D}AsDW#Oc@SE`XYs5M#VswVk|Tj44T3c=!j7bZye*6 z=!my945?}u(VBG`BKU+GWKRq7+^69-$etD$GE#ID`~N2Q`%&Z+F5IjK5@Awg3I<>h z*^3}eOiEC=Q8TniqxLVRQ`?C^m<~|1#2LDZss;okO>Q<#mP<|o?N}65L0OdCZpOn{ zS(;`TkK1AQFp|S#qg@`>B}iPqjazYfhs);R>=Ne?qy(3*a2Dm9F{K z0NRLDPjTVp9yiYjJWsL~#=IZNbV^WHTcA>^Ye76w;G%kq0Nedm8CZFRX{O%?plX0;I$|hPikv8Mjv_Nq)2uB9p0v z|1*n8SVZ$1QJ}+;26Pv0r=*fJxeeHc*@El3#?LE5aWN};Oo6}~ks(W?n z7fYA!{pQf>6Mvklj~1=a3c5fQQs7#NxQCKvFon!>L>WKJNLd{ z(>d>tF&V^^j6#g~`ObmZ$A>JPRL-c2pDk*74;Jld+i`98plm)jXWYU^s_$x30tR;W z-hJ)4wHwy$cZ?Vz=5%Ep#=7%1EE*ku>hb1tXN5bs^X)V9&Mg>M{~}+5Jzco?`qd3r zGB?lr@|9h{&drh6=#MWjvTXkeywgjup~{YFPo+mc1Wo@0|YzcfO7C~f!($F|Jh z&(F;}#m9RJ#RXH(XFqdq#;V7#ZLvAw`E^6LIP=FJ8QT1|Wh{|EGqBb!aK5Zfl3(g3No4G=*bHoI?=ohI3^*`8>p zI3tHB#e-TpAfO`S44}w}M?pGJs^fq#RHdazWyGU$4TB0Z9`$X~rl_c7X7k>@_x<1h zzW@K;4`Gz7v*+=X3e z-HV}$nO0THFRP6Oq2B>}OnLUc-4{zK@r8V(Y~fG(glv1mNW)wr+}F9+ww zGJ&Bfh+g5s3Jr&7&|ivrR1KhZ3x$g$NuqYAMG``S7z#~6X_BT0k|8JtCrQrge)k;kS5I$kZ*joiX4`{d!V{a9R>lt$x`~Nl`^dpHGT%uBorotqN1c-td zpqXCR8wUo z3OABv)7_}g>tQJ;%i^?!GVVt@ojlN#Dj*eUY79*kIHz1Az;@Xx3RYIanNUc?89T7y zPN$W^NgA+}L#Aj}h9OAXOIH;}xS-EvH#Wxh(}%B@JTWJ( zBOve8J`yXPL!H0qKKk}EU*Cd^H64FAI~ZI&nb@$hpl8yNGU1`ev)kY4%Ubxum0vr3 z-S*~s+vZhc+D3kRYr`vh%x&-Ik7nxGGBh&ryT-hYmbEi)&m&D=7q2XA#2W0+Ps-ak zYRRTR>o0GD%O~)O!CfzJ|9r~Qf@2M%P3D3F=Nfj5H;+Z;nE7*U+xI=an%{Hyw`h1k0yPud^t8U zZYS{cI?>Be(kXu$YbxqAW{6NR0_qHGh z%Qu~ke9T4nljW7j<{2x#pI(_0p17P}=FZvPu`2sm^O#*5%h{7BSp%1aqfYjjsfsw}jvBUij3X*WLjc literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/LaptopActive_128x52/frame_07.png b/assets/icons/Animations/LaptopActive_128x52/frame_07.png new file mode 100644 index 0000000000000000000000000000000000000000..8160007228c857ccb1bdd7939a60eca7f5552ad1 GIT binary patch literal 2200 zcma)84Qvx-7{0N|-x9`GRz=?iijd0vWf8re@GbW(5MSDBu=IVL@`9>ckNbCQE77hzWcuC zeV^}n-}ifSn<~mnv&K&wk03~vw~Y70F%BPkY&!g}JJHn!htU;F0-m9vAvj&}PS1Kc zjEj~%rXxsZuKA=PZF{CbRJt6fG%9^dI8lvQ1xXD8Yb+9lXap%(6pIRCEilj^sFoF% z<);&;ET}BGERWiKgfHp_HFDWn4J=<<9uU{oicZP0Xdzk<l9)&k1j;(Ck`NTcVDKT7A}A6kXq==mg5YdU zj;7J!p9RusQi${OCBtO!&1I=Ej3|fW4Gj&}2AfsYs&Ufkbm9bsQxpafnBJ%uLJU*% zStA~Jpo^LuHDpymO^-rQtutH}c+{kZNYv*`Iac)HNWqxlF(HbRRsxSiOkoMMZur5i zW84v~2O6UQ_XAz6(?kH_vu+uC>LK&6hPyEK)C0vxnZwxsxA6#%B&KlDIxUC;$(E(uj^bjwgLXLige`3^;cZ2%+iolIlu*SZ zwq8Xy1VscRyfWk^B#8zB!(w(?0vOE#78BTD5TjUDU>SxEk)b3v=hlE=s9Hc(!y{!{ zF%kuovRMiAL7yPXiW!%A3Cg4i-~|J?EN0PSB!v-lfTTFe&e80A!p0Fq66#YWIn?+! zs69YY98GZq{TC>_GLm2j{|lBxE~IJ^0Tz!O5vl44XYX?Hcxl^y4UTl z(A1C|h8w!Sv>5ez+zjbt7>u%#=KV;flLwky52O-Jji8AF=j1yCm<`!P!Ny1!9Sn+Q zfbE#mX(KU$0u1R0krWexAxPRww-rXRL%1xPm5HwI!4e!F;lvL78tPzxI0DCT;5Q>}4DX9!k=H-^?#NKU<4608o z!R}~IQ+*k}q&hoLplc2G?YtcHAcBmV=jDq6m8Syfi*h5R?&8Szbrw_M6}mv95UkE_p3Y@gYGGrzgnmoa~1)w6xM`4l?` zIsQyv*Vux>N69@OWj??0p=KL$a1612TKt3Nx364uPMk2gY1yRr`pNk5a3^wT;QBRo zr=}2B2ds7b(++klN!xwdiTrT$WV=1Gto@w-!YeslD=${Pc%^VG;+4mpoAt`E&(l#C zawh$N|MwZ=)?V1Tps1<0>QZfXbJu%?m(tP;bNELZ=Vav~%;>&(_|Z}>E2n4m;jaFI zy*n=7JK^YOk6j(Rvp)wB9(erMrCA@=?{CXq{r$98w+U&zyT4D{zv@dQ?$?g4o7SQHs3TAA zol>rad-J9vo$m~+EX?T29z5Ll+SL~0iP!Ht{|3lgcm3^kgI~}K&z#+Iv=aF)=jm(l zp*;tRzqgFTk zs+X^ND-$i4G|*b#ahk~pZXQ$Uc{q~axwv<4`-{gEGqBb#d>woNvr0a9ukXar$+*?mcNnq=c6oH)W&ms@C=vG~8G^$M5Ou>qFCdhdS%gkdr8W zD2ZV=kJcXp*0NzNLS@VTfEMu0;YB580+JGhrkYp+p)qVmeoX?1l~BWjFf7NN#O2mD z0+%HxQDO1XzJwb_eA_2m&z}oQAVB%TP2&F&s(LyxGBX9NzyS zkULch@nu3$zccjaBqExY;3=xQy4qB2HYsYDVjK+wO0~Q3B z6jeE)$x0m8ErOs@r8x<7)U<|J!sp8vjwkyggGMH4VR1qThq-$i)QslW`!*!57OJQ8g&{6FFn>^r05;M3&l^RWjNfId-g)w9= zi8L`8L5YZ>DanZPFQzlwsX*usP_+2Ds*I`zLB7ucw$&ig>gER+NiwIME-mOBQDXL#lq61}GIuHe% zHJfPsejgC!xE`0ugD6k{8gvqR(UJ^H(wv`RdDg;PY*T47Pt$3rPm$zM?cbmlKg;qQ z%hQg(K+%#LJAzd8bu$xOok znZ-0Lsf4s@pu)m1x(nA+QfZnP0r4QhUoJL=O+ zUq&yP&JN?qw2Jz6McX*^bC7k9S19xc4u8MCC!Rg=7QxZi*ZFwy{;sP>oBit+yj0xt zxi&6(f_~+#Hmm)2=Vu#xAD!^w=udYT4qQ6<@|!clPqpT>FMz|_FHpmtU24oK8Fy^m zsh`hZE^MD7EE(Rg?m*+Pf_dH3k1MwN-zqQUmel#yHV zmTmR7{=5_Z@)n!HXFV@2f7I{0z2LiD zcYW8;wXAzD-#JUI{9{DHx!&CuI}Sa$?8}zKt228pz;or&x>wZ>^D|MlVsrP}xA)EY z;CX{YV&~2zz-u|!gY9<|L|5cq-2CyxJWsQ!30t{{7>=(#k72dF>sykaA76weJ{cdG z@FsNk+OtbH^lk$^qYm!ba&pmW7XM{ltgvd~{L6m0eBlwk zZ2`P{gG)4ie0E|(OMKUvqK|Iene*euCyUnFb~KK-*VyI7Ze7#dH9hOZeMf)Tw*xy? zzV%|{JwAGvF0aD2&sz1(%&MI5!;x%Euh*81(Gn*y_!ec9UF rJ>6<*KL7NjBVoh)PtIyfubgqj?B#>ys6 zb291EQZlG%c@$2=(NWM?HvtIjj7UOmyNweFw+`;$CBU`kF#z|P7lVNjC@1R>S)PMDjHH<_ z5Opw+>h)lE_-HwyGfyC6h?{gEm=g7P>H?Zf{|&X`LXBl$ z;Y7HaP-(`XY63;QP!mtHxkWERF$Eftf#HNoOQ<6L1qCfflOow2u*pOuae_#46q97o z!9bLfWobf-lV+_smsW&R5s?ZFg-0rIGD54sFfAIc)@oEZNq6W1@dlnM@FcJ+o(A!1 z+@RNEMog_jQ4BNcBeh1%5NQlYJ!dKo8M$k6dl-VSxNBf-8T16~IP>oOX{*RfYRG>FKr_) zOyF}x7wKeTEug&J>1l5mWhFTa1BNC7dyFEU>Ed;Ucq{PSbjQ0FCQ%n0j5p7vZ?J+J z-)LqyKiC+Cizvs`T} zCg}vfCyNru2YhRfcjeH9%R3tr@A}*PR>wb`8ZnB^X^>uhq)r~4${WQmquXvs^~)uH z&oLp^!%?Hlt_;A&#%TTCn6!7}+Jr`R!-u`k3Ne$v&w8)_?jboJUCaxr=oQmYudF+K z!OfF7pUng@?(;Q#%>~{5-v#x6^FYI$=!m>J*xNyem!FBsL^^vX&Ne$(0CO+s3HcpU;ExWSj zjx8%#mi|LXa9CRnIe6az>lRzcq8T~8Y63=Yl{UQZ@C(i0j+EHf54Ubx%Fp;!9$S@? zT88w!I6Qo0+<~Oh%-Aui6~)c|k4sv2(Al3exy^32IwPt4ks zyKHuGa}iVosq0RYLsL#>hLEe~MOjWZV}HuOkX8S6_1VnW6Az{31>-8KZ;s#M`OHW% LrWn47%bEQTQ7$JG diff --git a/assets/icons/Animations/Laptop_128x51/frame_02.png b/assets/icons/Animations/Laptop_128x51/frame_02.png deleted file mode 100644 index 0fff5b1f9898d0ef0599b54c462d4d5308769588..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2231 zcmbVO2~ZPf6ka1L9*jq=BGs}kts`i%yGej#B~nPjQ5&RyRU8U#HcPUSWS8B=1QccB zbim?)+G;%uRXXEX6>Zf*v0~L?QLA=T9HCWPFN%&wwbp91|B?{x40fDmX0zA#egFI3 zd;gnVl%AFxG9YXK1VJIGDTWMiE(3=uSO)%2%2p?XQ-3ZcTY#W}uSiEPXzlt?2}u#K&U6IFl62o!asMo|Aaf8MfjU^hDiCTlYn>&?fz&<1G|4+k05&10dAVE(s4$?}a zoYRWHf!Yvy*3R-EaUi=YsqKL~DPEdq=FpZTo^`-o?MN^^WI&}g==Hc!2^;_mJvs1k zEj_sRb5$?oqJdyi7yK!TVN|HGaFez}tQL|rx- zNcuXi$2Ri81U6rEkvyGX1?7F2p7zlw8|k#tU}&O5cQZ6g=K{=d1fw6EoX09vQ~&-M&C`1A$IW zuJSgF+B%sj4ShItd+DCHH2YI_SC-YZ{$cpwQg|KSRCUJ{5b@C0Ez%95Srm z@~BV4eoqbEGH-1}MMUc`nY%QkJa~LFyToBXd3o?1W?jN5$mCs^lTBg8Meh=TYUY2;Y?ooF}pixQ1PbFO))=hQ*@kNth+d**Ok*Zf=_i0T>49G z;nK3tU*8r{Ha>4~QmMJNZQ}0uM$~veBsvmbHmas$Rn5V$;n}Z!dsUb+CMZfshtA zarJYjf0o~;b;P0tvsQYpuUs`V7rWVeohNk6MfW|qEG=mGg8JIbx5wQk$=0YfQxh74 zn<|k;?~uF2=Dh=u`SmsPm$5fz$Hhc&u~E&?;Y!xDAvYnct!bnzetFrn6T@tIX&wEB z?JYdVxfYzOsm>v<)*Wo78XmJ1y?=Q1&$elv@8&*S=dLJvld8+k(8C$7<(^3obE?`` zH@m=%0qs!}#CZ5Pv#eMHR@K^bHw50Lr$jgi4^NTx6TdHObl|C&}jcJDMiL*Ta E0FH7ZzW@LL diff --git a/assets/icons/Animations/Laptop_128x52/frame_01.png b/assets/icons/Animations/Laptop_128x52/frame_01.png new file mode 100644 index 0000000000000000000000000000000000000000..121ed069645140d341dee33cc2a1864a1dd5111d GIT binary patch literal 2260 zcma)84^R|U7+=s%(!?MuGaR?oOw+ynb9;Mtt0-`L$eBk3S5i$g?(M#VRc?3NTi`%N zWJ)s|(fk`)QBx`^W|mX=7s<3gV_F!b*<@5!W-4asFe<&hgVV~&o7sDB-~0W(@BO~- zd*AH*yxfWX`ws4lAV`024xbOlYWOfoz2JZ8_NF>GSn?+OJzZU0aQbj_OBEb$)^Z*V zBS^p7%qIbzFb1Vbnj%PspctGaIh%`P7_|F` zL3g?oIwpf-xf^f<{nQk_d%NVNrD0$Ol)Cab0xS zU!egaAB5FXT?7z5>?+w)20eFcxB;@K3@ApN4rBk{F`jz(_<&IJam?eXL@X0kIQ>(6ywNpFivNT%h>8u{ER|y+} zB7z>jGW07*0?pb)7PkY|i8H`X;(~*8;3Df3Z9oJpL)oHy&aDH%P<6kmmh_ZqUQZNI z+GZuukv>6`6*DfQuAu;4FhDwH7A;QEILY`anxpB_q>UrV7|y3ka54&t_I~2xDn2u zn1y;hZkBSfEKXY~^K!&;$pc+315&oGhR|qrbMkef>j>IJ!Ny8B69|Yn;{bNt<+4#Y zNduO01}T~i!Vtvx(lu2PYY%V*X6WjXNj4Z{ST=|UX&~UNoe^^W zM#PVpBZpzWD!MyD0eG@|Rw6@>@JexlXx?rpQ-Dg$W0;HAlW}83662Q_186dy?SE!5 z1`De}qg>EIW)ZvyH&RbAnpi9-MF2KjA}W+HJ5x*<5zEU}(b2tYx)@X+U4pIAoW`3n ze2KSppg_|)Y}&n+G?pPqVzHOc^cTMW>&nlR(f8cK&$`mJ_KZ8Vb)QJCYV!|bN~-l7AI9j#2lFGAbP?+r}D2BlSAeqi_6j;$RD+C=_X z@0Np`f4Ji5eY#=LisD0$q)NR{v5Ec{hb^eh$QYWS^mENU+O+kPMdv$e-l*Am?)0rm z7O^Fe+)!J6ujT&RH;tX2a$-`-aeRyQ@W|xN%YEyyw4{||bBA9@>UjLZG$fyGT)wWh ze%I3|M&g> z|Nhx!Mbq;JXWW&6Ajsf?e6|>li{L}2o8W)V&e%FQq!kqg{nxHtgVR~>eYg+~1ETp4 zX$UfKnDL|_>z=(6qD)e-OfL%*GJ+yoI8ot&rCyFgG=fZ>Rv+brIY38wP$@;+=JPxE zm{Cb|n@ep0A`ta~Dk*=S3QFcp4+`_<2rkh)EgPL$&p-n*&^feT4o5Vm-ffQCW#HUc z#?5FPqR(-ga}0-QS)d5@DJno677`N(fN@(Hb=z50fb1APi(^ zPlKAsq@ZY(qAOaJ@-L>7+wnjc4q&vH8L9-Uh6}TbP-B=ZVBKc8V-Y10W|8&zNIz+% z2!bU2KBvP^vQEE^@cJpQi>3Q)+>D!RB?v#60CqreSRhAH^kE+iWGUw=5TTtP1|^kb2*$C;UEZyz|p|Li*Y{VQvs(dYEV(aePvqI z7X_5ES_pJPfD@#M5toTKPyoy6z-=~)79%N)po1jEP!vO2ClgkNAQI4kB1)l#zd>z5 zh@&CY_7^C;G9ssQ{|gocCZwn`2a89Nxk`XXBb8<}nH$EZgcTJ!HcofrdV$YZq$(jP z3^%mmJTF?{_t{C8-HuTf(zqXqbh1E|YJr%mDl!@`a7MaGfE^*Lz*+4gM)SOY(GFn4 zTrMk#5freK&Jao2LofshzIa1nBsv6Kfl0c4WWpW_(RO>^54!IL;LkIhs{+tu zGU5NsVgjZqA-#@MK~5#S3%62I37SyFMJfU8xp-VCZZxNaGCYx&>!Ra(H#9P+KE4FI zqcKhPW%!cp>>vV7tFUj!E;i>ONUB`G<^;?3o@@Us(nAbl8?Ij4aye_|;jQdJOVOsu zn>;=Hj$N>4&iraSR@*q_{Dz8ic^3!&^dXWxhKb>*zCQKB_+?$L1gW+$p@zddosu@gb$*qXg;Kj zjXTv;IC#ykNcXR4TTZ1MeeInKo_ zGdo=+sc#;_m#ypUY6U;U9?RZv|3PoC;H9h&QVLfsA2O+b%k#rO+ddqb5FEDo=hk+7 z?1u5LIJ;X@Ter2H>DsboNAZv4NZBJPo3b+29RDPv>Ba8MZ=dvxGp()SN0g6_EvWvX zxCCihz8;y-&oTP+)ZG^b#V(zTeatUS>p$dYgg#R0p4+nY?1|lFrq-jSbKf4(h<*R% z-fvy8@Z-lB?Rk4KU%`03%RJCF|La9NQ!gKxvF+JMyXpNSk9>o8Ryp=9YwHTGb6B5i z{^s>;Wz2&woLMZiJXV|cz@hTD=!ZAk77p_;BdS-tabm{`w(ysfDP0Rm7h%_>?j^I| z-!*0buu111Y+iD8(95Gr)?WE3TJrkZ%AWnE&sPs^ySs7fn28&m=snfHSL~VphpF*G V|C75+a;NdNQQ)7>c6etm{u6|CA5s7S literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/Laptop_128x52/frame_03.png b/assets/icons/Animations/Laptop_128x52/frame_03.png new file mode 100644 index 0000000000000000000000000000000000000000..57aa7ea769b2b3713fa3ad86bf7dd9577af3d1a8 GIT binary patch literal 2262 zcma)832+lt7~b^Y5)tSKRJ3dZ3RpIKWOJ+U0f(!@G2j5=0fQIn;8cOa$docNh=QfQP1=BpN+z54_Py`>|M&g> z|NcpBY01O~`#sVRL68SMg)T1~WALH-q{82-mP6~{(5rNk&)wD41*cOFfAJz5`i2Xi zQ4r*T4DHb&>(&p0s8qpMu9g>1VmK*eV0p<84AD>+q7fuFFB)dKIY34Iph6Js`i_=^ zdQ{-;`st=(qB!gXl|tb>8BCd1;^XGc;cUD<{893LL zaXlJ`sB`T4e9a+RUR;VgB^jU=1Br12L7*0!foJ_J=l738DS{$#g2qW2BM8Q5V`v)f z{^+4QnGY~tS3$Qk_-5Bvs%n_Q@kk_Mh!_o$T!E7|n++!@oT4y@z?2$MWuus=jO?-C z0tzP!VO5YsRI|wXr7G2~heu6l2!)G_lZHj5J5n%ac$5v}q=CRgAx&5ut*Bmb=NR`y zE54dAz`a0`s$>p8_{ckCcQy3ft>He%?rI>aNji-Ef0KLs@LUoXu9AcCF!3A?f*=I# zDNqxc6cnzMR7t6n{>5~1J01wl0gM(iSr%Z`utAr^RcR(YF1sG?7LXo zQ9vo9fk4L;vz#DmaT$9T1-Muh*!5b`VkCtTw2!113V!Jv!pIOr0$MEbLZIevP?Hbh zXo?}Ne}Td)!?P;;zhItY0+JkJVetqdwgTW`u|kg~bHg~Lpd>@b+Uf3I_c)!UvJ?=4 za6|D))k%UMsRYnu zGU5NsVgjZ}0X4$PAio0Mh5IR~1dXd?#R>p>E*=+(Yt1R43{T|cj_CN_U5yN?k1xUQ zs7;f78NMVtI}o918TRdwV;^fqkdz9KE8kasq!fFU@V32AgDZ_fd{<|VL-vhpIs81^@bc%@-QPWXw%5|t_Ltfm&9(IxPF1C~(KcCiTl35A9mPTc&wSltjSZZ`zo57T}ydgRW zd8IYrTz_%sfz;*~o*L75X35(MlJhG!9?uw*vm0+i<~99%E&GLq*Pr`se&?lcsJv;% zM(5mcz9*KC`Td0M#OU4w*3A4Y_gGQNnRN843!lETxzzLa&bqbI$3N~GFJ_f(dVTY6 z`o8VUR-KwYxUQ;gTWyK%c;oT`Uq=5}IB?2kq~zUaH*`+8`F-}V9RqUC^<5p=nSbP$ z{sQA!SyHj;=1v#;-1YXWm*-#kc+r!~@(yH;-DsWgkm>dZvku(W4cni7(lle&58D3> MkGsUx9qc9zFKi*k(gFCWm%fphu@W7^!5%;D=Tki@4bER_xt_d|Kt5< z=len5JwTbY*X4BRsa2Vt(@q2oEd*QUAt!EY-28WBr>j;u^ zllcrlmMk3(QHhGb(x~*7u%a5Y@{%e5Ya|$kXapHOCKBewslY%5P^E-imR~o$Z$TBw zWx3zxCA?ubs8))mYoL63sb8EvRdh<0F?XS(BPwJMx+I-NK{;S_~I1g6)A3_gN|^o)K54(Ot$ zgbhUvp{61)s5OSm0*@N=AsF_0c2?Gx1)hD4Zvuz_h<^N8a}|OVvQ+T%(*OZ$0{ij%p&J@lOB?$2!bR% zZbz<%KC6i|w` z66h!|FDfB3F4>n+0LL4^Wig8uBPonv{3OLv6iZV%1kDnC>Rwe+zf4>Xc68jmKV(n4&CITC+0EC#VfgSb#)Ts*Hr^38Bh2>vlxTv zs%+Hp8px}Hcj0PEDn=8l`A`*rJr|EUikr@5}Hd z-q}G2N^7uh<8zkt2$E1$%;otjKlpj^{?I|eP$c_6fblOZ%DOcRS)b&{(&qh?@G-Wq=fe~>WpC%E{AP~$ zc1U^A`lL*5a(i3NZ9_XJZA+M#*;3+7OYBq@-7)x@gqb_u+U6>md3;hTy3)Hk`^T(3 zk2aku*x0e$o_;ZRzH)+nbKJtoi)UAkT=@8}Fm;-+@>uN?b65E4j-L5)+^J`We@$*}ug*TQ zQ|YQ*n#CqHmp*dh%YzFmG>%k}9DBOAbppM27z5DP7dl652(%uYTLyP&HQS2$@UeBNW@SpG` B9v%Py literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/Laptop_128x52/frame_05.png b/assets/icons/Animations/Laptop_128x52/frame_05.png new file mode 100644 index 0000000000000000000000000000000000000000..9c9951c3e5a829b828100a72c637d87524694447 GIT binary patch literal 2256 zcma)84^R~K9^X5RK}CIlm6`SSEjdZJw|{Q;U^gy>+e6O)36OATlD*yE9y{LM9=m&T zs1=w+SfMj!V~!O~VQHi|HBm7s>7*lr1*O^lKa&#Km=#m+ktOf9cX0aN^S$TI?EQZG z`+Yv2@9+EP_nmDkFIzHW+T3Xfg3RzO6)ND^3?C*f1^!2S`*y$~wY;RtJ3c-Rrz;M9 zct0GbMwYHL5M+9m_1KUdJLf=Didt1;)|8g;k`{7^vgQYlSSSL~2vV>p77?Y@z(oBZ zpoZPp`QC#Vs>*KcZnl&xjd(!4x^%4$D%X}(No!Y2oQy5H11*U0P#^?M5sig{VS|sk zvA8Y|=hiZTp>c@0+Km-j2GN?*a@3>g0L^nyxI~g9n#Vb0(JxAV|3Z`|X^J2jf?{xz zJs1y@ zED<0GLQv0uK2b@BBK4Z78THzKkxp*M17R6}(c+iuDy$kYC}>jDlJp5~4DL8&Rfbs< zJRZtRIcbulD6c0!&r1pUUY0EK(nXxWOln+-OFBsp$52H~J}1Pv3|lNX3-dgzv)Efq z7fo_~VZ#)|5}35BT6Pthk!i+>b1sp?8NaCDB18Id#ZPlij&+I*OUC)UM+c&*=~bE* zoGjDw$ta+-(?OyON<~QxTXD&`i~0?^epKrYs`5E?IVUcEwq^Ax8fI$bi1tzW{K zJiy`{=cI6w1}-XJp=g%^Ly+LhmlZ~$L%s6vbIR`H@_U2y282tBcmVJ%+CjjOAZ1i!H! zK*?mn|1*mTn4u|Vqo{+z0K5xVQ&I_b@5%BXo|Arj zS?)RSo)f$9^xt9yb-$fT?LFAqc-qHHTT{2sT6gboMR!|A!^r59 zYrpw+^|z@J3=41gG4QcDj@bjZ9m$^i#I`9n*lsUw-ebr=XQYi}_wC;zy)>hsH{GW_ z@Y9O!>MyUgzf;#$JMgz(GrC(^mOV6D=HK|{!)cMWuIcQilmW1{EA2-6@9kN~z9?G% z{k=06_wPEB8J&K1zHmSG)#*r9&mXOacJ>cXDV+YmqZ>}|N?>!HSsPwIfMd--*Lg6ooTN`E@m`g_bfl3d)MIJm$wWq zyKr-6{#JXeUmM71xVv!S(U}8-M?1Hblx)kH)iks2trP!1jqWMFwm2ixnfyQ%huzE}60 z&CEg`oPE7*%bf7p;q?o)YPNYhXVUY{;gNZL`k#YYJsThC|Nc>X^K<(?7_0tWda9uH z&Xu>@BL>@J|RL9MS*) literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/Laptop_128x52/frame_06.png b/assets/icons/Animations/Laptop_128x52/frame_06.png new file mode 100644 index 0000000000000000000000000000000000000000..c8294d27a2c9e0724739bf3ea736aa1b510f52eb GIT binary patch literal 2252 zcma)83s4kg9A6Oh0yUKyO-y#yC*s~dZtt~l@wh!6!71Sh=*Z~a?su?ycYE$F0-{DT zj?v4~6cx=!faNrpIy5>CK2p)9(y=JBoHSplX-wu=nxlPt2d9;lH?#MB`+dLP|M&eL z-+#8Da8k~IxZ!aKf(*#Z<%-}~2Omb)2mV*?*}oPJeG3a*j{EoT!|BwIzgz@|CjzorS1fRsd?&Q@B8qBx<(mMc&N|Zudl#CTWTw8G>SPl4K25mSNDI z9|q+V(Zd#T**#+L&4yK|YJeq(s;Vk|l|e5n1fbdZd$c}kXxyOgcAUoy(zZ#*#*#9@VS4R{gxIm@i4TVV*2;c=i zXfFtTq9P6jDr8j-R>=QiI*T$o`q=B?s87iBxSh*0FF=lgyOtal+$aZAYS-spm ze^BN90_fG1pst1V@D_tW;zo~P#2M0L!rd0qj02GpVcpRbEeIh#YgYiT%8E;ty}e~x z*c%0uHt0!oyptCszZRF|hbVyKRba!kqQxm1Cm9z-voy^bsT9({l4Ka_ltsx?^Ear` z1#t|;(x$&a;gu12mH%I`D6k$`@$s;DBp+W6h=9KwLnFCi?Xp)^ps;qjhu8D$_CiJW zNM5)REXv73^Bi^)Wrd-k^^|r$!s+CIBFzJ0wj%q`P=T}3BLZyp7zEy65^=`u7I4N4 zjJVZmpm34~Cd%TWXp;wqAj}sZDvWT4fGaRb4~|TlJRZhm^57mC@VLpy2sqChMci$q zX%VWJOcpanM2?s%1!2l+dYZx%Ft=ysm7pTLRV*)P7aY3DLr=70Xp4_>I<)stBZJL2`v(EjzmcHGbJKGM!a^^5+g zIWO^x=Cba%v2#b%pPHF??cT`m%hH>cT}ZsPC2GMtft(`?Cnt7~McO}2L^e#08GUPb z%#h(}sfRl+o~f_HFfux0O!wjFjl!vwm*VZK)Jvyl%asXa(yhB|@(+w%+_~xazOMMB znTh7Qgu!zY)bxX`e+(ULnL>>`vGIe^M|Iy&(XREQUR{=vkregDk`Z>_*;62Qe(iyh z1Ji3tbTReY{nXN~oc(?KPI&rQYQx}5!?FEicIdmt4Aa_XefRq?;H)LN0` zrd9b}_4t1c z+YM4CMLW+ZEE0D9*;Lo9ji>@?nT@sp5n&+ce|Cn&E34LvA<<_JnxyVi_fd5 z3gGc3bsM!QY)X6_uBXjHf~0kn&|$W6XdZ82q{B++vnUqOQ5i;yTrkjdQ~(%BxnP+z z9*(yvs7zyQzMWc{pP<#}XX!Cg5E%h1bl@C;nPLgRVK!M9+#weX^Wxmv^%@cY!w@!0 zE{JkD1XAJ?0R?TR091&8dKiWQ6cdt!j?n9L3jh%;LLgWIArcUVaWRHVB*5rTz`3)N z20Td_GwO_ck_$3f)`~+=Zf>qHS1hFM84!YD7zB$TkqG1vAd_cd2?uCl=8iEaDMoKM zT3I7)0bGoPj?QM~0xr~%9L(1E_;F$jGpZD)8RQ_W5F&&jv)Pr{Fq&bLsOMo!h-S2T zRtid@7&_aor#SfB=fc?@`Y`bY#CQ=VkCd$n5 zFIH7Brr?|QWS-fQp|vfMWQjDiR=-jLIjK9FfkIPL=crC8i7$&v`U4ERj3#i zM~&I4EeuOo^wgMdBj=kGlN5<6F2m|xu3BA$c(&o($! z-g{vxjlsE5=UR>rS?*zcOj8z)+RhDO^?rIXkLP||t&Gw-s(MpX?Kgp6ta2Z>vWG02+BTDu4?Gv z53Vd2O6gnOY5vUni^W-sY;~+24N{%1O{(t-c>*{#YpjY+pS|5jduyVr(+j@5Q*x|g zps(cKRsU*d#~Yv4RP0@&@-!43d0hCr3%B$?&&hssdE*_;{Ck(?T-Y5r+e_J1uTZ?7 zeeC#}h`i3Q&2cSzDqr0mP*KpXQGQUiI_NwjSqD5JTyTEFB&w1Nr{VE`kIdmr)YdNA^B}TcIVWFe#`$k$MJnh$dmmC zazCoebyn9GZu)v@7~^;AUGJdY#R=C+b${mH*m!+kYx04>q59hQwg_*my6Ik-_i4f9 zx>^1FWoh0A!k2{axcu=JZT}}d^3&zP>x!M*Cf&IW-futXxh$>rooJ$;_e$ESq2fNZ;@o`1iX9AMTLZzfRo7MxDG;oV?}n15a(u)z0E%h0ig0 zQc9Wg{MneqpR;oK{n>p`LC2#SwR?Wl?f^6F?;NsH>=x=i2GQ=Eb|EI}e|Cr{`;*`o0=fn?AkT z7d_k>UDngM@tfei#dW=Z<;Scj&=AqF%e$S6-LCi!ru*@?##k>6YM6CF{{96-x1zg_cB=XPXsFMnx2Bl9R(;cx z@TYovp?_d}T|)Bfl}B`2Z7sICh=H;;$%E2YBwgr-wx1qVq&5WiwW7=Y{L2R%K{t-f z^9j9NQoc1ryusb_QQ4Mqd`SRb-QQt@?-n-%zT`11YK!{k zx`5w%X9=n|(H`iT_ilyH`EbYneOJQ^{7%{cD|sqe=(LkLsHT8)jvcWNp8-mKXlr4-Gf(_FR%wc4&T#cq8)D($nLBg8@B5$k zPj-feEOv5qb)?Z~PC-Cz(dI7NBXg1%5^?hHoGZbU7KT)QF&-$_o%(Nr<3Go(z_0#iT+R zn4}|DB!z_INgHsKfc$*v3yeY_pe79%-KbV+^g^Qu8qyVlwe>X%q7Oj~8$^)5)gV1e z7D^XWI+D(3A`BdcVLBgW5||vr<#KO28)hRcn9D-A3>X%2P$8E~ANfGQoQ{YQhDjEU z7z0ltNMSH&g)CNLVj?qOV-2Z4V{FY5-(QxJ;)6U4yA46drGt43dZ-u)`#jgiubhF+PDJ3>0Rg z3@#t%GB6aCGf0x;6Ff8q<*?bKIT1raA6FkQ)8fklxi%NWN9_A5PhsZLNTSH zbigq1j$>{8;YvwJoic$W7U?K8eW-VZ%Gc!W&1yExC;s1>v&NhXRO&(QO(Q3K1sON8 zQYnFt;D~@aT2HG8(qq7PXyoPV9DlQd4~r%$NFX^}x!0Cs7^bIU42hVI^p6FN{U*IJ zOv4qJCYA&Plm%G>WmzZ9aAd6EO1unuXz!J&Gztf!&bk~MvfyECOp_WQtph{2lDFgl zjW&)EB=HY79=f->C7}==pBa7sMT+TTyB#8DdC=X)|J3iALi?_1LTyvL zNb&ZiRX0@j4cciA>z28-*!tm=ujUESuaO)FY#ulneDS43Ob;H~HJc~fYg=WHp= z>98-K_X2NAF8D2JW7ghrUoolt_G{9LgW$*G{N_hrx7Vu`SCofuq;@p_oT(Ii7+8L^ z3!QOpa#eu9>3svqQ_THEyfACv{nO!t=UR_Aql%k5`jS$vd^)j#sJ?j32Hn;>?uoSW znC#TM%7C<}_j2!8qJAH2&-LEeI^q1q0y`wrToAXAkj!g&aBGM9!%2_LjsGxx7xJ;U z{&Aq+v6+4;_xA;@W%f^4I>_*#b0_DAu(t}zoCw!d2dDFor3!6oY~9Xg zyY)pk-t*1Nv5|XEj*yy`-`g1=aQ?-9dAn?)XlZ)K!)XrR*4Z2Cc5^3{yPtAAS(Nu| zeeb1KS(O`o%AWcDo}yFRdam(*zYhJhz5Aiy1^ehsZT3Lvmy(C?{17tFsJtB+S)A>D zck&b{_o^kcQ#xm*=XNfq|2-XbB1JYgGR@I(*QAqi(M6^0`mFSzpVz`S3y$8*b=v$^ z;iFR}Tla5TD3f+FyTT_vSwD4d_j9gb9C!MW<`5$krdH*f?{rjHn!6wL2JdtC2o^uc zI8c_!4p!ATJfh93@hZ8I8u(;wVF=T=#d7g7t$eWYO!2gYQ^~eZc?+M;K6}CJxj4D# zUtJF>KK>+iP1>6K9XEUO=R#fnJ-aOqmGN~yy5>ehOZ^6#zwR`adF{-+UD{tC;^l8{ zhPnsaPsfCI);cs1yzn7%Z8?NMeqlz0{gSFB)Kt^*{DTkreU`0EnPV{qpD|Y-qd)!os;y!?dDgA-8Cj=~ z7k8!|X0-LCKW?v;-A}o!>f4 zZ2rt{t{s$_dvh>j{~c{ygXLcN=J|I{AZ57URdb4MhyU!`c6X20*ybF#wD+@TC4Y4Y zm@%#7x)Za-^3UW33+3^xvqfCDC2pXyxvXkO`HJEq*X!8>P7!OQ=DLhTdwbVsyAuw5 zVLJGv+HuiuPVQO0QEGFhu}AB6=#k1f`mi8t+YB7brfVPvE%=6tFZf1V^h1osEHNMsQ z=%)Pct#NZ)km}}ucWn>KbuEIuR;m`eQYUc|x!xUe(%zNpL8~!R z-JIYQ{Ma0zahREHA;ynrqVr>RVas$;S(Xt*XPi@%={Ct+oF71UMe6p4@sC|{_rCA* z{(jH*b4||D`KjtjY5)LI?Iom3Uc>T>C#mFb-Kj{syktq%a;Z$Hl7f`T0>zBrVIjMZ zTFJUtidkKIo;3l0s-AO~OXZG5Mq2P`s2D~Q^7&;p0GQ^6{1jcoN|1+L$?<0R{;9Jt z#4%=gX`Taf_$_QTSF%QA%hr^-=`}Sp!N7A1AyddGEAX)r1%-TGK41));ZeOtc^?y_ zFfS+)xZCdt+QIa&lEDFDcM`trdWQDMt|K`TeSN!_s2onz_m|2mX=fd!-nWk*gTABZ48>*rIuD}1|v$Dcfyeda?$?%;ARv*SoT-5|X~BzA24zRA5d zd1$1hd&2dBSH|UO7AfZUioE$_0~D{J5D4u_2VzrL0`Gb!mdre%=~=cOY^)x9H8>p22?O z&%eBVl)Ye?#${{+A06mYhw~G18`MXOO*>$bznob#0wlq|({cH?E@-zHN$lQa(LK^lsWYaJzz1 zXAB#x*DiK;&7OXBc-0=|xSR)>>E=sY&!u)XgXa>pGjd$!gFT6vUMPH0-L|Ks{B%>% z(VB~(^RpW_)|GsmQlWlGwhjR}=v-QteCT*m%I>svz%u0<9(To#`n6Nerp_%6f3fr2 zox-y8$1{%`aM$Y%9CkOMg7T}%Qd z_Al~5W(%~+?hyV;O{$;QoMHjLKP z(J3k;#bT{Tl~J5QohhaDKvRXWRzc-ZX2h$G^=L&~wQ5JGZRrMx?H`VRbZ2(od*A#0 zzWbY9Q;wOe;guP_C0G zrcE?q^(|?mH2{d0I?NW%V$8!S#wjC$7#Z($3v2*1>AahuN@)%v>0*aVD|rxTmOu`x zRx&@;h#1{E+V03HXX$z6`DUuTl)|i%^x2Sx#{~sWnj;|Ix!C2wd97qnFD~qZVpswV zLby_`WXLItu>jIBEDfn-aw&x%2&BSfR)QoblAHx85QQ8@P*{#i5d>FaIEq5Uk3=xX zT5Y&VZx}WvoU{@<$GLGB_IkZCuTsXa#jqU1Fc?w53WZcaNIgCmNAOaYCpn}+PkSiV z;pQBS3kqr^NT!U_N(5JjVsN^R#^;J%p5aUhIfHq^4a;Q+>~sbL8$^3J6aB9nFGPFH zJ~s`UXb)4yQbIv&$sw|kyq6ma0tIjIcUXr|6=JcTp~{@Ji_6t(CBlu&>agM@tsqoZ zOfJO`1tvvR6e=Y!jFi$et+J+KHcY8dg!H_KuTmn}N_i%NsxgCHo~=`(sRq3=Q>9B) z8nO+FtPnTX<>3eyMTcxV1lvPg%jy{T2Hf%rL@(+GEQhP&A8(QE~KTQ1WA#YRE?lYDXK)%q!@)-rAjr8q}kMj zl|nJeFyH!r(+3Mq!NFenPw#|8LPG|(&qqNxJRc_7B}@=2jLHO8%no79A`0@%*#iRu zB9UnAhvCNn5EbR>GtK;Q zE_ObS1DfM+f)6?xqF*h&J_b}4HvGKD^%>}2^sM^m#?d9$zcHD?LtDa5RYsMcs;Zhk zb+>56Bw%RWy{bXna@r1W?nykRtYSn(2TwIOYyy0^|M2>`=Nk^%#RGMX%aFeI;-9_!PEhA2CO>6-zC9RVOQaX1=+GlrF zYWp%$7Z&Owk!gnBOWXRNwa0%F7PDN{i<9fcQIq`fzfbh%ENKwMKMmXzKS}F|)A~KU ziXT^daz}*^n`Rp$jd_2@!6vFTHaR1&^J3d7_R#F{-@ltB`X!Js{q8kTtH^xgr{(@D ziFdxbFG45PryQ!gslL1f1sV~*CGu?a{-g!dK~2v*@wS>3VN*tPNfSEvdcX~dW5bpC zGn1F8cDJkkNV?eoKbNu*}X;Xjf&DS()B2VC_&s{o2t*nc0 zj;Pnx9P8dQmuk9j%d+QQ#Mj2dGx@rhqQI`ajrX>T7W_$mTy(y+_K)ATSNAWCdN{`) Z2F~O}Z;1P7UGVP#am0`Em@;(^G1*Xq5kXfOZfeZpzBDRsnFNvh_26k6m*2zVGw? ze$V%F4c4OkNy#rH0{|wO3yd~l4GS-pBoV&;uIO%InaP_<`4ZO22MCS^ITY)lA+v{Y z(Kec(sw>aa*#JnY-1btw)KaJ=S&xEy(H)*$h9;NIcS%g(aDCpK9fOi zN+(;MX+bPr16}SesNv|6nj$+{vzEju*^*GM>6Kd+Msu0D#vVY1l^lSU*P!1#!+xkcH$u-B27Tc%v=m+(K1|3L{JUJv76cjXIfdqoCZB)4OEQ;CQe6r*{$}p&{ej$D<$|9uE`E2ouB!qcY>}E5ZbV@zz4SDHe-~ z#p11Rjyny2*lsrF*n`)4-)rDLhf<7zSnT8L2M4!T)mD0MUhI|r(Nd>~MBy@x_UiDx zW#Q>PF5qnhBS(|lkKgj^Qp5MDb*fKA?T2e)yK0^Rds7UJ<7Z6q4jlzn+rnS&0wh;4 zKYKFB*sr7ZWQ;iH{5URJv2DZKJ3(+F@TKiMQ0Do1{OWH?nW2%v4JRHRo|+QvVK#Mh z8Imi@W9_k5l{&pO?0xV&m=^6gnyGJshk_-NBwz=T-y~;}E`?fVF8WKK`TDX=5`AB7 zD3Vqnn%QzG6<)RSVkP)V64|$S0%YsU7j1oT<5yA5ELX#vDBe9Qd!n_!xVL-ubLjQblImh@eYhW*o9?&~d`^V9y^ zFUglgSAyX|(J{&GEtjQW;NExOrGYYVUUDP1f3<(Ie)fwNZruTNYI@n6i3dNt5UOZA zOH1qRwTBvZx!$i^=zBPAz%L8Gb*9sHZb#_e()3^ev^I5q6n<^m5g568sF&TaxoLQN zrTt`eMssetZ&F9-R2J9Y97&37I~z)_UxcnY<(DkOn z8}r-1@kJNxop;h(IvS4{5VzI3zS~8eP7{wLA;9>vG;*gXH4y)^n@vT=PjcVb_z$zh BN5lXC literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/SleepActive_128x52/frame_04.png b/assets/icons/Animations/SleepActive_128x52/frame_04.png new file mode 100644 index 0000000000000000000000000000000000000000..f369571ad9c4e88782e50233382d6bc55afd5b67 GIT binary patch literal 1618 zcmbVNc~BEq7=I*`ORb31B3NC67uIAq$%bUNi5v+LDxoxnnz2r0ce5b@lZ~6jY#6Pn zqf=Byip5%wDx)}qI#WvPfu;&$t%AxS%!pSV>(Pp~YSoTV+tLk!?H`VRbZ2(od*A#0 zzWbY9lb<(dR7_$F0AN&3w!ti{0pUfX#KN~U*t|tp#&cO#ZXRRjd<08_3>!nzP>zcz zqRlj6^Dk+owE&2hIxSYtYRbha#w8;{7#Z*K2y6hfX}pJ^N@xxu=_03FC%GSNl0Z(I zPBLF*LQEb#?Qmw7vGlyMJPTD;LSZ&Z+H6S6&+F)V=w zAzX=0^2{l#DId}^EDfn;aw&x%2&BejHi9H5lAHx85QQ8@P*{#i5d>FaIEq3;k3=xX z+U&U5U>q_goOBWg$9ZrV_W67=pHjxKMX(&hFc?w53WZcaNWFeHNAOa&H+fitf%a0Y z)5AF#Hx$xHkW4A3lL)Rpi^1hFnVu_ldxtV5nL@6D#a+&CRJ)^B-O4V zY!r$~hWNJsn?6`@3J&$ke|l$FBs64b`+O9H!}DRH-NFR1!l-n$?U*2pSww!WC2L?{ zKqL~a{V@C(0HVSiLxzRFbmH?7>`iE-A$Wg9Z`-|u*t(?hHvWsfXT!%n?i@YkL0X#T z$c2taaX@?gP4Gc`ee|m(*T#T~g8HBLxIY8^i=I{;-8j1V+BaqkcwkT1sZOs9P?eR_ zr|uT5m;{V1yI0kVn@>C7%{__7l$DIA@ZhPY`b~fj4;)@Ux2yi3Lp)I1ung&ID{B0^ zU}{2O^$)oJ)~=BYo35Yf+f9}QGQy7kIv?bNp7!%#*D~VN*2HGeT--8wAf;nxq+@nx zg|07MwXi@RiA*#0UfkCIv@QOVu$blQUYuMnj+zvR|9xU0dr7@0{z>qL_;G4`oG#$y z)%>`clRL`&*fjeXY0UdG4mMIPvB~MV9T!?xv4>`l|Nh-f(J#S->36Pz8b!v0pOyzM zC*J<*o(P>(mvX4~hUU@|6lg{KmdLZw`;!(-2h~0E#M`P@giRUECB4zH*9)#ooEt9B zpP5|s@YaFC#Jy*GPBt{o3agrl96%lwKgy@uckKK&FWe)~o}5IqHc57nDm108eU6Ilw5t~Np&!&f-t~H=y-Kyv7O0`nl^U5&+4b&Ps`Rd0ue4yD zMU8@D);WyRF=gr;VzQwIBZ96n+|-!GeQ8wOG6^IzDEo4ok=b35y8U7NW0%~$@B6&J z-}C)kgRQt=QtFGT0DwuBLX%xsBf^WNNQ7^oE4D{iX7J`RzLa(GL4u<}F2y=&$l@j3 zw4ElXnyL$Q4givBkE4t)vli({)~g^A7)8kI6W9RcEDreyat+NxPTK8Z^s?cuPi2sY z(#w{qt%%iUq$@mywH#eqTkIff*N`|RTf7L$3F!m{UYaMMkhhZY>q2_js9v40Pl#a| zGz#I@=w*+bDzn-kBg@f{Mxm6G2!cQwTtN{|f^<4xflvfh!UzT{F*$0me*3@U;u1DQ{k)z2*NrEl z{f-(R4cloy8{kNxAg;MdvXH!|8%h8LZ*(P`N2m%>X=2HMmu7g2NiP#_6qJY3Icb#8 zP`FZ#BPcG%G$bY`aNH@UX<9?6aTl&a(WIUy@zr@IvoRZ0V%l6xsWcn4m^$C2%GDUv zs(f=knwR8S7(Y)iB%QSF5p0ifk*9KXMvf+UmUFOdWwH%y6)eyCD_9?dsuTz`-%5}k zCLzg8ROwOBCYtk9(^NjkdZE!Y>pV|zAv+r*oTL+%YY|K($5dFh949eKuF}#-wo6M; zB!Sy^|CP4Vlc$jELm>^CVm7b}YQen)-+ln0Kcswo^ zi?_Zx?hF88hsBiZ2wm@ew}JZ%N;3uH@sDmC8r)G`SLM5PsaN_(%N9j62A6Af*M{#c zjZE)x179N;IhNXf;&wov9=T7gRed6AKT;RpUHc5!mu74n|H2gC&@o`MFZlU4faEFW zA0$AbVedXzPQUzldsQx*KN4@a~y86K(w^z1_2(W2eYd zSIj?glH4^%X4tp)=sVJZ)$7pP1yX7Iu(P>!tt4`B+~3Hsr0+^B5}4j{-(c;Wm+|KT zNr5D`0t^p|j!W)rz9Iz!_r3)$50rxolAC$`s{)e^vtF`tYY(DRGs|aBJoLfEaAo5; zT3YX@JKV6_{oa-Z{)f{B0cf3EwPKMYi#l)W zny|xSUOYF_wz=zJbaj1bdS7WzG~HkX-?bgTKG^qcT2EIPEEo4LZw6(XE`RS-iHl11 zXE4z3nmb<>y6mkdOP2I}^M1(LnO74Dm<`0!%+iqj!tbgNZ-8#awLqIPZ-O{{S24 BM{EE9 literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/SleepActive_128x51/frame_rate b/assets/icons/Animations/SleepActive_128x52/frame_rate similarity index 100% rename from assets/icons/Animations/SleepActive_128x51/frame_rate rename to assets/icons/Animations/SleepActive_128x52/frame_rate diff --git a/assets/icons/Animations/Sleep_128x51/frame_01.png b/assets/icons/Animations/Sleep_128x51/frame_01.png deleted file mode 100644 index e9539c2b4c6f8eb7791925d21437781270d71def..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2526 zcmbVO3s4hh9*-hYP(eT)>*I*QS`{|CoA<5;4J16OLBxPqRNQ1YB$8xfvgCnsqA3+P zh4y@O2pjHoWv^xI5=Ev)OO=`~82v z|LgnD=ElWF&G4D$!(cFG#6(Nu>3bG^ao?Iu|2IzlB#ORy8>2Uw8H{Ox?rRdmSv;4) z@NCp7lBgv4T2w{q*%(eL3ARmdq|pq<%2hTarb;6yrjkh28pN!w^A}i5EiPtl@;GJ$X(E_HHVmjB2x1BmHjXJVl~NhX>YTTU8{eL$e)4^5aIAgj=H=HJ11rj*j9C&Dd2XA50t($Zan>7=A8-Ax%I6|?9aHm=1{CBeajI06F* z#6bX_P{ji<1W^J6K?rd^qDHtJ&KS=`_8dvLG=di?;ldIb49g7qOKWp@2nMV9N&w~~Jb=gLi2x<-2EbQ~5CM*J)JjM_Y>!5m2#g|4 z3X;@~wQAg0CYT&98)7b%V=Aq|ottH^nGjNpBE&3r;{q@Qa3KXOL?IZ3_#qG%g`g3r zoW!+i`|D5`fCLH{K{+B668syKJ~lW;VgD11t57v*(qnW3Y4unt0U8adEarH9&OYo>E=A3fn4h#jLVotD<1j|hsX+^1E{GGnywZejP!i5!2k zf{)l+H3UsLQn?AsF#Lrw@XC;~WekSL*%+xrVJmJ;jxn_|r)Mi33^hE> z4%wc$`plF;1F%`4{K%FuuP%lh+OzqtXLD1(WR2Q>gnx9h!FI^+x3Tk?(|#hQjNVGm z4K33aJX?C{*mc)-Pu7o32db9t^*H(D`J{?DwWrT$hHM*_99#tU^Jm)>2N zmHs4cOZEIOtIIAQ;s1&A`K0bl{Zz~4jj0t}|C!RDDd6*?2GPT;&~DN$U#eM*?W}Eg z)H%C)BorxYfAD-SwfMcSV`|!sevQ3NRZs5i%03mfB`5J{_qFgB$KU&Ne*51onrBtM zNxI;l_MZ<}806g9P%z|t^taZ>44VTwwnB=MAPBDkGO>&6rHf3p!SEx@-v3K8o5*ag)8|UTbcV8(DR){((1cl z3H!volB`olOLLZ38xq+Xr$}?Hlsq}}w8!#$k1C^kuLg0`dZg9!Te`B>c0REC6eS4H zdsI#(bEYQvlsDcI)GxWyE-X)J_)&D%6aK50z4>j=zwc&2!mN{u4NA+R;DgOjqmP75N`S*_g138YKT#xMUubqnv40(GMc=zo~vV!B_!7Kei z>WlW!u&z(qc)vJi^R5f`*hEJhY9JsG}j@4o=H@w`3& diff --git a/assets/icons/Animations/Sleep_128x51/frame_02.png b/assets/icons/Animations/Sleep_128x51/frame_02.png deleted file mode 100644 index 273d2d1c94ce9653d33991d41a78e52766541112..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2531 zcmbVO4Nwzj8eR}VP)|^)KUXybY(?2*Hye`dYNR0v!f2FYPU#`aW_Lp}B-u1sNTB7X z<*LP^3}~xTK&+w%a;SF&!9U=z6bFx!aU6a;KrIUAVO3y?ass#EPj801b1pNR{dT|S zd7t<1duKDkw{Dv6vD^ayfcaseiU{_e#$L!AXZHV=^N~&L&D|XOkre>uE^=H>KyKbr z0GNGCua0CQRa-EEHu7+i)=)gV(afR&U_+4Ij1zGb!_iQ&dXtp<^l~+qqbH@@oq;My zWtLMqeQ1(}+McvkO(ew;D9H`l$k|}WSOZ3i!8vxL!DPkkQtr52j9oik^SPXH2oope z${d26NL4sTPFpCBmvwD`z3K zScD>EQjC3)a&-)2#`t`j&Bn7KJlYb=hfx&eLjt})0I~?snrLEhJ7}`{PFYY;R>Gn; zGkV&@aahDPbUY*FvaU|VU^J^#(}qpf$xN|1<*9AlbD7Q;9?Sm zK@<|8pioQ*K^#RjAVpDPG7#0Gh(Iu9XC}Tf5EX{NLIi?UM4(VBCO{#KXg~=rL_v*KBhVru3fJPAaXu!uP&h+d z)HH3FYSr+mOmGAU58|v*;e_7g$c_IS6iR_Jl$7geTo8sp1X9CdjO|@Ga21AW#E~gc1nV zh_$$gJIN>i-O zC-^oU#hRR`+>GUzfLUoRW5X?!ES7ETx9N=u8ll5Yu@pN%`CLb!e8;4jh>Sl`iPu4o z@4YdVrr_+Tb1bKaEc-A$rYRF^+QJTD&#_D$0L-ciQ^?fzyoXU8mPed9f%(Z}JDYY( z8vFgn3LkB*YG~EFYPbb;G-n(nUP)zFK?J!3WoRmSKm?K>xS< z)_FH%Y@3sAS#f~6`%T>9dB+=9AC=scE_DBg+c9Nq$3pkZ!cCf>i>1*n87ZYM-amKV zUoP3=XDgSw-(M$Nw)uXJQQey>iTtsU?(`W1N+nr~M^B{N_U8$$emnNn4l6U6q#l2R zsNGwh1bueYrJQeNG@?09KNH9QjWw<2*GWGmM^{Gq|wcuV#eDdfI z_cGhL1qDSxiHE~ZJ9`0yu`2uK!IEEPzZbA*L8k)0EuTNeocFoOMmFy z^I(B!ep}EW=Yrb2OWBaqb!ex0Z0)kjtmE>P!uJ;wuB7>T!41KmBBX5vC8NmDb9=Ar ztjo@KXS-VkGHzqhhfy#8lGU>2qFasR{5th$`d&lM`jFq6&Sb5UkUtZHJ<+m?elNhc z{OTF#z6&iIJM2=q>Px4Ny(I?4Q^3<$XUz{r;=3gY&8^zf1j|Sbo;;<>;nx zN!Fd%)I=T<)cV1|r`Dt8;%kl9pSEVugMI;muIG~aeNni=rPFpH1v*mO-1M<2ujg8x+jG7qa!G~oRPelOC&<~S_tm{O zup+B&TVzXobYIxgp3iEst30B|{Az~V-i@_2w>DAyp&J`?!LH1QQNC#VANxP@?n&Rg zZGcS6e`?>=&jcJOebjHYA76AR@zixmz3E&^j%QW<4xg6O^>t<2?LV%rD}81E`)#oM m`=X6fk8^E*y;)iQ%aR3m(qJD|_!h@!SeSCFqAWP(^M3)-EX3ge diff --git a/assets/icons/Animations/Sleep_128x51/frame_03.png b/assets/icons/Animations/Sleep_128x51/frame_03.png deleted file mode 100644 index 64ac64e87309a69e0a1721de93756d3c49ea0787..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2526 zcmbVO3s4hh9*-hYP(eT)>*I*QS`{|CoA)jT4J16OK}0|-DsGYui6q&$S@J+R(Uc0D zLVG?s1dafM-g#27DizMT6JOXvt<;{iXDvQ}@~|VGMYw{%Z3tj*hP!hvGn@T(zu*7& z`@g>bY<_%P^emqRJ`4t9R&0zkfxhR^7x%5H^ndfzPon9Yw=rh3iNTl==(?sb9HsLa z49{k5VhWWaUxz9QJsVRI3Y=}#8)-Cyv1+x|h$%C0imAZUwFWV(=fXu6Q>zlQHu2?< z+!%>#v@uyEzA-BPFL~Qi8Y+*VB9^ zIwp7`Aftw$2$P2R57ZOeqls_{(Ah%QlUllKFrAc8X1XY2rD7Jn!&Yfkr~>C;LKOl7 z2*g1Eo>0jHFa%KmIF1Wdd_;|KIh=8x$?Ro(gck*Kqqwj{3d6F<2pAH|B4jdzD-&`d zu4LRc)?lJAgAyOt*3#Oz3Kj}QN;M! z6A3~$-m3BAnP76bY>2sBjw!VUS8i5}O1e#ODMsO9maB0A7y`IZA}m1p2+D;+ATA0) zZm674Y1Ou0LSXlaXO^|wwZXm55OUFT@A)UpXs1F)R z=m?S)roH33THjqMDNbt5xGIVy^vu!TMYWUUO#!PF0+wCZtOSd4Y!$6gBj9sdVqo~SD>J4(zqi7-IaJ9 z^yuC%rqVc^9(Ate#E_*QCdM>wps7iE2nQw22xBlj&c#Y4iPqBg)L62eIWsr$;Yic7 z+>jmFYtBv^HUL`^6(3o%7Bs{XBYU^p^K5Myl&n?Tj`EL9HCPY({W@+TbH)#Zl+j=9 zxv_1=qUXymAHU(;;mP{GY=a3oM$dxB6Ga{1lG zIhjv0w$?8Eytd-XQU0GepHAt`)=xKI*_2+z^`9*bng+f&W)MBf3GF3p^5vSP*sl6c zdxN8=PeKv0&WA7dQA^+ZGPbVM=-1reQuFlw?%dPSTl12S^o!tkm2UDnUY+-rd)O&K4e6%mr2108eBC7zLYirSpk ze?YmH$tQsiw$~N5B$G$>J?0jFP;%0Yg4*wzE6*AV>f{dbXU^37Y(@TGK+kuQ35)Nd zW$csp%W_U1E6-bIX-Z~m93sv2a^lqNGaf7NKdz4HzZS&J=#$niZ0pHg*Zt7uQ<5aS z;88uD$eW(zQ`vl5(75bwr?4`u>3h*VPx!B10@Kx5B}XDGi93OqXVM?Th>eA+CHwD$ zhJC$yo_7bsf2htg87Ubs9*OhLt@V%^;eM0DoL17I7}cr-;@Rr?Quxt*Df&o$JW=A}UXJFY&62+^M{sr(hc7Cx`uydb z#?nXpPG^8u|KjkJ^A(l&jmAC41$%6j(zH;&n^I?5@PqRMkDMO8Ro|5E<#)Z+yW{Y) zIf4DDp}zCBe$*K5pY~6{X+GRZn0{*?JeX(i%lF9r_WJqwz>v3BgZJLPEGs$z9=bXh zq`qVe4e$A+gZGntF7JkLzwKpI+q_p-)UR6YcZTq|MvMMTZgtps1{`4^}?@$2KdF6b)1_8MQfev&2b^M iT^p>o%u$V>)?T#qW${i_G-kWLz+z=_(o+%J_x%f1Q@jQM diff --git a/assets/icons/Animations/Sleep_128x51/frame_04.png b/assets/icons/Animations/Sleep_128x51/frame_04.png deleted file mode 100644 index 6fc1114ba7800f403f721ff03a2eaf4849a79a46..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2531 zcmbVO4Nwzj8eR}VP)|^)KUXybY(?2*H~+gDX-I-F8l{+1dWf>w-H;4PHcb{1XhB-8 zTCBrob3QSQ>;5Pi}&2V?lWoEPA?)N3g;1%SDWoR<%WgE7tf*be9=D4!Yv*e&n>7xh@?U$D6V<6JIGr1feiLgb&LUFszh^z>ruOqEsS$rI-)# zWmDX6laXxSHC-Q6P8lc* zBg}ZmceegSr4*z^pGXp+7RtyP?_E?sL*6v7RwIIi5GaCSF(?pWd=TM_AW#E~1QH0* zh_#rAJ;^8j-O zC-^oU$(Wp|+>GUzfLSRmZNn_2ERJdHx9N=u8m_}kaU?T9xol^kT<4^jh>SZ?iPu4o z@4YdVrr^w|b1tWcEb}lurb!cH+QJOsoX&1<0GL$~u8^tiIo;81mPf2P!rYXxoejGs z_5Fck`HwbN)HUnfHoWVt`lNIZYbd4W#g&ruyiW^aUpSJl9Mzq7oV)AtY%ON`L)pTY z$dfeoio%`;zv1ld+S4(VyX#tZf6?fY(;Zy^-KT*szW>SIfwnbszdQZY7g~39n5*3= zUs`4aICl=jRF^#&seKIf8RXZol0o-7nWf2+d3$2A8i)@Trg#^3ov(>Kn(e#eR7bb4 zFg7duuF7wil|Rr1*OeH3hGSCYNRemNmAT*Krabn!m1k*cTs3!z`{}l*=3ms6 z%OzU^Y^74q&ULb7n>!swb#JyL>c@Pl-ER;mmSip-J(X@dkRz}L?ATvDtUO33_XHY5 zZLeIOq1XI=y=C>6^2*j_CyPTX;gQHEe=gvJt=V|-xIflxSbXL5%8XWRModPlEpg{z z^{KSRwZZkl?*#S$z9ZK>b|cZl&p0s-FB(vr;h}h+OS<*Sy%#sC&m0ty3m&8TRX z;9x5|FRvgt>1g;_S04a3R%G2iT=c7~_ktEJXjfo&<@4v9bN$wZH_~$?pkbeK=?}eo z9xf2gZwVe`T~eEODeD{^M|P^m)-Eg0JSkr(cz-eOPMB}z-QxWzQrePNG|C@(Ztr!U zb=CF$Y)>ms#;z~;F#6?RGMm<1_NbCvT&EsQ-)C^F5B;s_T;?hX@iRWy6C*3@_W}G% zub+cD-6+}EQMd9{U%IsIE6U3{6r6D(!uwF~`TOY*{7%!nq3iIARlxc}FfP`2xXE1E z-JjO`dC+KK_io)RXfSl}^6bE>k=icVKX2yB`+kc4{a0UymzEOYkX>$fO7!btkcrK|;*}T%bKK;bw_PTrPO$UxSPNaMX z&2s$h*Z`wbE=_#!Mg9u6cH5;?=vZ}Q!^ftao*OwH&$*hYC1rv$A@gpWB4(f6U-RC; zip-jAQB4Ukec?-cKC8;A@QN7=s2Xm0H_q1B+(2@NZf($oxYHj-`y;J??ElEOCw=p_ z0U|B;seM;J9dxMpQNPuGa?z2bGdCr*rVFVK?~2+Teobd|5av5n%%~rk4=+aWM>m zV-TUz06lWb<#2*#KFET4wMIoF2m3$Col{ge<0CZ zkns?u7TdTn@nnF!f)F5JxTdB?U87a=!3tP|<2a0k>q#pFHRP#h?FLo5t(VpYf$7M`y1v3|jBF+k#tn&B9NVo_4h z;2ITx(3^Ey zo7ILECb)KgNFe<*o3PD^w#T`-PvsKkAWI5-u$<>tB-+5~=yF8C#I|fn#YVxF@)fn~RYYP2s9M1kOzB^;?xqsF zx%N(JtgCCzlvMYX6a61Kf7#P>|INBp}G^#v_HAaC1gZPhTh8Qq6UTshVCk)>+~eOdCB@UAxUG~Xe*GD{o}2L8z%Mcm-ZhVN`9+dhTdInTYtBGa6<%&B8CybTlU8e zMZ*l&tLO*kS0|scMxp5b>HAuc{gNT37g&n~oTrkUY`&(z^qMGWHHA1E-y`7V%4fM6L%H6KROI>s4#AaPxqbrfD-_lKJ zQ-3y>)t;Ezl72F;u;_aAu9pp!8IcZUQ_ja(qqC*t`Q`~NlW4PPas6m^<3{A1tUtxH z?3}JW{lTqwp1U+~H1kmAcL$0)-pHTly>B|U(VI5X*K@kEt;wFD`L(IxYs~-N=Dyjr zJDYY-aF0C0d3L6|y`4wa-k45ZIWYVDmX1!-pI0-gCge04JM6M*si- literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/Sleep_128x52/frame_02.png b/assets/icons/Animations/Sleep_128x52/frame_02.png new file mode 100644 index 0000000000000000000000000000000000000000..4834c7e57341e15d1ca300e37c97adeca6629cb2 GIT binary patch literal 1591 zcmbVMZBWx@91pP|FCuL6K?a^7AnIY7G!2wQ%3E8oN|8aGxXCn4QYp};rhyjpv~xOC z+(6x&bGu#V3sbk7BFY>p)Hj6NJm258-IUWiaC3)v>gg$TDN?r&o*$OG(JbRyY6vk@{KMVrg|tFA+LM`c@zDZj+W+QCBLK@Mh6T3mlNc@+J<_Tj?cS zF-NntOMAEs02otaF_wy@h60M=t#aCrk-MyRi46c5SuQ)xRB|F@;+9x!YIxvCCk$Cw zH9SAnfEnx>uG})KPT)%F3XM!%B}1}sRwk6;q9g@YPNX51waVt8TxxhkFD32$Vibl( zAY!E&e&JN9p$O9O0tcz&3WUKh3{sJDmNwCh$utAPF!EwB#PlEjw2ERan#yG+J)F0i2)5-&cO&4 zyJ+EUkY6Kh;;Th9EV=q32CLm*c&XUt7|oQFGt@=fQH2~styX_vBWQC=eE71;P zt(`-QIR{@YFj7Ixi2<^dyw@A@10`>$xq?Ni3SFh;nQAL%6ZKj(EZxXi3rm?eoK~@< z0wFP+LtG^xrw zT^^nr;OcD-k+v~hz_vxQJ<82_Etk>=94+#Kk>{%dZBSIsi@c+pw?nv6jzQB5G-I*( zCDZ*?dJ(ji6D&0xn#jjaXy7krQpU<-ya<{tV2yp#3!{EC^p@z$}Dlx%t+ce!!%jj5j1MLovl!I_yC zTTiPh!n>bzhF-5I8}B`RGwDQ(_sq(M``3VzPmWyj1i2N*^JFt3&cmlp#}zit9E_4> z*t#Znh7H$WOk5WHb&aNJp1VXAv^4HkS#R@$KKQGK2qcIcss>s+&Sz+bvq-VxyV8@1 z2mbivY;(%sxf9c1=vh?6y0);z{O2jRkN-4@d;5xPv2ZUIJm51neiQB9YuWHdQ(X3> zYvsJFXU=K1YoXK<0ONAFwR?>(9V3@zKyo8ruVXSj09hNpFx*1D6t zhobUQxw zCoV-A#^0W^KRLH=tS6y=-qt;5dmbgo_~*bwS$pTE9rC*sgZI0xM%_x@Zab<{q5E3Q z$!ii57G4OybU2m@slPLWD+jL+tRj@>;ysp*wv`VintC%0U0=2jyYHRRR7A{v)4O6) xWasL}$@xLsz)i9bqhgF%9XP&d4Uh$n0}jX{qc`r`Qt1Dc>ve_NA95G3`UmboMa2LB literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/Sleep_128x51/frame_rate b/assets/icons/Animations/Sleep_128x52/frame_rate similarity index 100% rename from assets/icons/Animations/Sleep_128x51/frame_rate rename to assets/icons/Animations/Sleep_128x52/frame_rate diff --git a/assets/icons/Animations/TVActive_128x51/frame_01.png b/assets/icons/Animations/TVActive_128x51/frame_01.png deleted file mode 100644 index 462ab8cb7acb5e2bb76a7d10544fd3ff9a069212..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2673 zcmbVO3se(l77l`M5sI~Fi)I`jpqOMP4?+e51QHcpqCik7TAd`55MVOtWH13l9&RmK zv|x)UA}IJo7d=V=X)X9de9(;=+@eH9+!c>vUD(R1KzG6;?Vh81JezYS^UuupegFOL zy>riOSuS7XI_~3f38`u)vJa0ysvYfEiEJ8xgY@9MDDRwf!~+1O^~ff*6$8 zHw0FNF9$*i5(9*6n5BXs2oQ?cYE+4;l*;)47vjPkh|hufEC@n)B81NehJGNu9jVqJ zkvX__junb zY*Zv0Fis?9B$7xKM#E*)}O%)SR%wjR?{4!T<9;2M(1#DO%aRU9l4!)ch2 zb_F})G{g}UVT>c*kp#zMM=A_RD2bsIK`IC$ak$LOhgASBj|~An;iyWdx9iTeTN4`XgNae?jS%Q==66 zKH%_hBusClP`wHZlZrt)D7H?gMg$_5t5HKLmY+t6viL$i%tHNz{w#=(aW$CGUxV=l z198!ODWOWTCvcdrrui}f%ohrzG9FB?U|FcYPzFo=WdbNf#tjik`NQ00q>g^i(8T{w zL#;wI1c{?`Pv~$|i*XEkEeJSjgM<=^1W6~3&Mwd1_Ov^DycnrlkEs`u1P%zu+N89i8?wqy4w*{Wq(7(pb@2G28V9G zE#UVn*`TN?4x=RpJMOJ*Gzc>i8p?!{m_$pL_kDVLkfw@5^;(P`njFw>lw+SRgU&dE z75Lrsz_UM0qG32a-t0@qV5Kh{qZ!lF(j+~2s|_(@7z~%FFsVdgF0#eOkQbmamv*-v zs(va-`M&sapP|$v)1u02-}%H`TYoVCW=@HISAR^ippz8l}YZiiE5_6k|Q z>+4xvo5*B{BY9QcRbmM`Vi}EzGbZ)4F!8ZbSAH${o>iyIh8M0<`*P0{g>pfl+0mo-+$6&j^MiID*%|7zmIWccVRkz@`=JzlF3)p ze-C`IQ&8eOqA5d~Q?$0QW@bQV_9xc<8xj6)tx@i!p~%seo`wd?$(=8&8!WEGJY#AU zqQTu5f^Cr($EP(vk*qkM*VpPA)y%!8>W*s>0V|xM%RfCFJE>^ZGx%tNrWZRNxU6_& z%#M(luq|t;M19rKzgmO;xxIF>GL8M5;js?$vaGME2+P^E5NPdtFpQv=FM$W4vpWu?7XR+7FN_|;cd~x!zj_{D`LTE0O}{sDowZNv^I6{pT>m2QtbB9p zbf1NPYuhDFPw)Ha;F}BE7B${J7(W_6=~?IU(Cg6iK3PX<+r+YIk7Kj3%b z5e<=_apzaEBJjqS84I45ffGkaz=sQ`)%-azcw5sB*an7GK8#OzJR!h0peyY=X%6F* ztj2ZTGSkSG33=Dr*iF%GdrDh$MgPb&H8Eb7TQz&W%U*vRnR=uJE8nt7TadQ8?|fC} zmzz>kZLUB0K5w>xEUV1#^{r!0vz2@9+*5RKFA)Az+p)3xx2}Mke#x;L!t*7Ev#-89 zvY>NrOtrEzO}N!Xc`G>iBD6JN1D4M`5#$%DeS}9mGfvyLJFg<{Ixq2A{&dY*ZFyf{Wc!+IhWdl)#Hd+K+mr5ul=os@@P_8pEM_Uo)@$|X zDq~ii>AJ7b-S+PI%hZfT!Dr$(eYUZfy_ax4C+hsUVDBqFvxeWWA@}pUC!Ed4p6T5$ zJ*ZgSaoO*qP_Ld8ymWQ#Xv5sz+7Hvh!nD1b;8SnBO?q|x?v;kqt+7`WKj+MT;W4Xc z-#y}mXy4sgKKakQ+DOl+9%z^E&TB1i+Oobij}mRWoaa5^n-Nx>lkBROd!w{@Vtaqh zIbLwI^hx{^TSRe_`wtzWbq5amV$lu9wsM;%9RAXo+m`O`$+S&sU5U#or=)Riiek|Rgr=S5pbnKi>y?6xDy^}_Z+&%vpHunckX=ucfaqy z|NYPG4i8;!KV!}e008Vmf~676J%hOfHs;KKqxr$*%x$_hcr6V8wk+di1{^MQ0syNj zRb-4VM*abUk!miAlL~^XS8EwG0QmUowJ4TE=s*RLsM1K-eU~fPpbD3;qdn!2TpLIz zRl%DmV)drbNNiIQCdS#m%RnDJ!Vstl9SZ8z$r>8bOW0$)2s1WL^Vr}RM3*FC`x_So zW8~prAW0FRHy7q$5CnnVVlIva?JU*YpAUJfoMu+M-8hYU*gOs2#N~P7Q zNDXLYL>1&lorKLu9rvKtnrJojM4p(8@${&c2Xi5#r%9k({=cDWwFyn@B8WfqPDxBh zrfUga1VNJja2ejnsAIqBok@|Ml-Hp zlTNLY)RDB3{EH-*UYk;(MFJ@T)sa*rNhVKjbND0+$QN)S&{d9NDvgnMiP6$T2q8sv zgoJI}bPf!01aKt8M}!ap3)~?A0zuge<8dZFC{Q5t3i1yUz(EiU%K}B-GFU2-c|rj)et=jioQw^lRLnU;lm9;s z977UFN{uo#p;DuX1W&6;WP_%?K?2ESl426aWLID;d&ZqnFF~nN2|S1*)!DU70uL4`oyVTO{7eWl2wd0rrHq{GoDZh zn?@PU?1{;#1i#sqjgzJ+35IgK;-)O4aTrY|=+aP%@K0p6_f2YgJPcE!nnZ$Wnmo4A zD9_kk#+~uTci<1xWAFadi6-GpdovDAjg@&YwPr%YP*Y6fC5~S?0|1uqhe-V+^@Xjm zYN`jak$&>OkLNtw|eg)KU>><`|tN2>pK}d^gF+3k74&0 z;q5Oej~zM8Tz2{Og1T!vsoHOc-Lqp`%X}9TD|xWBIyPXKtKc6J78+YjnZiVb>nB_4>L|<;s{9YwU`FEZbFmb!In1 z|KZ}-l|OzC6)6 z5Rlhp*BBa$vexHE7w`ahLv2|8#hiyPp6p31Ih2+DC;{l`@c}EYQtd7R1!U1&ZD+vN zC{t!feID}Ng|MsXEO^mym>m85RLQ!T2F!!EbXt{LvFn;m()y0>5sqWgHTt~5!-1bM z&~?C4Gi@N~-RViiZ0jluKUT~qz)!tP?MLGFZQHZLe8lG(@NCwntkVrS#%3^H3hxywfbprw?;BVzSnp_T#E(p7JDc!lD$*SF^;pg2Yjq|0O z#rov$we-st->O+aY3jU8Te?kTmuslJm$?|dpSAURR_Q%TO@6X98inSgY>Kkh4FNw~}675^({@ci{TXWCPJS(i(OjfYB zE~?FV?|!fI#nz6MhmJq^w(Y&sNwx5n8~kF&!5wRgb5>k9u-tiM=xOfWXf(ry$S^zH z?D6=fqo;#~kFs>vP~oyUGt7SJ|0u@dY2K9ryC=m?VVCZ7WP|aFRsGj3>hcNM>_XA= zr{|V_kTSx0*1R*RGCO5j*KhU%r=$F~;cmO?-F|kL=C>coP0c@;((>Ze5PI~+-CcDD zV$@ZhO+iD7ZnNR%u}3awItS}t*Y?HafA2ieapU+(4HG^hdCj<$UzP{6=>davtJ+_f=8QGy36XegcY@-1z4GfWP$H1^qBkWBW_>6vW%+%d@O3@bNdH+o``?kH)Hynm@yMtJ}R<-5K=ulRIvMasTeN)cT8umpE8#FnDi}&d>h(v#2cNcV37rRQgT8 HhdciRw($3n diff --git a/assets/icons/Animations/TV_128x51/frame_01.png b/assets/icons/Animations/TV_128x51/frame_01.png deleted file mode 100644 index 9014952e037a83e68c678e5424dc0ea906d50798..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2589 zcmbVO3se(l77n0Dc~k`z;;KvowfIP8@_>+mNP+OO1bNFtgh^&XA|#V00|e|=1auWd z)WZrQx>RhnYCsXR1VpOBk(Twrx}ri|DHeI7)Yl@Eo$yGz=ja~K=A6mAzWe>(ckli0 znccxbepcp7%_$U$Re--BlsspW2iwe;{J&*fAtFos61B+(R#yN5=Jh?6h^5MhZj1)nxjcbNvrP(E#=vk($0y)miG zKSPCuWdwzbGm^wSl;*JxaM!>jfgB?cKqF69s9_DCHpL5**ZRjG4VZ!uNqm~8enB8g z7z}vhDh%K(M>KoJol7KzpZEQrMfAr8po&>;wB^I#4KnEBDjOAjAS$EINsxtJ4((qM<9)4zmmbOf6Q)l!Odd z0D4A5gr^XE8Yy+!gIsB#Rj6n3L}m=sAWD$Qfb^bbfkNT`hRWpzw3-OTe%Jd}Vs&`B z5(7gqHJ+jpVtC(o8Sc$NiVu^ABHBt*nAg`Rhn-qK76CO`;` zPtzBj&V=Y}W;n!xIV_mvyar;!5Ht-H;;2lL{zoX24!MLgc`(ZrX1n|slx#T^A&~b0 z3x#liLQNnFF%}@;(@0SanGA)wE)p)n;_~QhMC458pdv1v$KpYBOeDe(j+l#ZnaGqb zGG2g-Q}hX(jYr9NwyzhP$rfErFn^V*L)~)6@v5nKtwA zZGzvgWYeT+QjDaW?zp$M(KJkrONcZ?g?T2D<$a%?o(>aB5k(?K4o#4zHwx;f%d|6a zx&ptOo_hC(Ni+*5$D97rFj&bO!)V47B(;hhypO6HMHGt3WPrdkTvPf}OvmTlkmYgr z;gvtt?jxRL5cZ=VS^8&LB=kYwqnxTaUFS6WL-+prYq@2w#y!6-Ot+$PhvQtvvF>MU zzs}rQTf9(re$GVbXwS8#z}Dl3wS(rG%orPP;N;l=D!M4zs7$JJ9RK(^C~8WurX2f5 zyX(M$MQD#v*{#SB$AjXBpcADKIU8ZQtMIvnHnVu?Uz6OfC0vv}mU_B=G4vq-JhlyK z{x*W$=wIzY&4&K%A}X){FqmtqMG=S9O>x1#6}@r8M<6?s!w7LPKX=fb@6vXChi0v_ zLnUp{4sCp}#a-vrxv^y=3mtF6tmkH}_q(WTuHS0b;WWaNTwMM8!<)O>Jgy8=U;fht%Ta$-z}JLKEXk<;ardg+R!VG`wcD_5 z!JcZk+-L9hFV7fv8Ws1XBy`>DS-NBN+_JA)y)J8F_nkiNBpK1s0-oc42}?N_cdFdj zIDX{ue*5V44fYd_=U*u+o!$%`?$ugG*Pdz_j0`Ec|1-Sv&)(PHG&kEF*c`e%+3}XI z$+@nBp79OUw+dVX`?EK&=#1?}%W5nJM)P!VLJdDmT($V@&#o!4jjTP~6`X^n4|RQe z$L?C6&K}CtSW)l!E*djq^jDm`y1yy?soh|xk@36|*Yk`5z;4Oj>+{6>ju@qPHpN1( z;&KS2X%C0#sMET6A3DLC-@aTv}v zow3Ps?N&)P)uLdCAgrzH`2QHNy^=#;KX8hcl`X|GH#Zs z*-d%Ka626C7`3=@b>YIAmq35x(`_xA?hFhtHpPSW=Dl$1`bn4hx*HFgfz`$AN3Vag zy7bE`3(2S2l86PTI`-&zezqG+SH1i0qr zAfcIsOP(%_q3Dj*p~9P$Huc83-1QO5&ICxe7ACS+bQ1PZ+p!qxkFP6^1#++UEzS%a zi$^QBg$vQK?{?+i?|UJwIT(wS#Y<{O`aN)ptz-0%vgz)+-%P$uy?ZqAM&1ei2V8(p Kkf6dVA?rU{V%oU? diff --git a/assets/icons/Animations/TV_128x51/frame_02.png b/assets/icons/Animations/TV_128x51/frame_02.png deleted file mode 100644 index 6c028a7cdc1b0163fb87ed930a1ad87970ff5436..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2605 zcmbVO3se(l79JiJVWH5fEDD7XL<`#_Gnp93K!QR*P=bU6d@Ga5B#b1PkO>kM6kSBO zP-U$xt_20V3ofF^C6)TX_hV5&sh|d}qQzI+fE6p+D!3B@Y4;r6467kU${dfLsoj%c2o1YK6{-npiq2WRyXSQ<#C! z8wpa!urZ{|rKFUNI8N4OGm#OiYmn&C7lF%GW5wKR;P zT|o|=`Yh5&Qd#61lHhplNQEAWGvKI^G{{L(Gg{`6W zE;?RJV!5^ij>aqLcsL;zhF~!WLkSQB#m7ZP#6#l9_-SBlJU3P#=8eYAF%a}VLpA>& zhY~|nq(O_)Jwa$uHO|rN)J%q>Hb@+)Aq{lm=lV}u9k2l+;W3bXUj?s+kXlesJcz-zJbrS$wy_3W<@3YQh#mkl$XO&ljzu2=2cBYLt!5X0_XI|7H;~t`Q6>crKfUZ zt22tuncKwkk5`XR>MF|)V@-*+cKi(l_>zBZOV1(whRkK11)+GE6H1yZ2E8qu1)twV zOJ}FHrp38?`c@SMpDfs4=f=yQz}%m8KXjtcyr6>tKH%xYzKuDH+0%neaOTxgtNe@S zK)UywHei_{a_>dy>{nAn)7_(b&Tjp-y6l#McdOcadG@u&yH7Ip-l@K&X^|@yYusHs zCtf|B)w?$hS{1zh(fo6@C@IuYzGL>Ku-#Knjb!&+8J zm(1)OmwEpoG61%{DR5~FrW@%01@f+51 za)UIQ4gP3KZdf}1;h^Pq?;tlcr9^Yb$EC9UirJ-yd-Xbe`qxt5O1jW-iLi}-?$%O}jjjCd2OGWvgSG}mb zzJ#Y6TZ5dbuUB=SOPIP_dg^7~m$E;8viV{zG3G`3%SC(EE1HkJH^htYBpzMpxU~iP z#PaxYL4fC(nv)F$sgUo=$uj?5ch9?8sa59RI&QaT^VE;qHl69=J;-@A^TDnK-Law$ zm*^<8qyJ8KiA%1T@3%Qv>0NbTNu|v9XJ8rfsgH(Jzx6@(f@|!I%E};1An@1ed))?h z^gM2Q*4i2#{;o<$sbGeC)Ky}w^NS#E>C)Uq0i17AHVy`F;a*zp2e&%y5J}l>z#7*R z694|Em(u?JM9X}b95sNeMQv^}Urf||u(t=e9^Q2VvmDwJHh}q;Kz+{;zO=E=$@tl; zLt6{NlGOQJM%Un{Q4!qRt+kZ7bK!Y;r00a8_a{HA+T{IASg5^xD7;H>>K$o^^P^#l8phlEUt2uTnu0fC@s*)Ef0AX$=3$P6Z+v=n?m z*&YOCQ5F?NSQTZ9575N|3Rdh{6k98>!pZ__M8(I3^#$xsc%N} z_x|@x&bsh5vmF;Y0st^OG(;3dpEKx#GsBktZ?i30L!V~qLN<~BFl&zGumOro<^zCz zvq~CE#Y)0ZIiX=<3POf6jT#+|1_1v6qYjfN;S?yt6IEIP^rWr<0#ynDv|*(Lk?4fD zQWcV>$D`B2rSh~SIbQ(1VKO^pQ*rPm|P}X0kRP`3r4swi_1U|l*324TyWwC(aY%-322lk zcw#a7P5>z>N{7O*!C+t-I7~vH2($QnK8&zoHk&~s7-XuJ!i)?p=`qP5!b!ParK41Y z7PK&8G9rZ%K(y3x4;r17R!dIgiOv{o#B?x=iC8>M0wt3F4b^C@Xp)M;f6+T7F)2;e z;cygA5-EB)PQyJWmm(?gW?JHe*>?yQZ^pHhHC!RL#_Ce^>ajE_ zbxMLFNG0)>Bv@ZtQ=vnJdK{w&y_6u-lVx5v$pW%DOa%0jU~-k#!s~6ZG!cS}FbWqy zmZCFQ2!q3tB5ah)MiHJ5!a)&a94a9cs)W>ELs<;OSIXj}Y(JF4`7bElate&X-UTd? zprKll!nATcR3w0CQB0LefpT%Vg2(mcF??k!xeP9nAZN(fJcPmb<;YoVKc0fcmW}D6 z<3)r##gf3ucm*BL2@c}0I6@(Z70hC>#6mxwm?iQPuS9~x>>$2~I~g0HSJC?nQ~!S) z3OSlU=rtJK6Dkdsh{HNn_#e}Fxx@S@+c6BtKJaMH~(c0*4M=`l&hYBDP zqcuYl52q6RZY3KhH7IeKa=hcFY@=})NhDAPOpga9(&c@Zo*oaAD=}>%P7h5OvKWOe z(`DQlJYIocOpm?$)g+pP)8ox@X&tQejde8RTAEr<58h>lr6vHF_Ccs9P--l>yQwp| z4{<8@A6(Xbe%Iq`Ltbv?OEW?;-*dpjGp{O@jGVrI>^XDg)sspmlhMEM%f*Y2&vG-*Gx?fxO^wshY4^U0S@g`@NDM{{`t~Ge1eupU zny%elYjiC3n4O+kB6;~kHG5Wi(ufQEz?9gotKBi`eRRmiz0h z8kT0CsvG?8}Yc}=F9tiMaNl37bup_3A{u&;oSk{`vCn^q0=;ynOeyomp?< zi=05ew#I!isnY^^*!p|wwot6}>FTEc6XJ1gPFRyz% z{OZn4=Zh>uYgzrdFj&$>u6{?#@2@~R?t|NKImjXCVY>)k}IrcvH?@!10# zurC_=@zw1;C!P|0rAa5MoFM45!_!T7x})cs0Ve9>E;_p)=AW(`&p$E`w>-9aFzwds z=D(Bv2VUgQ_bIalb01YFtS;HQ-#7QiQNx+W+B)Xx&f(V`*MshyB#Z5Kt%|I<3J4bd z;p@5PzOtOXEXb(<36NHJH2O_D=>Y_Urm*iai}>diUgW9ViCxS#i}v+v^!srI!jkD(4K$ zy%R;?q}Er6DVu9^B0cdAZ@o`)>Jj^3ia0dfFz&CdS?M>^Asx2k+;D jvl{JlD)z_KbbU{JUTZV-(cTDm%Qs!9I9yZ}6rcGY+g{;@ diff --git a/assets/icons/Animations/TV_128x51/frame_04.png b/assets/icons/Animations/TV_128x51/frame_04.png deleted file mode 100644 index 0154fbb5e09e89bd62a79b856c88c74c5da584f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2603 zcmbVO3se(l77i~d3dJhx;=0N(6a*!i$rCaXAtXU!8$d*~R=ZAShA@z1VrC$LAY!e$ zC|IN-;sab)1-q??N~P4#!WOs7z(gMeHGb$({Z0aIaj(o_tJ+Z_pghjM>h^jdS2o zAcy01nM_;5tkJxVV3dJ};*^%)Sq&x@&EdqvT1_aHO)!9#(2+(NIB?-22#~l8TrJkX z8k2&^Bop(^#LE1nG%P@2lZ=?~c3>@c0*tPRE1Onp_CR+x| zof`scG%0|BG7~@)kI%(m7zU!GJRH@cm{uDJ2w(vpf<+Kt#D!r*C`CjfVDbmD+nMnU zBvqL(xfy#U12Y-Mgg}tRV&PeYJj$$t_)@79f(4L3z-19!I?u?UR<4l_nPN~9G-f7E z3`rRQCnKt*au^xNN}cdvFu7=r^kkmcj6qh^1o3&W)6*1Cqxs)ZgTaNSnN;E@z0V}3 z)ACFNluFQ4ju|6Zc*xXNG^5I8B~F@sfnZfGVPst4IOd8q<(T#3X~Hpx&=Uq0MzgN? zE}f=KilOLC>N!bpJ$9wSgec4e%24JsiqcP&Ic16k5D0lN5UxQn(&*%ka9WxSA(SXX z$UtY&xqO%_1q#4wR5o)CjWJU2v5=SH=LW_$CAvY=m7ji`c0nSB*gqW)p!+fb07ia}i>9{U7 zUP)m&&IC@y<7|9_La34?#77DF2{50pQbb3o_{wON7>-v7;-yN_RBW=DWZyGX|Nn8| z7?MGm4Jg|aqyg0tkjbb60atAh1*NCVY~tAL3Y~4wx^wC!%w#TsCzvS%Fy4*``HT!q zIuJeI!9* zl1-3WG6|M)qT`;~MiVfa%3v(0nUL$)^1etMj_{PnQ#V8RNyDm zt=5Rdy)Jl1p^^jw&p&ShMJNpG4H%iXqu+{z(3sk_Vuq-{e2z_y@rcgi)tFry9KQBPj2O$EbnO_bhKNd zllOGZsQPu_O%K!kQNN|9JHHogvU^`Td!=m0vB<24rjUygofOM9&3sg~4VvfceMpc# z8%vfg?w@rG-+KFF-z%Oo8@7c0P<7;s(wOes_c)&g2u%mOP>$%4SN{8D4L)O+Pdxk} zHg8Gg+Nb?Kul$EsHz*(4gf4x}JAKR@RO40OAM%OR3`u7j$wT&S0|k0psUW?fz5wW~ zS%r6bxoI5rk|59cfy(rOm-01jT_YzBK1pf0e)V+5jK}8-e^(xE%azk}VF&uRu5(oP zV3_2+(_s6X2a0|7SDZSvyzSr1tKa=p-kdX7s449JX0K<`^`tEtGUxG|x$@$|p!r9s zof(uq=J=6_mEX_@^c=s>w(s&DJ@d$a^SAKHOFM*-XYBWL_PkZt(p#InLv0JkZr<%x zjy=sk+%dA@{?q)5nW=v~5PeQAU>uK&tn;%See$4o!aCCHugbH$ViqH{}V-B4tevJ>Ra3OnLB0V=8{SH0HPKu31jnI-AzOH-a-r z@$hZQ)sB)`j*GkS^`fOn%kf|J>h3id=j;p~21baTqC3?UJ&ksSx@3M(%@=Zo-hJ=W z1h3ceD=X*mw+g;J6FzwSWk+$H?~{eo6KX%&k=D{Q#-&$$2n7%Hx&32#z`@uN+s2M{ zk&^8z0`7S1ZnyM`lh<~59Lq|MuWPJJ?XM@-f6{QzRCsx?Xr|!$u>DKAtN&K@fj8vE zar^F8wQ_3je3UdVanIQN!%L|Z4>y9m&ZOUu{vniHu<2|o`tpWh<#7F6`?9#EthgY^ zk==sU~ZAVBFi2gwpzUHQv)iwoLAox_V=5zxVC#WuXWa6 z?JKcNi@tD?b^so21?9UczBHd`c2hnHt$RyB7j*P+8WYX?&eHp@9oBUJbHmA|IXiBJ zEDUS$djc=8Rdd4TCX&Im??~-s#hNAdX#XMK%tg!lv!oZm*m?V#`lLr{RTXE#?;qS5 zbEBlT)+6R_jXG(dbawaZhNI^KH+_8c##&y4`>1H==*eN)z3ElL*4z!;8uFiB5cBM2LfzK@ diff --git a/assets/icons/Animations/TV_128x51/frame_05.png b/assets/icons/Animations/TV_128x51/frame_05.png deleted file mode 100644 index 0c91315949a480833de46426567ff1f25abfcd84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2603 zcmbVO3se(l77i~d2*oPv>blA>6a*!inIyzyBtS@lU>iV0q*S{OGXo4HnV1k8QQxrJ`kM)6V5_LM_eC_CYiw&&;`&*q%T{4?`? z-+#Y*@7yz`@v$pB-GAfGojJIPmt@ z&g1c1&QpoWY_jG}6sL6pjG$9Vfk|iJ&^%sfxXFOwStJXjlIfIQ4i26<3j!1&2iJyZ zV2wdZW>C@jMsjt2Y$BeYh06#qJPZgmp`3t@WHG>`)9M-2BnKySQEqL!4S~P}gw2wJ z3fqQ2vL+r-(nbIb4WSW?zD=&LQ=zolf9(t|8l~ok$abL!_3}aWIB+ zh1laXWY8?lWY8~2g8i{Q6$VskBr%pYCepNay3Fy@Du7TVfPp{_hEsZ*ZjjB=6oph_ zEGY+VMdu?hUxXyWLR5@!bzcgLP#B(sYG{H=%lkPL;lq+dM1~5bsPLCiuH^`f#a;%i z(V#JUhQ;(a8KaVeTu=gvB2cN6kje-r<2^!gg~27$TnRjok5co_{sFd zv!6|(X*f6DY)kuKyLNZXKQcDk zzo}BpZeD`?^&liW=V9sk8c#Ax(slEGtoME|r3-L6^p`Q0{>G#|!&m0j0L1|z*5y6j z-UG$Miz>K0a5CH*^9(z2^?UIqi|e`8ig!bLK%e&w$G92i|c;d${`5#oaxQ(Ab`sl;( zyyZ11&j#FH`;VY$NHM$#3wy&gY1|QvA@+S=>lUmTmd(*qwU%vz1zK~3FsY@v0Jz$) zhUj&1&{&%#KF*PYHA#c7<*S}ZRzxSDfC;%f0Mf?-X|SH^!C3m;><}cluT1 z&+_YfMmOAhmR~(9;g9>JrxZfg`lQITFw6Q-;nPi;M*F?gdFF^~t;sRYyT1BCn?)H@zR;)P3x!haxcga@ z%bUc-)eDef;kPFPhmO2zEp766y4XFc@#B)j&h~LWv+5(rckrRZKUR7l2p=_X>{%Bq z*}lsAw$sk;-2RZblpd$UnQ@U#ZA}RS&D8o&TkaYP&kq&N5?&jze980<+^paKmZCIb z&z*f&c#XF|j$IJFYkXl{7`^JzMo@4y_V;6d@TV4SYQ2KJx?w~$(mda?BBDJr!UwWu zJ-~t27w;VVv#8;IaZrWC$J9HNQ>3lVv;+pM4cYdY4wIbEYwisA`we+S*WHFUt~OtK zSe`pWdgd%+1)RDHs&-U=X*}BDpnB@x^p27#=y||vi#G0QW%gdK)Aapw!?E_cB{%&R z2XuNqg%_FYc>(jIDc{DeGD~HtX1PV`HSCeGWaU7n>(e(5ZQwJ~?zfMG)jTCN3L0Ho`czzfPJv`hc6mUhW0{AGn!k R+dd0=@yHGD{ue%y-K_us diff --git a/assets/icons/Animations/TvActive_128x52/frame_01.png b/assets/icons/Animations/TvActive_128x52/frame_01.png new file mode 100644 index 0000000000000000000000000000000000000000..82d6b32d873b64b6a05f70087b06490a8caebc47 GIT binary patch literal 1885 zcmbVN4Qvxt9KUYq9MDOSLC^snR|7QcdLRARdakn37FJnDv(+%ZgzMegcF^A4?ryZ3 zf{2J95l1kS00O}QMuT%m_!z+r2%`8g3;|?IBoGo8gn$q-3}AiNbqx^w;*xjofA9U? z@Bi`s|NpHHmQTwW{M=v!L2~@1-U>J`gTtPk3E%aHIyb^8D_9otB@ziJzH;>RQaBBg zOJ}JFGGw?u49LdKqY%WHCxoiBsz4dTNl`1yOJQJ*M`egckfOcT*SF}Z1PKJQJjGUQJ}GCJQ@*ICho?PybP4} zWdcK!5N(kgE729ARe>PtkraRySSg$%NfIq^S$Q_ha^Y}3N|Q82kamKy<0Q%0T#Vh0 zrXCEcQ}}A8!aFsk41T$>T1}G~f{4Xp)|kyIDK!M;a=8eSCTJRm2wZItH8zfms(FCH z3sg=KWKEDnRA*$vQoZKJpsD>nMCCNCsHWlsBSyqonV_ts?o$%Tb7`DhuSAl{d5!=P z5Cx*9LM)ZW%C(XvskPGIP^Y&aQUGHc2&8p9)|O~AtwPm&i=i8-fIJqhh8ko*Q~*_~ zS2*BX49zs_-pGtc0jwq|AxVl1+*EMDWR$j9Npxa>wb?Xs7Td91a7Dm)25()pT|kLoKBp!Qb}_I0md(?8Y^Z zLlIyVvXLj|(Q8xB9;Q@K;k`Dbil-9PrKE^}CKHBXIlU0v7^i0d;IY)Q@Wc`5r;XJD zNcspx^30nI1$qV4yDc+|<{-U9_b0Eb;e7t{R;exy4d5Mi5B zU_T3#xlsf$ob`K4LRH7EZRpu|6g7FjOeA)7dCp`UY-+jP`&NFvWh8AnXj*lzyLCy) z$ESL1^4_6_Lj3Ni_}2T!$KSId-P-zjmFEu~$X=G=GX9FqC?4B6;zRSL#2BQx{OGbv z8}FNp-i!CfB9#-`etQE!lrw*BUQ>|WTUcsYKf)K6aSn+h)L^cKATsdcf?*z9e_lzelX=Gh{<9lPaPdI$O*HVczk9MwY z**SNA#*Ay{e($-n?}t6k@7kWqzuJ83@F(_;Z;vhgDRbQXIpuvwPxpb`{Tp__Iw9v) zQ`MfC)7>A>61mgxT4v{g73NdLYksB;H;P7@T%Tg0 xg}cfQ8$nikY-eBL#Xw*41!P;EaX)e=^M&@Tw&8j2uGN2ceqXuw^C=6K{{_&ukeUDh literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/TvActive_128x52/frame_02.png b/assets/icons/Animations/TvActive_128x52/frame_02.png new file mode 100644 index 0000000000000000000000000000000000000000..20df899b86fa8249e2dff86c059e0efa0acbd258 GIT binary patch literal 2139 zcmbVNeNYr-7~c~WgvV+6sOS&pXB zk)IKoQ$;VAZ_gev2H!G_rJ5Gta6A+WnL=ihqL$z!%d$8@;S_~I1Qx86H9m~V!IX#w zI|vG@6wo9^Ms(NYgbr%?;DH;X zqJ!?r0KoG>P$^dh0O2VQgdG*o@<ge@QB6I^VTii>k1X;uT?21sXtIV}$7~zdclthjetro&# zVK9R6kXV{XTQJrv5SW=~1(s$+c;b!d8BN~7WZKM>)j_9a(j@7yrO`~b-JEH)G3IPX zHkB2T&6R^1FAE@ITY|Pl#$u%@$OH?+@)(^)k(kFU5*TA<0Acm=gy2mZlILtH;59{c zD~c~dRaYbvC}lPg=-d^OEGnVk3l9kZJFkHZqfT3lq%eYZlN3ji97CrPW{x0+p-x4V zyp?~0GH#0EXoe%re}TfL5qXXOPp~L(UPblukUo;1F9CQ!E-|9f>Tov2r>M}d?%l)Z zxi*_iRlJf9UIgv50wI_GFsw))@>LTRJ>Ye9p=PYj21I6`$G#nW|T!{xk58XX9ydrQo5%q0!7Q>h5GzT(Nt-@KI!gkI>5X0?U zd#1aft$*9Ot!-$WgB=_^f3MS?n0b!*{!CtdMeW6c&Ed?qJDRG$jisNdy7j~t7iSvW zr^uMI7p#^aPb0qO9oOpK?{+l2m*g)yls+|&J$YZK5x*O_o43+(Fy@CRYtqLbtIl;6 zxt{L1zh>1XrFv3K?d-(_f`II~ggsO|y|L+1+p*^Yz#d=(AcwcO5YrVyq!y4 ze>H#I{P@nNh&@|o7;bc>8PX0vm%1xyY|_BSgYLK@kefi3U_En$tCY0=Wa)mIj zL!CXYy?6iedf&EC_v)%$uhw7gIiz)5%YHLwbJLMGk_R^Q7yiC!PQuS$oo-rkrE$S^ z(QqQ6%aeR{XUdc@5|Y|8P42aBms{)a=O6uGw_^Bu|F&scCf6+9pW1rmD!DfQ5EwXq zvUABdRBFhJ>_u|!wiKM;e7 ztd`SA-G;!L>GXu>$6k*2?VELA|r+@5o9eMVBS*zFm34)d9lK=n! literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/TvActive_128x52/frame_03.png b/assets/icons/Animations/TvActive_128x52/frame_03.png new file mode 100644 index 0000000000000000000000000000000000000000..3d0f48acabc0cc49268838b1df660dc6076a2fdb GIT binary patch literal 2128 zcmbVN3v3f*9KW##V>+gpJOYc{ZY*Hnde`>a?hXnYZMRj{SxRx6Xykf#ZEv)9HFv0j324#M?ZUuEHvFY{u?)!fK z|L_0qOU~kg)RZwP5Co;#3#~4&)_{jdjt9RL2R?2DOOmt5ZR_pr1=~4C&MXDXuux%{ z3_*{it4|!%xM4H|CHC;{Ql->UL@{DeL$jiX(?o(HfQF!{(<338na?S(hx74*8M%4j z5CZe887VP1a7W0(`T4?y5;uEcv71>qpCMUf`ZRcIgaQhJoI=BqU_g+mh#BeAOM$(5 zj3ICzM44|!@>D{&)Zv6JqQt=_jTU8a9EVM$hNV3;X0*8F}l@McE*iV~tQEF2DN!g`G;`7kX>k{GVTbUG9uP`OG_=m;vvSpyoZ zoXkjkNZ~~RRyEQdu|hE;z|^P@!H~ldQ!L2+kpeNpB6JATYH%zVR2}O>%ZiJ;XU3pt z*1hh<{8P=yre3lqy=T!0G# zeKPP#8*?b+7Zp+Viw{s8yY35wN&uooJtOg;YUqGfWGYmZcB>fyHyV~_DS|Z_agWh} z;s%cv&0z^6O6nOL)zc(H5(XBWcn9hnw%gFfGu zubVL-YZqjN78q`Tn+M#0M^9*T3@C@QEJ}bfLrJ5-gBlGSp{KnJ>mf{i@{~p5XhoFV zq8Jz`Rp&q?V4Yrr!xKw*ffd8@Q}+pQR$AfAh+4L&R)^w*TdSkM7uQe1^%Rarp$?Jd zy;XmM8r(V^MHm43FHq1lEUnQ031%6}D@s8cln)=IeH<1Nd+V0d zTP#jV^zs34A-f7@z;>I(s3na?RHxCZ9TH8bm6P~Nj?I_EAlz5t6hBCKIir_jJfs#i z5VRg8SUrP!2-1YotkJ}h1VM5viS)~}|F<--m{Eni3{q6pKL}=X3;K5f9&mt8qG(2K zYTy_RY*&fZ!@&%HxVnhShy5H-8B6g$^A?54qE`vi5|`%#_5Yv}a?lJfsO<%cC@RMI zX~D;VIg25xqnJ97qMl*VOx$z2@9w_gH2?<_QQgL7F?fkhb4~!NB`~XfExQXKD6ZRX z&2yKwb+5lJw84+&FS*#ex##U+qnNR6g(VK#j&&|%__5d1tRHoso7U9Qe!z5i#~+X9 zZv4u3Y2R<18*X`_JtrNNjuRK_u4GO)+f`nr*&u0pR>iGZaQgZbe($F0AG@LB40L`~ zM{8ns?SMa|a*;us*OHqzKB>Lhv?QTPUzgf` zsBx&j>BCkf+*Ff4ZtJ#nXIG4#){etl62~O%r#rJEc-p*nyu*KLNV0I$^~M*GwpmbS z89pxl_z&e{(=vo@*|jBy&W|V}W~NsaZq3cAF;cBD$DJ>OE_jG-sEg`H4mQihnv)=5N%zn7MoVqLt?E@X4(+ zXRU5nd9C?qVt#{j%Z&_Ov-M_u{hV`a5;LHs3*67eeUBu)aQXemmOpLxMY5bbzI-*4 z`ZhB(>9d2s6!0q=zGkIio4(uCIbq-8ROcQWZZwv**6Ez3#P5Yu{x$ zPp9N|-EA8=UQ;&}x(d})->!#pk}q{$4lO+7<52gF)$yyl-OSX>5rd0f@6l_^omMGrc|<{kI+;$#_3l@Cq3v~d2Q4N( z<1!s;+$$=ONpQwRMG>;85fwGV{V_KuamFDV;&evmBf5u=DEnQ3>NecWnqGgu`~5!O z@8|pOnxewo)TFUV2!f>M=Q)bux*R@C;xPDId9b|}E(t}mT+Y6}KDeEGtaB+`Mg;R- zR}myRO@CsL+WMCeB>oS{RjQR1%;E&uZ{S7Q4Gdv_5TX%e+Kh0J7b<{;xGvav|{s21!O_c4!ly{Vg-~eE_4ZtD+E@=W=uz?g*m9e4>TSP`+WhG3tO>>UJmZ{ zV**1X5Us+B*>pm*w4eyJ%L+g(1_~EQl0+@6LFC=M;C4?zX_BT0k|8JtCrQr8atwnG zd@x9-h#s!kkuyLB->jHd(}Em9ghC-h$Y_w2a)M%6mLO?@rg4bC)#`x8hw*@#KB&O~ zR6&t~nj{BMT_f+7D>W+yP3`x=A1o+{Dh{Xvk%BQJ!hDdR3?$+A>yAaxs#Xjhn=vF> zbyWueQ4CbMQV{@zr#}{URzc#fUs-R{*ccic6M# zgQZ$D7zva%8c1}~JSiZ`A@$WK1b~CrfEClr7N=;OWLy-@MZS|sBS(_`&;nVMJk@`L znp`x^F(!^8{{n?gBk~&mpI}koJhI~FVfjdYz8nz2Kskm+v%}eCpR7P)-MS~w^X>K` zMfONOc%c^OW~2E|yP0CmW}G%qdWZBU)BzN!3Wzz1>_;Od&PhXr7nnUjaI+L{Vt6CY zh(-Z-Gc1g;Xtszf!>~YPu>pDU|CR<3H7ZY1VT!5;20;mUYhdS-AP4Luju-T%hK}*j zcAZ#19Ln%#tBZd5kQYFe(G>qPZ~ZV;_Glqq0k(2j|4%ES0$z{;dV9el>K7Bde4re_ zIZI%=ql7+?`aL81Gx6Bz$lVjeYY+}6qP~sJV)zoB<{$u7D{xky-PX~KATf9I9X40# z@#~vb>^_brIuG>qbrR=x#jcEP?Yd33PTbjaarN@EqaJ?0XNk?;xX;sbZh9O!%G$rX5|gA+3p7aDHRq-VF~twQ`Q#Oe4Fv;*1Its2zF`e!q2FVS>xF^hoe%`ZEX0t1dQp}({$HvE2`;@oBGDaj+13I$>j^5Yh^FH z*txMw4(!^xKI!sFZ_%NT=f9)+W{#t`&oR7zp-C#^A7xdKzSBGB*tE^RnJX97T`PQH z`7X!x&ut}DtBTQ-hGA8oEI5+eg@;>yJTudKe{2I$b9!}ROfy!OKYjA}tr-BXOUtnD zEbT13@e8sENxZ*o{>s!_Nm=#p?LbzwEvfzB_jp7m7O_ZY#}6(0;0nrJ^LlGv(9RgFfo$`_cd~h(q^D#V-`DKrS3d-4Q`hEGn-~ac2 z|NEkULSe7Wftd(`^zs(Dis4!XAG${>{4L-6Nex^w{Nn@ewzf97oqX`*Jh=3X6;0I; zU!n zXgfro;lK(Eg=mS-k2)0x>kP8Ij;)gxN$A(Wv2AJ6h9=!5uU1iPi#@ zF+dapO(|Ce0O7fJgxwWTbEgjvAndLHvYr%&vHy4BEfdCN@g?t+H z$((d37FKjc3oG}bPF}YM!cYLC#XY4;uxj{-OA*QqO0Ua-!5fn(i5xB3tYpy2;3N|? z<93m@;;cm=aSP81EX|1UB-F)oFL{zSyGXm;LfZ=%v)S#m(~QSuDX=*ii^uJu#&*ei zWliU00d(n>pl%_^fDl8mxZMU=oVGFmXIZNa7ih*Nh*Z!{SwXuz=Trf&D{4SdB3-5G z?}`LUSxh84Y>Fg{N?d#5E&<@;b>P5^vc=65PSOE0#lbIS8%|m{lI(!`6j2IQ{te0m zD2k&Qj%5D=g-s*!I{%+wQQ$&~8s%a6NKw8N5HYzFLzCIzoJvGdp<=_jyU)E&r(ab< zQUqRT#f4*0uiI%gvsNoknaoCqbR^UTRH*`p9#x5=?Iq4h_XsbrhJX-c%{W8z7MvC> z0v@DU8_tVXo5<2M3q%&{lo$VRX%I=HiX;uDsIqeqOae1IcM%EdfSttgg3;8_F&^4( zC^io7W%z^DMTdMm3?OAP#sAD(2TW5!dYo55K`E^N`<0N77bMweFIYq!VnUdgO97m- z1ZFr&7z3%pGom9Ccbsm&yK8uL!Qn(Sw#iuxUy{=t$dFovv-)lR7Kt*A*Sh&XwID|Xy7asS zXWO=YcJpL)PVMD4)6xdy8rY}qRG7|)mscH|cf$!M5wo10c^S=6gxe@*vr z?MHQbytc|Sc;lv3rxp(w-9Vxn(g$Yj;hS<3WS{8`WMlYvw;uAL;@7`S)K5fmrjmnG zkNj9Rs86=MDR04){b%})r^jVg7H!PWt+H};^~-~02S+v^`1JDTeJ^EQ@*cYA&CAOF z_PyVH%`2`1_}(|m*%LSDzVmmk6#Dp^nXQk_-aX;x<5R;mrss1$*gSiQqa}W96v=l^pK7 zoY?Ts_x)NZEne}BsP-!BcEgFSfLaOH9s7CBP&Np3%%{#1p(YXFuWWoAD2e1K5)f>BpB8T&`7i1I% zkEWf^jMQX*hy_+{-_h7_#I)(H$A5V_>+wCiZlzV79cJ%#J$267?t!bzQkNP3@Lu-> K*S4|K7ybz}t>f+h literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/TvActive_128x52/frame_06.png b/assets/icons/Animations/TvActive_128x52/frame_06.png new file mode 100644 index 0000000000000000000000000000000000000000..6a8aa8533562ad929a34ce8f5b7b7088e2ac4ec7 GIT binary patch literal 2139 zcmbVNdrT8|96t~cc`Q>l-OSX>5rd0f?|OG_xzj48Estmsp-!gLalQMMUTAyW-2uhK zXI!R3jeA7}G6`;RQBj0!YD7iNaDU9r$((V>hB%$k`H1e}Bg%dUw7Ly9vnJQy?|#3} z_xt(2Z%tuAZferlBm_ZH^Ya`Q6C1j!Ia1}905W;upI z2Y(o(Q$#OU}w?%d!MX5fp_(1g=&GH9m|7)%1u4 z2T%n?3TcuYM0Jh4N3PJU7&LXjhd{{XiYgAOgOP$UBf@-$Fd9fA5YQd#N2^*9cx1+q zXw_XE0z?r|*jWjg2Yq-7VP_=>YEf|*`+paX@Q6Yb7phSF{b3RX0{B4y z>QkXl#;8LfpRCEMPkw^x=yiV}bOIPHZnh%9s^R?(S*Xxe<~ytyyfKK9$T6bDOnS^F zoHTiic&5mhah4WHoaR}9WlSPG@kaCvB~LO&2bq~^VKQwdqtR*4WK1~@+Geqv=p1Jb zl^v1I52_j;6hMSqg4`CGCOtH7!9Akj!5NWaaFzl9H=C$T-o$!Xk3jd!b9M#rnyk2G z*&iv@!bl`giZ+nwqXJpt zTm3hv$xTrlW8z5jU!bsQL|)_n6D$gxS5^W%EFUSrmjNOaEW^-fb~wB2mla5?Tle^R zzTIA^$X>}0FVv#kY&73#Hyc^A8K(?Jy+Z~P>HvyV3B(*l4xs%d&PhXr7nr?3@UTYQ z#PBo>FD>96hPB|lXtszf!>~YPu|aw9|CR<3H7ZY1VT!5;2SG7-V{qq}AP4Luju-T% zhK}*jcAZ#19Ln>BV2oDj$Fm<(Zj9nSq+I5R+ow%dv!s_K`Mm_j`_Y#}Eaj&=M?DRNt z%KemmUmt22(e@$&s?xb_ns#K(hO{PT!MTkEdp6uZjvQ$_etYcs<`pm9sYFf&kbO%% z?>FU6xZ#`KuCT!msPgnnR~M;=6~98(EG#*njyhcV&CS zW9(NhpwE28r+UQ$j znzzdF?e$+++3!r-yDmL%i_1zKm3&1y(%A5GF&NXayXlVIR#?*;H}$oR9Vbd_lFJr8 z)5>0QvvXsY?BBU{ebS{9zQTha&VNhw&m2c>n`3zQe3MklKg_BgeY3SHU5)B^vCJ8@a2OSEr`3dC$W7(N6qlV T^d2vxf9&&}1&&?Wr7Qmgv4G}i literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/TVActive_128x51/frame_rate b/assets/icons/Animations/TvActive_128x52/frame_rate similarity index 100% rename from assets/icons/Animations/TVActive_128x51/frame_rate rename to assets/icons/Animations/TvActive_128x52/frame_rate diff --git a/assets/icons/Animations/Tv_128x52/frame_01.png b/assets/icons/Animations/Tv_128x52/frame_01.png new file mode 100644 index 0000000000000000000000000000000000000000..d9e75332e239e61b8d9b457a33c2210eb813f746 GIT binary patch literal 1905 zcmbVN4Qvx-7`~1$2HS**Lj;t|G0?%T_tS1mPYP^prIi+z(T(9x2q?o%ofuH!(1CL}LNGA-8$&PwQorlE1_=JqEkalN1ilH4-R;<2amaF|xFeW_-RZn8Zl}!_63BMsb`nStzp^ zj{Oi|PGNbf(Ed`)7fI!s>QKQ4CsE+Gr zuyZP-2(l(fBCIpgKB-KzBEZ!?4Iw#BE2^+!^GJkpm?C~iX491DSrSU?_$R=pK6hZS=4Uqb zjD7=mzV^CFUR{;&DH=#T>u=gScx>XlGo4uz{R{YHD9f}wDQW4tqOmtFIz& zE#l{9>^9uY-1qdRgHG;p9eFh{a#yFR`uv?qKf5otf7ZMswR33~-ah5rgoz_k&Ro0+ z^(1v1X-yio{r2&+pnPlijf7W-^kVoJI&F+Af6~_WwG#}c!O4-X&Qny^)#Fa+@Pg&* z(_2FIt&Z%#=LyH2_-gC#>ocb9+2_5KY@T2AJ-7CR)^IZaoE7@0x%M%_;Tdbe-? z1sv}XyK4s3)isX!sdY!zhFr(y`itnjZ?06mlUTcEK-Ize-fGBsV#&uTC)t$Z?S8}N z%sE2StW!I`b?;@|Z}wI--#Pz7jdHITnPFM|-81!zhsw*g?W_8-IAy#+e!gK_tGCf! ziL6_+22p1erw;ogGHl7w#@d8ULFnX0X=wEtsQYfq{A5tKI&e3!`p2x(3D*bR_#&}! U#Gv|>`X|ukm}&nof8LV606J8rng9R* literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/Tv_128x52/frame_02.png b/assets/icons/Animations/Tv_128x52/frame_02.png new file mode 100644 index 0000000000000000000000000000000000000000..b5fcbadf4f50411ad9c490a0025518dbc60f408f GIT binary patch literal 1908 zcmbVNdu$VR9KUvBvcV7>17u6Q+=4u>cfG#W8%MXcdsOK*M;Tp2?e*^39cz2#?$&k# zm%-o<9)^KJ*dU+;kxT>f2;mWBI0+909}p#o2#5~B3FwF>!shR~t^tBCF8ST>cfa4~ z_xZlRx2&?fG&5s-1_VKwjxu`{n47`S4^08@`a_-VU`nf;=_>B;?+44-ADw9eQ+l|p zMuMPWS;|mB?Hk8I(2yM7<(A#fnIt0wH8d-DIZZ4W251PHZi$6yrjC zVFcz`3YlYY;?A&*tL4iYMQ&DOxr=G6W6UgKnE_9ak$@n`$ut}b20{`UqmVc+3D(Ls zhQM)%Tt^{Aia^-ytb}cX$iXI!7G-c8hfQV;OM7X?>zxJ@IHARGJ*L&8I8N%!q+Smv z9t4OJSsz(tFG&akUldX+%V843qS2@(s?!LfAJdx6W(+4Vf-XMdW zlNgZ?%e)YR6-L@C)XNkCR2{G(7*5iLq=cV<$FLY3#Tw* zs23ToI0DqnQ>+P-Hj$%cL39a1U@%gZgDS&>PJ_dfoHWCS6eA|zcZIXlGDjgw+)yon z;(C{sAhjTLrm47&#PI>BQ($>t!$VMmiy%n7fy9Xipdf2lTBiRM%rc};5Q8)@nGe!_ z4hx6;2%K~zX%hm12m~wI-M{a!*(ycB#|OZHR8?w)9mO`I)@(GQghm@z*Xbl3AxWk~ z4Ck;@2yl;v=ULLg_*jBAai}?;VNku-N1*uzHXqgLXtPOYG}2~0J$TlufPZ4plc}0WWNF*$&SZ` zK${amKb!K&GcE{H^*HQBE_YXt`^35yeE6Qe{&%_y;T0&RA}PHvBDl>{vo5>kxNz^Q zvC~FJeplz-*bMa^&rP|w;_%0*GloOo$ax!P)x5Mn9U3BLT(NFyp59!rrsY_F4z$j> zKXd7V+q%)6b=^^D=7w8uKN*U|(jjZ(%8K!xF{+L`ZCRyrw8zb!Y)747Otms6@c_Wd+>&TA!$?oJyzb!tSu^4{0CkN)w-ufFOfwH=hzapGo0 zZ2m+xSJ&3F=3rOn`V7nV>Is1*6aA?ZzA&GEVL=}~{?cjZstZk*OZqw^W6qD*I`ZY} z>hAKL>O#j7ui^S7f{w07Thrdp*ca`+V_BAKJ$Cbn(r52wcg`Nu*1tQei`%{S$34An z;(4m)t+NYXM_Pudp)RQP>MLtu=x5dXO{*iS{EAzfYAi#WSA{l0)Vq6s`Bv?jd@+kI zXfi-2Urg3-OEr8H{XpG~gcci;DX z&-*^__rC9~bd{BkNF9@kAjk-Z-Btm|CiobWb@0EgyJsUD^sZU%l7WE%IIa5Pn?^XK zNcPzZf~1Yoo&;p$hnWa6EK6`#tJTg~3?~K+EH8S1Arh1z8bJz+A`;8h0u}WDpAfQO zx4VyEsK8sWH}jmNQ?dfTU~iB?WkZ>pYpCVSJXSOnEsQXbAP7_zjRXTBg^5_OC@%x& z+A@KmQHWY=!HPA5XtmRYT16S4`34H-NRmYJ%?6(Ju$;&9I!co?MUX~jkwXo7T{)cz6a+EShI=C&(ACH4$6h+Z6a5vCBe{n z{(qh?mjzgbY~ZjiH7=$UJR}Hf=DE7f<{fEpWp!}T|Mzr2GW36~tUVs~}#kL!;%=yH;mZ+@`kM)tzC1bx!k{pMrVBi>Oh^E0Q7 zy*lOaRh>Sye35?V-E!n)$LXfadv^sAmke*(-~F|_OaUX1eWNRr?8`H1#$B1zv*UUj zax;g1xN5(>PuDj|&6rkrY}1|tyu0qv@cu`?H=DB0w{%9V(uTFUH&-^_43Fs-#xAWQ z&Je%aOE!CQi(z4pEtZEOB!>MTGqpgd=_-2>)0802IvcsC#J?*vnpyTg+0lpv;-Pw@#^Z)liHO($TEo<8-l*2+$C;s5~apOcSTTKCY1uTaa6a z`w*CCEyycI7w!^mT!61`lem>_%e+im6JutP^2P9?7zGGIoI=B~P%tc0F$v27S;Uq?oD2`JGGewec z>Op`wiS<(+`;wF}@MS>)iXu`N7L7)AQG-s98Zp9bHe~g3C)TH0jiGM5E9e0VL9a|;4v&lix{E9RhyDPmPzBpW+|8y&N3Jm z!HBvbR;_Fb^jS z%@V^oT7a6fRcl1bCULYPNM1n*PDIK*p)#yD=x}(Ri)Q$+YQ+3Uu5fl*;Vg(6H|+JKU{iA8C$%!m4Lk~A1-BUeTmC+^z?rddsbiTmvT zyuV!HK^4-$XXa6BQ_UW#nwLRbTT{iel8dBPK^{&f3`H|)Ay^Pb%>a%?QrrA9dtjV4 z8sGrwKjg(YOcwk~l$N-PM&Pagka-wTA5)8V+!E|bBa>&36!-)jbPaWx?pNR=-SN0E zXmb+iXE)F6U?E5|?6g;S>yC|WKh?VqpX@Lv5@%->xnOHNFxFik6`PtaUW-`U{~YaG z+fWiYNF#L7@nCNv0}5PNd|^0K^Fq!R&zEzoCl*KN$I3l@^49M!d!joF;d=ue z#EPXz)E{*1`(tl8ginPk z63a{Kpf%9GrCv?f+}OeyBYOs+FRIF}Xto!x`RwZSxbepJv0-m8r{VWdX7`cxJ)`lQ z_j2NQ4tBTKw75?c&Yf0qS$jVEiL!M1)w@@37eb%bic|WtPraU<@u0Z*WA)ePbS$&) IuWWehFI#7m761SM literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/Tv_128x52/frame_05.png b/assets/icons/Animations/Tv_128x52/frame_05.png new file mode 100644 index 0000000000000000000000000000000000000000..973a8522de35f01e32ee57282fd538aacf35bc2f GIT binary patch literal 1898 zcmbVNe{2&~9Df}!Heh2@CQN=^ZUh+G-u1`U^`H#aj!j3D9|nQ{D3m=aX{1H}b_s3Z&w(Sadj;fFBabzK7le{spX_wK#V z`+R?YZynLoq^FN3((->SAFLp#hjy9203~F;p-=405~`zkc|0 z9OGCkKEJ?4x`)S7Se;zZC20cNV2)#*5l9bUxnM_#X z!I3zL4NxBYtb{Q1WyPx$MWhHK8jb3rMx7u93BAQ)AxHyZFlZ4%E7$M}9n zBGP}zi$0hv1e7Q(!I?qit^bgD1X7<+i?+`a;!z{xXAcy3KOA)pb(!o}=p)(jAdlLd zg!g{j*Q7XMg3e88g3d`oc3hpShE$?Gb!M%JX<0Q()8YkMbwVOu`c zoG7@PJLHe{+qvMUiJx^JXc#+OgY7D7YtjU=-8UTCy@=! zb0aN_#vNr2I=W|1ZM}W+`{f(jwynQV^xo2?zUe2%WO~Tr@6I1Ol8KF$-sw3x!@4CS zeJ7LodYw=RR$A3X&N{9YH=r(nh%O@?z?)Raq_A%V7^6_zW>Wx z13}B56*|X}5iI~S194((FfgYy2V*Jxo%|_{jp;Ll)=&<=)(uAGo!+|liZ?WW$$;~_ z)@i^=-|5Z|X7BV|XKP0`=K5X>)~-zxYK7ZF!MvRpp8-VRe(L^Bf%*gLzt34(Zr@+B GsO~Qw3XWy~ literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/Tv_128x52/frame_06.png b/assets/icons/Animations/Tv_128x52/frame_06.png new file mode 100644 index 0000000000000000000000000000000000000000..442b2c29395c4cbfc09fcbf299e1c15999e73384 GIT binary patch literal 1901 zcmbVNYj6`)6uxOFmQr3V2qQQyTX_gg_L20Fg;;44nov?RZ7QjC#%^}E&Dvyl+1)m2 zc~y!E4hTAcK#`#ih&ojYb)-PCNN13T42-}CMH!VUKLm>-jvWS!chfWj48F+B=H9*c zyWctAx#yf+nCjgKs9`KDn*TI1J3>K%5U0{eBoq`BDq=-rycC>k z%NUBpAZm>joue5qF8Ihn1ZO6+sv#^9S34XCO_VOTgEHik_`QLe@ai^YQBBu0`3h%hMif=WjWf|5DN zVCNJ@<|UOE1w><{{bH?ZMWL$$8bVTnR#4(`f)T?aw1g2xT+SU7_ZWb&b-NQb9_ULblrW*FjyfnK9*_s36>q)7VI`a* z*2)a$sDo~1YHB3PCUdkZ%3e_n4&Ib!&}D=)8F6H~n`U@H6YspJa#mEkHv>T$ zaI=>nDT1Jg+?lwE!tnv9TV(mF`um{SUXq0OOA(fPpfGD#TBZLL%raD!D2He$nGey` z93~0XD3S;yWfOy<3=M1E-M#Lz**vmX#RuVrQc_rexE!_|!jh9?AdN)KUALQZ35rS! z4Ck_2Q5YU0&$E;%&&1+5lWibLHpgH#5x61GOy(Lm3**m*1Y9;VAQzsui%hMS1cT?< z|9SpdnTJ(K2OpY8t4%F?C?~JLd##TbPbs%BJ`3_lEMX{`(F(zeGFk?3EE-?tA36d9 zwBY~;N&g`)24IRI z-z#2h^IZ6LxYW8V=}e}Q7Qy};o6(Ph;Mq0TOdHO>(hNMvF2vY7?3lhI(-OJerK{{& zQQ_$rpKsH3%1a+<>{)>=k=nb9!04}-#n0=i#%$m6#GUU}W|R#X{l&hH*WN^Y>a>lU zLsyGb{R@OXD{tE46_YpF}}E?Twp-1ph4%h4i%yE5ts;3X=-2xkL!(Q2 N=W-O=KQ5?T{uk3YjQ;=t literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/TV_128x51/frame_rate b/assets/icons/Animations/Tv_128x52/frame_rate similarity index 100% rename from assets/icons/Animations/TV_128x51/frame_rate rename to assets/icons/Animations/Tv_128x52/frame_rate diff --git a/assets/icons/Animations/WavesActive_128x51/frame_01.png b/assets/icons/Animations/WavesActive_128x51/frame_01.png deleted file mode 100644 index e1c7582bca61823b5a2d690c9c9a9284a78a96fa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2311 zcmbVO3se+k6dqW?Krt2V0G(nSGy&b6ncWq4=dc2?D@(bEuq9fivoo{o#O}^8Gsv1iZk3>@zvfCCpJk+8?*bc=+?fOPmJz*>HdB5(&p$}u2GazHrCk`5`3dP1v(yAA||6KFe;VI12P3_KYS zha~X?ist9%tMWA}PRK@ayLGa)S7CBa9YC7$;rKkk*%6$kP{zr)7`G$>Ebhbd4o>1k z2lo%IeV_jn0MyoE@x|zoi_7H;Axfs{AdRkq^oSO%1w4ahFd~;HP>g9hpcy4+!xPB@ zLrR=r5QF^`xqMp9x7h^(6u1ES$p3@6k$fny^u4S`{u zPzy)1_JT*CI6%i)aXp~{D*qV@x`rkt@;|{eMc6sPMS_%B7n#kVygM6#eT5{FIVUH8 zz<`~mgN4OHq`F0kbW=>K(SU%gRV+&rIH}WUb&Og`GdfbK9i`VONjy%cw9^bt>FruA zL&tU78#yXZ*0$T82KH2(mQ>@TbV^*$j8bZC6s^=zcAHXf$1$zWMqxUguG@aRz=F+1 zI{&vHdCSR7L6}()$W_p_Co-Abu9cI8JNkeiDY?H52qg>4&`8&7wucHlUIv|R^BoLu z`Y&>K!bHw4<&y%Flntu&7!8H~6Md1K{_o@;PrkpA@3{g0ANj7*QV!Cc&47uCB62#Y zJX$)1LI0{*$G1nuP&XXRHhJlrs^Gylml-#3Er6+eyJq-)2=c#@YD}_v&R$)8Zr41x zuc`Lo8|5=Ehu8QA?Y#nDytz(Ov9Q>*E&ZqXIz?{(hWj}izA1~jmU#Q#H}iHt-*26A z@?qSm`8yX}UJ7M=*{gBuOla}WfuCnqel{%-Ui9GgtviMeXb>wMrof6UClvAPB4Nla zN0##b=QV5Z)p~xqu;Ay>%YTl4{|;TWzP_k1tWmruePg&pFc2H4!^BwPlwD66gPt7XyT-Ozq zHqlV(Et4NcRv%8=++>ZY4l3IcT|2cMemCdFtlayrel+8F+J*1K%Aw%522E^Qt&6(! zySMew(t7Nx`X8Q9e3)JOv0wAFUK9O#@oRRf!;0fqeIk8&rtjMJp(~Gmr+{@uY1Sfjw%vu?^ZQ5c&??r|{csDiMh~WopJ`;nniEo>+3}|O6BXejKM2bCWwK^- zd|<`ktB&f}1xG4XUsO-%XPsQNX>r@f{=ey;RNN1X$w(?cYQC}YG8P|>m^=nW}<$p|k^Yoa|cg&M4dxo8W zDxx+$J-4-~WZ$K8Epysp3u6{8dis^ARi(X(mzi^x58v6h`K41^A#LHdBc36H*{bo& zf8UEiO#hNY7xN%G@H`Sdf6l&ubqmUy0u$Jww~T!-$6+TLuy(*NLsS!uHtg57_2mYeR%EpNXW z4V^x69vXLS_Ic}`$l3bv{e7yBS6)^^OG>`Yg;#i2rX=r0EPmPcZmo z!rY4DqjB8t_iO!ntth#0lAN2X9L zR!kVA+MR>o3%T{mJ#~T=!vl;DC$)r{Qx}k9LpWctC6_FjY4V0YxJn1WD^ink2>(dYT}* zp*E4@ou&6cNr+B$kQA*a=oI~ZP}nsbqcHyq=2+S(N&*8@<^{$DaG%$Op`k+3nW9IO zU|`5j-^Idaqpe<9VZ1D`noStYTFdhsO>%%T8VN>Ypa@E1a59vJp$tGnFnYjIDS9Jt za=rFuku6rW?X~BieJYt^AdF5@lSTnfV=%HnLovEEjXqUJ=~WzZA-;5bik?; zos*PXb^6v}E73biwEE)%J7w~KQ26xT{ojKdd}FNylb`J?|+>S z8kT%E8wrcr`E$qYboStiMMB)+_bb7?+3+mE6ftZ_RBGmF@Yh`hcRnl@b;75myZ z;P9bJW$|&rHEi|V+Qd66hOAktEUb!cD9ZNFYddkSap_wJ_T|Km(2T3-dx_oM?>XVz z`KZH3uj7N4wABF`yVFP^@+ia+fZ=vT1In3 z;v22;DJ9OSFBHTE4<7Fub0(qcNbZD}t5*#PGw+L9`pl5r);*40=&{XM=d9&DQp;r{z|8Z zPwp4-l9xF8d{a^5vU- z>UVG66H|!oV!(WG{ttd<946D{*jRkwXi__39)9` K&AXm|Y1!XeS}W@S diff --git a/assets/icons/Animations/WavesActive_128x52/frame_01.png b/assets/icons/Animations/WavesActive_128x52/frame_01.png new file mode 100644 index 0000000000000000000000000000000000000000..eb49aaed49c4188b14d225f81e30dbaa3c256a5c GIT binary patch literal 2092 zcmbVNdu$VR9KUU44{$;vAq0sYH$fa+@7c#)){(6bwv29dlrR_$u6Ms~CvC4>Z(BzQ z%n1f0lPI8bAVI>!paMY%AW;VkBauf$9xAU5|9~x#$D*Kvk@>rJEvQq8O|HM+{eGX% z_x=6e8c*rW?2!{jA_$UQT;wQ+Ya@Kv%ry94d$_$7F6o|GUgzN8Al%M5dUiQnvcg64 zA_y|-8U0B?S~rhJkP-c|w?eCM&*DWTXcQ#H2aM5R7@`p*Z$>mMh>L-S`arcDvSGIm ze~qECWW(l~+@w2f2Q_lhQWeZzTIv;-E*3cnn~{&^MR_P72s8nW1_Pl8AGKjIxjfwK z#{`DPAlhOZR-h|HE8HH`uBZUD7%5yNNfNbiMoI7qqR%%SrAeA1NS2^joFsXM<5?CR z`e9I=D*5?xhiga~e6wLSnil2>qQ1V~SkD+0wVI$fjw48#plKW;@JK^Q6QX!1l9Q0& z01;7@!|200FI(? zhW0Ty3nYO17{-rVIoc;uoQV{zri7f~_^gR8-$!92BYn5e`*jXfi*%T?r^ERIFR~_<6D2 z?ok!L9Do;*@|lHbvD0p*II|h2jg;Oa@sv7%D%SzYr7A%*R^+@qOn@y`6CeT0;*1%H zI7?e;+$xY1?&D~|Oi3)TidJlhFa6)*Ad*HE$q|^OhM`d~8!Q>x1!SlL_7X3MdRs%s z1ZcaiSU()j@F%N`IKRFIK#|E5|2=PUSVZw_^@0its$mB_NfE_qVvP{025{06nC>W{ zkEFO~L_8CZoQ~Z+Hog*YI1}}4avH;zk9CF-_T{v#)6%$TXxHV`Zx>$V>jo~JMK-nUR&L~G^*!uzzV^dghb9)a zeqXsF^9ujPSCdn=x9r^n^1Xq3CkL*KSZiO{*8IHE|6)(h`?so7pGNv!mS$v8UCX

$n8K|*46y>tIsvQJ+mu+Yx=RNN0#lpkTv&2>-_GL z`5$hPvzyLu&#OCARqLJ7y`(q8u#G%&eNSmeRo{k^;{!5Az9T+Zbq*ufzW33IOnm1H zM+;ILQw^?-T|1hxggIk=OItngb5HjRDQgBQJOy{Zo1TlUYp?A%w9>Vz(bc)xQgWKh zyma#5iZ9z6}#(nqPpPw>Z{49O{#`VpFckU;avsJHbcs+Q{bK?GjuDp)EjLioP-;A4fpiTdJ N7duNGy9yUI{Q(_K)MEeu literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/WavesActive_128x52/frame_02.png b/assets/icons/Animations/WavesActive_128x52/frame_02.png new file mode 100644 index 0000000000000000000000000000000000000000..cb2c7359686b035f078e9fd16284dd15b5d30344 GIT binary patch literal 2097 zcmbVNdu$VR9KXWYOO^qG3=}=PUS#U8p9y%467!4RTJT%PTwQE70N^Eld{qFbse7^7R z_nJye3bQgNW+DiZ;tCSa1^2uWX7!8C@)k34fTP56tNqxA3AD8 zCDCqNX!a1Er~?G0qIw0C*Oz#O`bvQnjk9K=Gio^~APh7ftqq4FDpzYa#^iEvuOH(^ zGzQTs?Z$jvAzI-nMIEvNP^*c=1cD$?D{B&YA20ZP(@=__NSt7BlEDaqqgjq&(7~S( zs#8QiSLQ4jR0iMd#-OG}IUKL4sWH{iCRqvKB+IfmLE#jIK?J7OMKrz^i>SE?2~MC2 ziWJo(IfCjEd7oUR*^SWDxDVl|$CDHsQ3oRhV}{rAQJgdpcsQ&(7DKCA8MtT0kZ9Fg z7X^43P~|E`01%#gkL;?3ng@M&0J5tZM6@Iw#{S>Q2|c2a#6_!=P%KQMfP)YSLwPFn ziA*{a4a%CV2IYScoxF|(LRSEz#m!SBST%geDGOD)NVn5&gf}Kp5;+S)^MEBujHY}v z#sCpuKAQGpHkR@UBx@!Fn>it8C_ZDRX0tYHK4W7GNYdr7G3Ej%oo{uR=>k^)H9Ns| zM^ufE2q2+bg1W7Y02sed#B3xZVhm+rFrJ|RMlvi7d={G@@U|GAb0~nc zCL)1Sw246TJiH)9^w>UKFSBx|u?l!?@PB%V?yP^4-g7ASHUjTJd34HaOU84!SBFxmnH7+@QP z*?5A)d@RLVNRa_H0R}kE7yoZ@;7Oy3Bo!v9Zg3QogQbJJkOXzWUgCH`Z)@ln4{g^K z>xV-c{y>!x=hp-Q6q!u%-}4rSsj^?I;T4b{fF1B4MHHtAK|T@yaMI#N-BDa0Npa8c zcqZ;S9lN`4d?ny;ChFVdG=?w9c@82_v;wEKvG~x}2x91RJM+C2$9{aPclR+gedX=1 z2DWt4XmSxDzJ^7)nH+=0VH@0!@h+p1d6E+&=7!bvM7i z_Fh_lQFHIwqx;&{2xqspRUTm)Hdl|&_bqG+=DpC}c?+>G{cgoeiw^hC%70?zmCw^{ z$mK^bF~b_J878Gz+OK?;itJ&!I?-H1CUS6m*C=$i;TuD9?`xIAds5D~oya(M$-S-* zG#)Q*OFvk-F(bH>8}s3pO}|zv)8?S96B^r(bWO`#J%tTTA2q7wDAT;8nOJ|oQuu9W zYg-|+>I~AdrLW8T(Feb6NY`j&RaeWA`HhP&Si=2Nw~xDfx$|7==+R>4$1j_u*Uwvr zPw(4icz#XRo$OO3y}75xe%g~Z^P)XGY+PZWdxUaj@5b%Vbk9|8){hCUZrl^OxIX)8 z&YkS0Vo-q~1dynMg^|c3AP<$-hJV18$YW8^!N~kwyB5@`#3t9@?|#3} z=llMCZ;iKfM)vS=!x03@E-rGG!Lrc) zKPE6V2GJJVu>xHoTJG_p4p{}L)kxt2Ns_3QHHy5S7ySNdC{5B7K{5oz;3UbJSdL-P z!5;?IsbYXDbGiqW!8bcrt!WBJ5OsBR#yXQxR;vh#Wm$rx37W=Va=!jMZ9-A>F zI^wHW08s`aa*Zkg2+w&;cGW`7gFZY3*;Na|T9OW9|L^349#Kf*lo~Y{3zH}iAP7QG zUIh9?B^^?#WlfG$%l{xcc^wOct^h`ho25#yYWSd27HV{n#ZEg0Z;YZOau&wK1D2w2 z6YV$Q3=jeCH<<#sjivnp#hOXMW=_Z%iqDwoLe^$=F*epsQ7(s#F}t0n0;|Jpa=YAg zVS-y6j%a*X014d^)NM1H7{ARz;(m%TjFIpmKfUs8THu-KrcyV@1wMLj>4rGXoMZ3~sUj z0cU6%joWyV!u>4GTPTqMHo=As^2PsK97NKnA}IosR6jThW`iYzyPyPhz+U2bL2qm5 z7!PgN73+sX8UA#Y5$D%c11K_?;=kuD4vWYEt&UegK^5$PrzxU1O{nI>RRB&}0@EEO z^pOzVh~4&1ZMD zqnU5^bq=)7+IwM4E{X=M$0t=BARieFE4x={&n)Y>*HiML3t7JIZoP8s^rZuLhyWV)yee0kbIl67-wj9Ig zJ$Khz8hYA#0>?TOgn1=x>(n$h8s2p!^~}OcTy6j5bI7LV-SW-ctlmeRuGfEf`_TBJ zmhUT8WM1XI{CZN#_U65tK)x?{|78EwVQU==Tbo{#`(EnK`QUa{>a$3n+uDRIs%?I6 zgh8>5TZFXl8;(@Cdw(z5vPNnckK75iW?jo~yY@oEJ2N`-x27MPa%9=gi&=9|w9M}+ zng7uiDZBB)_PpA&l{LP}T}yg04BN;fH};gaSN3iwIo>Z}917o$nle__Z^wg zc(HOGFz&nW`Qnt}(&y>>H?D6Yd~-jwo~wLy!yBRN-V+ZNbmq19W^6ua_;$?H1Fibk NyVzCg+*P=!@edUi)1m+X literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/WavesActive_128x52/frame_04.png b/assets/icons/Animations/WavesActive_128x52/frame_04.png new file mode 100644 index 0000000000000000000000000000000000000000..368aa2229258f99bf41c32f25251cd16ae0fab00 GIT binary patch literal 2144 zcmbVNd2AF_7@wtuEJtk>1cHA!PQfEEJLeuVvb5Vh+9ln#E^8>DgxQ(5?PPanmf7h= zOany;BEpDa3mZ;0)iAup+FlHkou;Cden)z3_`R#P=>ly4WM=lg^MIfqIS+A31LADho_)4NmB&L5)_M*B+qa>%cA{1 z4AN;*gb#Xr{bcaXiB;-)f+vWYni@+DV^OsVg5o%iAZdc8afrZ^b&4+3;z}}iK!XP) zMNLlVvZ|nlMj@ z%-}4L03K$T2=3tMut;%MQgm1c^b9IbT3tT3!_GQ5A4PfH4%X`PFfO~>%J{rKx?n)o zuOxLr5y1er47u%8m~)U031@Ah4RTWvT%Z{eCpi&tb}1~90@EkYyEP!_suoh!*g&b4 z4MYN^84HQN91uiVF=F$|V42HVT)qP9_Pm_Ow!nTnFUHDJ1B=Qkeiwm%TU<)lQ2nj{i9$8nBTvP$&dr~5-*5GTSLbLXuCmd z91d#u6IDh^zNQjDmFX1!J#Q&kQjO>}f(Bd_umhf?h*Dx=rJz&*IB5yYaFj4cQpz(T zm5E1A_uV}xvM}E~(=va1gg#$ea1=H57VdYgx^!oETgRNt+c%$HxVy0jyL0erSNB0>Saajg z`i5o5J+h@Ud(27XNcWk{>#j+`YIIb_=cen==W@AYP3GYzB6lp4^ zj$#+SI_xz!PVGj9+_E&iZ3~r->WLmi+z+O#&MIBL8i{}p-#NFfu%mNru()a4jp)iB zo{eXh{n&lW6KyEjes<@%hew)QY>0X8GYc0-XO9SKTG8Iq8Fw=`KGi+_?x|yX z`8|6xyXyT-W$!H-<2sa)lRd9_$nm0J=22(Y;hJ$H7Qfh$%S~K&k!%jcUR%nV+U+-9 z5SR|6=VJTS{5O_wY=~~MITNSX&q3I0hfaQ16n*Q&Dz)j8J+n7YSbKZR*jdreH<9`R z^!HcW@gr@f^7HQN`;e2F(<_RsosGMSOMgB4(2{X!1$qoU(CXiRvU+@b!?J92C@T!#5(2HbspeQ^8IiEo#|B_~ln zM@5j_QTj6k*}Qcuf@JkdfuI(wn8^up%*2aw7?>Jj35Z6J;^_?uUZ@2c8V1!;+>YHm zauh=)(T>fwRFD-3C#aFi7b~D@ab-YQTr035Hhmge+`vHvF`)5iLo6CsxduCy(#yfU zeoSC!3Zm88F^5iw1}l81Q&s?KHBq=gk|b(nO(GxWg>ZN(N|Q82kPJaFI7xD5mSY%n z;Dn#1a)1X~l7MAW|@9L<657C=*GcN;{OOku_PZk^ez;`Z^T|od8CQo25vwYWS#27V31BUY8w%HzrXMxgy5Q1D2w2 zGaWYL3=jbxHk%{3jiti^#ac+gW*OA;NO{uY@HlOyjE(hBl-p@zEFPEHVRc%}9=C@s z9hCLPRgI4eV31pa++hlkG)YBp#v%$hBUo6R4U+)3T8jWBM63~;nNG=bP6hCqtOR5^ zI#{Z{!APLA*+im+6}%wD_1H{)NCdce4cIZgaB+&pNhUzidf{5ADWsVr$$n^sEJ~3@ ze}P&8G|e$Z9L4?#3fo5HHU2-rqQFIDCC0-7l45){AQJIv3{B^UbIMU!fyBCX51)IT zPM;!2q$s>l{bi-7*X=B#*rFnwHc@(y^rzGX6saDF9z~9!sUqj3M+Devvj7q>3~nw0 zFu=5p#%(-F;bE5Miztx+Ho=As$cz8CIEb`S<&p}Mv}j-yRDp#9yQl;?U@vjJptm)2 zjEA=C#QNc*41c`J=$B8{0H`vZ;=kvuAEwF?Ey*juQ4Krbaf+y4OsL`G)c{Uf0@EEO z^pVu>8PT7K2TrH%9vWYRa5xk7ZF(BRm-IXbaj05>(|XmUssMrvx#@K|0>RI2yy;k< z@vOn!+jI1GG@6x}x#jH(t(`Mo*w|KVoK|?Y?<)LYw4S-sDH|J)mZ2@NuIZPT1>UIc zyYcn*y>)>@ojHxo9r6O7meG3Sx13{+**jclc}8gH$yYPlja!f|B$+&(F}Cqc;FsQw z3qtj~kuw*whGZkgRpaLTaDK~;j=W>{Yo;LnC&;a{hm{Ns&9ZGstR0fo9u9d*^Fpg5 zdFxj7eBRR9B4e>!Fs|g}+TH_QcV^t1k#qdHpSth)_gqJA`CG1Zd%CwZ?^^r8P?PWQ zUhTw}yZ3Jv>`Zr8P+E$d*ner8!LWViSEEm!_P*ZuX?Ee%*Rc4^5hYhg=Fi>q#I>;{ z-Zo29?yV(zf=xfGb1uD?S%!3;@;r5H@~!8G9Zcet*F)6R7ZTuYfLPJ;Og*BVLxw1Y!EYw_l zA!qZ!eLe2O=h=1FzBdLAZps;%#JZ=HF8^Y}$G)Xo?@uTgwd7Ftyv)5lyR2%5Iq%)X z&Wq=AC-3ex-5wtr)3iO~(27@@4VUJ39{K&wi!1hC&d&cNt1x#%C{O>&d)<|;eWju0 Fe*kPY*K+^> literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/WavesActive_128x52/frame_06.png b/assets/icons/Animations/WavesActive_128x52/frame_06.png new file mode 100644 index 0000000000000000000000000000000000000000..9020efbaed51cbd0d5885f7a057efda52543f34e GIT binary patch literal 2144 zcmbVN3v3f*9KW(b#sD`3fuM=!4SWQy_iWdml&$My?Xr$pY8aq|>)qGw()O<0-Co3y zZ77+_Fo5BuAjCuh4ADSh%mO1Q4_|`-OBe_V2r?LB1Gb=m%MCCU_C(aMy65S_g44}_rrMvI%RO0a79m|GFb4UvAg1A{kaQ4%>T%kaQXQ8+_~ z8Jq9;b)~XhIn;mjXCx3CwVmFh4kfCT5PU}6|qGu7rbkFa0hDyHfT>q{54VmU{ z>g(I4)#H0>a?|FT7w?GB=d1FLqo%(6L(bKgZtrXESde&cpZ4ZYayBUih7j>w~S zHT6S(?(NK&(25-EIg@(bIW1U$j!pU8bp5$3d)7o#yGd@T8`+KQ-@W?YwC2-o z=TaI?cOK+q_8_VCE%o;|&(bqiRj2~nC_1O)j_v8XlE)mrf+LqVcx&Y?pZ?TVJC!0$ zh17BE!dESxw1$~I$cUTf#<#4Y*<*X7M-bQj8EeMPUa`h3b6v2oar=$v zsvn+?XB7X~bJHEIE81~(_qhkhcI~wyX$zmKSr(n29#mD|fwq)8shghYDY$d`gkE+l zcX@8_fzI|>Y9~04retO;+BM>&FPM7V(cMxxDSg=s9a;9N>o1bK0?6`Sg!o2`yS+lB=Qd+liJcfRPGr&cSCpX{H%Wy-o+TPMzocD{iu z%|m~Gr5!)kY$`eLx_%I8O)V((Svni`6wdzj>;rSkrIqLj^l+2^P;15H_PR-^;b)G|NL8koixW$Reih|4;86RBbtqnV`IahAoI~kcby6`Ilp}0sc);jcXz$_W=a|{GVM&(Im8_!~RZ0-(_3qd0Lfb2Mw{;_c z8$=$<7zhCkplpPPlZOH^6NxeqO+XDn;SX?8LxKX1FcaLE1m^G7t)QY3n_Pdt`~5!O z@8|ozb-wbMBS%aafgs38PpPv4uJ!O?v(w>!_3@5va2f6^^Sk={`{DNGQ{S$DOHRCW zo{Av3`TCQFY}+voK{ER!e?SX(%Q!)f8hKF;0b^}64$%lwJiRu~3yXn#q(5hAe9+>e+ zwCb;m1EK<`a+MAp%cJpakCW(Rt+C<%0jiS(&MyY@Wv=gB3HyRJg`y} z&d?zSXMqUt5W|FVi-tUS5!5dTb^?Bm$hg25gvKxHv`QBhXVcUqj#{VZ+6u7XgM0r?1Qk1U*L_AiBp{e|E4mlz#kXX0w;d76} z;Zx+W6oD6N#mo}a<8l;H)}kVuHd1BPpM#0#Ict#edIR5~j*wEx{|mUI{zkaf&D@CRFjUN&qJpgKh63NWS*#6F?rnXrxZfPzyOe;L!e+_;xn$F#6lMVGJW}=PJuIX1+_}{GT zzxnm9gVp}_ww(Gkt@0wDmfm#px10|9+}%#JG(9-%^lRxYhV4ifl1Q9PA6I|Q|4ZMN zMZuc=$hpgzX<3M2?f7{=T-<)MHLv4-)fA-S33A8W;WLH>XInPMH>72@go5spyx_WU z-o~}PpEou&%2+fPjGu9OL*J3EJG1W1$~pP`Pd)c44%|SxD;lr%xO;Z4*}LI`VMgDv zgW9Pt_aELS*w~(~fV3Prb+~h9cJ{8aug07{>v^O8)2za&uVb;YQ8TWM9yx#O6W7Ph z@HCqma=Vuu2sHex&g*s={oSbD&osI=?d1CD~o&m)39n=IW-{@Zg%_ zOF7$)9_n=+yJ+2b{dOk39M&I$;vM#e(YPmVygeZ}wqaL#`>I#hWOpuXJO2BfmsTCTk~Q*^%);Ew!94vd?{Sqo50wO0 F{sCYc*qZ{tG=_{?hDoOj^i}al2*i7nXOht@X8ih#$mMm*#PjHsOKqfE&v%rg3!ilw{ zaRSGuaj$Xh{QOb?v9>y$GsY{qm`u(Pybzu(rr{{aE780@#{#fez;jtv283seGy|k; zER@CyXo0ipIWDtLshB>>u$+|PaG;K6jAki`i7%J{EiC{wBI${-d43=PIvz@njs6cSa)gAFK6;|!{zaV10IA#x^E*=HYZ zHHw>y&U|M-(w38&f{HNmqFgzSJuwd~ajY_pa8DmlG$Zx58et@10gE_Z8(&p{x5}W` ztt}0RPX9;lUKr1%2sYXZrl*S4dW(j_UPqs&v)@4et>pU;`ByjKyODR4mPw<{sX&~V z7$T*ENu#A#80_Dg^?Z9_4E4dq*(NQWQ&oI$&ShX0U0cPe+q|vf4g|SwkJL`r+nYLy zYl?orJ+AmkBd9$#(X*E^41UH7wpMu&B=3_Y&x~%NPR*^$K#ft&?rq(QbFR4 zMTH)4*u#XbvoT0P*3MLy($j8_%9leov;%I+<}hhTpsvxKK9Pv+;M(vY`IEZiLrOQt zUD_FZ_Gs>((HY+9M{5(h?|1s0>kKU_ZD_xo3uO>bw)yx&A3dB462l%hdF1V`9I5t) z?9gnV@v54#B_);afsLmuD|}amjq|epiVuNugIZl;T=TAn;EiV+WXoorB6rf;o+VB( zcQ3`ZuD*G7;qv!3qIcT&4{v`qag((yzcPPR!!uoN-l2u*&-1H-J!+eMOU@ta9zM2I zvn=T^$ZO5hZ$W54rdM@&?UjCwg};=oS#+l8<1LeY=UlipLJ42-itB<`#-BM~SiCxY zZTv}D%aq)TKLAh=vyoyaGc+zgM7=+ZRKUP*FIOdtF9c!C)LUG@0vF~ zT$x>Qx_H-j`iP{qs_3Ot}?>FlGHZm+TB(R~WQqaT0=Y8t3d@5WRo&1iAjacP4^maAA^RTC@qG(W*({O$GJm?tIML?GA7s>)s5*_tC4L5 zwhgV}E|(9_Ez+#}eGz%yYft}bdiy;$pZuDm<3G7Icng#_?(yB2vF;C6m-D%a6i8H$tLLZt@^I(e;ll3;iu?Z>H|Qp&A(2uVZJ`t2wg;FlBIL3)CveG*XGc(H{O6e0-3$@GR4IPK1fP?~AYAVQ_ zC+@MtbcAl^sCc|BdmP~KC>-Ia0Txb1b)My+8^qe4Jd4a$V)A z1lMw|x{e+{Ig$p5U#h~$XoyQi=_s4WY1VX{Pm@j6@RC;cYE;!1e{v3kkKep+S)(#9 z?RAlEP1FNSL6!Y$!sNEkH5N+7_oHq^38QK=HN^Y3R2ZFyC#w%?5B55Up!k5TroK`P zmva!bIO3e*mLbUCF!0`Fqvx?V&KmDY!uL~|rsf?3EQu`wZ21(;x81*G=r0VB@)`WR zEr5!8dK=}1dzamd^gG)D$*C1rB0;KZYn3GeA zcxnrBi`1OxSL?G)S8g;?cJ7;BJ}RJGMY(RT8^}4ks3^GV zuK?1|3=+v{k-(ikcP;vfxmfk3){jEBsk+$Ig`A8<(U#S#4{9aPbuEh95TiNW{<{yH zm=IJI5(htDe&D{AM{it&gHHqx>`uJETAR}TN@>m?RF1ebjcHd_J>9-#1|_v{zhlc~ z9v&0k-Eo4C56F)I21h`p94LdIc2{mOLQHI<6Q86Be-THt@_<4wzmPtncjG+gsEwek zKFV95RezU`KzoGwd)eDOw20*+TP--0Ba(MO!eab*C8XiWA*F355?yDXf}wwEKU`bZz&a! zYuUuLchca!BZK!2s6A5ny*xwt4WJmg_xY{@z?_mi}PxAI`Q^t@f2HxSaBHs{4u+zTQ=5T zXSOD)b$oPKI`=^Y_+p60| zQ!kd>m2b{!-aMdkOgKpGj>>lht3Pf!|-cQbjuQ;8}#DmJ=(RC820-J%Dw zHzDs4?~Di&wZyw5z7)fcyJvFG{1mi8Ki4SNfM7CMyVJwYzRQ$ZO)4Wr4sC4vlz_4e zQiG~Vsa@+1DUvNpwA*3F>e@=Rr-qL@jBXj-(dB%#fK-k=grp&T(|OY)kW!?FY8!A_ zg9q`pXnR?%poGIF$4g^4%UntOraTcF3YknwZ9CKE^`z%fc8Ywyk`^>W3L5ETw%1DT zTEpSooA;?3DQ)x0*UitQJbeO9W+i=iw5_eW?QKfvF6-35MC+7(<$kp_8=m~j1!9G9 z`Q@Gix%ZyhjoJ0(m*(TlFTxrMHmHxOfz-+zbqjlM=oDNn9lDZK=8(_Ury8YS8!ybf z>Q;8#DELrhF5$*KM>S_m$xM=_d0=iqr}}8aoU0?w(c1CK(S|Y3*r|+~LxqPL4_*4r z!2cB1K+mJWt-(0V$pF`4y~8>W_aR%wBk@XlVXbqOHOs^Nu)3R1iBmyOQcY$}YCu`Q zg?T>t%Gii@*(^}j;W}yeGqlRdeQ)JL%CjRqay??+`G>jm+vSurS%-H5enM&)T%cDpFrsHX7)Qg?C#U*zu7kzh|)u) zxW>GOvMOuqmq4?cvr*++lo{yU7W=;%e4#zxco#-A<3-}`-Z=SvE zvdlN1CsHh8aTav8HFhl4w^gOpbeDU<&VoFvjx5W}rS^&TSxvO&C%5)mNSQ(zu8fa{ zq+OxCq+NXT@{Pos!*3{h8oE6pnX`tWUxFrQwtu#pAq4LUeHL;!_{QwyA4*I7%MQ!B z^Dk$ImjjlYPrN%(|5c&1)2;dN^HI^2hLynO{hK;PTqLH6U==vHTxHrcj%wp!;|W*R zQCT#Z{v`H$Tvy!k73`IJo!RiV@{#h7rW2C0pAx9u$~FT7S* zn@m$*D9wzjiPDT#@W^l29r`l)rBI2zQ%-DrH2z^`6t4A5tHQakjyVb%{`=sa!J{9% zTs2D@N-4g^0hrJXVyoH*i-&y=QXg0=_bQKDrCG5}N=-5c>KG-pums)2v4oF_UlT=@ z!_78YQ_UabKfIPb)Ha+> zV|*K@lS0jLOu!$!mE_Z!0~q3xuy(8*gqwmz;tp)(G%=;4^_tV7OC3WpSL zHButJoH?~wLQW5@@XoL|>CR}u@x+zN73WJW+JRE4+k7>o`v)uX^KEkDJasBx2Kc;1 zccUk3PELI6E2#YeN9^E|tL+qykDgm(pxPZ;sbNgPu@aucKn)m$TS*xP#Vhl92 zZf?_nMRU3}h1JoXWxijVwQpc0$l9XgtFX8f?GMnrh}&Fk&{D#3zHpdT7zNhnzR&-` z$H#3Y(Ir{0G;a9M9iF?jM*3{O%o#q=>R=Z|?E9Nq6q(>yqqRPOb3`dr#O?sfPG))*|$SUw{2{V4|?=RK=9~ z{*el(8RiGM7fLYE#Lf}`LR7ey&C>wzg*(I<0RVqE0E`_0 z0BjlnNHH?&Y<0O48yP09EC3LeSbuqdj7(_&0L4)qT-Yv_7FZ(PPZLj~6UdrDehe-e z0Ce{UG4MnmG8;@FQ>ZjO$W(n31WYCAL7ewk!YvsFWN)fT2$O6dV&y;#@gZVJkp26> zxBp#_D*u_z2yOAGw{fpE<+NnThxL!M1+xj$$n%So5jT< zeqtHkbT*ykP5(Ele@_340d8z9Eq~hhOJDr_ewtvhaRFQ!-vjcOXqH1TgAB7Hv*`Xz zA{iIJb#uo$8wS>ZNyfA3Ob0sM_eZ8|ez*)qqBP-PRZBdPN?RwP_KOJF5YHy-LDusI zg>#dJaDXGQNCXxESBImpaQL54OFD__75obn!9}AT5Ev{HgWZGr7bv%CNO(5>{{)kW zST8!$56`7c^}|!hFb0hR0sjmn)`0FyXL1d5y+eKT!qO6JN@KC{G$Ps5P!Gaotx2Vl zusTR2UK_(L7KApz3#vupeh6eO6jYmlN9w>)7!=YA|3lu8PV`^T?GJepSDr+IleCcp z6cj=5LP53QcoY<)t)m4cAW#G?j1GZ>#%ukMw`Nkgiwp1jkM*oCx%HyJnowEXbOnE3 z6ZYg|-+R7P@V7d^;)(0^tp_2lCzectd>^L%MFjpHgFn>_9w| ztWV)a>u(ek?BBW1!Uz0k=e1E}Z4?4dgc3<)GE~cpfPw0uxalK%>5xbm6bVJZ@A*Og z7w3O1Km_JT0sb@RzlWCSji*t_+#M4J`R8>0UN!!&T>MJszt_|MCmq=OPWfk@!Tx6n zew+JcSLG)2+YooFUhn=qB)C66j~OzJ8!0CD5UHm-w*UZdm8qe=L(p#%nV)Da;7yS& z%lp~rBD)@*W6@!;&8kbbMTZRTDmEr2&+3YfIGQc3j>$C1j!m9|Db4KO39RB_qv2=9 z?wLSCgn;5SPF=MqM_OG;S9vdJFW@@&sytcwv+i)aB$>pxo~tw5B~+)L+TSFr&~4T< zgHR2ZfPHNmKH%kP`ndKJ*%!)j+fJ&E>EGR8XLGEu{XjeY%C3AvF5<+ni^iz z{HV%zL3Dcg_oL>7h1EIUhrM+qnfSq~noRA-cVBoOHWU343^2~SPYt~S!fPHqyzDM- zI@zr&lWg>$)H$C=LU_D*k!L>{CxFb*sIHC4^i^1&yGp6y2V~> z9c_o}0a1aDXs2iS_5)>MfDU22X!dM5ykpI*EO7{Jq07N98Uy><9-{ zZ38H32hkv=VxNMsFX%nEDU9AN2gyU(R<~TuWsM>h=0_6p1iieSDpbWtuV~)xm373-KHM;sAHK<+@(u4k9j;R ZSeZSs{jSFmk@X9dDbC8U?BJ18{{=ekiQ)hN diff --git a/assets/icons/Animations/Waves_128x52/frame_01.png b/assets/icons/Animations/Waves_128x52/frame_01.png new file mode 100644 index 0000000000000000000000000000000000000000..8d6c70ea5b6ea8fd7377622d4b402303d33cd55f GIT binary patch literal 2066 zcmbVNeQXnD7{ASdV-uMmObNnqLxYa?K6>ria|O1x+ZyN?rD_Kx>^|Og2kl*VcVpcW zuucVsun-}91r2}9IU>#gPDTcS0VWC&WnNW*JySOni}^Z6!v(M#F9E3DHt<6!iI6uNZ_H6?pO@1YF_Zjj8W05 zuPzL5FHq$gg$EFx^GMjW7HS^$VGP2qwLsF6;xP9AE}YOK@JU>_MhV8kB=9&0f)M0W zp-*Jep>UO~$!eAS57f!)SRix-Fj~wKMTAwu2Awirqf@$_b`0Ja1yNuuw21{ak~Eko z&Sap001TYTRB5oW`ehx6Fj5I6NPznk;73y=Q&&?>2g?UbCJ_jkmoR)id;oh zVM5j|sTwQsAfa1?x(U)^wVG(Cj5FB`w7^;noB%ij&zmX1%#v0B$e29iPynmRicgk< ziBc^~L;|HuMgpDdVR=!~WAow&5#VGsV8`^rH9#LJtB)cXGLJD^a|she5OJtS7R1WB zkxQI{)V#%E zs$8knvI-~&zz!Ho5yi#$Dpm>rIB9WAcNEu0Qrt5aquLK;c%iBNTko4of13Po>r2H84`&b$ z?NcWq$epYG`wwSDhc;GxzN7ld=)T_b3(fN*Kesdx*Nd5_yOG|$8wW0=wsUC@kd8UO zsl}&|<db%h}nMfef_Hem1=!#ZrCuIV5%J2dTTxKG~SNBirA7@XYDe z=E2^91)HC@{MuCh*}Sfqo<&dT`si#g1b)ue`e1UtwIo{QmD3)}hnOdU}U; zx7=?_KNH}ZJ1$eHbMno<^j$f&=}OnVje)wnTWNi7tUq_6XTwaqtzzk_`tPExvo53|pAlpk%q_Q&ncqiXKU^E0b6FZVTC z?wzcjb*qQW++NhRn*QkHeboNlA7)R!c=ufzFaPGiTm3ctU)?y~vSIgeWM|j7DJ$Am QuF${HZda+Zt+1luFS9(+YXATM literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/Waves_128x52/frame_02.png b/assets/icons/Animations/Waves_128x52/frame_02.png new file mode 100644 index 0000000000000000000000000000000000000000..d1746df375c7a2287b9bdcee243feeb91e900a97 GIT binary patch literal 2074 zcmbVN4Qvxt9Pc(ak!^uMFl>Mx2RJ~k_tkd0gEH1HRXOGtDbeYaVTPa+hfsbKS3jD9$f4BuMX(dH&`@p~e+&*&j^fI{I6E0k& z=yd7hwI@l}vT>qLmwH=tdsL6Bh~=fAo)aW5&_{w{h}P-mk$Xph%oB;G_W~2$p78g8>=* zp-`PH_}EgLV^A47=f^T2?(hPaTxo57mn)@_yjIoEeE1u5_lX0KoIgN z&?hqCP`FZ3C8bjO2kOLiG!U8s7%lc;S%g)?1#A*utx-B{W)$A&1yNv42ATs5Nn$kR zr7;5#0OqA>AC|{ZUY=x(1fOS&^9(1?SZP~<#bPw%TJ0ohx8@m)4jWyNYclUGIA4kz9+QeZ-Dwo6zCIi4Yf#fltkue%c&LjZB7nNtNGT>B6c1uzq zUaBSWNFWrgCy<#gju%5(Y-SA+0X9wrW>hO&4Ejjrxhaw*^H|dGAVISP5reuULG;xQ zg;E${bW;>-FtG&lHz;fyfm6Bv1PeUtljI-=3rGxdet?HVeiTXMhqX!pNrs9w>xP~? zt=1A*@`(X>p_DGPAWpm0L^385M(IhdM`9_p0a;uE1cxjIk!X>#;xGXoS#o3Y!v8G} zJYiI!sK6xE4vvB{@Z{hwAVM2qFR>i2wKa5%gSMlChr<~@vdV~&)>HyW8B6i7d5ggm z$*0zEGAQuF4j4%h#l-kZF60Mr(&DJ*D6Wm9m}ht_6L*}B-VGUFaX6fb+BPwb;Y(tk zgAk;a;j|uW%v`6_CB5sk6}UYgUiUbkPnnwWPXEBwZ5><2XFMSg#^%;B&KZVrp2+yy z_fJXL^;7?I{tIooKJ&^io5SbI=Y}WmI@jG_Vn?&|8f)qJeb-ICR9?JoHF zO8MHPyoS>o@JUV6dgrvXuRd_CW9;UwqfILpOkVKX3;N`1ZSQ}YeX*rH+0$5WJ+QRl z#2S+SeDBUc-~4O!FPG2x)05XQFsUoswy$CCj_;1oc3F0=$=)70wBks`(Nc;0>VfUc z=ryap=&QWZgnP11F#TK9V^eN+kFq>9|Kj?IyK|7=idG-D@9xN&*fry@zpS{e{^Olh zA6-2{-JNlC@k`+MhLe|*Yu-#Md3;&lxyCHZgx+nZa!#DN-V2a|v9FhH-Zv#}!p5FU zS6|tLeABS2V(mKXEz9w9j{KuR<{copl^UB}uIC$f1Z(Z@Gz2CR?{c`4m&I66> z7pJG@oI2m;{GnlaCOc;8*#%24?rq=Lb8yz8w_b%G-%j~_)yY)vp%)#i+AqIBe7)Pz eoK^hZ)coB0QqyMsG2x2#t#;arZS9td<$nQ#0@6(Y literal 0 HcmV?d00001 diff --git a/assets/icons/Animations/Waves_128x51/frame_rate b/assets/icons/Animations/Waves_128x52/frame_rate similarity index 100% rename from assets/icons/Animations/Waves_128x51/frame_rate rename to assets/icons/Animations/Waves_128x52/frame_rate From 604d80aed4ed6f74d94b9e66747d88cad1e16aee Mon Sep 17 00:00:00 2001 From: Albert Kharisov Date: Tue, 7 Dec 2021 17:13:07 +0400 Subject: [PATCH 19/32] [FL-2083] Bring Passport back (#868) * [FL-2083] Bring Passport back * Move Passport to Settings * Hide icounter editing Co-authored-by: Aleksandr Kutuzov --- applications/applications.c | 6 +- applications/applications.mk | 12 + applications/desktop/views/desktop_debug.c | 6 + applications/dolphin/helpers/dolphin_state.c | 12 + applications/dolphin/helpers/dolphin_state.h | 2 + applications/dolphin/passport/passport.c | 115 ++++ assets/compiled/assets_icons.c | 614 ++++++++++-------- assets/compiled/assets_icons.h | 173 ++--- assets/icons/Passport/passport_bad1_46x49.png | Bin 0 -> 1237 bytes assets/icons/Passport/passport_bad2_46x49.png | Bin 0 -> 1295 bytes assets/icons/Passport/passport_bad3_46x49.png | Bin 0 -> 1304 bytes .../icons/Passport/passport_bottom_128x18.png | Bin 0 -> 1149 bytes .../icons/Passport/passport_happy1_46x49.png | Bin 0 -> 1296 bytes .../icons/Passport/passport_happy2_46x49.png | Bin 0 -> 1328 bytes .../icons/Passport/passport_happy3_46x49.png | Bin 0 -> 1348 bytes assets/icons/Passport/passport_left_6x46.png | Bin 0 -> 1083 bytes .../icons/Passport/passport_okay1_46x49.png | Bin 0 -> 1244 bytes .../icons/Passport/passport_okay2_46x49.png | Bin 0 -> 1281 bytes .../icons/Passport/passport_okay3_46x49.png | Bin 0 -> 1304 bytes 19 files changed, 573 insertions(+), 367 deletions(-) create mode 100644 applications/dolphin/passport/passport.c create mode 100644 assets/icons/Passport/passport_bad1_46x49.png create mode 100644 assets/icons/Passport/passport_bad2_46x49.png create mode 100644 assets/icons/Passport/passport_bad3_46x49.png create mode 100644 assets/icons/Passport/passport_bottom_128x18.png create mode 100644 assets/icons/Passport/passport_happy1_46x49.png create mode 100644 assets/icons/Passport/passport_happy2_46x49.png create mode 100644 assets/icons/Passport/passport_happy3_46x49.png create mode 100644 assets/icons/Passport/passport_left_6x46.png create mode 100644 assets/icons/Passport/passport_okay1_46x49.png create mode 100644 assets/icons/Passport/passport_okay2_46x49.png create mode 100644 assets/icons/Passport/passport_okay3_46x49.png diff --git a/applications/applications.c b/applications/applications.c index f9c12932..f8e7f422 100644 --- a/applications/applications.c +++ b/applications/applications.c @@ -33,6 +33,7 @@ extern int32_t keypad_test_app(void* p); extern int32_t lfrfid_app(void* p); extern int32_t lfrfid_debug_app(void* p); extern int32_t nfc_app(void* p); +extern int32_t passport_app(void* p); extern int32_t scened_app(void* p); extern int32_t storage_test_app(void* p); extern int32_t subghz_app(void* p); @@ -151,7 +152,6 @@ const FlipperApplication FLIPPER_APPS[] = { #ifdef APP_BAD_USB {.app = bad_usb_app, .name = "Bad USB", .stack_size = 2048, .icon = &A_BadUsb_14}, #endif - }; const size_t FLIPPER_APPS_COUNT = sizeof(FLIPPER_APPS) / sizeof(FlipperApplication); @@ -303,6 +303,10 @@ const FlipperApplication FLIPPER_SETTINGS_APPS[] = { {.app = desktop_settings_app, .name = "Desktop", .stack_size = 1024, .icon = NULL}, #endif +#ifdef APP_PASSPORT + {.app = passport_app, .name = "Passport", .stack_size = 1024, .icon = NULL}, +#endif + #ifdef APP_ABOUT {.app = about_settings_app, .name = "About", .stack_size = 1024, .icon = NULL}, #endif diff --git a/applications/applications.mk b/applications/applications.mk index 051d6f7f..093da7bb 100644 --- a/applications/applications.mk +++ b/applications/applications.mk @@ -32,6 +32,7 @@ APP_LF_RFID = 1 APP_NFC = 1 APP_SUBGHZ = 1 APP_ABOUT = 1 +APP_PASSPORT = 1 # Plugins APP_MUSIC_PLAYER = 1 @@ -100,6 +101,13 @@ SRV_GUI = 1 endif +APP_PASSPORT ?= 0 +ifeq ($(APP_PASSPORT), 1) +CFLAGS += -DAPP_PASSPORT +SRV_GUI = 1 +endif + + APP_LF_RFID ?= 0 ifeq ($(APP_LF_RFID), 1) CFLAGS += -DAPP_LF_RFID @@ -223,6 +231,10 @@ endif SRV_DOLPHIN ?= 0 ifeq ($(SRV_DOLPHIN), 1) CFLAGS += -DSRV_DOLPHIN +SRV_DOLPHIN_STATE_DEBUG ?= 0 +ifeq ($(SRV_DOLPHIN_STATE_DEBUG), 1) +CFLAGS += -DSRV_DOLPHIN_STATE_DEBUG +endif endif diff --git a/applications/desktop/views/desktop_debug.c b/applications/desktop/views/desktop_debug.c index 7ccfcd0c..91a32e95 100644 --- a/applications/desktop/views/desktop_debug.c +++ b/applications/desktop/views/desktop_debug.c @@ -112,12 +112,18 @@ bool desktop_debug_input(InputEvent* event, void* context) { DesktopViewStatsScreens current = 0; with_view_model( debug_view->view, (DesktopDebugViewModel * model) { +#if SRV_DOLPHIN_STATE_DEBUG == 1 if(event->key == InputKeyDown) { model->screen = (model->screen + 1) % DesktopViewStatsTotalCount; } else if(event->key == InputKeyUp) { model->screen = ((model->screen - 1) + DesktopViewStatsTotalCount) % DesktopViewStatsTotalCount; } +#else + if((event->key == InputKeyDown) || (event->key == InputKeyUp)) { + model->screen = !model->screen; + } +#endif current = model->screen; return true; }); diff --git a/applications/dolphin/helpers/dolphin_state.c b/applications/dolphin/helpers/dolphin_state.c index 2878edf5..016d8a50 100644 --- a/applications/dolphin/helpers/dolphin_state.c +++ b/applications/dolphin/helpers/dolphin_state.c @@ -102,6 +102,18 @@ uint8_t dolphin_get_level(uint32_t icounter) { } } +uint32_t dolphin_state_xp_above_last_levelup(uint32_t icounter) { + uint32_t threshold = 0; + if(icounter <= LEVEL2_THRESHOLD) { + threshold = 0; + } else if(icounter <= LEVEL3_THRESHOLD) { + threshold = LEVEL2_THRESHOLD + 1; + } else { + threshold = LEVEL3_THRESHOLD + 1; + } + return icounter - threshold; +} + uint32_t dolphin_state_xp_to_levelup(uint32_t icounter) { uint32_t threshold = 0; if(icounter <= LEVEL2_THRESHOLD) { diff --git a/applications/dolphin/helpers/dolphin_state.h b/applications/dolphin/helpers/dolphin_state.h index 25d2d9d2..1196e256 100644 --- a/applications/dolphin/helpers/dolphin_state.h +++ b/applications/dolphin/helpers/dolphin_state.h @@ -42,6 +42,8 @@ void dolphin_state_butthurted(DolphinState* dolphin_state); uint32_t dolphin_state_xp_to_levelup(uint32_t icounter); +uint32_t dolphin_state_xp_above_last_levelup(uint32_t icounter); + bool dolphin_state_is_levelup(uint32_t icounter); void dolphin_state_increase_level(DolphinState* dolphin_state); diff --git a/applications/dolphin/passport/passport.c b/applications/dolphin/passport/passport.c new file mode 100644 index 00000000..4be35566 --- /dev/null +++ b/applications/dolphin/passport/passport.c @@ -0,0 +1,115 @@ +#include "assets_icons.h" +#include "cmsis_os2.h" +#include "dolphin/helpers/dolphin_state.h" +#include "furi/check.h" +#include "furi/record.h" +#include +#include +#include +#include "dolphin/dolphin.h" +#include "math.h" + +#define MOODS_TOTAL 3 +#define BUTTHURT_MAX 3 + +static const Icon* portrait_happy[BUTTHURT_MAX] = { + &I_passport_happy1_46x49, + &I_passport_happy2_46x49, + &I_passport_happy3_46x49}; +static const Icon* portrait_ok[BUTTHURT_MAX] = { + &I_passport_okay1_46x49, + &I_passport_okay2_46x49, + &I_passport_okay3_46x49}; +static const Icon* portrait_bad[BUTTHURT_MAX] = { + &I_passport_bad1_46x49, + &I_passport_bad2_46x49, + &I_passport_bad3_46x49}; +static const Icon** portraits[MOODS_TOTAL] = {portrait_happy, portrait_ok, portrait_bad}; + +static void input_callback(InputEvent* input, void* ctx) { + osSemaphoreId_t semaphore = ctx; + + if((input->type == InputTypeShort) && (input->key == InputKeyBack)) { + osSemaphoreRelease(semaphore); + } +} + +static void render_callback(Canvas* canvas, void* ctx) { + DolphinStats* stats = ctx; + + char level_str[20]; + char mood_str[32]; + uint8_t mood = 0; + + if(stats->butthurt <= 4) { + mood = 0; + snprintf(mood_str, 20, "Mood: Happy"); + } else if(stats->butthurt <= 9) { + mood = 1; + snprintf(mood_str, 20, "Mood: Ok"); + } else { + mood = 2; + snprintf(mood_str, 20, "Mood: Angry"); + } + + uint32_t xp_progress = 0; + uint32_t xp_to_levelup = dolphin_state_xp_to_levelup(stats->icounter); + uint32_t xp_for_current_level = + xp_to_levelup + dolphin_state_xp_above_last_levelup(stats->icounter); + if(stats->level == 3) { + xp_progress = 0; + } else { + xp_progress = xp_to_levelup * 64 / xp_for_current_level; + } + + // multipass + canvas_draw_icon(canvas, 0, 0, &I_passport_left_6x46); + canvas_draw_icon(canvas, 0, 46, &I_passport_bottom_128x18); + canvas_draw_line(canvas, 6, 0, 125, 0); + canvas_draw_line(canvas, 127, 2, 127, 47); + canvas_draw_dot(canvas, 126, 1); + + // portrait + furi_assert((stats->level > 0) && (stats->level <= 3)); + canvas_draw_icon(canvas, 9, 5, portraits[mood][stats->level - 1]); + canvas_draw_line(canvas, 58, 16, 123, 16); + canvas_draw_line(canvas, 58, 30, 123, 30); + canvas_draw_line(canvas, 58, 44, 123, 44); + + const char* my_name = furi_hal_version_get_name_ptr(); + snprintf(level_str, 20, "Level: %hu", stats->level); + canvas_draw_str(canvas, 58, 12, my_name ? my_name : "Unknown"); + canvas_draw_str(canvas, 58, 26, mood_str); + canvas_draw_str(canvas, 58, 40, level_str); + + canvas_set_color(canvas, ColorWhite); + canvas_draw_box(canvas, 123 - xp_progress, 47, xp_progress + 1, 6); + canvas_set_color(canvas, ColorBlack); + canvas_draw_line(canvas, 123, 47, 123, 52); +} + +int32_t passport_app(void* p) { + osSemaphoreId_t semaphore = osSemaphoreNew(1, 0, NULL); + furi_assert(semaphore); + + ViewPort* view_port = view_port_alloc(); + + Dolphin* dolphin = furi_record_open("dolphin"); + DolphinStats stats = dolphin_stats(dolphin); + furi_record_close("dolphin"); + view_port_draw_callback_set(view_port, render_callback, &stats); + view_port_input_callback_set(view_port, input_callback, semaphore); + Gui* gui = furi_record_open("gui"); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + view_port_update(view_port); + + osStatus_t status = osSemaphoreAcquire(semaphore, osWaitForever); + furi_assert(status == osOK); + + gui_remove_view_port(gui, view_port); + view_port_free(view_port); + furi_record_close("gui"); + osSemaphoreDelete(semaphore); + + return 0; +} diff --git a/assets/compiled/assets_icons.c b/assets/compiled/assets_icons.c index b0276f28..cfe0e39a 100644 --- a/assets/compiled/assets_icons.c +++ b/assets/compiled/assets_icons.c @@ -2,12 +2,12 @@ #include -const uint8_t _I_Certification2_119x30_0[] = {0x01,0x00,0x3c,0x01,0x00,0x5c,0x06,0x01,0x40,0x07,0x5e,0x0b,0xff,0x20,0x07,0x5d,0x92,0x01,0x13,0x03,0xa4,0x70,0x06,0x5f,0xe0,0x10,0xc6,0x20,0x10,0xc8,0x1c,0xce,0x70,0x07,0x19,0xf0,0x08,0x70,0x10,0x18,0x1c,0x03,0xe1,0xff,0x83,0x83,0x84,0x34,0x57,0xf0,0x10,0xd8,0x03,0x23,0x00,0x1c,0x8c,0x08,0x1c,0x30,0xf0,0xc8,0xf8,0xc1,0xc3,0x10,0x00,0x90,0x48,0x60,0x70,0x3d,0x98,0x90,0x70,0x1c,0x10,0x70,0xc2,0x03,0x65,0xa0,0xc0,0x07,0x47,0xe6,0x6d,0x1e,0x07,0x04,0x06,0x20,0xe3,0x90,0x5f,0x41,0xc9,0xe0,0xc0,0x08,0x46,0x09,0x18,0x41,0x0c,0x82,0x44,0x0e,0x11,0x61,0x5c,0x27,0xd0,0x70,0x70,0xc5,0xc1,0xc3,0x40,0x8a,0x17,0x84,0x94,0x53,0x0a,0x0c,0x1a,0x01,0xe2,0x88,0x7e,0x01,0xc3,0x08,0x80,0xff,0xcd,0x05,0xb8,0x80,0x43,0xa0,0x11,0xe8,0x80,0x84,0x43,0xa5,0xfe,0x98,0xa1,0x86,0xb9,0x00,0x8e,0x9c,0x47,0xe0,0x5d,0x1a,0x04,0x88,0x8e,0x20,0x02,0x97,0x60,0x27,0x40,0xe1,0x03,0x95,0x02,0x82,0x0e,0x49,0x35,0x0a,0x65,0x00,0xe1,0x28,0x04,0xfe,0x38,0x05,0xc8,0xf8,0xe3,0xf0,0x09,0x3c,0x8a,0xe4,0x0e,0x4e,0x02,0xe0,0x7f,0xff,0x39,0xfe,0x02,0x47,0x14,0xf1,0x0b,0x13,0x41,0xc0,0x52,0x0c,0xc2,0x61,0xc0,0x90,0xc3,0x38,0x50,0x1e,0x27,0xfe,0x8f,0x00,0xc8,0x48,0x20,0xc0,0xe3,0x40,0x0e,0x04,0x1c,0x98,0x8d,0x04,0x28,0x1c,0x4a,0x31,0x00,0x0c,0x0e,0x11,0x38,0x59,0x8c,0x12,0x7f,0x12,0x81,0xfc,0x27,0xf7,0x08,0x05,0x06,0x01,0x07,0x07,0x1c,0x08,0x6c,0x20,0xe2,0x98,0x40,0x27,0xd0,0x08,0x34,0x42,0x70,0xef,0x13,0xa8,0xd0,0x05,0x84,0x1d,0x10,0x00,0xc1,0xdf,0x43,0x0c,0x41,0x1a,0xcc,0x47,0x63,0xff,0x00,0x0c,0x0c,0xe4,0x2d,0x91,0x00,0x17,0xf8,0x1c,0x3c,0x00,0x71,0x09,0xc7,0xfc,0x0d,0x30,0x06,0x7f,0x3f,0xea,0x11,0x07,0x78,0x3b,0xc1,0xd6,}; -const uint8_t *_I_Certification2_119x30[] = {_I_Certification2_119x30_0}; - const uint8_t _I_Certification1_103x23_0[] = {0x01,0x00,0x98,0x00,0x9f,0xff,0xbe,0x30,0x38,0x04,0xf2,0x01,0xe0,0x80,0x82,0x87,0xf9,0x01,0x06,0x24,0xfe,0x01,0xf8,0x80,0xfe,0x21,0xff,0xf8,0x3c,0xff,0x9c,0x0c,0x1e,0x00,0x30,0x7f,0xc0,0xc1,0xe3,0xc0,0xe3,0xd0,0x7e,0x75,0xc4,0x46,0x30,0x70,0xd9,0x46,0x3c,0x10,0x09,0xc0,0x30,0xfe,0x10,0x1c,0x04,0x3c,0x18,0x37,0x08,0x05,0xc0,0x18,0x77,0x88,0x07,0x00,0x6e,0x31,0x89,0x87,0xe2,0x00,0x0c,0x39,0xc0,0x30,0x49,0x83,0x18,0x8c,0x7f,0xa0,0x60,0xc3,0x2c,0xa0,0x30,0x60,0xe0,0x01,0x06,0x14,0x70,0x18,0x26,0x51,0x8c,0x43,0x20,0x70,0x20,0x64,0xe3,0x03,0xa2,0x74,0x10,0x62,0x5f,0xce,0xc3,0x8f,0x06,0x78,0x31,0xc4,0xc6,0x33,0xc2,0x6f,0x99,0xf5,0x03,0x89,0xb7,0xb0,0x2d,0x7d,0x9f,0x2e,0x98,0x8c,0x0a,0x86,0x3c,0x0c,0x30,0xb9,0x7e,0x20,0x30,0x88,0x07,0xfe,0x0e,0x0c,0x42,0xda,0x40,0x3f,0x90,0x10,}; const uint8_t *_I_Certification1_103x23[] = {_I_Certification1_103x23_0}; +const uint8_t _I_Certification2_119x30_0[] = {0x01,0x00,0x3c,0x01,0x00,0x5c,0x06,0x01,0x40,0x07,0x5e,0x0b,0xff,0x20,0x07,0x5d,0x92,0x01,0x13,0x03,0xa4,0x70,0x06,0x5f,0xe0,0x10,0xc6,0x20,0x10,0xc8,0x1c,0xce,0x70,0x07,0x19,0xf0,0x08,0x70,0x10,0x18,0x1c,0x03,0xe1,0xff,0x83,0x83,0x84,0x34,0x57,0xf0,0x10,0xd8,0x03,0x23,0x00,0x1c,0x8c,0x08,0x1c,0x30,0xf0,0xc8,0xf8,0xc1,0xc3,0x10,0x00,0x90,0x48,0x60,0x70,0x3d,0x98,0x90,0x70,0x1c,0x10,0x70,0xc2,0x03,0x65,0xa0,0xc0,0x07,0x47,0xe6,0x6d,0x1e,0x07,0x04,0x06,0x20,0xe3,0x90,0x5f,0x41,0xc9,0xe0,0xc0,0x08,0x46,0x09,0x18,0x41,0x0c,0x82,0x44,0x0e,0x11,0x61,0x5c,0x27,0xd0,0x70,0x70,0xc5,0xc1,0xc3,0x40,0x8a,0x17,0x84,0x94,0x53,0x0a,0x0c,0x1a,0x01,0xe2,0x88,0x7e,0x01,0xc3,0x08,0x80,0xff,0xcd,0x05,0xb8,0x80,0x43,0xa0,0x11,0xe8,0x80,0x84,0x43,0xa5,0xfe,0x98,0xa1,0x86,0xb9,0x00,0x8e,0x9c,0x47,0xe0,0x5d,0x1a,0x04,0x88,0x8e,0x20,0x02,0x97,0x60,0x27,0x40,0xe1,0x03,0x95,0x02,0x82,0x0e,0x49,0x35,0x0a,0x65,0x00,0xe1,0x28,0x04,0xfe,0x38,0x05,0xc8,0xf8,0xe3,0xf0,0x09,0x3c,0x8a,0xe4,0x0e,0x4e,0x02,0xe0,0x7f,0xff,0x39,0xfe,0x02,0x47,0x14,0xf1,0x0b,0x13,0x41,0xc0,0x52,0x0c,0xc2,0x61,0xc0,0x90,0xc3,0x38,0x50,0x1e,0x27,0xfe,0x8f,0x00,0xc8,0x48,0x20,0xc0,0xe3,0x40,0x0e,0x04,0x1c,0x98,0x8d,0x04,0x28,0x1c,0x4a,0x31,0x00,0x0c,0x0e,0x11,0x38,0x59,0x8c,0x12,0x7f,0x12,0x81,0xfc,0x27,0xf7,0x08,0x05,0x06,0x01,0x07,0x07,0x1c,0x08,0x6c,0x20,0xe2,0x98,0x40,0x27,0xd0,0x08,0x34,0x42,0x70,0xef,0x13,0xa8,0xd0,0x05,0x84,0x1d,0x10,0x00,0xc1,0xdf,0x43,0x0c,0x41,0x1a,0xcc,0x47,0x63,0xff,0x00,0x0c,0x0c,0xe4,0x2d,0x91,0x00,0x17,0xf8,0x1c,0x3c,0x00,0x71,0x09,0xc7,0xfc,0x0d,0x30,0x06,0x7f,0x3f,0xea,0x11,0x07,0x78,0x3b,0xc1,0xd6,}; +const uint8_t *_I_Certification2_119x30[] = {_I_Certification2_119x30_0}; + const uint8_t _A_BadBattery_128x51_0[] = {0x01,0x00,0xa4,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0x1f,0xf4,0x78,0x1d,0x9e,0x0c,0x1d,0xc4,0x1f,0x93,0x08,0x05,0x00,0x1f,0x91,0xf0,0x10,0xc0,0x81,0xd5,0x80,0x8d,0x80,0xc6,0x18,0x0f,0xb0,0x19,0x46,0x01,0xf5,0xc0,0x21,0x20,0x02,0x49,0x87,0x20,0x04,0xa5,0xc0,0x27,0x16,0x00,0x2a,0x42,0x00,0xa8,0x1b,0x31,0x18,0xc7,0x22,0xf9,0x9c,0xa4,0xe3,0xdd,0xdc,0x98,0xc6,0x41,0xed,0xa0,0xda,0x69,0x72,0x94,0x8a,0x4d,0x4a,0x95,0x25,0x07,0xa7,0x82,0x01,0x98,0xaa,0x6f,0x7a,0xe0,0xf2,0xbd,0x49,0xe0,0x11,0x00,0x79,0x7c,0x03,0xe3,0x16,0xc2,0xed,0x29,0x14,0xda,0xd4,0x2a,0x4b,0x01,0x07,0xac,0x72,0x2b,0xb9,0xca,0x4c,0x29,0x5d,0x4b,0x8c,0x64,0x1e,0x9d,0x88,0x09,0xed,0xd3,0xa2,0x0f,0x19,0xfc,0x03,0xff,0x0f,0x45,0xcc,0x43,0x01,0x7f,0xf0,0x40,0x4f,0x4a,0x00,0x48,0x87,0xc3,0x66,0x04,0x1a,0x80,0x3e,0xb3,0x1f,0x75,0x03,0x83,0xd6,0x19,0x5f,0x1c,0x2c,0x70,0x1e,0xd0,0x8b,0x60,0x10,0x6f,0xc0,0x82,0x81,0x03,0xda,0x71,0x38,0x79,0x8c,0x0c,0x10,0x5c,0xeb,0x8f,0x9e,0x24,0xd5,0x3b,0x04,0x38,0x5c,0x2b,0x43,0x5e,0x0e,0x48,0x1e,0x81,0xc3,0x07,0xb4,0x79,0xea,0xd0,0x49,0x80,0x3c,0xed,0x5d,0x20,0xf9,0xab,0xcb,0x01,0x07,0xfe,0x28,0x0b,0x99,0x51,0xd1,0x03,0xd9,0xdc,0x3f,0x7f,0xfc,0x1c,0xe6,0x80,0x01,0x9f,0x83,0xca,0x61,0x80,0xf0,0xc3,0xe1,0x80,0xf5,0xc0,0x48,0x41,0xe5,0x1c,0xb0,0x0f,0xc5,0xcc,0x60,0x02,0xe0,0x48,0x01,0x07,0x30,0x2c,0x08,0x3d,0xac,0x00,0xf4,0xc0,0x13,0x84,0x1e,0xd3,0x00,0x7a,0x3c,0x06,0x01,0x18,0x07,0xac,0x62,0x40,0x7a,0x35,0x88,0xa1,0x90,0x00,0x50,0xc1,0x80,0xa4,0xd6,0x08,0x0f,0x58,0x36,0x00,0x1e,0x48,0xd3,0x83,0x03,0xd6,0x07,0x80,0xb0,0x37,0x4b,0xf0,0xa2,0x20,0x7a,0xc0,0x70,0x18,0x02,0x98,0x83,0x46,0x07,0xf1,0x78,0x98,0x3d,0x38,0x10,0x14,0xd0,0xbe,0xc6,0x1e,0xf4,0x11,0x7b,0x1a,0xc4,0x74,0x57,0x83,0x11,0x80,0x0e,0x05,0x80,0xd0,0x1e,0xc5,0x2c,0x4d,0x32,0x07,0xb4,0x80,0x1e,0x6c,0xb1,0x28,0x31,0xbc,0x81,0xeb,0x00,0x9e,0x03,0xd2,0x08,0x0f,0x51,0xe9,0x60,0x27,0xe1,0xf6,0x34,0x8f,0xc3,0xfe,0x90,0x24,0x30,0xc7,0xc0,0x85,0x0e,0xa0,0x48,0x15,0x23,0x18,0x17,0x10,0x00,0xbf,0xc4,0x21,0x3e,0x08,0x08,0x4f,0xc2,0xc4,0x12,0xe2,0xff,0x20,0xf7,0x01,0xb9,0x33,0x06,0x3c,0xec,0x60,0x80,0x8c,0x8b,0x01,0x10,0x80,0x59,0x13,0x8c,0x44,0x38,0x00,}; const uint8_t _A_BadBattery_128x51_1[] = {0x01,0x00,0xc3,0x01,0x80,0x7c,0x38,0x30,0xf0,0x7e,0x46,0x20,0x13,0x80,0x75,0xe0,0x03,0xa3,0x20,0x07,0xdf,0x82,0x0c,0x03,0x18,0x08,0x3e,0x83,0x87,0x03,0x07,0xd4,0xc0,0x06,0x42,0x22,0x00,0x44,0x40,0x06,0x50,0xc0,0x7d,0x42,0x00,0x6c,0x0f,0xb3,0x90,0x83,0xf4,0x66,0x60,0x07,0x82,0x03,0xe2,0xe0,0x0f,0x85,0x02,0x91,0x54,0x1e,0x73,0xc8,0x04,0x72,0x2f,0x99,0xca,0x4e,0x3d,0xdd,0xc9,0x8c,0x64,0x1e,0xda,0x0d,0xa6,0x97,0x29,0x48,0xa4,0xd4,0xa9,0x52,0x50,0x78,0xf0,0x18,0x03,0x76,0x80,0x66,0x2a,0x9b,0xde,0xb8,0x3c,0xaf,0x52,0x70,0x78,0xf8,0x23,0xfc,0x0f,0xfc,0x0f,0x41,0x16,0xc2,0xed,0x29,0x14,0xda,0xd4,0x2a,0x4b,0x01,0x82,0x7f,0x25,0x97,0x88,0x04,0x0a,0x39,0x15,0xdc,0xe5,0x26,0x14,0xae,0xa5,0xc6,0x32,0x0f,0x1f,0x34,0xf4,0xa8,0xa0,0x02,0xa0,0x3f,0x44,0x14,0x3c,0x38,0xba,0x82,0x01,0xe2,0x1a,0x28,0x14,0x6d,0x41,0x90,0x28,0x74,0x3a,0x01,0xf0,0x8f,0x83,0xeb,0x31,0x03,0x80,0x7f,0x01,0xf7,0xf0,0x01,0x8f,0xfa,0x7e,0x08,0x28,0xe0,0x3d,0x80,0x65,0xff,0x90,0x82,0x18,0x0c,0xbc,0x00,0xf1,0xc0,0x39,0xd7,0x1f,0x3c,0x48,0x1e,0xbf,0x08,0x39,0x7c,0xd7,0x83,0x92,0x07,0xb7,0xf2,0x01,0xf8,0x61,0x88,0x3c,0xe3,0xc0,0xf5,0x9f,0x10,0x07,0xfe,0x0f,0x2b,0x57,0x48,0x3e,0xb8,0x08,0x3e,0x03,0xff,0x81,0x80,0xc0,0x39,0x95,0x1d,0x14,0x4b,0x80,0x06,0x10,0x78,0xf8,0x20,0x3e,0x04,0x10,0x81,0x85,0x58,0x76,0x00,0x78,0xc1,0xa0,0x12,0x08,0x05,0xe8,0x4c,0x60,0xf3,0x98,0x01,0x85,0xb4,0x6b,0x11,0x3e,0xb4,0x60,0x3a,0x20,0xf2,0x20,0x08,0x0c,0x46,0x22,0x00,0x38,0x40,0x3c,0x61,0x80,0x51,0xf0,0x04,0xc8,0x70,0x20,0x03,0x86,0x09,0x8f,0xf1,0xff,0x0f,0x8e,0x01,0x58,0xb0,0x60,0x78,0xc6,0x0a,0x24,0xde,0x1e,0x03,0xf1,0xe0,0x13,0xcc,0x00,0xa8,0x6e,0x03,0x21,0x1f,0xac,0x0e,0xf1,0x00,0x9a,0x06,0x89,0x0c,0x33,0xe1,0x20,0x80,0x0e,0x02,0x0c,0x19,0xa0,0x1c,0xfc,0xf0,0x11,0xb0,0x83,0xd0,0x42,0x32,0x40,0x39,0xb4,0x46,0x60,0x2f,0x58,0x04,0x70,0x1e,0x90,0x81,0x91,0x13,0xd2,0x01,0x10,0x07,0xb4,0x01,0x26,0x40,0xf4,0xb2,0x01,0xcd,0xfc,0x44,0x04,0x4c,0x0c,0x42,0x88,0x05,0x1f,0xf7,0xfc,0x58,0x5e,0x04,0xfa,0x03,0xc7,0x90,0x9b,0x18,0x1b,0x4c,0xd8,0x86,0x37,0x28,0x86,0x21,0x36,0x47,0xc4,0x8e,0x00,0xca,0x20,0x36,0x18,0x42,0x0c,0x70,0x25,0xb4,0x18,0x19,0xd4,0x79,0x90,0x88,0x1d,0xc3,0xcc,0xbc,0x51,0x81,0x58,0x11,0x23,0x18,0x83,0x46,0x27,0x80,0xf5,0xfc,0x35,0x8e,0x09,0x10,0xce,0x1b,0x08,0x00,0xbe,0x08,0xfd,0xf0,0x84,0x60,0x0d,}; const uint8_t *_A_BadBattery_128x51[] = {_A_BadBattery_128x51_0,_A_BadBattery_128x51_1}; @@ -16,10 +16,10 @@ const uint8_t _A_BoxActive_128x51_0[] = {0x01,0x00,0x61,0x01,0x00,0x78,0x03,0xe0 const uint8_t _A_BoxActive_128x51_1[] = {0x01,0x00,0x8d,0x01,0x00,0x78,0x03,0xe0,0x1f,0x08,0x08,0x26,0x20,0x00,0xa3,0x84,0x47,0x81,0xef,0x10,0x80,0x83,0xce,0x09,0xe0,0x10,0x3c,0x43,0x33,0x33,0x83,0x83,0xca,0x01,0x0e,0x80,0x70,0x2f,0xe2,0xf4,0x92,0x52,0x43,0x45,0x02,0x0b,0x8c,0x02,0x61,0x80,0x04,0x14,0x3e,0x21,0x3c,0xbc,0x83,0xd2,0x40,0x43,0x18,0x04,0x18,0x9a,0x51,0x08,0x24,0x24,0x1e,0x5f,0xf8,0x08,0x3c,0x46,0x62,0x11,0x11,0xa8,0xc4,0x23,0x13,0x10,0x79,0x40,0x61,0xc0,0xf1,0x19,0x90,0xc4,0xc0,0x09,0x01,0x98,0x03,0xce,0x41,0x40,0x07,0x36,0x00,0xb8,0x31,0x14,0x39,0x50,0x02,0x82,0x0f,0x78,0x04,0x58,0x1e,0x69,0x47,0x07,0x94,0x60,0x1e,0x40,0x62,0x07,0xc1,0x6c,0x41,0xe9,0x88,0x04,0x15,0x02,0x10,0x0f,0x60,0x11,0x52,0x01,0xe6,0x38,0x30,0x30,0xe0,0x4c,0x02,0x0f,0x19,0x47,0x33,0x97,0x24,0xac,0xc2,0x81,0xe9,0x55,0x8a,0xc0,0x19,0x23,0x18,0x89,0x4a,0xa4,0xb4,0x58,0x48,0x3d,0x35,0x72,0xa8,0x04,0x68,0x3e,0x39,0x29,0x4c,0x97,0x93,0x08,0x07,0x8e,0x01,0x5a,0x3f,0xf8,0xbc,0x02,0xc8,0x3f,0x1a,0x94,0xa2,0x4b,0x51,0x84,0xa1,0xc6,0x80,0x0f,0x29,0x7c,0x03,0x09,0x01,0xc4,0x0f,0xc7,0xb1,0x4c,0x85,0x03,0xc7,0x81,0x3f,0x80,0x7f,0x83,0xe3,0x08,0x29,0x08,0x01,0x01,0xe3,0x20,0xe0,0x40,0xff,0xd0,0xa7,0x61,0x03,0xe0,0x3c,0x35,0x78,0x28,0x3c,0x4a,0xa2,0x0f,0x69,0x83,0x78,0x4b,0xc2,0x07,0x18,0x80,0x3e,0x93,0xe4,0xe0,0x70,0x79,0x4a,0x01,0xfd,0x18,0xc1,0x24,0x8b,0x00,0xf1,0x60,0x79,0x42,0x01,0xe2,0x5c,0x10,0x7c,0xc8,0x21,0x18,0xe8,0x04,0x2c,0x10,0x38,0x10,0x7b,0xd8,0x3f,0x1f,0x3f,0x01,0xbc,0x41,0xf3,0xa0,0x6d,0x0f,0xfe,0x17,0x80,0x80,0x09,0x04,0x1e,0xc3,0xc2,0x80,0x41,0x41,0xe3,0x72,0x07,0xbb,0x3c,0xa0,0x18,0x2a,0x3a,0x10,0x43,0xf7,0x7e,0xbe,0x03,0xdc,0xcc,0x40,0xf2,0x81,0x20,0x04,0x1f,0x2c,0x92,0x80,0x83,0xfc,0x06,0x2b,0x32,0x07,0xf8,0x00,0xcd,0x02,0xfa,0x10,0x79,0x44,0x30,0x00,0xfe,0xb0,0x03,0xf3,0xc5,0x11,0x8e,0x03,0xd8,0x6e,0x48,0x22,0xc2,0x7f,0xb0,0x60,0xe6,0x07,0xad,0xe0,0x4e,0x60,0x05,0x3b,0x88,0xbc,0x8b,0xc2,0x0f,0xa8,0x60,0x3f,0x20,0x9c,0x08,0x18,0x3f,0x67,0x00,0x43,0x4b,0x98,0x01,0x63,0x10,0x70,0x7e,0xf8,0x08,0x8a,0x64,0x20,0x05,0x03,0xe4,}; const uint8_t *_A_BoxActive_128x51[] = {_A_BoxActive_128x51_0,_A_BoxActive_128x51_1}; -const uint8_t _A_Box_128x51_0[] = {0x01,0x00,0x1f,0x01,0x00,0x7c,0x03,0xf1,0xff,0x83,0x83,0xf2,0x09,0x00,0x84,0x03,0xf2,0x05,0x00,0x88,0x03,0xf2,0x03,0x00,0x90,0x03,0xfc,0x08,0x38,0x0b,0xf8,0x3f,0x6c,0x18,0x00,0x30,0x83,0xee,0x30,0x46,0x20,0x03,0x7f,0x7f,0xf2,0xf3,0x21,0x80,0x44,0x00,0xd0,0x38,0x04,0xc0,0xc8,0x67,0x48,0x17,0xa0,0x10,0x41,0xfe,0x84,0x80,0x7f,0x83,0xcf,0x00,0x06,0x10,0x7f,0xa9,0x20,0x1f,0xe0,0xf4,0xaa,0x83,0xfb,0x55,0x02,0x07,0xed,0xfe,0x0b,0x40,0x07,0xe7,0xfe,0x04,0x0f,0xce,0x07,0xfc,0x3f,0x9c,0x0f,0x87,0xfe,0x07,0xc0,0x07,0xd4,0x82,0x13,0x40,0x80,0x9c,0x88,0x1f,0x11,0x08,0x50,0x18,0x70,0x00,0x71,0x07,0xc4,0x22,0x18,0x0f,0x27,0x90,0x83,0xe2,0x09,0x1c,0x07,0x94,0x10,0x1f,0x30,0x29,0xd0,0x3c,0xa1,0x00,0xfa,0xef,0xc1,0xc1,0xe2,0xe0,0x70,0x79,0x60,0xbf,0xff,0xf2,0xf8,0xac,0x1c,0x1e,0x5c,0x29,0xfd,0x60,0x1f,0x9a,0x48,0xde,0x80,0x5e,0x2a,0x07,0x07,0x95,0x62,0x3b,0x60,0x0f,0x88,0x3e,0xb6,0x10,0xac,0x06,0x07,0x00,0xa0,0x70,0x79,0x58,0x21,0xb0,0x0a,0x10,0x3e,0xf0,0x10,0xf8,0x04,0xf8,0x1c,0x2b,0x06,0x77,0x9c,0x7e,0x01,0x02,0x07,0xe4,0x68,0x0a,0x38,0x08,0x38,0x3e,0xae,0x80,0x51,0xd0,0x46,0x01,0xf5,0xe8,0x16,0x8e,0x82,0x40,0x0f,0x30,0x19,0x03,0xcf,0xe1,0x43,0x80,0x64,0x38,0x05,0xf9,0x80,0x70,0x24,0xe0,0xf1,0x07,0x30,0x3d,0x20,0x17,0xe8,0x06,0x20,0x1f,0x9b,0xe8,0x0e,0x10,0x1f,0x95,0x68,0x36,0x0c,0x1f,0x92,0xaf,0xc2,0xb9,0xc1,0xeb,0x16,0x77,0x88,0x3f,0x21,0x40,0xf9,0x81,0x40,0x22,0x00,0x43,0x07,0xc4,0x12,0x01,0x08,0x07,0xe7,0xe3,0xff,0x07,0x07,0xe0,0xd1,0x81,0xee,}; -const uint8_t _A_Box_128x51_1[] = {0x01,0x00,0x40,0x01,0x00,0x78,0x03,0xe0,0x1f,0x08,0x08,0x3f,0x61,0x11,0xe0,0x7e,0xc1,0x3c,0x02,0x0d,0x82,0x40,0x21,0xd0,0x0e,0x05,0xfc,0x1f,0x30,0x28,0x04,0x42,0x01,0x30,0xc0,0x08,0xe4,0x1e,0x32,0x02,0x18,0xc0,0x20,0xc0,0xf8,0xff,0xc0,0x41,0xe2,0x33,0x10,0x88,0x80,0x1e,0x03,0x0e,0x07,0x88,0xcc,0xc1,0xf1,0x30,0x07,0x98,0x0c,0x40,0x0d,0x80,0x2e,0x0c,0x44,0x26,0x30,0x0a,0x00,0x3e,0x60,0x11,0x60,0x7f,0x46,0x01,0xe4,0x06,0x20,0x7c,0x16,0xc4,0x1f,0xe8,0xd2,0x48,0x38,0xe0,0x81,0xe3,0x81,0x30,0x08,0x3f,0x2a,0xb1,0x58,0x04,0x1c,0x1f,0x7a,0xb9,0x54,0x02,0x34,0x0f,0x8c,0x02,0xb4,0x7f,0xf1,0x78,0x05,0x90,0x1e,0xc9,0x81,0xa0,0x03,0xca,0x5f,0x00,0xc2,0x10,0x18,0x1e,0x3c,0x09,0xfc,0x03,0xfc,0x1f,0x18,0x41,0x48,0x41,0xed,0x20,0xe0,0x40,0xff,0xd0,0xa6,0x80,0x89,0x44,0x1e,0xe1,0xe1,0xab,0xc1,0x41,0xe2,0xf1,0x60,0x68,0xcc,0x1b,0xc2,0x5e,0x10,0x38,0xbc,0x58,0x1e,0x84,0xb2,0xa0,0x3c,0x58,0x1e,0x52,0x80,0x7f,0x46,0x30,0x49,0x22,0xc0,0x3c,0x58,0x1e,0x50,0x80,0x78,0x97,0x04,0x1f,0x32,0x08,0x46,0x3a,0x01,0x0b,0x04,0x0e,0x04,0x1e,0xf6,0x0f,0xc7,0xcf,0xc0,0x6f,0x10,0x7c,0xe8,0x1b,0x43,0xff,0x85,0xe0,0x20,0x02,0x41,0x07,0xb0,0xf0,0xa0,0x10,0x50,0x78,0xdc,0x99,0xf5,0x00,0xc1,0x51,0xd0,0x82,0x1f,0xbb,0xf5,0xf0,0x1e,0xe6,0x62,0x07,0x94,0x09,0x00,0x20,0xf9,0x64,0x94,0x04,0x1f,0xe0,0x31,0x59,0x90,0x3f,0xc1,0xa6,0x68,0x17,0xd0,0x83,0xca,0x21,0x80,0x0f,0xb0,0x3d,0xec,0x00,0xfc,0xf1,0x44,0x63,0x80,0xf6,0x1b,0x92,0x08,0xb0,0x9f,0xec,0x18,0x39,0x81,0xeb,0x78,0x13,0x98,0x01,0x4e,0xe2,0x2f,0x22,0xf0,0x83,0xea,0x18,0x0f,0xc8,0x27,0x02,0x06,0x0f,0xd9,0xc0,0x10,0xd2,0xe6,0x00,0x58,0xc4,0x1c,0x1f,0xbe,0x02,0x22,0x99,0x08,0x01,0x40,0xf9,}; -const uint8_t _A_Box_128x51_2[] = {0x01,0x00,0xf9,0x00,0x00,0x7c,0x03,0xf1,0xff,0x83,0x83,0xf2,0x09,0x00,0x84,0x03,0xf2,0x05,0x00,0x88,0x03,0xf2,0x03,0x00,0x90,0x03,0xfc,0x08,0x38,0x0b,0xf8,0x3f,0x6c,0x18,0x00,0x30,0x83,0xee,0x30,0x46,0x20,0x03,0x7f,0x7f,0xf2,0xf3,0x21,0x80,0x44,0x00,0xd0,0x38,0x04,0xc0,0xc8,0x67,0x48,0x17,0xa0,0x10,0x41,0xfe,0x84,0x80,0x7f,0x83,0xcf,0x00,0x06,0x10,0x7f,0xa9,0x20,0x1f,0xe0,0xf4,0xaa,0x83,0xfb,0x54,0x0f,0xea,0xfc,0x06,0x80,0x0f,0xcd,0xfc,0x00,0x1f,0x9c,0x07,0x70,0x83,0xf2,0x61,0x54,0x31,0x18,0x3e,0x57,0x85,0xa0,0x07,0xf7,0x00,0x1f,0xc2,0xfb,0xc0,0x45,0xc0,0xe8,0x0f,0x8a,0x04,0xe0,0x0e,0x50,0x20,0x7c,0xc8,0x3c,0x10,0x70,0x38,0xc1,0x01,0xf3,0x10,0xa0,0x5f,0x80,0xe2,0x43,0x20,0x7c,0x60,0x2a,0xc0,0x71,0x88,0x03,0xe4,0x34,0x32,0xb0,0x7f,0x07,0xc9,0xc0,0xe0,0xf4,0x95,0x21,0x4c,0x7f,0x30,0x0e,0xb8,0x1c,0x5a,0x0e,0x0f,0x2d,0x06,0x01,0x00,0x40,0xfa,0xe0,0x50,0x40,0xe4,0xb0,0x32,0x99,0x8e,0x4e,0x46,0x0f,0x66,0x7b,0xcd,0xc1,0xc5,0x83,0x07,0xd4,0x7c,0x1e,0x58,0xc0,0x7d,0x4f,0xc1,0xe5,0x90,0x07,0xd2,0xf8,0x5e,0x63,0x60,0x07,0xd7,0xe0,0xb2,0x24,0xe7,0x07,0xa7,0x82,0x03,0x08,0x07,0xe4,0x02,0x0f,0x06,0x07,0xef,0xfa,0x02,0x0f,0xd8,0xb2,0x3a,0x01,0xeb,0x0a,0x07,0xcc,0x09,0x6a,0x60,0x41,0x07,0xc4,0x12,0x00,0xfe,0x10,0x7d,0xfe,0x3f,0xf0,0x70,0x7e,0x0d,0x18,0x1e,0xe0,}; -const uint8_t _A_Box_128x51_3[] = {0x01,0x00,0x3c,0x01,0x00,0x78,0x03,0xe0,0x1f,0x08,0x08,0x3f,0x61,0x11,0xe0,0x7e,0xc1,0x3c,0x02,0x0d,0x82,0x40,0x21,0xd0,0x0e,0x05,0xfc,0x1f,0x30,0x28,0x04,0x42,0x01,0x30,0xc0,0x08,0xe4,0x1e,0x32,0x02,0x18,0xc0,0x20,0xc0,0xf8,0xff,0xc0,0x41,0xe2,0x33,0x10,0x88,0x80,0x1e,0x03,0x0e,0x07,0x88,0xcc,0xc1,0xf1,0x30,0x07,0x98,0x0c,0x40,0x0d,0x80,0x2e,0x0c,0x44,0x26,0x30,0x0a,0x00,0x3e,0x60,0x11,0x60,0x7f,0x46,0x01,0xe4,0x06,0x20,0x7c,0x16,0xc4,0x1f,0xe8,0xd2,0x48,0x38,0xe0,0x81,0xe3,0x81,0x30,0x08,0x3f,0x2a,0xb1,0x58,0x04,0x1c,0x1f,0x7a,0xb9,0x54,0x02,0x34,0x0f,0x8c,0x02,0xb4,0x7f,0xf1,0x78,0x05,0x90,0x1e,0xc9,0x81,0xa0,0x03,0xca,0x5f,0x00,0xc2,0x10,0x18,0x1e,0x3c,0x09,0xfc,0x03,0xfc,0x1f,0x18,0x41,0x48,0x41,0xed,0x20,0xe0,0x40,0xff,0xd0,0xa6,0x80,0x89,0x44,0x1e,0xe1,0xe1,0xff,0xdf,0xc1,0xe2,0xf1,0x60,0x68,0xcc,0x1b,0xc4,0x07,0x27,0x8b,0x03,0xde,0x80,0xf1,0x60,0x79,0x4a,0x01,0xfd,0x18,0x07,0x9e,0x01,0xe2,0xc0,0xf2,0x35,0x20,0x3e,0x64,0x10,0x88,0x70,0x20,0xf0,0x20,0xf7,0xb0,0x7e,0x3e,0x60,0xfc,0xd0,0x36,0x85,0x42,0x20,0x01,0xc7,0x83,0xde,0x00,0x99,0x15,0x08,0x81,0x46,0xe2,0xcf,0xa5,0x08,0x88,0xc5,0x9f,0x01,0xf2,0x80,0x55,0x20,0xa0,0xf7,0x33,0x10,0x3c,0x7c,0x1a,0xf3,0x90,0x83,0xe5,0x92,0x35,0x0a,0xf8,0x34,0x41,0xf7,0xb0,0x97,0x81,0x44,0x1f,0x75,0x88,0xf8,0x3d,0x81,0xa3,0x80,0x02,0x0b,0xa4,0x75,0x12,0xa0,0xfc,0x03,0xd2,0xb1,0x1d,0x07,0xee,0xa2,0x34,0x0f,0x80,0x39,0x20,0x84,0x3e,0x41,0x72,0x07,0xce,0xc2,0x3c,0x0f,0x94,0x48,0x8b,0xc7,0x81,0x13,0x07,0xdc,0x30,0xe4,0x60,0xf8,0x82,0x37,0x0c,0x1f,0x73,0x80,0x21,0xa5,0xcc,0x00,0xb1,0x87,0x50,0x83,0xf3,0xc0,0x44,0x57,0xb9,0x00,0x28,0x1f,0x20,}; +const uint8_t _A_Box_128x51_0[] = {0x01,0x00,0x1c,0x01,0x00,0x7c,0x03,0xf1,0xff,0x83,0x83,0xf2,0x09,0x00,0x84,0x03,0xf2,0x05,0x00,0x88,0x03,0xf2,0x03,0x00,0x90,0x03,0xfc,0x08,0x38,0x0b,0xf8,0x3f,0x6c,0x18,0x00,0x30,0x83,0xee,0x30,0x46,0x20,0x03,0x7f,0x7f,0xf2,0xf3,0x21,0x80,0x44,0x00,0xd0,0x38,0x04,0xc0,0xc8,0x67,0x48,0x17,0xa0,0x10,0x41,0xfe,0x84,0x80,0x7f,0x83,0xcf,0x00,0x06,0x10,0x7f,0xa9,0x20,0x1f,0xe0,0xf4,0xaa,0x83,0xfb,0x55,0x02,0x07,0xed,0xfe,0x0b,0x40,0x07,0xe7,0xfe,0x04,0x0f,0xce,0x07,0xfc,0x3f,0x9c,0x0f,0x87,0xfe,0x07,0xc0,0x07,0xd4,0x82,0x13,0x40,0x80,0x9c,0x88,0x1f,0x11,0x08,0x50,0x18,0x70,0x00,0x71,0x07,0xc4,0x22,0x18,0x0f,0x27,0x90,0x83,0xe2,0x09,0x1c,0x07,0x94,0x10,0x1f,0x30,0x29,0xd0,0x3c,0xa1,0x00,0xfa,0xef,0xc1,0xc1,0xe2,0xe0,0x70,0x79,0x60,0xbf,0xff,0xf2,0xf8,0xac,0x1c,0x1e,0x5c,0x29,0xfd,0x60,0x1f,0x9a,0x48,0xde,0x80,0x5e,0x2a,0x07,0x07,0x95,0x62,0x3b,0x60,0x0f,0x88,0x3e,0xb6,0x10,0xac,0x06,0x07,0x00,0xa0,0x70,0x79,0x58,0x21,0xb0,0x0a,0x10,0x3e,0xf0,0x10,0xf8,0x04,0xf8,0x1c,0x2b,0x06,0x77,0x9c,0x7e,0x01,0x02,0x07,0xe4,0x68,0x0a,0x38,0x08,0x38,0x3e,0xae,0x80,0x51,0xd0,0x46,0x01,0xf5,0xe8,0x16,0x8e,0x82,0x40,0x0f,0xaf,0x85,0x0e,0x01,0x90,0xe0,0x17,0xe6,0x01,0xc0,0x93,0x83,0xc4,0x1c,0xc0,0xf4,0x80,0x5f,0xa0,0x18,0x80,0x7e,0x6f,0xa0,0x38,0x40,0x7e,0x55,0xa0,0xd8,0x30,0x7e,0x4a,0xbf,0x0a,0xe7,0x07,0xac,0x59,0xde,0x20,0xfc,0x85,0x03,0xe6,0x05,0x00,0x88,0x01,0x0c,0x1f,0x10,0x48,0x04,0x20,0x1f,0x9f,0x8f,0xfc,0x1c,0x1f,0x83,0x46,0x07,0xb8,}; +const uint8_t _A_Box_128x51_1[] = {0x01,0x00,0x3f,0x01,0x00,0x78,0x03,0xe0,0x1f,0x08,0x08,0x3f,0x61,0x11,0xe0,0x7e,0xc1,0x3c,0x02,0x0d,0x82,0x40,0x21,0xd0,0x0e,0x05,0xfc,0x1f,0x30,0x28,0x04,0x42,0x01,0x30,0xc0,0x08,0xe4,0x1e,0x32,0x02,0x18,0xc0,0x20,0xc0,0xf8,0xff,0xc0,0x41,0xe2,0x33,0x10,0x88,0x80,0x1e,0x03,0x0e,0x07,0x88,0xcc,0xc1,0xf1,0x30,0x07,0x98,0x0c,0x40,0x0d,0x80,0x2e,0x0c,0x44,0x26,0x30,0x0a,0x00,0x3e,0x60,0x11,0x60,0x7f,0x46,0x01,0xe4,0x06,0x20,0x7c,0x16,0xc4,0x1f,0xe8,0xd2,0x48,0x38,0xe0,0x81,0xe3,0x81,0x30,0x08,0x3f,0x2a,0xb1,0x58,0x04,0x1c,0x1f,0x7a,0xb9,0x54,0x02,0x34,0x0f,0x8c,0x02,0xb4,0x7f,0xf1,0x78,0x05,0x90,0x1e,0xc9,0x81,0xa0,0x03,0xca,0x5f,0x00,0xc2,0x10,0x18,0x1e,0x3c,0x09,0xfc,0x03,0xfc,0x1f,0x18,0x41,0x48,0x41,0xed,0x20,0xe0,0x40,0xff,0xd0,0xa6,0x80,0x89,0x44,0x1e,0xe1,0xe1,0xab,0xc1,0x41,0xe2,0xf1,0x60,0x68,0xcc,0x1b,0xc2,0x5e,0x10,0x38,0xbc,0x58,0x1e,0x84,0xb2,0xa0,0x3c,0x58,0x1e,0x52,0x80,0x7f,0x46,0x30,0x49,0x22,0xc0,0x3c,0x58,0x1e,0x50,0x80,0x78,0x97,0x04,0x1f,0x32,0x08,0x46,0x3a,0x01,0x0b,0x04,0x0e,0x04,0x1e,0xf6,0x0f,0xc7,0xcf,0xc0,0x6f,0x10,0x7c,0xe8,0x1b,0x43,0xff,0x85,0xe0,0x20,0x02,0x41,0x07,0xb0,0xf0,0xa0,0x10,0x50,0x78,0xdc,0x99,0xf5,0x00,0xc1,0x51,0xd0,0x82,0x1f,0xbb,0xf5,0xf0,0x1e,0xe6,0x62,0x07,0x94,0x09,0x00,0x20,0xf9,0x64,0x94,0x04,0x1f,0xe0,0x31,0x59,0x90,0x3f,0xc0,0x06,0x68,0x17,0xd0,0x83,0xca,0x21,0x80,0x07,0xf5,0x80,0x1f,0x9e,0x28,0x8c,0x70,0x1e,0xc3,0x72,0x41,0x16,0x13,0xfd,0x83,0x07,0x30,0x3d,0x6f,0x02,0x73,0x00,0x29,0xdc,0x45,0xe4,0x5e,0x10,0x7d,0x43,0x01,0xf9,0x04,0xe0,0x40,0xc1,0xfb,0x38,0x02,0x1a,0x5c,0xc0,0x0b,0x18,0x83,0x83,0xf7,0xc0,0x44,0x53,0x21,0x00,0x28,0x1f,0x20,}; +const uint8_t _A_Box_128x51_2[] = {0x01,0x00,0xf6,0x00,0x00,0x7c,0x03,0xf1,0xff,0x83,0x83,0xf2,0x09,0x00,0x84,0x03,0xf2,0x05,0x00,0x88,0x03,0xf2,0x03,0x00,0x90,0x03,0xfc,0x08,0x38,0x0b,0xf8,0x3f,0x6c,0x18,0x00,0x30,0x83,0xee,0x30,0x46,0x20,0x03,0x7f,0x7f,0xf2,0xf3,0x21,0x80,0x44,0x00,0xd0,0x38,0x04,0xc0,0xc8,0x67,0x48,0x17,0xa0,0x10,0x41,0xfe,0x84,0x80,0x7f,0x83,0xcf,0x00,0x06,0x10,0x7f,0xa9,0x20,0x1f,0xe0,0xf4,0xaa,0x83,0xfb,0x54,0x0f,0xea,0xfc,0x06,0x80,0x0f,0xcd,0xfc,0x00,0x1f,0x9c,0x07,0x70,0x83,0xf2,0x61,0x54,0x31,0x18,0x3e,0x57,0x85,0xa0,0x07,0xf7,0x00,0x1f,0xc2,0xfb,0xc0,0x45,0xc0,0xe8,0x0f,0x8a,0x04,0xe0,0x0e,0x50,0x20,0x7c,0xc8,0x3c,0x10,0x70,0x38,0xc1,0x01,0xf3,0x10,0xa0,0x5f,0x80,0xe2,0x43,0x20,0x7c,0x60,0x2a,0xc0,0x71,0x88,0x03,0xe4,0x34,0x32,0xb0,0x7f,0x07,0xc9,0xc0,0xe0,0xf4,0x95,0x21,0x4c,0x7f,0x30,0x0e,0xb8,0x1c,0x5a,0x0e,0x0f,0x2d,0x06,0x01,0x00,0x40,0xfa,0xe0,0x50,0x40,0xe4,0xb0,0x71,0xc9,0xc8,0xc1,0xfd,0x37,0x07,0x16,0x0c,0x1f,0x51,0xf0,0x79,0x63,0x01,0xf5,0x3f,0x07,0x96,0x40,0x1f,0x4b,0xe1,0x79,0x8d,0x80,0x1f,0x5f,0x85,0x68,0x93,0x9c,0x1e,0x9e,0x08,0x0c,0x20,0x1f,0x90,0x08,0x3c,0x18,0x1f,0xbf,0xe8,0x08,0x3f,0x62,0xc8,0xe8,0x07,0xac,0x28,0x1f,0x30,0x22,0xd8,0x81,0x0c,0x1f,0x10,0x48,0x03,0xf8,0x41,0xf7,0xf8,0xff,0xc1,0xc1,0xf8,0x34,0x60,0x7b,0x80,}; +const uint8_t _A_Box_128x51_3[] = {0x01,0x00,0x37,0x01,0x00,0x78,0x03,0xe0,0x1f,0x08,0x08,0x3f,0x61,0x11,0xe0,0x7e,0xc1,0x3c,0x02,0x0d,0x82,0x40,0x21,0xd0,0x0e,0x05,0xfc,0x1f,0x30,0x28,0x04,0x42,0x01,0x30,0xc0,0x08,0xe4,0x1e,0x32,0x02,0x18,0xc0,0x20,0xc0,0xf8,0xff,0xc0,0x41,0xe2,0x33,0x10,0x88,0x80,0x1e,0x03,0x0e,0x07,0x88,0xcc,0xc1,0xf1,0x30,0x07,0x98,0x0c,0x40,0x0d,0x80,0x2e,0x0c,0x44,0x26,0x30,0x0a,0x00,0x3e,0x60,0x11,0x60,0x7f,0x46,0x01,0xe4,0x06,0x20,0x7c,0x16,0xc4,0x1f,0xe8,0xd2,0x48,0x38,0xe0,0x81,0xe3,0x81,0x30,0x08,0x3f,0x2a,0xb1,0x58,0x04,0x1c,0x1f,0x7a,0xb9,0x54,0x02,0x34,0x0f,0x8c,0x02,0xb4,0x7f,0xf1,0x78,0x05,0x90,0x1e,0xc9,0x81,0xa0,0x03,0xca,0x5f,0x00,0xc2,0x10,0x18,0x1e,0x3c,0x09,0xfc,0x03,0xfc,0x1f,0x18,0x41,0x48,0x41,0xed,0x20,0xe0,0x40,0xff,0xd0,0xa6,0x80,0x89,0x44,0x1e,0xe1,0xe1,0xff,0xdf,0xc1,0xe2,0xf1,0x60,0x68,0xcc,0x1b,0xc4,0x07,0x27,0x8b,0x03,0xde,0x80,0xf1,0x60,0x79,0x4a,0x01,0xfd,0x18,0x07,0x9e,0x01,0xe2,0xc0,0xf2,0x35,0x20,0x3e,0x64,0x10,0x88,0x70,0x20,0xf0,0x20,0xf7,0xb0,0x7e,0x3e,0x60,0xfc,0xd0,0x36,0x85,0x42,0x20,0x01,0xc7,0x83,0xde,0x00,0x99,0x15,0x08,0x81,0x46,0xe2,0xcf,0xa5,0x08,0x88,0xc5,0x9f,0x01,0xf2,0x80,0x55,0x20,0xa0,0xf7,0x33,0x10,0x3c,0x7c,0x1a,0xf3,0x90,0x83,0xe5,0x92,0x35,0x0a,0xf8,0x34,0x41,0xf7,0xb0,0x97,0x81,0x44,0x1f,0x75,0x88,0xf8,0x3e,0x30,0x00,0x21,0x74,0x8e,0xa2,0x54,0x0f,0xda,0xc4,0x74,0x3f,0xd1,0xa0,0x7c,0x01,0xc9,0x04,0x21,0xf2,0x0b,0x90,0x3e,0x76,0x11,0xe0,0x7c,0xa2,0x44,0x5e,0x3c,0x08,0x98,0x3e,0xe1,0x87,0x23,0x07,0xc4,0x11,0xb8,0x60,0xfb,0x9c,0x01,0x0d,0x2e,0x60,0x05,0x8c,0x3a,0x84,0x1f,0x9e,0x02,0x22,0xbd,0xc8,0x01,0x40,0xf9,}; const uint8_t *_A_Box_128x51[] = {_A_Box_128x51_0,_A_Box_128x51_1,_A_Box_128x51_2,_A_Box_128x51_3}; const uint8_t _A_CardBad_128x51_0[] = {0x01,0x00,0x01,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0xf8,0x07,0xfc,0x00,0x33,0xf0,0x75,0x60,0x01,0xe5,0x7f,0x07,0xde,0x4e,0x49,0x49,0xb9,0x03,0xfe,0x01,0x82,0x04,0x0c,0x4a,0x01,0x70,0x8f,0x01,0x46,0x08,0x0f,0x5e,0x30,0x24,0x60,0x50,0x0c,0x44,0x88,0x1f,0x1a,0xaa,0x64,0xeb,0xaf,0x71,0x84,0x48,0xb1,0x93,0xb8,0x39,0x3d,0x72,0x55,0x2a,0x50,0x04,0x6e,0x12,0x2a,0x96,0x28,0x3e,0x20,0xf4,0xc1,0x03,0xcf,0x01,0x22,0xa1,0x03,0xf0,0x7e,0x21,0xf9,0xc6,0x52,0xea,0x57,0x22,0xf8,0xe3,0x21,0x63,0xf6,0x00,0x1d,0x01,0x3f,0xd3,0x05,0x7f,0x83,0xfc,0x1f,0xe0,0xf5,0xcf,0xfc,0xee,0x77,0xe0,0x5b,0x7e,0x28,0x10,0x18,0x25,0x02,0x7f,0xf9,0x93,0x87,0xde,0x11,0x00,0x07,0x8e,0x82,0xff,0xfc,0xc7,0x83,0xe2,0xb9,0x19,0x83,0xf4,0x01,0xf5,0x78,0xa9,0x69,0x60,0x9f,0x01,0x7d,0xd4,0xb7,0xa0,0xf1,0x27,0xd0,0x3c,0x70,0xa0,0xf1,0x37,0xd0,0xfc,0xc1,0xf6,0x00,0x30,0x7f,0xf0,0x01,0xff,0xff,0x83,0xfe,0x01,0xfb,0xf9,0xf0,0x83,0xf6,0x19,0xc6,0x07,0xb0,0xe8,0xe0,0x34,0x0f,0xfc,0x1b,0x90,0x0f,0x69,0x80,0x0c,0xa0,0x5a,0x0f,0xfc,0xd8,0x1e,0xf1,0x80,0x19,0x41,0x3a,0x05,0xd1,0xfe,0x03,0xec,0xff,0x51,0x8b,0x84,0x8a,0x04,0x0f,0xcc,0x44,0x4a,0x0c,0x0f,0xd8,0x54,0x38,0x1f,0xb0,0x68,0xf0,0x7f,0xc7,0xfe,0x5f,0xf0,0x7e,0x1f,0xfc,0x1f,0xd3,0x85,0xf9,0x83,0xe8,0x14,0x70,0x1f,0x00,0x10,0xa7,0xe0,0xf5,0x05,0x18,0x25,0x40,0x1e,0x00,0xf0,0x07,0x80,0x28,}; @@ -107,8 +107,8 @@ const uint8_t _A_Level1ReadActive_128x51_0[] = {0x01,0x00,0x06,0x02,0x00,0x2e,0x const uint8_t _A_Level1ReadActive_128x51_1[] = {0x01,0x00,0x06,0x02,0x00,0x2e,0x03,0xff,0x03,0x07,0xe7,0x82,0x01,0x30,0x07,0xe4,0x72,0x01,0xc0,0x07,0xe4,0x18,0x04,0x30,0x10,0x10,0xfe,0x3f,0xff,0xfb,0xf8,0x3d,0x47,0xa5,0x07,0x21,0x8c,0x7c,0x0a,0x3b,0x82,0x72,0xc0,0x84,0x44,0x31,0x41,0xb2,0xf0,0x05,0x85,0x0c,0xa0,0x06,0x50,0x1e,0x96,0x00,0x19,0x43,0x2c,0x12,0x02,0x74,0x06,0x8e,0x11,0x20,0x90,0x83,0xe0,0xf8,0x71,0x89,0x07,0x83,0xb8,0x00,0x10,0x7a,0xc4,0x00,0x67,0x30,0x90,0x49,0x40,0x02,0x48,0x20,0xd9,0xf0,0x0d,0x43,0x10,0x88,0x03,0xea,0x40,0x4b,0x10,0xfd,0xc3,0x03,0x62,0x43,0x12,0xf8,0x83,0xca,0xaa,0x0f,0x69,0x70,0x3c,0x6f,0x0b,0xe9,0x07,0x8c,0xf6,0x01,0x38,0x9e,0x03,0xe6,0x09,0x90,0x9f,0x83,0xc7,0xdc,0x03,0x14,0xc0,0xa7,0xd6,0x09,0xf0,0x07,0x97,0xfe,0x1e,0xf7,0x2f,0xe0,0x3d,0x60,0x13,0xe6,0xc8,0xdf,0xfe,0x0e,0xe1,0xff,0xc1,0xc1,0xeb,0xe0,0x80,0xf8,0x25,0xfc,0x09,0xfb,0xf5,0xc1,0xe3,0x18,0x83,0xc7,0xae,0x84,0xe9,0x07,0x8c,0x22,0x19,0x00,0xf0,0x03,0xed,0xba,0x2f,0x91,0x4d,0x28,0x01,0x20,0x40,0x43,0x25,0x28,0x3e,0x44,0x82,0x00,0x88,0x18,0xf8,0x40,0x03,0x06,0x05,0xaf,0xfb,0xc2,0xeb,0x18,0x1c,0x78,0x48,0xb2,0x01,0x98,0xe0,0x20,0x73,0xf6,0xd8,0xc0,0x62,0x7d,0x84,0xe0,0xc0,0xd1,0xe5,0x30,0x07,0x8a,0xd0,0xe0,0x31,0x18,0x07,0xeb,0x8f,0x03,0xa0,0x02,0x86,0x4e,0x0f,0x3a,0x06,0x03,0x03,0xf1,0x8f,0xe6,0x3f,0xf0,0x1b,0x00,0x68,0x81,0xe7,0xc0,0xe0,0x01,0x06,0xa1,0x1b,0xe7,0x8f,0x44,0x34,0x40,0xf2,0xfc,0x7f,0xdc,0xa5,0x10,0x87,0xdf,0x3f,0xd2,0x10,0x78,0xe8,0x01,0xe3,0xe7,0xff,0xd0,0xc1,0xe5,0xa4,0x83,0xdc,0x3c,0x60,0xf2,0xa8,0x0b,0x07,0xfe,0x34,0x1b,0x07,0x02,0x01,0xf4,0xff,0xfa,0x7f,0xa0,0xf2,0x94,0x0f,0xcf,0x31,0x77,0x1b,0x0f,0xf3,0xf3,0xff,0xc3,0xd8,0x47,0x22,0x44,0x1e,0x07,0x88,0xea,0x37,0x20,0x78,0xf1,0x02,0x23,0x83,0xe0,0xcf,0xe0,0x17,0x06,0xa0,0xa9,0x8a,0xaa,0x0f,0x1f,0x23,0xbc,0x78,0x30,0x18,0x1b,0x90,0xd4,0xc5,0x59,0x01,0x08,0x7c,0x7c,0x16,0x18,0x38,0x28,0x41,0xeb,0xd1,0x01,0x0e,0x10,0x1e,0x33,0x18,0x20,0xa8,0x41,0xeb,0x81,0x01,0x0f,0x18,0x1e,0x31,0x08,0x44,0x13,0xff,0x7f,0x07,0x9e,0x00,0xc6,0x5c,0x20,0x79,0xff,0xe0,0xf2,0x08,0x0e,0x00,0xbc,0x37,0xf0,0x79,0x7a,0x01,0xe3,0x30,0x84,0x07,0x05,0x10,0x20,0x01,0xfe,0x45,0x46,0xa4,0x88,0x1d,0x04,0xc3,0x10,0xbf,0x4f,0xec,0x0d,0x68,0x20,0xf1,0x94,0x83,0xe1,0xc8,0x50,0x10,0x78,0xce,0x5b,0xa2,0x0f,0x37,0x7a,0x58,0x21,0x28,0x81,0x96,0xc0,0x26,0x15,0x00,0x79,0x28,0x44,0x82,0x56,0x08,0x54,0x09,0xca,0x2d,0xa1,0xb0,0x61,0x37,0x7f,0xf9,0x8a,0x04,0xf4,0x10,0xd8,0x37,0x03,0x85,0x01,0xa8,0x54,0x30,0x81,0xd1,0x00,0x14,0x0d,0xe2,0x30,0xb8,0x67,0xc3,0x81,0x37,0xa8,0x57,0x13,0x24,0x00,0x23,0xf8,0x88,0x47,0xf1,0x7c,0x03,0x0f,0x46,0xde,0x0f,0x50,0x01,0xf8,0x1d,0x25,0xff,0xf0,0x85,0xc4,0x00,0x40,}; const uint8_t *_A_Level1ReadActive_128x51[] = {_A_Level1ReadActive_128x51_0,_A_Level1ReadActive_128x51_1}; -const uint8_t _A_Level1Read_128x51_0[] = {0x01,0x00,0xa4,0x01,0x00,0x2e,0x03,0xff,0x03,0x07,0xe7,0x82,0x01,0x30,0x07,0xe4,0x72,0x01,0xc0,0x07,0xe4,0x18,0x04,0x30,0x10,0x7d,0x8f,0x4a,0x0e,0x4e,0xb8,0x10,0x89,0x00,0x11,0xc0,0x16,0x14,0x30,0x1f,0x56,0x00,0x19,0x03,0xee,0x80,0x03,0x28,0x40,0x3e,0x8f,0x87,0x18,0x07,0xd4,0x40,0x06,0xc0,0x07,0x8c,0x70,0x21,0xe0,0xfd,0xb0,0x03,0x44,0x1f,0x70,0xc9,0x04,0x81,0x81,0x90,0xc8,0x84,0xb8,0x1f,0xd3,0xd8,0x04,0xe0,0x1f,0x50,0x4c,0x80,0x3f,0xe7,0xe0,0xff,0x07,0xed,0x82,0x3f,0xe0,0x97,0x83,0xee,0x31,0x07,0x8f,0x5d,0x01,0xf7,0x08,0x6e,0x8f,0x80,0x1f,0x6d,0xd2,0xc0,0x40,0x41,0xf3,0x02,0x02,0x1c,0x1c,0x1f,0xc2,0x41,0x00,0x44,0x0c,0x08,0x70,0x60,0x5a,0xff,0xbc,0x31,0xf0,0x7a,0x89,0x0a,0x40,0x33,0x1c,0x04,0x0e,0x7e,0xdb,0x12,0x50,0xf6,0x21,0xe1,0x41,0xf8,0x7f,0xff,0xed,0x41,0xc0,0x05,0x46,0xc0,0x5a,0x3f,0xd7,0x1e,0x07,0x40,0x02,0x8c,0x9c,0x1e,0x74,0x03,0x52,0x7f,0xe0,0x36,0x00,0xd1,0x03,0xcf,0x81,0xc0,0x09,0x90,0x14,0x47,0xa2,0x06,0x30,0x78,0xfe,0x3f,0xe1,0x82,0x0f,0x0d,0xff,0xfd,0x21,0x02,0x8e,0x80,0x1e,0x3e,0x7f,0xfd,0x0c,0x1e,0x58,0x0c,0x3c,0x3f,0xc6,0x0f,0x2a,0x80,0x98,0x7f,0xe3,0x41,0x07,0x96,0xc3,0xfd,0xff,0xfe,0x83,0xca,0x50,0x3f,0x3c,0xc4,0xdc,0x86,0x58,0x0f,0xfe,0x1e,0xc2,0x39,0x1e,0x78,0x20,0x7c,0x47,0x51,0x99,0x12,0x0a,0x71,0xf8,0xc1,0xf0,0x67,0xf0,0x0b,0x81,0xa4,0x54,0xc5,0x15,0x01,0x0f,0x82,0x7f,0xe0,0xe0,0xc0,0x54,0xc2,0x79,0x25,0x31,0x46,0x41,0xe5,0x20,0xf0,0x58,0x60,0xe0,0xa1,0x07,0xac,0x44,0x04,0x33,0x00,0x78,0xcc,0x60,0x82,0xa1,0x07,0xac,0x06,0xe1,0x00,0x8e,0x03,0xc6,0x21,0x08,0x82,0x21,0x04,0x1e,0x66,0x21,0xe0,0x70,0x60,0xe0,0xf3,0xff,0x81,0x46,0x02,0x67,0x10,0xa0,0xa7,0x49,0x58,0x3e,0x09,0x84,0x20,0x38,0x2b,0x92,0x80,0x7f,0x0b,0xc4,0x40,0x2d,0x04,0xc3,0x10,0xbf,0x4f,0xec,0x0f,0x41,0x08,0x07,0xdb,0x90,0xa1,0x20,0xf2,0x86,0x48,0x01,0xe6,0xef,0x40,0x7a,0x42,0xa6,0x15,0x00,0x79,0x28,0x44,0x82,0x56,0x08,0x53,0x7c,0xa0,0xb5,0x0b,0x06,0x13,0x77,0xff,0x98,0xa0,0x4f,0x41,0x0d,0x07,0x94,0x1e,0xa1,0x50,0xc2,0x07,0x44,0x00,0x50,0x37,0x88,0xc2,0xdb,0xe4,0x2e,0x1a,0xe2,0x64,0x80,0x04,0x7f,0x18,0x0c,0x40,0x66,0x5f,0x8e,0x8d,0xbc,0x1e,0xa0,0x02,0xf8,0x00,0x86,0x70,0x17,0x1f,0x08,0xe4,0x40,0x04,}; -const uint8_t _A_Level1Read_128x51_1[] = {0x01,0x00,0xb2,0x01,0x00,0x2e,0x03,0xff,0x03,0x07,0xe7,0x82,0x01,0x30,0x07,0xe4,0x72,0x01,0xc0,0x07,0xe4,0x18,0x04,0x30,0x10,0x7d,0x8f,0x4a,0x0e,0x4e,0xb8,0x10,0x89,0x00,0x11,0xc0,0x16,0x14,0x30,0x1f,0x56,0x00,0x19,0x03,0xee,0x80,0x03,0x28,0x40,0x3e,0x8f,0x87,0x18,0x07,0xd4,0x40,0x06,0xc0,0x07,0x8c,0x70,0x23,0xe0,0xfd,0x90,0x48,0x01,0xf9,0x0c,0x88,0x03,0xc5,0x81,0x70,0xcc,0x84,0x9c,0x1f,0xbd,0x09,0x74,0x02,0x70,0x0f,0xa8,0x27,0x42,0x5e,0x0f,0xdf,0x80,0x7f,0xbe,0x13,0xf0,0x7e,0xf8,0x23,0xfe,0x01,0x88,0x83,0xea,0x31,0x07,0x8f,0x5d,0x01,0xf7,0x08,0x6e,0x8f,0x80,0x1f,0x6d,0xd2,0xc0,0x40,0x41,0xf3,0x02,0x02,0x1c,0x1c,0x1f,0xc2,0x41,0x00,0x44,0x0c,0x08,0x70,0x60,0x5a,0xff,0xbc,0x2e,0xb1,0x07,0xa0,0x90,0xa4,0x03,0x31,0xc0,0x40,0xe7,0xed,0xb1,0x25,0x0f,0x62,0x1e,0x14,0x1f,0x87,0xff,0xfe,0xd4,0x1c,0x00,0x54,0x6c,0x05,0xa3,0xfd,0x71,0xe0,0x74,0x00,0x28,0xb9,0x84,0x1e,0x54,0x00,0x79,0xe6,0x3f,0xf0,0x1b,0x00,0x68,0x81,0xe7,0xc0,0xe0,0x04,0xca,0x37,0xcf,0x1e,0x88,0x18,0x81,0xe5,0xf8,0xff,0x86,0x0a,0x01,0x0f,0xbe,0x7f,0xa4,0x20,0x51,0xd0,0x03,0xc7,0xcf,0xff,0xa1,0x83,0xcb,0x01,0x07,0xb8,0x78,0xc1,0xe5,0x50,0x16,0x0f,0xfc,0x68,0x20,0xf2,0x2d,0x8f,0xa7,0xfa,0x0f,0x29,0x40,0xfc,0xf3,0x17,0x70,0x18,0xff,0x3f,0x3f,0xfc,0x3d,0x84,0x72,0x24,0x41,0xe0,0x78,0x8e,0xa3,0x72,0x0a,0x8f,0x1c,0x22,0x38,0x3e,0x0c,0xfe,0x01,0x70,0x34,0x8a,0x98,0xaa,0xa1,0x51,0x76,0x8f,0x83,0x83,0x01,0x53,0x09,0xe4,0x94,0xc5,0x59,0x80,0x4e,0x0e,0x43,0xe0,0xb0,0xc1,0xc1,0x42,0x0f,0x5e,0x89,0xb4,0x48,0xc3,0xe0,0x98,0xc1,0x05,0x42,0x0f,0x5c,0x0a,0x4c,0x81,0xe3,0x10,0x84,0x41,0x3f,0xf7,0xf0,0x79,0xe0,0x14,0x66,0x0f,0x3f,0xfc,0x1e,0x41,0x01,0xc0,0x17,0x86,0xfe,0x0f,0x22,0x79,0x4c,0x21,0x01,0xc1,0x5c,0x91,0xa0,0x62,0xa3,0x52,0x5d,0x8e,0x82,0x61,0x88,0x5f,0xa7,0xf6,0x06,0xb4,0x10,0x7d,0xb9,0x0a,0x02,0x0f,0x19,0xc0,0x44,0x41,0xe6,0xef,0x4b,0x04,0x25,0x10,0x32,0xc8,0x04,0xc2,0xa0,0x0f,0x25,0x08,0x90,0x4a,0xc1,0x0a,0x31,0x8f,0x99,0xb4,0x36,0x0c,0x26,0xef,0xff,0x31,0x40,0x9e,0x82,0x1a,0x88,0x1e,0x1c,0x06,0xa1,0x50,0xc2,0x07,0x44,0x00,0x50,0x37,0x88,0xc2,0xe1,0x9c,0x0e,0x0c,0xde,0xa1,0x5c,0x4c,0x90,0x00,0x8f,0xe2,0x4d,0x2b,0x80,0x18,0x7a,0x36,0xf0,0x7a,0x80,0x0f,0xc1,0x1f,0x74,0x8f,0xff,0xc2,0x17,0x10,0x01,0x00,}; +const uint8_t _A_Level1Read_128x51_0[] = {0x01,0x00,0xa4,0x01,0x00,0x2e,0x03,0xff,0x03,0x07,0xe7,0x82,0x01,0x30,0x07,0xe4,0x72,0x01,0xc0,0x07,0xe4,0x18,0x04,0x30,0x10,0x7d,0x8f,0x4a,0x0e,0x4e,0xb8,0x10,0x89,0x00,0x11,0xc0,0x16,0x14,0x30,0x1f,0x56,0x00,0x19,0x03,0xee,0x80,0x03,0x28,0x40,0x3e,0x8f,0x87,0x18,0x07,0xd4,0x40,0x06,0xc0,0x07,0x8c,0x70,0x21,0xe0,0xfd,0xb0,0x03,0x44,0x1f,0x70,0xc9,0x04,0x81,0x81,0x90,0xc8,0x84,0xb8,0x1f,0xd3,0xd8,0x04,0xe0,0x1f,0x50,0x4c,0x84,0xfc,0x1f,0xe0,0xff,0x07,0xed,0x82,0x3f,0xe0,0x97,0x83,0xee,0x31,0x07,0x8f,0x5d,0x01,0xf7,0x08,0x6e,0x8f,0x80,0x1f,0x6d,0xd2,0xc0,0x40,0x41,0xf3,0x02,0x02,0x1c,0x1c,0x1f,0xc2,0x41,0x00,0x44,0x0c,0x08,0x70,0x60,0x5a,0xff,0xbc,0x31,0xf0,0x7a,0x89,0x0a,0x40,0x33,0x1c,0x04,0x0e,0x7e,0xdb,0x12,0x50,0xf6,0x21,0xe1,0x41,0xf8,0x7f,0xff,0xed,0x41,0xc0,0x05,0x46,0xc0,0x5a,0x3f,0xd7,0x1e,0x07,0x40,0x02,0x8c,0x9c,0x1e,0x74,0x03,0x52,0x7f,0xe0,0x36,0x00,0xd1,0x03,0xcf,0x81,0xc0,0x09,0x90,0x14,0x47,0xa2,0x06,0x30,0x78,0xfe,0x3f,0xe1,0x82,0x0f,0x0d,0xff,0xfd,0x21,0x02,0x8e,0x80,0x1e,0x3e,0x7f,0xfd,0x0c,0x1e,0x58,0x0c,0x3c,0x3f,0xc6,0x0f,0x2a,0x80,0x98,0x7f,0xe3,0x41,0x07,0x96,0xc3,0xfd,0xff,0xfe,0x83,0xca,0x50,0x3f,0x3c,0xc4,0xdc,0x86,0x58,0x0f,0xfe,0x1e,0xc2,0x39,0x1e,0x78,0x20,0x7c,0x47,0x51,0x99,0x12,0x0a,0x71,0xf8,0xc1,0xf0,0x67,0xf0,0x0b,0x81,0xa4,0x54,0xc5,0x15,0x01,0x0f,0x82,0x7f,0xe0,0xe0,0xc0,0x54,0xc2,0x79,0x25,0x31,0x46,0x41,0xe5,0x20,0xf0,0x58,0x60,0xe0,0xa1,0x07,0xac,0x44,0x04,0x33,0x00,0x78,0xcc,0x60,0x82,0xa1,0x07,0xac,0x06,0xe1,0x00,0x8e,0x03,0xc6,0x21,0x08,0x82,0x21,0x04,0x1e,0x66,0x21,0xe0,0x70,0x60,0xe0,0xf3,0xff,0x81,0x46,0x02,0x67,0x10,0xa0,0xa7,0x49,0x58,0x3e,0x09,0x84,0x20,0x38,0x2b,0x92,0x80,0x7f,0x0b,0xc4,0x40,0x2d,0x04,0xc3,0x10,0xbf,0x4f,0xec,0x0f,0x41,0x08,0x07,0xdb,0x90,0xa1,0x20,0xf2,0x86,0x48,0x01,0xe6,0xef,0x40,0x7a,0x42,0xa6,0x15,0x00,0x79,0x28,0x44,0x82,0x56,0x08,0x53,0x7c,0xa0,0xb5,0x0b,0x06,0x13,0x77,0xff,0x98,0xa0,0x4f,0x41,0x0d,0x07,0x94,0x1e,0xa1,0x50,0xc2,0x07,0x44,0x00,0x50,0x37,0x88,0xc2,0xdb,0xe4,0x2e,0x1a,0xe2,0x64,0x80,0x04,0x7f,0x18,0x0c,0x40,0x66,0x5f,0x8e,0x8d,0xbc,0x1e,0xa0,0x02,0xf8,0x00,0x86,0x70,0x17,0x1f,0x08,0xe4,0x40,0x04,}; +const uint8_t _A_Level1Read_128x51_1[] = {0x01,0x00,0xb0,0x01,0x00,0x2e,0x03,0xff,0x03,0x07,0xe7,0x82,0x01,0x30,0x07,0xe4,0x72,0x01,0xc0,0x07,0xe4,0x18,0x04,0x30,0x10,0x7d,0x8f,0x4a,0x0e,0x4e,0xb8,0x10,0x89,0x00,0x11,0xc0,0x16,0x14,0x30,0x1f,0x56,0x00,0x19,0x03,0xee,0x80,0x03,0x28,0x40,0x3e,0x8f,0x87,0x18,0x07,0xd4,0x40,0x06,0xc0,0x07,0x8c,0x70,0x23,0xe0,0xfd,0x90,0x48,0x01,0xf9,0x0c,0x88,0x03,0xc5,0x81,0x70,0xcc,0x84,0x9c,0x1f,0xbd,0x09,0x74,0x02,0x70,0x0f,0xa8,0x27,0x42,0x5e,0x0f,0xdf,0x80,0x3f,0xe7,0xe0,0xfd,0xf0,0x47,0xfc,0x02,0x11,0x07,0xd4,0x62,0x0f,0x1e,0xba,0x03,0xee,0x10,0xdd,0x1f,0x00,0x3e,0xdb,0xa5,0x80,0x80,0x83,0xe6,0x04,0x04,0x38,0x38,0x3f,0x84,0x82,0x00,0x88,0x18,0x10,0xe0,0xc0,0xb5,0xff,0x78,0x5d,0x62,0x0f,0x41,0x21,0x48,0x06,0x63,0x80,0x81,0xcf,0xdb,0x62,0x4a,0x1e,0xc4,0x3c,0x28,0x3f,0x0f,0xff,0xfd,0xa8,0x38,0x00,0xa8,0xd8,0x0b,0x47,0xfa,0xe3,0xc0,0xe8,0x00,0x51,0x73,0x08,0x3c,0xa8,0x00,0xf3,0xcc,0x7f,0xe0,0x36,0x00,0xd1,0x03,0xcf,0x81,0xc0,0x09,0x94,0x6f,0x9e,0x3d,0x10,0x31,0x03,0xcb,0xf1,0xff,0x0c,0x14,0x02,0x1f,0x7c,0xff,0x48,0x40,0xa3,0xa0,0x07,0x8f,0x9f,0xff,0x43,0x07,0x96,0x02,0x0f,0x70,0xf1,0x83,0xca,0xa0,0x2c,0x1f,0xf8,0xd0,0x41,0xe4,0x5b,0x1f,0x4f,0xf4,0x1e,0x52,0x81,0xf9,0xe6,0x2e,0xe0,0x31,0xfe,0x7e,0x7f,0xf8,0x7b,0x08,0xe4,0x48,0x83,0xc0,0xf1,0x1d,0x46,0xe4,0x15,0x1e,0x38,0x44,0x70,0x7c,0x19,0xfc,0x02,0xe0,0x69,0x15,0x31,0x55,0x42,0xa2,0xed,0x1f,0x07,0x06,0x02,0xa6,0x13,0xc9,0x29,0x8a,0xb3,0x00,0x9c,0x1c,0x87,0xc1,0x61,0x83,0x82,0x84,0x1e,0xbd,0x13,0x68,0x91,0x87,0xc1,0x31,0x82,0x0a,0x84,0x1e,0xb8,0x14,0x99,0x03,0xc6,0x21,0x08,0x82,0x7f,0xef,0xe0,0xf3,0xc0,0x28,0xcc,0x1e,0x7f,0xf8,0x3c,0x82,0x03,0x80,0x2f,0x0d,0xfc,0x1e,0x44,0xf2,0x98,0x42,0x03,0x82,0xb9,0x23,0x40,0xc5,0x46,0xa4,0xbb,0x1d,0x04,0xc3,0x10,0xbf,0x4f,0xec,0x0d,0x68,0x20,0xfb,0x72,0x14,0x04,0x1e,0x33,0x80,0x88,0x83,0xcd,0xde,0x96,0x08,0x4a,0x20,0x65,0x90,0x09,0x85,0x40,0x1e,0x4a,0x11,0x20,0x95,0x82,0x14,0x63,0x1f,0x33,0x68,0x6c,0x18,0x4d,0xdf,0xfe,0x62,0x81,0x3d,0x04,0x35,0x10,0x3c,0x38,0x0d,0x42,0xa1,0x84,0x0e,0x88,0x00,0xa0,0x6f,0x11,0x85,0xc3,0x38,0x1c,0x19,0xbd,0x42,0xb8,0x99,0x20,0x01,0x1f,0xc4,0x9a,0x57,0x00,0x30,0xf4,0x6d,0xe0,0xf5,0x00,0x1f,0x82,0x3e,0xe9,0x1f,0xff,0x84,0x2e,0x20,0x02,}; const uint8_t *_A_Level1Read_128x51[] = {_A_Level1Read_128x51_0,_A_Level1Read_128x51_1}; const uint8_t _A_Level1ToysActive_128x51_0[] = {0x01,0x00,0xe5,0x01,0x00,0x78,0x03,0xc0,0x0d,0xf0,0xff,0x80,0x16,0x7e,0x0f,0x68,0x40,0x1d,0xa8,0x00,0x21,0xff,0x04,0xcc,0x1f,0x3c,0x08,0x1f,0x82,0x02,0x0f,0xbb,0x80,0x10,0x60,0xe0,0xf2,0xf1,0xcb,0x3c,0x31,0x8b,0x3c,0x24,0x1e,0x51,0xc0,0x60,0xc3,0x00,0x43,0x88,0xca,0x48,0xa4,0x3a,0x58,0xa0,0x3c,0xe0,0xc0,0xc1,0x09,0x16,0x23,0x2f,0x24,0x90,0xef,0x64,0x80,0xf3,0x81,0x83,0x06,0x60,0x0f,0x2c,0x84,0xa2,0x43,0x85,0xa2,0x03,0xcb,0x00,0x4c,0x2b,0x00,0xfc,0xf8,0xc3,0xf1,0x9b,0xc3,0x81,0xe3,0xc0,0x3a,0x29,0x7c,0xa4,0x20,0x53,0xa0,0x06,0xc8,0xe4,0x20,0x93,0xe0,0x48,0x00,0xa2,0x4b,0x1a,0x00,0x14,0xa0,0x18,0x03,0xfd,0x03,0xd0,0x86,0x20,0xf8,0x2d,0x90,0x00,0x41,0xe3,0x88,0x07,0xbc,0x40,0x1f,0xd1,0x81,0x68,0xab,0x86,0x04,0x0f,0x1e,0x66,0x36,0x73,0x30,0xcb,0xe3,0x2f,0x34,0x91,0xc0,0xc8,0x02,0x42,0x0f,0x2a,0x95,0x4a,0x94,0xb3,0x1a,0x95,0x08,0x1e,0x5f,0x08,0x88,0x3c,0xeb,0xc0,0xf1,0xc8,0x65,0x3b,0xd3,0x30,0x79,0x5e,0x24,0x47,0x72,0xc4,0x50,0x81,0xe3,0xa0,0xca,0x50,0xa1,0x00,0xf3,0x93,0x40,0x3c,0xd0,0xfc,0x45,0x33,0x25,0x49,0x8c,0x79,0xc7,0xe3,0x4e,0x07,0x8f,0xe2,0xcf,0x00,0xfe,0x46,0x0f,0xe9,0x04,0x01,0x0d,0x21,0xf6,0x20,0xf1,0xc0,0x47,0xe4,0x00,0xa2,0x07,0xa5,0x18,0x06,0x3f,0x89,0x3f,0xc1,0xc2,0x25,0x11,0x3f,0xb0,0x3c,0xa6,0x69,0x31,0x9c,0x3d,0x48,0x1e,0xe6,0xf2,0x80,0x6f,0xff,0xe0,0x06,0x9f,0x83,0xc6,0xc0,0x42,0x1e,0x04,0x7e,0x09,0xe0,0x83,0x6c,0x35,0x58,0x1b,0x5e,0x02,0x0c,0x0c,0x1c,0x04,0x3e,0x01,0xe0,0x87,0xc0,0xac,0x10,0x5a,0x85,0x56,0x83,0xd5,0xc0,0x41,0x51,0x43,0xc0,0x57,0x8f,0xc2,0x07,0x02,0xd8,0x41,0xb7,0x1a,0xae,0x06,0xa8,0x3e,0x20,0xf1,0xa0,0x48,0x0f,0xe2,0xb1,0x1a,0x84,0x36,0xb1,0xd5,0xb0,0xd5,0x70,0x21,0xf2,0x07,0x0c,0x03,0xfc,0x0f,0x1d,0x44,0x2b,0x51,0xaa,0xd0,0x10,0x46,0x0c,0xec,0x19,0x05,0x03,0x01,0xff,0x8f,0xc0,0x6a,0x81,0xf2,0xb0,0x07,0xca,0x0a,0x74,0x2e,0x04,0x04,0x1e,0x3a,0xa0,0xfb,0x0b,0xc5,0x4c,0x3f,0x0c,0x04,0x5e,0x03,0x56,0x8a,0x87,0xce,0x83,0x05,0x54,0x14,0x13,0xfd,0xff,0x8c,0x40,0x75,0x71,0xa0,0xf8,0x97,0xc7,0x81,0x0a,0x07,0x97,0xe3,0xff,0x00,0xc6,0x14,0x86,0x3e,0x1f,0x1c,0x05,0x56,0x81,0x0d,0x81,0xad,0x93,0x1c,0x03,0x20,0xb1,0x4f,0xc3,0xe2,0xc8,0x5c,0x3b,0x39,0xe1,0xa0,0xf4,0xc0,0x60,0x41,0xec,0x1f,0x6f,0x85,0x00,0x3f,0xb3,0xe0,0x7b,0xf0,0x20,0xc0,0xf3,0xe8,0x47,0xc3,0xf0,0x5e,0x4f,0xc4,0x7f,0x80,0xb1,0x10,0xfa,0x83,0xd3,0xc0,0x0c,0x2f,0x07,0xfc,0x00,0x2c,0xb1,0xe0,0x05,0x56,0x7e,0x2d,0x54,0x08,0xdf,0xc1,0x0b,0x3c,0x1f,0x30,0x01,0xef,0x00,0xfe,0xb8,0x03,0xfb,0xc0,0x0f,0xee,0x03,0x15,0x40,0x06,}; @@ -186,47 +186,47 @@ const uint8_t _A_Level3Lab_128x51_1[] = {0x01,0x00,0x9f,0x02,0x00,0x1e,0x20,0x04 const uint8_t _A_Level3Lab_128x51_2[] = {0x01,0x00,0xa6,0x02,0x00,0x1e,0x20,0x04,0x34,0x00,0x39,0xfc,0x3f,0xff,0xf9,0xff,0xf8,0x06,0x3f,0xfc,0xb8,0x3c,0xff,0x10,0x1d,0x84,0x04,0x26,0x59,0xef,0x27,0xe7,0xf7,0xbf,0x07,0x9c,0x1a,0x0d,0xb0,0xc4,0xc4,0x28,0x58,0x80,0x79,0x08,0x04,0x1e,0x70,0x18,0x40,0xdc,0x41,0xeb,0x07,0xfe,0x43,0xc1,0xe3,0x80,0xf8,0x44,0x03,0xef,0x81,0xe1,0xdf,0xc1,0xe3,0x40,0x86,0x48,0xc1,0xe5,0x47,0xc4,0x13,0xc6,0xfe,0x4b,0x3a,0x04,0x82,0x05,0x44,0x17,0x90,0x3c,0xe7,0xf2,0x08,0x07,0x02,0x07,0xf0,0x90,0x40,0x69,0x01,0xf4,0xcf,0x4f,0x23,0xe0,0xf1,0x80,0x41,0xe1,0x11,0x1b,0x0e,0x20,0x7e,0xb3,0xc8,0x7c,0x40,0x1e,0x31,0xe8,0x46,0x47,0x21,0x90,0x2f,0xac,0xf2,0x0e,0x0f,0x2f,0xe4,0x27,0x23,0x68,0xc8,0x83,0xcf,0x39,0x9e,0xde,0x40,0xcf,0x03,0x40,0xfa,0xc2,0xc1,0xe5,0xfc,0xe4,0xc4,0x41,0xe2,0x4f,0x14,0x41,0x6a,0x21,0xff,0x71,0x70,0x8b,0xc7,0x90,0x0f,0x5f,0xe4,0x02,0xeb,0x00,0xa7,0x44,0x09,0xe3,0xf0,0x0f,0x91,0xbc,0x41,0xa3,0x03,0xd1,0xc3,0xa0,0x14,0xc3,0x79,0x0f,0xcb,0xc4,0x0f,0x2c,0x07,0xe2,0xa9,0x07,0x07,0x92,0x3c,0x7f,0x86,0xf1,0x07,0x95,0xf2,0x81,0x04,0xd4,0xc6,0x01,0xe2,0xaf,0x20,0xfa,0x83,0xc7,0xe5,0x5a,0x48,0x8d,0x31,0x9e,0x5e,0x04,0x79,0xff,0xaf,0xf2,0x08,0x4c,0xd5,0x82,0x34,0xc7,0x79,0x5f,0x11,0xe6,0x0f,0x1d,0x04,0x52,0x35,0x80,0x81,0x03,0xc6,0x0d,0x06,0xff,0x63,0xc1,0xe5,0x92,0x9b,0xe4,0x2c,0x51,0xbc,0x00,0x7c,0x9c,0x63,0x03,0xfe,0x03,0xd7,0x24,0x1f,0x15,0x80,0xc0,0x56,0x83,0x03,0xf4,0x43,0xc0,0x83,0x92,0xff,0x83,0xcf,0x01,0xff,0x39,0x09,0x04,0x40,0xa2,0xfc,0x1c,0x94,0x7f,0x2f,0xea,0x07,0x8d,0x82,0x01,0x3f,0x80,0x60,0x04,0x43,0x80,0x8f,0xc0,0x3f,0xd1,0xfc,0xd4,0x12,0x33,0x80,0xbf,0x40,0x2f,0x0b,0xd1,0x19,0x17,0xfa,0x43,0x01,0x86,0x49,0x7f,0x30,0xcc,0x06,0x06,0x03,0xe0,0x80,0x78,0x01,0xe4,0x20,0x1f,0xf4,0x3e,0x55,0x02,0x83,0x5f,0x20,0x11,0x2e,0x04,0x07,0xd1,0x71,0x07,0x8c,0x02,0x11,0x08,0x83,0x51,0x7f,0x9f,0x32,0x60,0xc1,0x07,0xa3,0xc8,0xe0,0x7f,0xcb,0xe3,0x0c,0x07,0x8e,0x0a,0x0f,0x06,0x0b,0x90,0x3c,0x6d,0x00,0x51,0x75,0x88,0x3c,0x95,0x24,0x0f,0x24,0x00,0xda,0x22,0x10,0x08,0xf4,0x0e,0x09,0x08,0x83,0xa3,0x04,0x00,0x59,0x8e,0x38,0x3c,0x4e,0x83,0x1f,0x25,0x0c,0xfa,0x06,0x0f,0x4f,0x81,0x3c,0x67,0xc8,0xe1,0x3f,0x0c,0x1a,0x45,0x03,0x32,0x08,0x3c,0xa7,0x1e,0x0c,0x0c,0xd6,0x00,0x50,0x18,0x1c,0x1a,0x54,0x0f,0x58,0x77,0xc2,0x83,0x18,0x80,0x71,0x23,0x30,0xe8,0x18,0x7c,0x8a,0x02,0x12,0x18,0x1f,0xc2,0x40,0x0f,0x1f,0x44,0x65,0xa6,0x23,0xf1,0x07,0x8c,0x08,0x7c,0x23,0x01,0x90,0x19,0x47,0xe1,0x0c,0x07,0x8e,0x20,0x1e,0x51,0xc2,0xc0,0xc0,0x27,0xd1,0x08,0x64,0xc2,0xf1,0xc6,0x07,0xaf,0x83,0xfe,0x31,0x18,0x78,0x3c,0x7b,0x17,0x8c,0x36,0x1e,0x03,0x88,0x82,0x9b,0x8c,0x24,0x30,0x78,0x44,0x13,0x0d,0x3c,0x81,0x29,0x44,0x1e,0xdf,0xc1,0x40,0xc1,0xf8,0x79,0xf8,0x7e,0x02,0x3b,0x88,0x29,0x88,0x00,0xff,0xe5,0xc1,0x81,0xdc,0x3f,0xd1,0x8c,0x04,0x4f,0x11,0x61,0x17,0x21,0x40,0x6f,0x10,0x29,0x85,0xfe,0x60,0x0f,0x1c,0x86,0x84,0x96,0x20,0x01,0xfc,0x3c,0x44,0x78,0x39,0x8f,0x3d,0x83,0x81,0x12,0xc8,0x50,0x5d,0xa4,0xb9,0x10,0x18,0x83,0xc7,0xb1,0xc3,0xe0,0xd0,0x23,0xda,0x08,0x0c,0x24,0x9a,0x40,0xf2,0x8f,0x40,0xbf,0x1c,0x0c,0x0d,0x86,0x28,0x0f,0x18,0x90,0x2c,0x7f,0xc0,0xf2,0x87,0x40,0xaf,0x1c,0x08,0x1c,0x82,0x18,0xe7,0x18,0xa0,0x2c,0x7d,0x00,0xf2,0x87,0xc0,0x6e,0x2c,0x51,0x5a,0x0a,0x04,0x41,0xe5,0x54,0xee,0xc0,0x78,0x50,0x78,0x0d,0xe0,0x1e,0x33,0x03,0x08,0x83,0xcf,0x51,0xaa,0x80,0xec,0x20,0x60,0xf4,0xe0,0x07,0xd7,0xab,0x81,0xc1,0xc0,0x60,0x33,0xcc,0x04,0xfe,0x60,0x6a,0x10,0xfa,0xc0,0xff,0x0d,0x31,0x8e,0x07,0xc7,0xe1,0xff,}; const uint8_t *_A_Level3Lab_128x51[] = {_A_Level3Lab_128x51_0,_A_Level3Lab_128x51_1,_A_Level3Lab_128x51_2}; -const uint8_t _I_LevelUp2_04_0[] = {0x01,0x00,0x16,0x01,0x00,0x37,0xf2,0x02,0x0f,0xda,0xbc,0xfc,0x1d,0x9c,0x0f,0x5f,0xac,0x1f,0x97,0x0b,0xaf,0x54,0x61,0x9b,0x8d,0xd6,0xaa,0x06,0x0f,0xba,0xa5,0x76,0xaa,0x0f,0xcd,0x66,0xbb,0x55,0x06,0x07,0xdd,0x5b,0xef,0x5f,0x86,0x83,0xef,0x55,0xbb,0xdd,0x42,0x81,0xf7,0xd7,0xee,0xdd,0xe3,0xa0,0xfb,0xff,0xeb,0xbd,0xf1,0xa0,0x7d,0xf5,0x7a,0xf5,0xf9,0xa8,0x36,0x60,0x90,0x0d,0x5f,0xfb,0xfd,0x2a,0xb0,0x03,0xe2,0x39,0x00,0xaa,0xf5,0x7b,0xf7,0x59,0xc0,0x3e,0x26,0x10,0x0f,0x5f,0xfb,0x7f,0x6a,0x84,0x0f,0xea,0xba,0x40,0x1a,0xa9,0x3e,0xfd,0x7a,0xef,0x57,0xa9,0x3f,0x9d,0xdb,0xff,0x55,0x3f,0x9b,0xff,0x5e,0xa8,0x1f,0x7f,0xef,0xaf,0x57,0xab,0xf1,0x07,0xd3,0x78,0x40,0x03,0x01,0x06,0xc4,0x08,0x7e,0x35,0x50,0x00,0x83,0xe6,0x1c,0x9f,0x10,0xfe,0x46,0x30,0x01,0xd1,0xae,0x87,0xea,0x01,0xc0,0x0e,0x8e,0xbc,0x3f,0x50,0x0b,0x05,0x57,0xea,0x21,0x1e,0x08,0x3e,0x76,0x07,0xf1,0x10,0x8e,0x06,0x06,0x0f,0x8a,0x85,0xfc,0xbf,0x90,0x0f,0x81,0x7f,0x60,0x17,0x01,0xf9,0x83,0xe7,0x81,0xe1,0xd5,0x6f,0x83,0xf7,0x70,0xe0,0x7f,0xea,0xe3,0xfc,0x30,0x10,0xff,0x20,0x15,0x82,0xfe,0xc0,0x35,0x01,0xff,0x0f,0xf6,0xb0,0x3f,0xd5,0x40,0xff,0x87,0xc8,0x1d,0x40,0x0f,0x00,0x76,0x23,0x7d,0x24,0x82,0x57,0xfe,0x90,0x58,0xa8,0x3e,0x30,0x40,0xf1,0xa0,0xc5,0x20,0x80,0xf8,0xcc,0x03,0xfb,0x51,0x9e,0x07,0x8e,0x3f,0xe4,0x0f,0x9e,0x40,0x7c,0xb0,0x31,0x20,0x7c,0x8f,0xce,0x03,0x11,0x82,0x17,0xe6,0x7d,0x1b,0xbe,0x47,0xfe,0x37,0xd0,0xfc,0x00,0x3c,0x01,0xe0,0x0b,}; -const uint8_t *_I_LevelUp2_04[] = {_I_LevelUp2_04_0}; - -const uint8_t _I_LevelUp2_03_0[] = {0x01,0x00,0xa3,0x00,0x00,0x37,0xf2,0x02,0x0f,0xdf,0xfc,0xfc,0x1d,0x9c,0x0f,0xff,0xfc,0x1f,0x9f,0x00,0x78,0x8c,0x33,0xf0,0x0f,0x18,0x19,0x3b,0x01,0xfe,0x0f,0x18,0x38,0x3e,0xff,0xc0,0xf1,0x87,0x83,0xfc,0xfd,0x80,0x01,0x8f,0x83,0xfc,0x1f,0xca,0x0c,0x07,0xf8,0x3c,0xaf,0xe0,0xff,0x07,0xf8,0x3f,0x9c,0x18,0x8f,0x20,0x7f,0x83,0xff,0xff,0x01,0x07,0xf8,0x3f,0xcb,0xfc,0x0f,0xac,0x00,0x3f,0xb8,0x00,0xfe,0xf0,0x03,0xfb,0xe0,0x0f,0xf0,0x7f,0x83,0xfc,0x9f,0xe6,0xff,0x07,0xf0,0xc1,0x01,0xf7,0xf8,0x07,0xf8,0x3f,0xc1,0xfd,0xfc,0x07,0xf8,0x3f,0xc1,0xfc,0x00,0xf0,0x06,0xe2,0x37,0xd2,0x48,0x25,0x7f,0xe9,0x05,0x8a,0x83,0xe3,0x04,0x0f,0x1a,0x0c,0x52,0x08,0x0f,0x8c,0xc0,0x3f,0xb5,0x19,0xe0,0x78,0xe3,0xfe,0x40,0xf9,0xe4,0x07,0xcb,0x03,0x12,0x07,0xc8,0xfc,0xe0,0x31,0x18,0x21,0x7e,0x67,0xd1,0xbb,0xe4,0x7f,0xe3,0x7d,0x0f,0xc0,0x03,0xc0,0x1e,0x00,0xb0,}; -const uint8_t *_I_LevelUp2_03[] = {_I_LevelUp2_03_0}; - const uint8_t _I_LevelUp2_07_0[] = {0x01,0x00,0xf1,0x00,0x00,0x37,0xf2,0x02,0x0f,0xd8,0x3c,0xfc,0x1d,0x9c,0x0e,0x0f,0x84,0x1f,0x96,0x0b,0x86,0x00,0x61,0x91,0x88,0xc4,0x02,0x06,0x0f,0xb8,0x24,0x32,0x01,0x02,0x07,0xe4,0x1a,0x00,0x01,0x10,0x05,0x41,0xbc,0x70,0xf1,0x08,0x80,0x2a,0x05,0x19,0x88,0x42,0x01,0xf7,0x83,0xe6,0xc9,0xca,0x22,0x00,0xaf,0xfe,0x92,0xdf,0x10,0x07,0xde,0x07,0xaf,0x5f,0x98,0x03,0xee,0x03,0xd4,0xef,0x48,0x01,0xfb,0x9f,0x07,0xe5,0x24,0x1e,0x34,0x00,0x7e,0x65,0x3a,0xe0,0xfc,0xa5,0xcb,0x29,0x00,0xfc,0x81,0x76,0x2f,0xf8,0x00,0x7e,0x4f,0xe8,0x60,0xfc,0xfd,0x7c,0x70,0x20,0xfc,0x86,0x03,0x4a,0x02,0xdf,0xb4,0x19,0x83,0xea,0x07,0x00,0x6f,0x08,0x3e,0xb0,0x00,0xb1,0x7f,0x08,0x3e,0xb8,0x00,0x21,0x83,0x83,0xed,0x76,0x3e,0x01,0xfe,0x4c,0x30,0x11,0xf0,0x7e,0x44,0x2f,0xc5,0xfd,0xf8,0x17,0xc4,0x5f,0xa3,0xfe,0xb0,0x40,0x27,0x80,0xfc,0xe0,0x7f,0xc6,0x04,0x9f,0xb8,0x82,0xbf,0xa3,0x00,0xfe,0x5e,0x88,0x3f,0xc1,0xfa,0xcd,0x10,0x7e,0xc1,0x01,0x74,0x0f,0xf0,0x07,0x80,0x3c,0x00,0x38,0x8d,0xf4,0x92,0x09,0x5f,0xfa,0x41,0x62,0xa0,0xf8,0xc1,0x03,0xc6,0x83,0x14,0x82,0x03,0xe3,0x30,0x0f,0xed,0x46,0x78,0x1e,0x38,0xff,0x90,0x3e,0x79,0x01,0xf2,0xc0,0xc4,0x81,0xf2,0x3f,0x38,0x0c,0x45,0x07,0x38,0x89,0xf4,0x6e,0xf9,0x1f,0xf8,0xdf,0x43,0xf0,0x00,0xf0,0x07,0x80,0x2c,}; const uint8_t *_I_LevelUp2_07[] = {_I_LevelUp2_07_0}; -const uint8_t _I_LevelUp2_05_0[] = {0x01,0x00,0x1d,0x01,0x00,0x37,0xf2,0x02,0x0f,0xd8,0x3c,0xfc,0x1d,0x9c,0x0e,0x0f,0x84,0x1f,0x96,0x0b,0x86,0x00,0x61,0x91,0x88,0xc4,0x02,0x06,0x0f,0xb8,0x24,0x32,0x01,0x02,0x07,0xe4,0x1a,0x00,0x01,0x10,0x05,0x41,0xbc,0x70,0xf1,0x08,0x80,0x1e,0x80,0x02,0x18,0x14,0x66,0x21,0x08,0x36,0x48,0x08,0x70,0x7c,0xd9,0x39,0x44,0x42,0xe4,0x00,0x43,0x51,0x7f,0xf4,0x96,0xf8,0x84,0x02,0xf8,0x20,0x73,0x50,0xe0,0x7a,0xf5,0xf9,0x86,0x02,0x0e,0x4d,0x88,0x04,0x07,0xa9,0xde,0x90,0x0d,0x88,0xda,0xe0,0xf2,0xcf,0xc8,0x0d,0xf7,0x49,0x07,0x89,0x35,0xc1,0xeb,0x94,0xeb,0x83,0xf2,0x97,0x2c,0xa4,0x03,0xf2,0x05,0xd8,0xbf,0xe0,0x01,0xf9,0x3f,0xa1,0x83,0xf3,0xf5,0xf1,0xc0,0x83,0xc7,0xfd,0x0f,0x06,0x2c,0x70,0x04,0x30,0xc0,0xe9,0x29,0x44,0x00,0xd7,0x04,0x89,0x83,0xe9,0x30,0x4b,0x11,0x6f,0x08,0x3e,0x1a,0x28,0xfe,0x10,0x7d,0x08,0x49,0x98,0x20,0xfa,0x5d,0x8f,0x80,0x7f,0x40,0x01,0x75,0x8c,0x7c,0x1f,0x91,0x0b,0xf1,0x7e,0xc0,0x03,0xf0,0x2f,0x88,0x3c,0xa6,0x02,0xf9,0x1f,0xa0,0x0c,0x80,0x0d,0x60,0x80,0x4f,0x01,0xe4,0x75,0x20,0x02,0x78,0x23,0xfc,0x0f,0xf8,0xc0,0x87,0xf1,0x38,0x28,0x11,0x3f,0x60,0x11,0x80,0x7f,0x2f,0x44,0x1f,0xe0,0xfd,0x66,0x88,0x3f,0x60,0x80,0xba,0x07,0xf8,0x03,0xc0,0x1e,0x00,0x1c,0x46,0xfa,0x49,0x04,0xaf,0xfd,0x20,0xb1,0x50,0x7c,0x60,0x81,0xe3,0x41,0x8a,0x41,0x01,0xf1,0x98,0x07,0xf6,0xa3,0x3c,0x0f,0x1c,0x7f,0xc8,0x1f,0x3c,0x80,0xf9,0x60,0x62,0x40,0xf9,0x1f,0x9c,0x06,0x22,0x83,0x9c,0x44,0xfa,0x37,0x7c,0x8f,0xfc,0x6f,0xa1,0xf8,0x00,0x78,0x03,0xc0,0x16,}; -const uint8_t *_I_LevelUp2_05[] = {_I_LevelUp2_05_0}; - -const uint8_t _I_LevelUp2_02_0[] = {0x01,0x00,0xe1,0x00,0x00,0x37,0xe2,0x02,0x0f,0xda,0xbc,0xfc,0x1d,0x9c,0x0d,0x5f,0xa8,0x1f,0x97,0x0a,0xaf,0x54,0x61,0x9b,0x8d,0x56,0xaa,0x06,0x0f,0xba,0xa5,0x56,0xaa,0x0f,0xcd,0x60,0x7c,0x60,0xc0,0xfb,0xab,0x07,0xc6,0x1a,0x0f,0xb0,0xf0,0xea,0xa1,0x47,0xec,0xfa,0xd5,0xe3,0xa0,0xfb,0xd5,0xfe,0xb5,0xd1,0xa0,0x7d,0xd5,0x6f,0xb5,0xd9,0xa8,0x7f,0x3d,0xda,0xa9,0x50,0x7f,0x3e,0xb5,0xfb,0xa8,0x7f,0x75,0x76,0xa0,0xff,0x55,0x43,0xfb,0xaf,0x70,0x65,0x5b,0xfb,0x57,0xea,0xa7,0xf3,0xd5,0xab,0xd5,0x2f,0xfb,0xab,0x01,0x5f,0xee,0xa8,0x1f,0x61,0xf2,0xaa,0x83,0xec,0x7a,0x21,0xfc,0xc0,0x07,0x88,0x3f,0x7c,0x0d,0x56,0xe8,0x3f,0x96,0x0a,0xaa,0x78,0x43,0xf7,0xb0,0xd5,0x10,0x08,0x1f,0x55,0x0b,0xf8,0xff,0x7e,0x1a,0xb1,0xfe,0xdc,0x07,0xfd,0xe0,0x5f,0x10,0x7e,0xf8,0x03,0xfe,0x30,0x12,0xff,0x6b,0x01,0xfe,0xd4,0x07,0xfc,0x3f,0xda,0xc0,0xff,0x55,0x03,0xfe,0x1f,0x20,0x75,0x00,0x3c,0x01,0xd8,0x8d,0xf4,0x92,0x09,0x5f,0xfa,0x41,0x62,0xa0,0xf8,0xc1,0x03,0xc6,0x83,0x14,0x82,0x03,0xe3,0x30,0x0f,0xed,0x46,0x78,0x1e,0x38,0xff,0x90,0x3e,0x79,0x01,0xf2,0xc0,0xc4,0x81,0xf2,0x3f,0x38,0x0c,0x46,0x08,0x5f,0x99,0xf4,0x6e,0xf9,0x1f,0xf8,0xdf,0x43,0xf0,0x00,0xf0,0x07,0x80,0x2c,}; -const uint8_t *_I_LevelUp2_02[] = {_I_LevelUp2_02_0}; - const uint8_t _I_LevelUp2_06_0[] = {0x01,0x00,0x11,0x01,0x00,0x37,0xf2,0x02,0x0f,0xd8,0x3c,0xfc,0x1d,0x9c,0x0e,0x0f,0x84,0x17,0x18,0x00,0x19,0x58,0x2e,0x18,0x01,0x84,0xc1,0x80,0x43,0x18,0x8c,0x40,0x20,0x60,0xf8,0x86,0x00,0x86,0x08,0x03,0x18,0x10,0xfe,0xe0,0x82,0x31,0x12,0x95,0xe0,0x65,0x3e,0x38,0x78,0x94,0xa1,0xc0,0xf8,0x81,0x46,0x62,0x10,0x80,0x29,0x03,0xe3,0x07,0xcd,0x93,0x94,0x44,0x01,0x5f,0xfd,0x25,0xbe,0x20,0x0f,0xbc,0x0f,0x5e,0xbf,0x30,0x07,0xdc,0x07,0xa9,0xde,0x90,0x03,0xf7,0x3e,0x0f,0xca,0x48,0x3c,0x68,0x00,0xfc,0xca,0x75,0xc1,0xf9,0x4b,0x96,0x52,0x01,0xf9,0x02,0xec,0x5f,0xdc,0xc6,0x0f,0x99,0xfd,0x0c,0x1e,0x5c,0x00,0x7c,0x7e,0xbe,0x38,0x10,0xf9,0xac,0xc8,0x00,0x36,0x07,0x91,0x83,0x4a,0x02,0x2f,0xa7,0x61,0x03,0xe1,0xaa,0x70,0x31,0x51,0x07,0xeb,0x00,0x0b,0x17,0xf0,0x83,0xe8,0xb0,0x50,0x70,0x7d,0xae,0xc7,0xc0,0x4f,0xc9,0x86,0x02,0x3e,0x0f,0xc8,0x85,0xf8,0xbf,0x40,0x02,0xf8,0x17,0xc4,0x5f,0xa3,0xfe,0x51,0x0c,0xf0,0x1f,0x9c,0x0f,0xf8,0xc0,0x81,0xf0,0xc5,0x28,0x80,0xfd,0x19,0xc8,0x00,0x48,0xc0,0x3e,0xd8,0x04,0x09,0x31,0x7c,0x0e,0xc8,0x1e,0xaa,0x61,0x66,0x23,0xfc,0xcf,0xfb,0x00,0x82,0x02,0xe8,0x1f,0xe0,0x0f,0x00,0x78,0x00,0x71,0x1b,0xe9,0x24,0x12,0xbf,0xf4,0x82,0xc5,0x41,0xf1,0x82,0x07,0x8d,0x06,0x29,0x04,0x07,0xc6,0x60,0x1f,0xda,0x8c,0xf0,0x3c,0x71,0xff,0x20,0x7c,0xf2,0x03,0xe5,0x81,0x89,0x03,0xe4,0x7e,0x70,0x18,0x8a,0x0e,0x71,0x13,0xe8,0xdd,0xf2,0x3f,0xf1,0xbe,0x87,0xe0,0x01,0xe0,0x0f,0x00,0x58,}; const uint8_t *_I_LevelUp2_06[] = {_I_LevelUp2_06_0}; +const uint8_t _I_LevelUp2_04_0[] = {0x01,0x00,0x16,0x01,0x00,0x37,0xf2,0x02,0x0f,0xda,0xbc,0xfc,0x1d,0x9c,0x0f,0x5f,0xac,0x1f,0x97,0x0b,0xaf,0x54,0x61,0x9b,0x8d,0xd6,0xaa,0x06,0x0f,0xba,0xa5,0x76,0xaa,0x0f,0xcd,0x66,0xbb,0x55,0x06,0x07,0xdd,0x5b,0xef,0x5f,0x86,0x83,0xef,0x55,0xbb,0xdd,0x42,0x81,0xf7,0xd7,0xee,0xdd,0xe3,0xa0,0xfb,0xff,0xeb,0xbd,0xf1,0xa0,0x7d,0xf5,0x7a,0xf5,0xf9,0xa8,0x36,0x60,0x90,0x0d,0x5f,0xfb,0xfd,0x2a,0xb0,0x03,0xe2,0x39,0x00,0xaa,0xf5,0x7b,0xf7,0x59,0xc0,0x3e,0x26,0x10,0x0f,0x5f,0xfb,0x7f,0x6a,0x84,0x0f,0xea,0xba,0x40,0x1a,0xa9,0x3e,0xfd,0x7a,0xef,0x57,0xa9,0x3f,0x9d,0xdb,0xff,0x55,0x3f,0x9b,0xff,0x5e,0xa8,0x1f,0x7f,0xef,0xaf,0x57,0xab,0xf1,0x07,0xd3,0x78,0x40,0x03,0x01,0x06,0xc4,0x08,0x7e,0x35,0x50,0x00,0x83,0xe6,0x1c,0x9f,0x10,0xfe,0x46,0x30,0x01,0xd1,0xae,0x87,0xea,0x01,0xc0,0x0e,0x8e,0xbc,0x3f,0x50,0x0b,0x05,0x57,0xea,0x21,0x1e,0x08,0x3e,0x76,0x07,0xf1,0x10,0x8e,0x06,0x06,0x0f,0x8a,0x85,0xfc,0xbf,0x90,0x0f,0x81,0x7f,0x60,0x17,0x01,0xf9,0x83,0xe7,0x81,0xe1,0xd5,0x6f,0x83,0xf7,0x70,0xe0,0x7f,0xea,0xe3,0xfc,0x30,0x10,0xff,0x20,0x15,0x82,0xfe,0xc0,0x35,0x01,0xff,0x0f,0xf6,0xb0,0x3f,0xd5,0x40,0xff,0x87,0xc8,0x1d,0x40,0x0f,0x00,0x76,0x23,0x7d,0x24,0x82,0x57,0xfe,0x90,0x58,0xa8,0x3e,0x30,0x40,0xf1,0xa0,0xc5,0x20,0x80,0xf8,0xcc,0x03,0xfb,0x51,0x9e,0x07,0x8e,0x3f,0xe4,0x0f,0x9e,0x40,0x7c,0xb0,0x31,0x20,0x7c,0x8f,0xce,0x03,0x11,0x82,0x17,0xe6,0x7d,0x1b,0xbe,0x47,0xfe,0x37,0xd0,0xfc,0x00,0x3c,0x01,0xe0,0x0b,}; +const uint8_t *_I_LevelUp2_04[] = {_I_LevelUp2_04_0}; + +const uint8_t _I_LevelUp2_05_0[] = {0x01,0x00,0x1d,0x01,0x00,0x37,0xf2,0x02,0x0f,0xd8,0x3c,0xfc,0x1d,0x9c,0x0e,0x0f,0x84,0x1f,0x96,0x0b,0x86,0x00,0x61,0x91,0x88,0xc4,0x02,0x06,0x0f,0xb8,0x24,0x32,0x01,0x02,0x07,0xe4,0x1a,0x00,0x01,0x10,0x05,0x41,0xbc,0x70,0xf1,0x08,0x80,0x1e,0x80,0x02,0x18,0x14,0x66,0x21,0x08,0x36,0x48,0x08,0x70,0x7c,0xd9,0x39,0x44,0x42,0xe4,0x00,0x43,0x51,0x7f,0xf4,0x96,0xf8,0x84,0x02,0xf8,0x20,0x73,0x50,0xe0,0x7a,0xf5,0xf9,0x86,0x02,0x0e,0x4d,0x88,0x04,0x07,0xa9,0xde,0x90,0x0d,0x88,0xda,0xe0,0xf2,0xcf,0xc8,0x0d,0xf7,0x49,0x07,0x89,0x35,0xc1,0xeb,0x94,0xeb,0x83,0xf2,0x97,0x2c,0xa4,0x03,0xf2,0x05,0xd8,0xbf,0xe0,0x01,0xf9,0x3f,0xa1,0x83,0xf3,0xf5,0xf1,0xc0,0x83,0xc7,0xfd,0x0f,0x06,0x2c,0x70,0x04,0x30,0xc0,0xe9,0x29,0x44,0x00,0xd7,0x04,0x89,0x83,0xe9,0x30,0x4b,0x11,0x6f,0x08,0x3e,0x1a,0x28,0xfe,0x10,0x7d,0x08,0x49,0x98,0x20,0xfa,0x5d,0x8f,0x80,0x7f,0x40,0x01,0x75,0x8c,0x7c,0x1f,0x91,0x0b,0xf1,0x7e,0xc0,0x03,0xf0,0x2f,0x88,0x3c,0xa6,0x02,0xf9,0x1f,0xa0,0x0c,0x80,0x0d,0x60,0x80,0x4f,0x01,0xe4,0x75,0x20,0x02,0x78,0x23,0xfc,0x0f,0xf8,0xc0,0x87,0xf1,0x38,0x28,0x11,0x3f,0x60,0x11,0x80,0x7f,0x2f,0x44,0x1f,0xe0,0xfd,0x66,0x88,0x3f,0x60,0x80,0xba,0x07,0xf8,0x03,0xc0,0x1e,0x00,0x1c,0x46,0xfa,0x49,0x04,0xaf,0xfd,0x20,0xb1,0x50,0x7c,0x60,0x81,0xe3,0x41,0x8a,0x41,0x01,0xf1,0x98,0x07,0xf6,0xa3,0x3c,0x0f,0x1c,0x7f,0xc8,0x1f,0x3c,0x80,0xf9,0x60,0x62,0x40,0xf9,0x1f,0x9c,0x06,0x22,0x83,0x9c,0x44,0xfa,0x37,0x7c,0x8f,0xfc,0x6f,0xa1,0xf8,0x00,0x78,0x03,0xc0,0x16,}; +const uint8_t *_I_LevelUp2_05[] = {_I_LevelUp2_05_0}; + const uint8_t _I_LevelUp2_01_0[] = {0x01,0x00,0xdc,0x00,0x00,0x37,0xe2,0x02,0x0f,0xd8,0x3c,0xfc,0x1d,0x9c,0x08,0x0f,0x80,0x1f,0x96,0x08,0x06,0x00,0x61,0x91,0x80,0x10,0xc0,0xc1,0xf7,0x04,0x01,0x0c,0x08,0x1f,0xd0,0x60,0x7d,0x83,0x0a,0x18,0x0f,0xb1,0x61,0x42,0x01,0xf7,0x03,0xf8,0x41,0xca,0x44,0x00,0x98,0x0f,0x62,0x09,0x10,0x07,0xe5,0xa2,0x19,0x30,0x07,0xe7,0xb2,0x11,0x20,0x07,0xe7,0x92,0x1e,0x0f,0xe8,0x5d,0x00,0x1f,0x9a,0x48,0x78,0x3f,0x20,0x7e,0xc0,0x7e,0xc0,0xbf,0x10,0x7c,0x00,0x3f,0x3c,0x10,0x30,0x7e,0x80,0x84,0x1f,0x85,0x34,0x6f,0xe8,0x3f,0x20,0x60,0xfd,0xc0,0x02,0xcc,0x1f,0x5c,0x08,0x03,0x34,0x81,0xf4,0xbb,0x18,0x70,0x3f,0x26,0x18,0x02,0x01,0x03,0xea,0x21,0x7e,0x1f,0xef,0xc2,0x07,0x10,0x17,0xec,0x02,0x3c,0x0f,0xcb,0x07,0x00,0x18,0x46,0xfb,0xbf,0xa7,0xf8,0x7c,0x40,0xfc,0x8c,0x03,0xfa,0x10,0x0f,0xf0,0x7f,0x43,0x01,0xfd,0x04,0x05,0xd0,0x3f,0xc0,0x1e,0x00,0xf0,0x00,0xe2,0x37,0xd2,0x48,0x25,0x7f,0xe9,0x05,0x8a,0x83,0xe3,0x04,0x0f,0x1a,0x0c,0x52,0x08,0x0f,0x8c,0xc0,0x3f,0xb5,0x19,0xe0,0x78,0xe3,0xfe,0x40,0xf9,0xe4,0x07,0xcb,0x03,0x12,0x07,0xc8,0xfc,0xe0,0x31,0x14,0x1c,0xe2,0x27,0xd1,0xbb,0xe4,0x7f,0xe3,0x7d,0x0f,0xc0,0x03,0xc0,0x1e,0x00,0xb0,}; const uint8_t *_I_LevelUp2_01[] = {_I_LevelUp2_01_0}; -const uint8_t _I_LevelUp3_07_0[] = {0x01,0x00,0x0b,0x01,0x00,0x37,0xf2,0x0e,0x0f,0xd8,0x3c,0xe0,0x1d,0x9c,0x08,0x6f,0xc0,0x1f,0x96,0x08,0xc6,0x42,0x02,0x0f,0xb8,0xc4,0xc2,0x21,0x03,0x07,0xdc,0x12,0x41,0x10,0x81,0x03,0xfa,0x0c,0x0f,0xb8,0x37,0x82,0x3f,0x0c,0x07,0xdc,0x0a,0x31,0x10,0x84,0x03,0xee,0x07,0xcc,0x93,0xc6,0x01,0xf7,0xff,0x92,0x5a,0x62,0x00,0xfb,0xe0,0xc5,0xea,0x33,0x00,0x7d,0xd0,0x72,0x9d,0x39,0x00,0x3f,0x3e,0x99,0xe0,0x7e,0xe5,0x32,0x74,0x00,0x7e,0x45,0x3a,0x34,0x30,0x7e,0x4b,0x29,0x34,0x40,0x7d,0xf0,0xbb,0x17,0xfe,0x40,0x3e,0xf0,0x53,0xfa,0x1f,0xa0,0x1f,0x7f,0xaf,0x9e,0x07,0x4e,0x0f,0xb8,0x66,0x0b,0x01,0x30,0x80,0xb7,0xec,0x18,0x31,0x80,0x7d,0xe0,0xe0,0x10,0x88,0x60,0x3e,0xb0,0x14,0x11,0x88,0x88,0x88,0x01,0x1c,0x0b,0x04,0x02,0x0f,0x02,0x07,0xd4,0x82,0x41,0xe0,0x80,0x03,0xee,0x61,0xa0,0x8f,0x83,0xf2,0x21,0x7e,0x31,0x20,0x02,0x3e,0x10,0x30,0x18,0xc1,0x05,0xf7,0x00,0x1f,0x89,0xbe,0xcb,0xc3,0x3c,0x80,0x43,0xcd,0xf7,0xff,0x81,0xf0,0x20,0x29,0xfb,0x88,0x40,0x2e,0x10,0x00,0x7d,0xc6,0x00,0x24,0x0f,0xb8,0x40,0x04,0x81,0xfe,0x0f,0xb8,0x60,0x3f,0xa0,0x80,0xf2,0x00,0x58,0x3f,0xc0,0x1e,0x00,0xdc,0x46,0xfa,0x49,0x04,0xaf,0xfd,0x20,0xb1,0x50,0x7c,0x60,0x81,0xe3,0x41,0x8a,0x41,0x01,0xf1,0x98,0x07,0xf6,0xa3,0x3c,0x0f,0x1c,0x7f,0xc8,0x1f,0x3c,0x80,0xf9,0x60,0x62,0x40,0xf9,0x1f,0x9c,0x06,0x22,0x83,0x10,0x7c,0x4f,0xa3,0x77,0xc8,0xff,0xc6,0xfa,0x1f,0x80,0x07,0x80,0x3c,0x01,0x60,}; -const uint8_t *_I_LevelUp3_07[] = {_I_LevelUp3_07_0}; +const uint8_t _I_LevelUp2_02_0[] = {0x01,0x00,0xe1,0x00,0x00,0x37,0xe2,0x02,0x0f,0xda,0xbc,0xfc,0x1d,0x9c,0x0d,0x5f,0xa8,0x1f,0x97,0x0a,0xaf,0x54,0x61,0x9b,0x8d,0x56,0xaa,0x06,0x0f,0xba,0xa5,0x56,0xaa,0x0f,0xcd,0x60,0x7c,0x60,0xc0,0xfb,0xab,0x07,0xc6,0x1a,0x0f,0xb0,0xf0,0xea,0xa1,0x47,0xec,0xfa,0xd5,0xe3,0xa0,0xfb,0xd5,0xfe,0xb5,0xd1,0xa0,0x7d,0xd5,0x6f,0xb5,0xd9,0xa8,0x7f,0x3d,0xda,0xa9,0x50,0x7f,0x3e,0xb5,0xfb,0xa8,0x7f,0x75,0x76,0xa0,0xff,0x55,0x43,0xfb,0xaf,0x70,0x65,0x5b,0xfb,0x57,0xea,0xa7,0xf3,0xd5,0xab,0xd5,0x2f,0xfb,0xab,0x01,0x5f,0xee,0xa8,0x1f,0x61,0xf2,0xaa,0x83,0xec,0x7a,0x21,0xfc,0xc0,0x07,0x88,0x3f,0x7c,0x0d,0x56,0xe8,0x3f,0x96,0x0a,0xaa,0x78,0x43,0xf7,0xb0,0xd5,0x10,0x08,0x1f,0x55,0x0b,0xf8,0xff,0x7e,0x1a,0xb1,0xfe,0xdc,0x07,0xfd,0xe0,0x5f,0x10,0x7e,0xf8,0x03,0xfe,0x30,0x12,0xff,0x6b,0x01,0xfe,0xd4,0x07,0xfc,0x3f,0xda,0xc0,0xff,0x55,0x03,0xfe,0x1f,0x20,0x75,0x00,0x3c,0x01,0xd8,0x8d,0xf4,0x92,0x09,0x5f,0xfa,0x41,0x62,0xa0,0xf8,0xc1,0x03,0xc6,0x83,0x14,0x82,0x03,0xe3,0x30,0x0f,0xed,0x46,0x78,0x1e,0x38,0xff,0x90,0x3e,0x79,0x01,0xf2,0xc0,0xc4,0x81,0xf2,0x3f,0x38,0x0c,0x46,0x08,0x5f,0x99,0xf4,0x6e,0xf9,0x1f,0xf8,0xdf,0x43,0xf0,0x00,0xf0,0x07,0x80,0x2c,}; +const uint8_t *_I_LevelUp2_02[] = {_I_LevelUp2_02_0}; -const uint8_t _I_LevelUp3_02_0[] = {0x01,0x00,0xf4,0x00,0x00,0x37,0xf2,0x02,0x0f,0xda,0xbc,0xfc,0x1d,0x9c,0x0f,0x5f,0xac,0x1f,0x97,0x0b,0xaf,0x54,0x61,0x9b,0x8d,0xd6,0xaa,0x06,0x0f,0xba,0xa5,0x76,0xaa,0x0f,0xcd,0x66,0xbb,0x55,0x06,0x07,0xdd,0x5b,0xef,0x5f,0x86,0x83,0xef,0x55,0xbb,0xdd,0x42,0x81,0xf7,0xd7,0xee,0xdd,0xe3,0xa0,0xfb,0xff,0xeb,0xbd,0xf1,0xa0,0x7d,0xf5,0x7a,0xf5,0xf9,0xa8,0x3e,0xf5,0x7f,0xef,0xf4,0xa8,0x1f,0x75,0x5e,0xaf,0x7e,0xea,0x0f,0xbf,0x5f,0xfb,0x7f,0x6a,0x07,0xdd,0x74,0x80,0x35,0x50,0xfe,0x6b,0xbd,0x5e,0xa4,0xfe,0x77,0x6f,0xfd,0x54,0xfe,0x6f,0xfd,0x7a,0xa0,0x7d,0xff,0xbe,0xbd,0x5e,0xac,0x04,0x1f,0x4d,0xe1,0x00,0x08,0x3e,0xea,0xd5,0x50,0x00,0x83,0xef,0x56,0x1f,0xdc,0x00,0x74,0x6b,0xa1,0xfb,0xe0,0x07,0x47,0x5e,0x1f,0xbb,0x05,0x57,0xea,0x3f,0xcd,0x81,0xfc,0x47,0xf9,0x50,0xbf,0x97,0xf7,0xe0,0x5f,0xeb,0x80,0xff,0xbc,0x1a,0xad,0xf0,0x7f,0x38,0x1f,0xfa,0xba,0x7f,0x4c,0x02,0xbf,0xda,0xc2,0xff,0xb5,0x01,0xff,0x0f,0xf6,0xb0,0x3f,0xd5,0x40,0xff,0x87,0xc8,0x1d,0x40,0x0f,0x00,0x76,0x23,0x7d,0x24,0x82,0x57,0xfe,0x90,0x58,0xa8,0x3e,0x30,0x40,0xf1,0xa0,0xc5,0x20,0x80,0xf8,0xcc,0x03,0xfb,0x51,0x9e,0x07,0x8e,0x3f,0xe4,0x0f,0x9e,0x40,0x7c,0xb0,0x31,0x20,0x7c,0x8f,0xce,0x03,0x11,0x82,0x17,0xe6,0x7d,0x1b,0xbe,0x47,0xfe,0x37,0xd0,0xfc,0x00,0x3c,0x01,0xe0,0x0b,}; -const uint8_t *_I_LevelUp3_02[] = {_I_LevelUp3_02_0}; - -const uint8_t _I_LevelUp3_04_0[] = {0x01,0x00,0x21,0x01,0x00,0x37,0xf2,0x0e,0x0f,0xda,0xbc,0xf4,0x1d,0x9c,0x0d,0x7f,0xe8,0x1f,0x97,0x0a,0xef,0x56,0x02,0x0f,0xbd,0xc6,0xeb,0x75,0x03,0x07,0xdd,0x52,0xeb,0x55,0x07,0xe6,0xb3,0x55,0xba,0x83,0x03,0xee,0xad,0xf5,0xaf,0xc3,0x41,0xf6,0x1e,0x1d,0xd4,0x28,0xfd,0x9d,0xdb,0xbc,0x74,0x1f,0x7f,0xfd,0x77,0xae,0x34,0x0f,0xbe,0xad,0x5e,0xab,0x35,0x06,0xcc,0x12,0x01,0xeb,0xdf,0x7e,0xe5,0x56,0x00,0x7c,0x47,0x20,0x15,0x5f,0xaf,0x7e,0xeb,0x38,0x07,0xc4,0xc0,0x3e,0x5b,0xbb,0x54,0x20,0x7f,0x55,0x5a,0xa9,0x04,0x49,0xf7,0xeb,0x2f,0x8f,0xb8,0x1f,0x7d,0x6e,0xed,0xff,0xba,0x9f,0xcd,0xff,0xaf,0xd4,0x0f,0xbf,0xf7,0xdf,0xab,0xf7,0xf8,0x83,0xeb,0x5d,0xaa,0x60,0x8c,0x04,0x1b,0x10,0x26,0xf8,0x98,0x06,0xba,0x0f,0x98,0x74,0x03,0x56,0x1f,0x1d,0x70,0x3e,0x63,0x18,0x00,0xf1,0x55,0xc1,0xf3,0x00,0xe0,0x7a,0xb5,0x5a,0xfd,0x50,0x3e,0xac,0x17,0x5f,0xad,0x56,0xaf,0xc1,0x07,0xce,0xc0,0xfe,0x24,0x01,0xc0,0xc0,0xc1,0xf1,0x50,0xbf,0x90,0x04,0x7f,0x7f,0x02,0xfe,0xc0,0x2e,0x0f,0xf1,0x3f,0xdf,0x03,0xc3,0xaa,0xdf,0x18,0x04,0x1f,0x37,0x0e,0x07,0xfe,0xaf,0xd5,0xaa,0x8b,0xe8,0xc0,0x5f,0xa3,0xfd,0xc0,0x2b,0x03,0xe1,0x0f,0xe6,0xa0,0xbe,0x21,0xff,0x0f,0xe6,0xb0,0x3f,0xd5,0x40,0xff,0x87,0xc8,0x1d,0x40,0x0f,0x00,0x76,0x23,0x7d,0x24,0x82,0x57,0xfe,0x90,0x58,0xa8,0x3e,0x30,0x40,0xf1,0xa0,0xc5,0x20,0x80,0xf8,0xcc,0x03,0xfb,0x51,0x9e,0x07,0x8e,0x3f,0xe4,0x0f,0x9e,0x40,0x7c,0xb0,0x31,0x20,0x7c,0x8f,0xce,0x03,0x11,0x82,0x17,0xe6,0x7d,0x1b,0xbe,0x47,0xfe,0x37,0xd0,0xfc,0x00,0x3c,0x01,0xe0,0x0b,}; -const uint8_t *_I_LevelUp3_04[] = {_I_LevelUp3_04_0}; +const uint8_t _I_LevelUp2_03_0[] = {0x01,0x00,0xa3,0x00,0x00,0x37,0xf2,0x02,0x0f,0xdf,0xfc,0xfc,0x1d,0x9c,0x0f,0xff,0xfc,0x1f,0x9f,0x00,0x78,0x8c,0x33,0xf0,0x0f,0x18,0x19,0x3b,0x01,0xfe,0x0f,0x18,0x38,0x3e,0xff,0xc0,0xf1,0x87,0x83,0xfc,0xfd,0x80,0x01,0x8f,0x83,0xfc,0x1f,0xca,0x0c,0x07,0xf8,0x3c,0xaf,0xe0,0xff,0x07,0xf8,0x3f,0x9c,0x18,0x8f,0x20,0x7f,0x83,0xff,0xff,0x01,0x07,0xf8,0x3f,0xcb,0xfc,0x0f,0xac,0x00,0x3f,0xb8,0x00,0xfe,0xf0,0x03,0xfb,0xe0,0x0f,0xf0,0x7f,0x83,0xfc,0x9f,0xe6,0xff,0x07,0xf0,0xc1,0x01,0xf7,0xf8,0x07,0xf8,0x3f,0xc1,0xfd,0xfc,0x07,0xf8,0x3f,0xc1,0xfc,0x00,0xf0,0x06,0xe2,0x37,0xd2,0x48,0x25,0x7f,0xe9,0x05,0x8a,0x83,0xe3,0x04,0x0f,0x1a,0x0c,0x52,0x08,0x0f,0x8c,0xc0,0x3f,0xb5,0x19,0xe0,0x78,0xe3,0xfe,0x40,0xf9,0xe4,0x07,0xcb,0x03,0x12,0x07,0xc8,0xfc,0xe0,0x31,0x18,0x21,0x7e,0x67,0xd1,0xbb,0xe4,0x7f,0xe3,0x7d,0x0f,0xc0,0x03,0xc0,0x1e,0x00,0xb0,}; +const uint8_t *_I_LevelUp2_03[] = {_I_LevelUp2_03_0}; const uint8_t _I_LevelUp3_05_0[] = {0x01,0x00,0x34,0x01,0x00,0x37,0xf2,0x0e,0x0f,0xd8,0x3c,0xe0,0x1d,0x9c,0x08,0x6f,0xc0,0x1f,0x96,0x08,0xc6,0x42,0x02,0x0f,0xb8,0xc4,0xc2,0x21,0x03,0x07,0xdc,0x12,0x41,0x10,0x81,0x03,0xfa,0x0c,0x0f,0xb8,0x37,0x82,0x3f,0x0c,0x06,0x45,0x00,0x04,0x30,0x28,0xc4,0x42,0x10,0x6c,0x90,0x10,0xc0,0xf9,0x92,0x78,0xc0,0x5c,0xc0,0x09,0x80,0x35,0x0f,0xfe,0x49,0x69,0x88,0x40,0x2f,0x82,0x07,0x35,0x0f,0x06,0x2f,0x51,0x98,0x60,0x16,0x50,0x5a,0x1a,0x0e,0x53,0xa7,0x20,0x1b,0x11,0xb5,0xc1,0xe3,0xf4,0xcf,0x48,0x0d,0xf6,0x1f,0x1c,0x99,0x35,0xc1,0xeb,0x14,0xe8,0xd0,0xc1,0xf9,0x2c,0xa4,0xd1,0x01,0xf7,0xc2,0xec,0x5f,0xf9,0x00,0xfb,0xc1,0x4f,0xe8,0x7e,0x80,0x7d,0xfe,0xbe,0x78,0x1d,0x3c,0x03,0xfd,0x0f,0x06,0x2c,0x70,0x04,0x30,0xcc,0x16,0x02,0x60,0xa5,0x10,0x03,0x5c,0x12,0x24,0x0c,0x18,0xc0,0x3e,0x13,0x05,0x83,0x80,0x42,0x21,0x80,0xf8,0x68,0x95,0x04,0x62,0x22,0x22,0x78,0xcd,0x82,0x01,0x07,0x81,0x03,0xea,0x41,0x20,0xf0,0x40,0x01,0xf7,0x30,0xd0,0x47,0xc1,0xf9,0x10,0xbf,0x18,0x90,0x01,0x1f,0x08,0x1b,0xd0,0xa0,0x33,0x01,0x7c,0xc0,0x07,0xe2,0x6f,0x10,0x18,0x80,0x1c,0xbc,0x33,0xc8,0x04,0x3e,0x03,0x80,0x18,0xb7,0x82,0x3f,0xc0,0xff,0xc0,0xf8,0x10,0x11,0xfc,0x4e,0x0a,0x04,0xb4,0x22,0x7d,0x2f,0x04,0x02,0x40,0xfb,0x84,0x00,0x48,0x1f,0xe0,0xfb,0x86,0x03,0xfa,0x08,0x0f,0x20,0x05,0x83,0xfc,0x01,0xe0,0x0d,0xc4,0x6f,0xa4,0x90,0x4a,0xff,0xd2,0x0b,0x15,0x07,0xc6,0x08,0x1e,0x34,0x18,0xa4,0x10,0x1f,0x19,0x80,0x7f,0x6a,0x33,0xc0,0xf1,0xc7,0xfc,0x81,0xf3,0xc8,0x0f,0x96,0x06,0x24,0x0f,0x91,0xf9,0xc0,0x62,0x28,0x31,0x07,0xc4,0xfa,0x37,0x7c,0x8f,0xfc,0x6f,0xa1,0xf8,0x00,0x78,0x03,0xc0,0x16,}; const uint8_t *_I_LevelUp3_05[] = {_I_LevelUp3_05_0}; -const uint8_t _I_LevelUp3_01_0[] = {0x01,0x00,0xf1,0x00,0x00,0x37,0xf2,0x02,0x0f,0xd8,0x3c,0xfc,0x1d,0x9c,0x0e,0x0f,0x84,0x1f,0x96,0x0b,0x86,0x00,0x61,0x91,0x88,0xc4,0x02,0x06,0x0f,0xb8,0x24,0x32,0x01,0x02,0x07,0xe4,0x1a,0x00,0x01,0x10,0x05,0x41,0xbc,0x70,0xf1,0x08,0x80,0x2a,0x05,0x19,0x88,0x42,0x01,0xf7,0x83,0xe6,0xc9,0xca,0x22,0x00,0xaf,0xfe,0x92,0xdf,0x10,0x07,0xde,0x07,0xaf,0x5f,0x98,0x03,0xee,0x03,0xd4,0xef,0x48,0x01,0xfb,0x9f,0x07,0xe5,0x24,0x1e,0x34,0x00,0x7e,0x65,0x3a,0xe0,0xfc,0xa5,0xcb,0x29,0x00,0xfc,0x81,0x76,0x2f,0xf8,0x00,0x7e,0x4f,0xe8,0x60,0xfc,0xfd,0x7c,0x70,0x20,0xfc,0x86,0x03,0x4a,0x02,0xdf,0xb4,0x19,0x83,0xea,0x07,0x00,0x6f,0x08,0x3e,0xb0,0x00,0xb1,0x7f,0x08,0x3e,0xb8,0x00,0x21,0x83,0x83,0xed,0x76,0x3e,0x01,0xfe,0x4c,0x30,0x11,0xf0,0x7e,0x44,0x2f,0xc5,0xfd,0xf8,0x17,0xc4,0x5f,0xa3,0xfe,0xb0,0x40,0x27,0x80,0xfc,0xe0,0x7f,0xc6,0x04,0x9f,0xb8,0x82,0xbf,0xa3,0x00,0xfe,0x5e,0x88,0x3f,0xc1,0xfa,0xcd,0x10,0x7e,0xc1,0x01,0x74,0x0f,0xf0,0x07,0x80,0x3c,0x00,0x38,0x8d,0xf4,0x92,0x09,0x5f,0xfa,0x41,0x62,0xa0,0xf8,0xc1,0x03,0xc6,0x83,0x14,0x82,0x03,0xe3,0x30,0x0f,0xed,0x46,0x78,0x1e,0x38,0xff,0x90,0x3e,0x79,0x01,0xf2,0xc0,0xc4,0x81,0xf2,0x3f,0x38,0x0c,0x45,0x07,0x38,0x89,0xf4,0x6e,0xf9,0x1f,0xf8,0xdf,0x43,0xf0,0x00,0xf0,0x07,0x80,0x2c,}; -const uint8_t *_I_LevelUp3_01[] = {_I_LevelUp3_01_0}; +const uint8_t _I_LevelUp3_04_0[] = {0x01,0x00,0x21,0x01,0x00,0x37,0xf2,0x0e,0x0f,0xda,0xbc,0xf4,0x1d,0x9c,0x0d,0x7f,0xe8,0x1f,0x97,0x0a,0xef,0x56,0x02,0x0f,0xbd,0xc6,0xeb,0x75,0x03,0x07,0xdd,0x52,0xeb,0x55,0x07,0xe6,0xb3,0x55,0xba,0x83,0x03,0xee,0xad,0xf5,0xaf,0xc3,0x41,0xf6,0x1e,0x1d,0xd4,0x28,0xfd,0x9d,0xdb,0xbc,0x74,0x1f,0x7f,0xfd,0x77,0xae,0x34,0x0f,0xbe,0xad,0x5e,0xab,0x35,0x06,0xcc,0x12,0x01,0xeb,0xdf,0x7e,0xe5,0x56,0x00,0x7c,0x47,0x20,0x15,0x5f,0xaf,0x7e,0xeb,0x38,0x07,0xc4,0xc0,0x3e,0x5b,0xbb,0x54,0x20,0x7f,0x55,0x5a,0xa9,0x04,0x49,0xf7,0xeb,0x2f,0x8f,0xb8,0x1f,0x7d,0x6e,0xed,0xff,0xba,0x9f,0xcd,0xff,0xaf,0xd4,0x0f,0xbf,0xf7,0xdf,0xab,0xf7,0xf8,0x83,0xeb,0x5d,0xaa,0x60,0x8c,0x04,0x1b,0x10,0x26,0xf8,0x98,0x06,0xba,0x0f,0x98,0x74,0x03,0x56,0x1f,0x1d,0x70,0x3e,0x63,0x18,0x00,0xf1,0x55,0xc1,0xf3,0x00,0xe0,0x7a,0xb5,0x5a,0xfd,0x50,0x3e,0xac,0x17,0x5f,0xad,0x56,0xaf,0xc1,0x07,0xce,0xc0,0xfe,0x24,0x01,0xc0,0xc0,0xc1,0xf1,0x50,0xbf,0x90,0x04,0x7f,0x7f,0x02,0xfe,0xc0,0x2e,0x0f,0xf1,0x3f,0xdf,0x03,0xc3,0xaa,0xdf,0x18,0x04,0x1f,0x37,0x0e,0x07,0xfe,0xaf,0xd5,0xaa,0x8b,0xe8,0xc0,0x5f,0xa3,0xfd,0xc0,0x2b,0x03,0xe1,0x0f,0xe6,0xa0,0xbe,0x21,0xff,0x0f,0xe6,0xb0,0x3f,0xd5,0x40,0xff,0x87,0xc8,0x1d,0x40,0x0f,0x00,0x76,0x23,0x7d,0x24,0x82,0x57,0xfe,0x90,0x58,0xa8,0x3e,0x30,0x40,0xf1,0xa0,0xc5,0x20,0x80,0xf8,0xcc,0x03,0xfb,0x51,0x9e,0x07,0x8e,0x3f,0xe4,0x0f,0x9e,0x40,0x7c,0xb0,0x31,0x20,0x7c,0x8f,0xce,0x03,0x11,0x82,0x17,0xe6,0x7d,0x1b,0xbe,0x47,0xfe,0x37,0xd0,0xfc,0x00,0x3c,0x01,0xe0,0x0b,}; +const uint8_t *_I_LevelUp3_04[] = {_I_LevelUp3_04_0}; + +const uint8_t _I_LevelUp3_06_0[] = {0x01,0x00,0x30,0x01,0x00,0x37,0xf2,0x0e,0x0f,0xd8,0x3c,0xe0,0x1d,0x9c,0x08,0x6f,0xc0,0x17,0x18,0x00,0x19,0x58,0x23,0x19,0x08,0x08,0x42,0x20,0xc0,0x21,0x8c,0x4c,0x22,0x10,0x30,0x7c,0x43,0x00,0x43,0x04,0x90,0x44,0x20,0x43,0xfb,0x07,0x90,0x94,0xaf,0x03,0x29,0xf0,0x47,0xc4,0xa5,0x0e,0x07,0xc4,0x0a,0x31,0x10,0x84,0x01,0x48,0x1f,0x10,0x3e,0x64,0x9e,0x30,0x3f,0xbf,0xfc,0x92,0xd3,0x10,0x07,0xdf,0x06,0x2f,0x51,0x98,0x03,0xee,0x83,0x94,0xe9,0xc8,0x01,0xf9,0xf4,0xcf,0x03,0xf7,0x29,0x93,0xa0,0x03,0xf2,0x29,0xd1,0xa1,0x83,0xf2,0x59,0x49,0xa2,0x03,0xef,0x85,0xd8,0xbf,0xf2,0x01,0xf7,0x82,0x9f,0xd0,0xfd,0x00,0x51,0xe0,0x03,0xe3,0xf5,0xf3,0xc0,0xe9,0xc0,0xc4,0xb3,0x20,0x00,0xd8,0x1e,0x47,0x82,0xc0,0x4c,0x20,0x22,0xfa,0x83,0x03,0x06,0x30,0x0f,0x76,0xa9,0xe0,0xc5,0x43,0x0c,0x0f,0xd6,0x02,0x82,0x31,0x11,0x11,0x00,0x23,0x80,0x43,0x18,0x3c,0x08,0x1f,0x52,0x09,0x07,0x80,0x6c,0x20,0xfa,0x98,0x68,0x23,0xe0,0xfc,0x88,0x5f,0x8c,0x48,0x00,0x8f,0x84,0x0c,0x06,0x30,0x41,0x7d,0xc0,0x07,0xe2,0x6f,0xb2,0xf0,0xcf,0x20,0x10,0xf3,0x7d,0xff,0xe0,0x7c,0x08,0x08,0x3e,0x18,0xa5,0x10,0x80,0x5c,0x20,0x00,0xf1,0x67,0x20,0x01,0x23,0x00,0x12,0x07,0xc3,0x00,0x81,0x22,0x01,0x11,0x7c,0x1b,0x08,0x1e,0xb2,0x06,0x62,0xbf,0xcc,0x3f,0x60,0x02,0x82,0x12,0xe8,0x1f,0xe0,0x0f,0x00,0x78,0x00,0x71,0x1b,0xe9,0x24,0x12,0xbf,0xf4,0x82,0xc5,0x41,0xf1,0x82,0x07,0x8d,0x06,0x29,0x04,0x07,0xc6,0x60,0x1f,0xda,0x8c,0xf0,0x3c,0x71,0xff,0x20,0x7c,0xf2,0x03,0xe5,0x81,0x89,0x03,0xe4,0x7e,0x70,0x18,0x8a,0x0c,0x41,0xf1,0x3e,0x8d,0xdf,0x23,0xff,0x1b,0xe8,0x7e,0x00,0x1e,0x00,0xf0,0x05,0x80,}; +const uint8_t *_I_LevelUp3_06[] = {_I_LevelUp3_06_0}; + +const uint8_t _I_LevelUp3_07_0[] = {0x01,0x00,0x0b,0x01,0x00,0x37,0xf2,0x0e,0x0f,0xd8,0x3c,0xe0,0x1d,0x9c,0x08,0x6f,0xc0,0x1f,0x96,0x08,0xc6,0x42,0x02,0x0f,0xb8,0xc4,0xc2,0x21,0x03,0x07,0xdc,0x12,0x41,0x10,0x81,0x03,0xfa,0x0c,0x0f,0xb8,0x37,0x82,0x3f,0x0c,0x07,0xdc,0x0a,0x31,0x10,0x84,0x03,0xee,0x07,0xcc,0x93,0xc6,0x01,0xf7,0xff,0x92,0x5a,0x62,0x00,0xfb,0xe0,0xc5,0xea,0x33,0x00,0x7d,0xd0,0x72,0x9d,0x39,0x00,0x3f,0x3e,0x99,0xe0,0x7e,0xe5,0x32,0x74,0x00,0x7e,0x45,0x3a,0x34,0x30,0x7e,0x4b,0x29,0x34,0x40,0x7d,0xf0,0xbb,0x17,0xfe,0x40,0x3e,0xf0,0x53,0xfa,0x1f,0xa0,0x1f,0x7f,0xaf,0x9e,0x07,0x4e,0x0f,0xb8,0x66,0x0b,0x01,0x30,0x80,0xb7,0xec,0x18,0x31,0x80,0x7d,0xe0,0xe0,0x10,0x88,0x60,0x3e,0xb0,0x14,0x11,0x88,0x88,0x88,0x01,0x1c,0x0b,0x04,0x02,0x0f,0x02,0x07,0xd4,0x82,0x41,0xe0,0x80,0x03,0xee,0x61,0xa0,0x8f,0x83,0xf2,0x21,0x7e,0x31,0x20,0x02,0x3e,0x10,0x30,0x18,0xc1,0x05,0xf7,0x00,0x1f,0x89,0xbe,0xcb,0xc3,0x3c,0x80,0x43,0xcd,0xf7,0xff,0x81,0xf0,0x20,0x29,0xfb,0x88,0x40,0x2e,0x10,0x00,0x7d,0xc6,0x00,0x24,0x0f,0xb8,0x40,0x04,0x81,0xfe,0x0f,0xb8,0x60,0x3f,0xa0,0x80,0xf2,0x00,0x58,0x3f,0xc0,0x1e,0x00,0xdc,0x46,0xfa,0x49,0x04,0xaf,0xfd,0x20,0xb1,0x50,0x7c,0x60,0x81,0xe3,0x41,0x8a,0x41,0x01,0xf1,0x98,0x07,0xf6,0xa3,0x3c,0x0f,0x1c,0x7f,0xc8,0x1f,0x3c,0x80,0xf9,0x60,0x62,0x40,0xf9,0x1f,0x9c,0x06,0x22,0x83,0x10,0x7c,0x4f,0xa3,0x77,0xc8,0xff,0xc6,0xfa,0x1f,0x80,0x07,0x80,0x3c,0x01,0x60,}; +const uint8_t *_I_LevelUp3_07[] = {_I_LevelUp3_07_0}; const uint8_t _I_LevelUp3_03_0[] = {0x01,0x00,0xa3,0x00,0x00,0x37,0xf2,0x02,0x0f,0xdf,0xfc,0xfc,0x1d,0x9c,0x0f,0xff,0xfc,0x1f,0x9f,0x00,0x78,0x8c,0x33,0xf0,0x0f,0x18,0x19,0x3b,0x01,0xfe,0x0f,0x18,0x38,0x3e,0xff,0xc0,0xf1,0x87,0x83,0xfc,0xfd,0x80,0x01,0x8f,0x83,0xfc,0x1f,0xca,0x0c,0x07,0xf8,0x3c,0xaf,0xe0,0xff,0x07,0xf8,0x3f,0x9c,0x18,0x8f,0x20,0x7f,0x83,0xff,0xff,0x01,0x07,0xf8,0x3f,0xcb,0xfc,0x0f,0xac,0x00,0x3f,0xb8,0x00,0xfe,0xf0,0x03,0xfb,0xe0,0x0f,0xf0,0x7f,0x83,0xfc,0x9f,0xe6,0xff,0x07,0xf0,0xc1,0x01,0xf7,0xf8,0x07,0xf8,0x3f,0xc1,0xfd,0xfc,0x07,0xf8,0x3f,0xc1,0xfc,0x00,0xf0,0x06,0xe2,0x37,0xd2,0x48,0x25,0x7f,0xe9,0x05,0x8a,0x83,0xe3,0x04,0x0f,0x1a,0x0c,0x52,0x08,0x0f,0x8c,0xc0,0x3f,0xb5,0x19,0xe0,0x78,0xe3,0xfe,0x40,0xf9,0xe4,0x07,0xcb,0x03,0x12,0x07,0xc8,0xfc,0xe0,0x31,0x18,0x21,0x7e,0x67,0xd1,0xbb,0xe4,0x7f,0xe3,0x7d,0x0f,0xc0,0x03,0xc0,0x1e,0x00,0xb0,}; const uint8_t *_I_LevelUp3_03[] = {_I_LevelUp3_03_0}; -const uint8_t _I_LevelUp3_06_0[] = {0x01,0x00,0x30,0x01,0x00,0x37,0xf2,0x0e,0x0f,0xd8,0x3c,0xe0,0x1d,0x9c,0x08,0x6f,0xc0,0x17,0x18,0x00,0x19,0x58,0x23,0x19,0x08,0x08,0x42,0x20,0xc0,0x21,0x8c,0x4c,0x22,0x10,0x30,0x7c,0x43,0x00,0x43,0x04,0x90,0x44,0x20,0x43,0xfb,0x07,0x90,0x94,0xaf,0x03,0x29,0xf0,0x47,0xc4,0xa5,0x0e,0x07,0xc4,0x0a,0x31,0x10,0x84,0x01,0x48,0x1f,0x10,0x3e,0x64,0x9e,0x30,0x3f,0xbf,0xfc,0x92,0xd3,0x10,0x07,0xdf,0x06,0x2f,0x51,0x98,0x03,0xee,0x83,0x94,0xe9,0xc8,0x01,0xf9,0xf4,0xcf,0x03,0xf7,0x29,0x93,0xa0,0x03,0xf2,0x29,0xd1,0xa1,0x83,0xf2,0x59,0x49,0xa2,0x03,0xef,0x85,0xd8,0xbf,0xf2,0x01,0xf7,0x82,0x9f,0xd0,0xfd,0x00,0x51,0xe0,0x03,0xe3,0xf5,0xf3,0xc0,0xe9,0xc0,0xc4,0xb3,0x20,0x00,0xd8,0x1e,0x47,0x82,0xc0,0x4c,0x20,0x22,0xfa,0x83,0x03,0x06,0x30,0x0f,0x76,0xa9,0xe0,0xc5,0x43,0x0c,0x0f,0xd6,0x02,0x82,0x31,0x11,0x11,0x00,0x23,0x80,0x43,0x18,0x3c,0x08,0x1f,0x52,0x09,0x07,0x80,0x6c,0x20,0xfa,0x98,0x68,0x23,0xe0,0xfc,0x88,0x5f,0x8c,0x48,0x00,0x8f,0x84,0x0c,0x06,0x30,0x41,0x7d,0xc0,0x07,0xe2,0x6f,0xb2,0xf0,0xcf,0x20,0x10,0xf3,0x7d,0xff,0xe0,0x7c,0x08,0x08,0x3e,0x18,0xa5,0x10,0x80,0x5c,0x20,0x00,0xf1,0x67,0x20,0x01,0x23,0x00,0x12,0x07,0xc3,0x00,0x81,0x22,0x01,0x11,0x7c,0x1b,0x08,0x1e,0xb2,0x06,0x62,0xbf,0xcc,0x3f,0x60,0x02,0x82,0x12,0xe8,0x1f,0xe0,0x0f,0x00,0x78,0x00,0x71,0x1b,0xe9,0x24,0x12,0xbf,0xf4,0x82,0xc5,0x41,0xf1,0x82,0x07,0x8d,0x06,0x29,0x04,0x07,0xc6,0x60,0x1f,0xda,0x8c,0xf0,0x3c,0x71,0xff,0x20,0x7c,0xf2,0x03,0xe5,0x81,0x89,0x03,0xe4,0x7e,0x70,0x18,0x8a,0x0c,0x41,0xf1,0x3e,0x8d,0xdf,0x23,0xff,0x1b,0xe8,0x7e,0x00,0x1e,0x00,0xf0,0x05,0x80,}; -const uint8_t *_I_LevelUp3_06[] = {_I_LevelUp3_06_0}; +const uint8_t _I_LevelUp3_02_0[] = {0x01,0x00,0xf4,0x00,0x00,0x37,0xf2,0x02,0x0f,0xda,0xbc,0xfc,0x1d,0x9c,0x0f,0x5f,0xac,0x1f,0x97,0x0b,0xaf,0x54,0x61,0x9b,0x8d,0xd6,0xaa,0x06,0x0f,0xba,0xa5,0x76,0xaa,0x0f,0xcd,0x66,0xbb,0x55,0x06,0x07,0xdd,0x5b,0xef,0x5f,0x86,0x83,0xef,0x55,0xbb,0xdd,0x42,0x81,0xf7,0xd7,0xee,0xdd,0xe3,0xa0,0xfb,0xff,0xeb,0xbd,0xf1,0xa0,0x7d,0xf5,0x7a,0xf5,0xf9,0xa8,0x3e,0xf5,0x7f,0xef,0xf4,0xa8,0x1f,0x75,0x5e,0xaf,0x7e,0xea,0x0f,0xbf,0x5f,0xfb,0x7f,0x6a,0x07,0xdd,0x74,0x80,0x35,0x50,0xfe,0x6b,0xbd,0x5e,0xa4,0xfe,0x77,0x6f,0xfd,0x54,0xfe,0x6f,0xfd,0x7a,0xa0,0x7d,0xff,0xbe,0xbd,0x5e,0xac,0x04,0x1f,0x4d,0xe1,0x00,0x08,0x3e,0xea,0xd5,0x50,0x00,0x83,0xef,0x56,0x1f,0xdc,0x00,0x74,0x6b,0xa1,0xfb,0xe0,0x07,0x47,0x5e,0x1f,0xbb,0x05,0x57,0xea,0x3f,0xcd,0x81,0xfc,0x47,0xf9,0x50,0xbf,0x97,0xf7,0xe0,0x5f,0xeb,0x80,0xff,0xbc,0x1a,0xad,0xf0,0x7f,0x38,0x1f,0xfa,0xba,0x7f,0x4c,0x02,0xbf,0xda,0xc2,0xff,0xb5,0x01,0xff,0x0f,0xf6,0xb0,0x3f,0xd5,0x40,0xff,0x87,0xc8,0x1d,0x40,0x0f,0x00,0x76,0x23,0x7d,0x24,0x82,0x57,0xfe,0x90,0x58,0xa8,0x3e,0x30,0x40,0xf1,0xa0,0xc5,0x20,0x80,0xf8,0xcc,0x03,0xfb,0x51,0x9e,0x07,0x8e,0x3f,0xe4,0x0f,0x9e,0x40,0x7c,0xb0,0x31,0x20,0x7c,0x8f,0xce,0x03,0x11,0x82,0x17,0xe6,0x7d,0x1b,0xbe,0x47,0xfe,0x37,0xd0,0xfc,0x00,0x3c,0x01,0xe0,0x0b,}; +const uint8_t *_I_LevelUp3_02[] = {_I_LevelUp3_02_0}; + +const uint8_t _I_LevelUp3_01_0[] = {0x01,0x00,0xf1,0x00,0x00,0x37,0xf2,0x02,0x0f,0xd8,0x3c,0xfc,0x1d,0x9c,0x0e,0x0f,0x84,0x1f,0x96,0x0b,0x86,0x00,0x61,0x91,0x88,0xc4,0x02,0x06,0x0f,0xb8,0x24,0x32,0x01,0x02,0x07,0xe4,0x1a,0x00,0x01,0x10,0x05,0x41,0xbc,0x70,0xf1,0x08,0x80,0x2a,0x05,0x19,0x88,0x42,0x01,0xf7,0x83,0xe6,0xc9,0xca,0x22,0x00,0xaf,0xfe,0x92,0xdf,0x10,0x07,0xde,0x07,0xaf,0x5f,0x98,0x03,0xee,0x03,0xd4,0xef,0x48,0x01,0xfb,0x9f,0x07,0xe5,0x24,0x1e,0x34,0x00,0x7e,0x65,0x3a,0xe0,0xfc,0xa5,0xcb,0x29,0x00,0xfc,0x81,0x76,0x2f,0xf8,0x00,0x7e,0x4f,0xe8,0x60,0xfc,0xfd,0x7c,0x70,0x20,0xfc,0x86,0x03,0x4a,0x02,0xdf,0xb4,0x19,0x83,0xea,0x07,0x00,0x6f,0x08,0x3e,0xb0,0x00,0xb1,0x7f,0x08,0x3e,0xb8,0x00,0x21,0x83,0x83,0xed,0x76,0x3e,0x01,0xfe,0x4c,0x30,0x11,0xf0,0x7e,0x44,0x2f,0xc5,0xfd,0xf8,0x17,0xc4,0x5f,0xa3,0xfe,0xb0,0x40,0x27,0x80,0xfc,0xe0,0x7f,0xc6,0x04,0x9f,0xb8,0x82,0xbf,0xa3,0x00,0xfe,0x5e,0x88,0x3f,0xc1,0xfa,0xcd,0x10,0x7e,0xc1,0x01,0x74,0x0f,0xf0,0x07,0x80,0x3c,0x00,0x38,0x8d,0xf4,0x92,0x09,0x5f,0xfa,0x41,0x62,0xa0,0xf8,0xc1,0x03,0xc6,0x83,0x14,0x82,0x03,0xe3,0x30,0x0f,0xed,0x46,0x78,0x1e,0x38,0xff,0x90,0x3e,0x79,0x01,0xf2,0xc0,0xc4,0x81,0xf2,0x3f,0x38,0x0c,0x45,0x07,0x38,0x89,0xf4,0x6e,0xf9,0x1f,0xf8,0xdf,0x43,0xf0,0x00,0xf0,0x07,0x80,0x2c,}; +const uint8_t *_I_LevelUp3_01[] = {_I_LevelUp3_01_0}; const uint8_t _A_LevelUpPending_128x51_0[] = {0x01,0x00,0xa9,0x01,0x00,0x1c,0xfc,0x1d,0xbf,0x0e,0x04,0x04,0x1f,0x90,0xc8,0x04,0x18,0x1f,0x90,0x28,0x04,0x20,0x1d,0x62,0xd2,0x98,0x03,0xfe,0x01,0x80,0xf9,0xdf,0x39,0xd8,0x7f,0x45,0x2e,0xe4,0x2b,0x18,0x04,0x80,0x04,0x34,0x00,0x08,0xc5,0x20,0xb1,0x1c,0x0c,0xa2,0x91,0x8a,0x07,0x94,0x40,0x04,0x38,0x00,0x78,0xc4,0x01,0xe5,0x29,0xa4,0x42,0x81,0xe7,0xf8,0x07,0x8c,0x06,0x81,0xf6,0x9e,0x47,0xf0,0x3e,0xaa,0x48,0xbc,0xe1,0x10,0x48,0x0e,0x02,0x07,0x40,0xaa,0x41,0x03,0xe3,0x2c,0xa4,0x60,0x81,0xe5,0x00,0xba,0x40,0xbe,0x1d,0xfa,0x06,0x50,0x1e,0x43,0xf2,0x07,0x16,0x13,0x77,0x02,0x86,0x70,0x30,0x31,0x3b,0xe8,0x3c,0x7d,0x1b,0x3b,0x88,0x7c,0xa8,0x9f,0xa8,0x14,0x0e,0x00,0xb1,0xad,0x17,0xef,0x84,0x04,0x10,0x7d,0x78,0xae,0x72,0x20,0x7f,0x83,0xf3,0xf3,0x07,0x88,0xc0,0x3f,0xe0,0xf4,0x53,0x08,0x00,0xe8,0xb8,0xc2,0xf0,0xd5,0x60,0x1f,0x09,0xe6,0x7f,0xc7,0xc0,0x07,0x1e,0x03,0x09,0x79,0x81,0xfe,0x35,0x4a,0x51,0xa2,0xd0,0x62,0x9c,0x11,0x29,0xe0,0x30,0x42,0xe1,0xae,0x07,0xc4,0x1e,0x51,0x0e,0x01,0xdc,0x41,0xe6,0x15,0x1d,0x7d,0xa8,0x5e,0x58,0xf1,0x78,0x83,0xce,0xc1,0x81,0x5f,0x0d,0x56,0x6a,0x1f,0x18,0xa4,0x06,0x08,0x2f,0x40,0x78,0xc0,0xf8,0x1a,0xa8,0xd0,0x3c,0x64,0x83,0xf2,0x27,0x9f,0x81,0xb8,0x3e,0x0a,0xbc,0x74,0x1e,0x34,0x42,0xf8,0x9b,0xd3,0xe1,0x80,0x83,0xfe,0x35,0xf1,0xf4,0x74,0xdc,0x20,0x10,0xaf,0xf7,0xfe,0x66,0x0f,0xbf,0xd7,0xfc,0x1f,0xbc,0x20,0x78,0xc8,0x41,0xf3,0x18,0x80,0x40,0xa7,0xfc,0x09,0x18,0x3f,0x2f,0xd0,0x0f,0x78,0x3f,0x3f,0x90,0x1e,0xe0,0x3e,0x61,0x00,0xf2,0x83,0xfc,0x01,0xf9,0xa8,0x8f,0xf0,0x1f,0xe8,0x0f,0x7a,0x87,0xff,0xc2,0x0f,0x98,0x20,0x3c,0x74,0x1f,0xad,0xfb,0x64,0xc1,0xed,0x80,0x80,0xd0,0x2a,0xb8,0x70,0x7e,0x60,0x35,0x70,0x60,0x7c,0xc0,0x81,0xe3,0x00,0xab,0x41,0x60,0xc0,0xfb,0x84,0x6f,0x21,0xc4,0x51,0x00,0x38,0xb4,0x60,0x37,0x0f,0x84,0x3c,0x1f,0x03,0xd2,0x27,0x8a,0x90,0x61,0x80,0xf8,0x08,0x9c,0x0e,0x18,0xb5,0x10,0x03,0x70,0x20,0x01,0xd1,0x80,0x77,0xa1,0xf1,0x00,0x7b,0x83,0x44,0x1e,0x5f,0x08,0x3c,0xc0,0x1f,0x83,0x01,0x90,0x03,0xde,0xc0,0x0f,0x33,0xa0,0x81,0x0c,0x00,0x81,0x81,0x07,0xa1,0x18,0x40,0x0c,0x38,0x11,0x51,0xc1,0x8c,0xc2,0x00,0x62,0xc0,0x83,0xcd,0x1c,0x2f,0x07,0x3c,0x08,0x3f,0x61,0x00,0xf4,0x02,0x8b,0x81,0xc0,}; const uint8_t _A_LevelUpPending_128x51_1[] = {0x01,0x00,0xad,0x01,0x00,0x1c,0xfc,0x1d,0xbf,0x0e,0x04,0x04,0x1f,0x90,0xc8,0x04,0x18,0x1f,0x90,0x28,0x04,0x20,0x1d,0x62,0xd2,0x98,0x03,0xfe,0x01,0x80,0xf9,0xdf,0x39,0xd8,0x7f,0x45,0x2e,0xe4,0x2b,0x18,0x04,0x80,0x04,0x34,0x00,0x08,0xc5,0x20,0xb1,0x1c,0x0c,0xa2,0x91,0x8a,0x07,0x94,0x40,0x04,0x38,0x00,0x78,0xc4,0x01,0xe5,0x29,0xa4,0x42,0x81,0xe7,0xf8,0x07,0x8c,0x06,0x81,0xf6,0x9e,0x47,0xf0,0x3e,0xaa,0x48,0xbc,0xe1,0x10,0x48,0x0e,0x02,0x07,0x40,0xaa,0x41,0x03,0xe3,0x2c,0xa4,0x60,0x81,0xe5,0x00,0xba,0x40,0xbe,0x1d,0xfa,0x06,0x50,0x1e,0x43,0xf2,0x07,0x16,0x13,0x75,0x02,0x86,0x70,0x30,0x31,0x3b,0xe8,0x3c,0x7d,0x1b,0x3b,0x88,0x7c,0xa8,0x9f,0xa8,0x14,0x0e,0x00,0xb1,0xad,0x17,0xeb,0x84,0x04,0x10,0x7d,0x50,0xae,0x72,0x20,0x7e,0x68,0x81,0xfd,0x81,0x83,0xc4,0x60,0x1f,0xf0,0x7a,0x29,0x84,0x00,0x74,0x1c,0x61,0x78,0x6a,0xb0,0x0f,0x84,0xf3,0x3f,0xe3,0xe0,0x03,0x8f,0x01,0x3c,0xbc,0x40,0xff,0x1a,0xa5,0x28,0xd1,0x68,0x31,0x4e,0x08,0x94,0xf0,0x16,0x26,0x00,0xd7,0x03,0xe2,0x0f,0x28,0x87,0x00,0xee,0x20,0xf2,0x36,0x96,0xbe,0xd4,0x2f,0x2c,0x78,0xbc,0x41,0xe9,0x82,0x01,0x0d,0x56,0x6a,0x1f,0x18,0xa4,0x06,0x08,0x2f,0x4e,0x00,0x3c,0x78,0x1a,0xa8,0xd0,0x3c,0x64,0x83,0xf2,0x27,0x98,0x3c,0x60,0x3e,0x0a,0xbc,0x34,0x1e,0x34,0x42,0xf8,0x9b,0xd3,0x81,0x83,0x82,0xfe,0x35,0xf0,0xf4,0x74,0xf0,0x20,0x30,0x9f,0xf7,0xfe,0x16,0x0f,0x9f,0x04,0x07,0xf3,0xff,0x07,0xe4,0x03,0x82,0x0f,0x15,0x88,0x83,0xea,0x03,0x0f,0xe0,0x24,0x84,0x01,0x17,0x00,0x78,0xcf,0xa0,0x13,0x30,0x7e,0x7c,0x20,0x13,0x60,0x7e,0x70,0x21,0xf7,0xc0,0x7c,0xca,0x01,0xe3,0x00,0xff,0x5f,0xc1,0xf3,0x38,0x07,0x97,0xc3,0xa6,0x0f,0x98,0xc0,0x3c,0xa8,0x1b,0x00,0x7c,0xc2,0x30,0x10,0x18,0x64,0x03,0x30,0x0f,0xc1,0x90,0xc4,0x1d,0x26,0x00,0x58,0x20,0x3c,0x7c,0x10,0x78,0xe0,0x3f,0x30,0x1f,0xd8,0x38,0xbe,0x60,0x40,0xf1,0x80,0x00,0x86,0x04,0x0f,0x88,0x18,0x3c,0x8c,0x43,0x04,0x07,0xc0,0xb4,0x43,0xe6,0x0f,0x80,0x50,0xd0,0x00,0x83,0xc0,0x81,0xc2,0x01,0xef,0xc0,0x46,0x08,0x10,0x64,0x10,0x20,0x7c,0x03,0x44,0x1e,0x58,0x08,0x1a,0x94,0x40,0x0d,0x60,0x07,0x99,0x90,0x66,0x00,0xf7,0x90,0x03,0xd4,0x0c,0x20,0x06,0x0c,0x08,0x28,0xe0,0xc4,0x61,0x00,0x34,0x40,0x1e,0x8a,0x41,0x77,0x48,0x3d,0x58,0x0e,0x68,0x10,0x79,0x81,0x46,0x06,0x0f,0x60,}; @@ -276,20 +276,23 @@ const uint8_t _A_Waves_128x52_0[] = {0x01,0x00,0xba,0x01,0x00,0x78,0x03,0xc0,0x0 const uint8_t _A_Waves_128x52_1[] = {0x01,0x00,0xbf,0x01,0x00,0x78,0x03,0xc0,0x0f,0xe0,0xf3,0xc0,0xc0,0x83,0xf8,0x07,0xce,0x03,0xff,0x0f,0x0a,0x10,0x4c,0x80,0x0f,0xfe,0x8e,0x01,0x08,0x1f,0x57,0xc0,0x19,0x7c,0x20,0xe0,0xf9,0xff,0xc0,0x47,0xe5,0xff,0x1f,0xce,0x7c,0x36,0x51,0xcf,0xf8,0xc2,0x30,0x11,0x92,0x79,0x61,0x23,0xe3,0x08,0xe0,0x46,0x61,0x00,0x42,0x9e,0x8b,0xe2,0x81,0x18,0x42,0x1c,0xe0,0x08,0x62,0x34,0x07,0xa7,0xc2,0xe0,0x04,0x2c,0x81,0x60,0x80,0x04,0x0f,0x3b,0x87,0x00,0x32,0x60,0xf5,0x15,0x1d,0xe3,0x00,0x0f,0xbf,0xf4,0x7e,0xf0,0x06,0x11,0xe1,0x40,0x81,0xeb,0xc0,0xff,0xff,0xc1,0xe5,0x7a,0x07,0x9f,0xf8,0x14,0x20,0x02,0x81,0xfc,0x3f,0x60,0xc1,0xea,0x88,0x06,0x05,0xff,0xaa,0x80,0x0e,0xfa,0xe3,0x20,0x78,0xea,0xa7,0xfe,0x0f,0xfe,0xa8,0x00,0x91,0xe0,0x60,0xef,0xa1,0xfe,0x0a,0xaf,0xfe,0xbe,0x1c,0x3a,0xa5,0x56,0xa2,0xaf,0x2b,0xc7,0xd6,0xbf,0xea,0x0e,0x9e,0x2b,0x55,0x2a,0xff,0x6a,0xcb,0x25,0xe0,0xd5,0xea,0x87,0x48,0x00,0x2f,0xff,0x5d,0xb4,0x5c,0x0a,0xbd,0x54,0x76,0xa0,0x01,0x81,0xef,0xd0,0xc7,0xaf,0x0f,0xa7,0x56,0xac,0x02,0x18,0x0f,0xf0,0x1e,0x75,0xe0,0xfa,0x4a,0xb5,0x1a,0xaf,0x53,0x2c,0x52,0x87,0xbc,0x0f,0x9f,0xd7,0xff,0x7f,0xaa,0xdd,0x47,0x62,0x0f,0x3b,0xc5,0x44,0x3c,0x50,0xe0,0x58,0xeb,0xed,0x48,0xc1,0x17,0x9f,0xc0,0x3e,0x34,0x5e,0xa9,0x60,0x8f,0x02,0x0d,0x16,0x31,0xd8,0x07,0xe4,0xc1,0x21,0x00,0xfb,0xcf,0xa3,0x0c,0x03,0x97,0x80,0x7e,0x49,0x72,0x10,0x10,0x34,0x66,0x01,0x73,0x43,0x8f,0xfd,0xfc,0x93,0x00,0x68,0xd0,0x01,0xe7,0xab,0x7d,0xa0,0x3c,0x8b,0xc7,0x3e,0x2a,0x0d,0x54,0x1e,0xf0,0x01,0x31,0x3b,0x85,0xe2,0x60,0x04,0xb8,0x17,0x8c,0x74,0x46,0xb2,0x00,0x27,0x82,0x01,0x04,0x3e,0x90,0x34,0x5c,0x84,0x00,0x4e,0x04,0x06,0x30,0x04,0x20,0x78,0xc1,0x81,0xed,0x80,0x81,0xc8,0x01,0xe4,0x1d,0x10,0x7b,0xff,0x20,0xe6,0x02,0xc0,0x03,0xc7,0xfc,0x1e,0x76,0x20,0x8b,0x04,0x1e,0x50,0xc2,0x82,0xde,0x20,0x11,0xc2,0x81,0x03,0xce,0xf8,0x6b,0x32,0xb1,0x4e,0x20,0x05,0x01,0x12,0x88,0x58,0x70,0x17,0xf8,0x03,0x01,0x02,0x83,0x60,0x58,0x8c,0x14,0x4c,0x49,0x26,0x40,0x0e,0x03,0x03,0xa0,0x85,0x09,0x09,0x01,0x10,0x0b,0xf0,0x7c,0x86,0xc2,0x80,0x74,0xc9,0x07,0xc8,0x1f,0x10,0x03,0x80,0x8f,0xcf,0xf0,0x0f,0x89,0xe0,0x15,0x39,0x00,0xf8,0xfe,0x7f,0xff,0xe6,0xa1,0x80,0x42,0x07,0xcf,0xff,0x4c,0x16,0x02,0x3e,0x0f,0x6f,0x84,0x07,0xf8,0x74,0x60,0xfb,0x7f,0x96,0xcb,0x00,0xbf,0xe2,0x07,0xf0,0x36,0x5b,0xf8,}; const uint8_t *_A_Waves_128x52[] = {_A_Waves_128x52_0,_A_Waves_128x52_1}; +const uint8_t _I_dir_10px_0[] = {0x01,0x00,0x11,0x00,0x00,0x0c,0xfe,0x01,0x41,0x80,0x7f,0xe0,0x70,0x18,0x10,0x05,0x7f,0xd0,0x10,0x88,0x80,}; +const uint8_t *_I_dir_10px[] = {_I_dir_10px_0}; + +const uint8_t _I_Nfc_10px_0[] = {0x00,0x80,0x00,0x00,0x01,0x22,0x02,0x43,0x02,0x45,0x02,0x49,0x02,0x31,0x02,0x22,0x02,0x00,0x01,0x80,0x00,}; +const uint8_t *_I_Nfc_10px[] = {_I_Nfc_10px_0}; + const uint8_t _I_sub1_10px_0[] = {0x01,0x00,0x12,0x00,0x81,0x40,0x69,0x30,0x2c,0x2c,0x0b,0x6a,0x01,0x28,0x0c,0x0a,0x65,0x01,0x98,0x40,0x00,0x26,}; const uint8_t *_I_sub1_10px[] = {_I_sub1_10px_0}; const uint8_t _I_ir_10px_0[] = {0x00,0xFC,0x00,0x02,0x01,0x79,0x02,0x84,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x58,0x00,0x78,0x00,0xFF,0x03,}; const uint8_t *_I_ir_10px[] = {_I_ir_10px_0}; -const uint8_t _I_unknown_10px_0[] = {0x01,0x00,0x12,0x00,0xbc,0x40,0x39,0x90,0x0c,0x24,0x03,0x81,0x00,0xb0,0x40,0x26,0x00,0x12,0x00,0x08,0x14,0xc0,}; -const uint8_t *_I_unknown_10px[] = {_I_unknown_10px_0}; - const uint8_t _I_ibutt_10px_0[] = {0x00,0x80,0x03,0x40,0x02,0x20,0x02,0x10,0x01,0x8E,0x00,0x41,0x00,0x2D,0x00,0x2D,0x00,0x21,0x00,0x1E,0x00,}; const uint8_t *_I_ibutt_10px[] = {_I_ibutt_10px_0}; -const uint8_t _I_Nfc_10px_0[] = {0x00,0x80,0x00,0x00,0x01,0x22,0x02,0x43,0x02,0x45,0x02,0x49,0x02,0x31,0x02,0x22,0x02,0x00,0x01,0x80,0x00,}; -const uint8_t *_I_Nfc_10px[] = {_I_Nfc_10px_0}; +const uint8_t _I_unknown_10px_0[] = {0x01,0x00,0x12,0x00,0xbc,0x40,0x39,0x90,0x0c,0x24,0x03,0x81,0x00,0xb0,0x40,0x26,0x00,0x12,0x00,0x08,0x14,0xc0,}; +const uint8_t *_I_unknown_10px[] = {_I_unknown_10px_0}; const uint8_t _I_ble_10px_0[] = {0x00,0x04,0x00,0x8C,0x00,0x15,0x01,0x56,0x02,0x8C,0x02,0x8C,0x02,0x56,0x02,0x15,0x01,0x8C,0x00,0x04,0x00,}; const uint8_t *_I_ble_10px[] = {_I_ble_10px_0}; @@ -297,65 +300,68 @@ const uint8_t *_I_ble_10px[] = {_I_ble_10px_0}; const uint8_t _I_125_10px_0[] = {0x00,0xE0,0x00,0x00,0x01,0x0E,0x02,0x31,0x02,0x45,0x02,0x91,0x00,0xAA,0x00,0x92,0x00,0x44,0x00,0x38,0x00,}; const uint8_t *_I_125_10px[] = {_I_125_10px_0}; -const uint8_t _I_dir_10px_0[] = {0x01,0x00,0x11,0x00,0x00,0x0c,0xfe,0x01,0x41,0x80,0x7f,0xe0,0x70,0x18,0x10,0x05,0x7f,0xd0,0x10,0x88,0x80,}; -const uint8_t *_I_dir_10px[] = {_I_dir_10px_0}; - const uint8_t _I_BLE_Pairing_128x64_0[] = {0x01,0x00,0xb7,0x01,0x00,0x6c,0x38,0x1f,0xd0,0x10,0x76,0xe0,0x03,0xdd,0x40,0x07,0xf4,0x82,0x01,0x08,0x07,0xf4,0xc0,0x1f,0x91,0x08,0x07,0x00,0x1f,0xc0,0x0d,0x1e,0xe8,0x3f,0xc0,0x03,0x58,0x80,0xcf,0x11,0xd9,0xaf,0x85,0x77,0x01,0xf7,0x60,0xf8,0x45,0xff,0x05,0xed,0x9e,0x7c,0x09,0xdb,0xe0,0x2f,0x78,0x03,0x3c,0x8e,0xee,0x8a,0x43,0x81,0xfb,0x0c,0x66,0xe8,0xfc,0x59,0xba,0x6f,0x28,0x1b,0xfb,0xa3,0x80,0xfc,0xa0,0x1f,0xc6,0x86,0xbf,0xc3,0x78,0xce,0x04,0x19,0x26,0x77,0xfa,0x43,0xbe,0x12,0xa0,0x7e,0xf8,0x2a,0xa2,0x02,0xff,0x89,0x27,0x01,0xbf,0x99,0x38,0x8a,0xfc,0x0f,0x8e,0x07,0xfe,0x0e,0x94,0x2c,0x07,0xfc,0x7f,0x1f,0xf5,0x00,0xc3,0x00,0xe4,0x31,0x13,0xd1,0x00,0x0a,0xb8,0x19,0x25,0x91,0xc0,0x81,0xe2,0xb9,0x4d,0x5d,0x78,0x64,0x2e,0x84,0x80,0x61,0x07,0x02,0x3e,0x2a,0xa4,0xa2,0x00,0xf2,0x40,0x20,0xe3,0x21,0xa0,0x62,0x9f,0x60,0x05,0x02,0x3e,0x36,0x41,0x66,0x23,0x20,0x51,0xfc,0x40,0x68,0x0f,0x15,0x90,0x60,0x20,0x1b,0x09,0x89,0x70,0x46,0x42,0x07,0x14,0x99,0x41,0xe8,0x1f,0x18,0x0c,0x07,0xc1,0x19,0xff,0xc3,0xce,0x6b,0x54,0x8f,0xe0,0x3f,0x90,0x78,0x17,0x02,0x1a,0x70,0x39,0x01,0xa0,0xb1,0x53,0xb5,0x88,0xc7,0xe0,0x98,0x08,0x3a,0xd5,0xe8,0x97,0xd0,0x78,0xcf,0xe1,0x07,0xf1,0x0d,0x08,0x00,0x74,0x10,0x80,0x18,0xe8,0x97,0xc3,0xf2,0xff,0xc4,0x03,0xe3,0x04,0x8c,0x19,0xcc,0x00,0x35,0x0c,0x3c,0x03,0xf9,0x3f,0xb0,0x8f,0xc6,0x31,0x0e,0x0f,0x90,0x90,0xb5,0x45,0xc1,0xf8,0x4f,0xf0,0xde,0x18,0xcc,0x82,0x08,0x1f,0x22,0x20,0xd0,0x3a,0xab,0xd1,0xe0,0x5f,0xa1,0x1b,0x19,0x8d,0x02,0x04,0x9a,0x1d,0x04,0x28,0x26,0x36,0xa8,0x05,0xf0,0xe0,0x3f,0x04,0xf8,0xd0,0x30,0x55,0xfa,0xad,0x54,0x3e,0x35,0x09,0xab,0xac,0xbf,0x2b,0xf2,0x0a,0x0e,0xfb,0x55,0xaa,0x0f,0x94,0x68,0x04,0x30,0x6f,0xd3,0x7c,0xb0,0x15,0x0f,0xfd,0x7f,0xeb,0x05,0x4f,0x0b,0x60,0xa3,0x1f,0x28,0x0b,0xfc,0xbc,0x30,0x1f,0xf7,0xfe,0x54,0x2c,0x18,0x30,0x3c,0x6f,0x00,0xf2,0x1c,0x8c,0xf8,0x10,0x3c,0x00,0xf8,0xd5,0x5c,0x05,0xb8,0xb0,0xaa,0xdb,0x01,0x2b,0x31,0x0a,0xdc,0xa7,0x00,0xe6,0x00,0x0c,0x56,0x00,0x7e,0x10,0x00,0xcc,0x01,0xf0,0x1f,0x1b,0x40,0x2e,0x00,0x07,0x16,0x10,0x90,0x02,0xe5,0x90,0x06,0x29,0x00,0x2a,0xa9,0x00,0x2f,0x10,0x02,0xa5,0x10,0x02,0xf1,0x00,0x2a,0xa0,0x0d,0xc0,0x00,0xec,0x01,0xfd,0x60,0x17,0x6a,0xc0,0x60,0x40,0xfd,0xc0,0x30,0x04,0x01,0xb0,0xb0,0x7f,0x45,0x80,}; const uint8_t *_I_BLE_Pairing_128x64[] = {_I_BLE_Pairing_128x64_0}; +const uint8_t _I_UsbTree_48x22_0[] = {0x01,0x00,0x3c,0x00,0x00,0x14,0x3c,0x08,0x78,0x08,0xf8,0x10,0xff,0xe0,0x59,0xb0,0x04,0x52,0xc0,0x1d,0x48,0xc0,0x9d,0x00,0xa7,0x02,0x80,0x41,0x80,0xa5,0x0e,0x02,0xa4,0xfb,0xfe,0x00,0xa1,0x49,0x04,0x48,0x0a,0x81,0xd1,0xc0,0x40,0x45,0x26,0x05,0x30,0x01,0x41,0xbe,0x10,0x30,0x2c,0x7e,0x3f,0xe0,0x59,0x80,0x04,0x50,0x0a,0x60,}; +const uint8_t *_I_UsbTree_48x22[] = {_I_UsbTree_48x22_0}; + +const uint8_t _I_EviWaiting2_18x21_0[] = {0x01,0x00,0x31,0x00,0x86,0x70,0x20,0x10,0x6c,0x04,0x06,0x0f,0x80,0x81,0xf3,0xf9,0xf0,0x3f,0xff,0xfc,0x04,0x7f,0xef,0xfc,0x04,0x04,0xa0,0xb2,0xeb,0xed,0xe0,0x7f,0x7f,0xb8,0x08,0xf1,0xf8,0xf0,0xd4,0xff,0x3f,0xf0,0x0f,0xc5,0xfe,0x01,0xf0,0x9f,0xc0,0x38,0x10,0xf8,0x00,}; +const uint8_t *_I_EviWaiting2_18x21[] = {_I_EviWaiting2_18x21_0}; + +const uint8_t _I_Clock_18x18_0[] = {0x01,0x00,0x31,0x00,0xe0,0x43,0xe0,0x1f,0x09,0xfc,0x03,0xf1,0x7f,0x80,0x47,0x3c,0x10,0x0d,0xf7,0xde,0x02,0x02,0x2d,0xff,0xde,0x07,0x7f,0xfd,0xc0,0xff,0xff,0xc0,0x11,0xdf,0xff,0x30,0x3d,0xff,0xca,0x07,0x3e,0xfa,0x85,0xc7,0xe5,0x01,0x10,0x10,0x98,0x85,0x84,0x32,0x20,}; +const uint8_t *_I_Clock_18x18[] = {_I_Clock_18x18_0}; + +const uint8_t _I_Smile_18x18_0[] = {0x01,0x00,0x2d,0x00,0xe0,0x43,0xe0,0x1f,0x09,0xfc,0x03,0xf1,0x7f,0x80,0x7f,0x3f,0xf0,0x0f,0xf7,0xfe,0x02,0x02,0x2f,0xff,0xfe,0x07,0xcf,0xe7,0xc0,0xf0,0xf8,0x70,0x11,0x82,0x08,0x1c,0x41,0x42,0xdf,0x7d,0xe0,0x37,0xcf,0xc0,0x98,0xc5,0x84,0x32,0x20,}; +const uint8_t *_I_Smile_18x18[] = {_I_Smile_18x18_0}; + +const uint8_t _I_EviSmile1_18x21_0[] = {0x01,0x00,0x39,0x00,0x86,0x70,0x20,0x10,0x6c,0x04,0x06,0x0f,0x80,0x81,0xf3,0xf9,0xf0,0x3f,0xff,0xfc,0x04,0x7f,0xef,0xfc,0x04,0x04,0xbf,0x7d,0xfc,0x0f,0xcf,0x9f,0x81,0xf1,0xf1,0xf0,0x3c,0x3e,0x1e,0x07,0x8f,0xe3,0x86,0x9b,0xbd,0xef,0x80,0xef,0x3e,0x90,0x0b,0xc5,0xe2,0x01,0xf0,0x9f,0xc0,0x38,0x10,0xf8,0x00,}; +const uint8_t *_I_EviSmile1_18x21[] = {_I_EviSmile1_18x21_0}; + +const uint8_t _I_Percent_10x14_0[] = {0x00,0x0C,0x03,0x1E,0x03,0x33,0x03,0xB3,0x03,0xDE,0x01,0xEC,0x00,0x70,0x00,0x38,0x00,0xDC,0x00,0xEE,0x01,0x37,0x03,0x33,0x03,0xE3,0x01,0xC3,0x00,}; +const uint8_t *_I_Percent_10x14[] = {_I_Percent_10x14_0}; + +const uint8_t _I_Error_18x18_0[] = {0x01,0x00,0x2c,0x00,0xe0,0x43,0xe0,0x1f,0x09,0xfc,0x03,0xf1,0x7f,0x80,0x7f,0x3f,0xf0,0x0e,0x77,0x3e,0x03,0x8e,0xe3,0xc0,0x63,0xfe,0x38,0x1c,0xff,0xe1,0x03,0xbf,0xfe,0x00,0x46,0x08,0x20,0x71,0x05,0x08,0x34,0x42,0x02,0x13,0x10,0xb0,0x86,0x44,}; +const uint8_t *_I_Error_18x18[] = {_I_Error_18x18_0}; + const uint8_t _I_EviWaiting1_18x21_0[] = {0x01,0x00,0x34,0x00,0x86,0x70,0x20,0x10,0x6c,0x04,0x06,0x0f,0x80,0x81,0xf3,0xf9,0xf0,0x3f,0xff,0xfc,0x04,0x7f,0xef,0xfc,0x04,0x04,0xa0,0xb2,0xdb,0xeb,0xe0,0x7b,0xfd,0xfc,0x0f,0x3f,0x9f,0x81,0xf1,0xf8,0xe1,0xa9,0xfe,0x7f,0xe0,0x1f,0x8b,0xfc,0x03,0xe1,0x3f,0x80,0x70,0x21,0xf0,0x00,}; const uint8_t *_I_EviWaiting1_18x21[] = {_I_EviWaiting1_18x21_0}; const uint8_t _I_EviSmile2_18x21_0[] = {0x01,0x00,0x37,0x00,0x00,0x14,0x3b,0x81,0x01,0x83,0xe0,0x20,0x7c,0xfe,0x7c,0x0f,0xff,0xff,0x01,0x1f,0xfb,0xff,0x01,0x01,0x2f,0x9f,0x3f,0x03,0xe3,0xe3,0xe0,0x78,0x7c,0x3c,0x0f,0x1f,0xc7,0x0d,0x37,0x3b,0x99,0x01,0xcf,0x79,0x20,0x33,0xcf,0x84,0x03,0xf1,0x7f,0x80,0x7c,0x27,0xf0,0x0e,0x04,0x3e,0x00,}; const uint8_t *_I_EviSmile2_18x21[] = {_I_EviSmile2_18x21_0}; -const uint8_t _I_Error_18x18_0[] = {0x01,0x00,0x2c,0x00,0xe0,0x43,0xe0,0x1f,0x09,0xfc,0x03,0xf1,0x7f,0x80,0x7f,0x3f,0xf0,0x0e,0x77,0x3e,0x03,0x8e,0xe3,0xc0,0x63,0xfe,0x38,0x1c,0xff,0xe1,0x03,0xbf,0xfe,0x00,0x46,0x08,0x20,0x71,0x05,0x08,0x34,0x42,0x02,0x13,0x10,0xb0,0x86,0x44,}; -const uint8_t *_I_Error_18x18[] = {_I_Error_18x18_0}; - -const uint8_t _I_Percent_10x14_0[] = {0x00,0x0C,0x03,0x1E,0x03,0x33,0x03,0xB3,0x03,0xDE,0x01,0xEC,0x00,0x70,0x00,0x38,0x00,0xDC,0x00,0xEE,0x01,0x37,0x03,0x33,0x03,0xE3,0x01,0xC3,0x00,}; -const uint8_t *_I_Percent_10x14[] = {_I_Percent_10x14_0}; - -const uint8_t _I_EviSmile1_18x21_0[] = {0x01,0x00,0x39,0x00,0x86,0x70,0x20,0x10,0x6c,0x04,0x06,0x0f,0x80,0x81,0xf3,0xf9,0xf0,0x3f,0xff,0xfc,0x04,0x7f,0xef,0xfc,0x04,0x04,0xbf,0x7d,0xfc,0x0f,0xcf,0x9f,0x81,0xf1,0xf1,0xf0,0x3c,0x3e,0x1e,0x07,0x8f,0xe3,0x86,0x9b,0xbd,0xef,0x80,0xef,0x3e,0x90,0x0b,0xc5,0xe2,0x01,0xf0,0x9f,0xc0,0x38,0x10,0xf8,0x00,}; -const uint8_t *_I_EviSmile1_18x21[] = {_I_EviSmile1_18x21_0}; - -const uint8_t _I_EviWaiting2_18x21_0[] = {0x01,0x00,0x31,0x00,0x86,0x70,0x20,0x10,0x6c,0x04,0x06,0x0f,0x80,0x81,0xf3,0xf9,0xf0,0x3f,0xff,0xfc,0x04,0x7f,0xef,0xfc,0x04,0x04,0xa0,0xb2,0xeb,0xed,0xe0,0x7f,0x7f,0xb8,0x08,0xf1,0xf8,0xf0,0xd4,0xff,0x3f,0xf0,0x0f,0xc5,0xfe,0x01,0xf0,0x9f,0xc0,0x38,0x10,0xf8,0x00,}; -const uint8_t *_I_EviWaiting2_18x21[] = {_I_EviWaiting2_18x21_0}; - -const uint8_t _I_UsbTree_48x22_0[] = {0x01,0x00,0x3c,0x00,0x00,0x14,0x3c,0x08,0x78,0x08,0xf8,0x10,0xff,0xe0,0x59,0xb0,0x04,0x52,0xc0,0x1d,0x48,0xc0,0x9d,0x00,0xa7,0x02,0x80,0x41,0x80,0xa5,0x0e,0x02,0xa4,0xfb,0xfe,0x00,0xa1,0x49,0x04,0x48,0x0a,0x81,0xd1,0xc0,0x40,0x45,0x26,0x05,0x30,0x01,0x41,0xbe,0x10,0x30,0x2c,0x7e,0x3f,0xe0,0x59,0x80,0x04,0x50,0x0a,0x60,}; -const uint8_t *_I_UsbTree_48x22[] = {_I_UsbTree_48x22_0}; - -const uint8_t _I_Smile_18x18_0[] = {0x01,0x00,0x2d,0x00,0xe0,0x43,0xe0,0x1f,0x09,0xfc,0x03,0xf1,0x7f,0x80,0x7f,0x3f,0xf0,0x0f,0xf7,0xfe,0x02,0x02,0x2f,0xff,0xfe,0x07,0xcf,0xe7,0xc0,0xf0,0xf8,0x70,0x11,0x82,0x08,0x1c,0x41,0x42,0xdf,0x7d,0xe0,0x37,0xcf,0xc0,0x98,0xc5,0x84,0x32,0x20,}; -const uint8_t *_I_Smile_18x18[] = {_I_Smile_18x18_0}; - -const uint8_t _I_Clock_18x18_0[] = {0x01,0x00,0x31,0x00,0xe0,0x43,0xe0,0x1f,0x09,0xfc,0x03,0xf1,0x7f,0x80,0x47,0x3c,0x10,0x0d,0xf7,0xde,0x02,0x02,0x2d,0xff,0xde,0x07,0x7f,0xfd,0xc0,0xff,0xff,0xc0,0x11,0xdf,0xff,0x30,0x3d,0xff,0xca,0x07,0x3e,0xfa,0x85,0xc7,0xe5,0x01,0x10,0x10,0x98,0x85,0x84,0x32,0x20,}; -const uint8_t *_I_Clock_18x18[] = {_I_Clock_18x18_0}; - -const uint8_t _I_ButtonDown_7x4_0[] = {0x00,0x7F,0x3E,0x1C,0x08,}; -const uint8_t *_I_ButtonDown_7x4[] = {_I_ButtonDown_7x4_0}; - -const uint8_t _I_ButtonCenter_7x7_0[] = {0x00,0x1C,0x22,0x5D,0x5D,0x5D,0x22,0x1C,}; -const uint8_t *_I_ButtonCenter_7x7[] = {_I_ButtonCenter_7x7_0}; +const uint8_t _I_ButtonRightSmall_3x5_0[] = {0x00,0x01,0x03,0x07,0x03,0x01,}; +const uint8_t *_I_ButtonRightSmall_3x5[] = {_I_ButtonRightSmall_3x5_0}; const uint8_t _I_ButtonLeft_4x7_0[] = {0x00,0x08,0x0C,0x0E,0x0F,0x0E,0x0C,0x08,}; const uint8_t *_I_ButtonLeft_4x7[] = {_I_ButtonLeft_4x7_0}; -const uint8_t _I_ButtonUp_7x4_0[] = {0x00,0x08,0x1C,0x3E,0x7F,}; -const uint8_t *_I_ButtonUp_7x4[] = {_I_ButtonUp_7x4_0}; +const uint8_t _I_ButtonLeftSmall_3x5_0[] = {0x00,0x04,0x06,0x07,0x06,0x04,}; +const uint8_t *_I_ButtonLeftSmall_3x5[] = {_I_ButtonLeftSmall_3x5_0}; const uint8_t _I_DFU_128x50_0[] = {0x01,0x00,0x2e,0x02,0x00,0x57,0xfe,0x0e,0x0e,0xcf,0x84,0x02,0x70,0x0f,0xc8,0x74,0x03,0x80,0x0e,0xbc,0x7c,0x04,0x06,0x30,0x30,0x74,0xe0,0x2f,0xe0,0x42,0x82,0x03,0xe7,0x81,0xff,0x02,0x14,0x20,0x1f,0x3e,0x00,0x79,0xc4,0x01,0xfd,0x20,0x07,0xd5,0xd4,0xe2,0x53,0xf2,0x74,0xff,0xe1,0x40,0x41,0x87,0xd8,0x01,0xf1,0x60,0xf0,0x43,0xca,0x43,0xe0,0xa7,0x83,0xe2,0x30,0x01,0x29,0x84,0x7b,0x20,0x0f,0x88,0x30,0x3c,0xb1,0x90,0x1d,0x00,0xfa,0x30,0x3f,0xf8,0xcc,0x02,0xc6,0x31,0x1f,0x83,0x49,0xa8,0x16,0x0a,0xf4,0x7f,0x00,0x21,0x1f,0x04,0x38,0x06,0x20,0x04,0x90,0x46,0x35,0xf0,0xfa,0x00,0xcc,0x7f,0x10,0x14,0x0b,0x46,0x20,0xd5,0x70,0x50,0xb4,0x06,0xf1,0x00,0x9f,0x03,0xd7,0x09,0x81,0xd7,0xc0,0x8b,0x85,0x38,0xc0,0x50,0x41,0xeb,0x63,0xc0,0x07,0xc6,0x90,0xbf,0x2b,0x05,0x01,0xb8,0xb1,0x0c,0x06,0xae,0x01,0x24,0x6f,0x94,0x42,0x80,0xb2,0x49,0xc4,0x33,0x80,0x1f,0x18,0x93,0xfc,0xa1,0x14,0x0e,0x02,0x9c,0x43,0xc3,0x07,0x81,0xfc,0x03,0xe2,0xc0,0x28,0x14,0x10,0x5e,0x3f,0x03,0xc0,0xcf,0xf8,0x10,0x0f,0xe5,0x56,0x03,0x05,0xf0,0x40,0x20,0x20,0xf2,0x42,0x0d,0xfd,0x72,0x30,0x0f,0xf8,0x7c,0x41,0xe3,0x80,0x10,0x0d,0x00,0x5c,0x4a,0xd1,0x87,0xf8,0x39,0xf5,0x5c,0x0c,0x0b,0xe0,0x1c,0x10,0x78,0xfc,0x02,0x04,0x20,0x1f,0xf7,0x0f,0x57,0x80,0x81,0x5e,0x13,0x83,0x01,0x1f,0x97,0xff,0xfe,0x03,0x2e,0x07,0x57,0x03,0x01,0xbf,0x1d,0x45,0x70,0x27,0xe4,0xff,0x8c,0x07,0xf5,0x83,0xe0,0xcf,0xe1,0x00,0xf6,0x10,0x8c,0x07,0xb1,0x07,0xc1,0xfc,0x63,0xe5,0xd2,0x07,0x8f,0x80,0x1a,0x21,0xe1,0xc0,0x71,0xe0,0x20,0xf1,0x24,0x88,0x34,0x62,0x00,0xe3,0x3f,0x8d,0xfe,0x81,0x80,0xc1,0xf8,0x5b,0xe2,0x0f,0x18,0xc7,0xf0,0x1e,0x50,0x35,0xa0,0xc8,0x3f,0x98,0x30,0x70,0x87,0x44,0x1e,0x21,0xe3,0xf8,0x02,0x4b,0xaf,0x01,0x81,0xb3,0xca,0x01,0x1c,0x25,0x94,0x01,0x04,0x58,0x8d,0x5c,0x0b,0xc6,0x08,0x10,0x78,0xc3,0x3f,0xf0,0x72,0x88,0x98,0x8b,0x89,0x55,0x82,0xc7,0x9b,0xe5,0x00,0x87,0x26,0xc4,0x46,0x20,0xf2,0xd1,0x87,0xc6,0x0c,0xdf,0x21,0x50,0x8a,0xc7,0x00,0x38,0x2e,0x04,0x42,0xaf,0x05,0x06,0x0a,0xb8,0x70,0x0f,0x91,0x80,0x5c,0x03,0xc5,0x30,0x84,0x6a,0xe1,0x40,0xf1,0x7b,0x0f,0x00,0x7a,0x24,0x21,0x07,0x94,0x33,0x09,0x57,0x8a,0x93,0x85,0xec,0x3e,0x00,0x79,0x0b,0x88,0x06,0x3c,0x3f,0xfc,0xa8,0x1e,0x21,0x91,0x76,0x90,0x90,0x40,0x03,0xe0,0xe0,0x78,0x3f,0xd5,0x58,0x0e,0x08,0x32,0x3f,0x88,0xa8,0x90,0x8c,0x25,0x30,0xbc,0x7f,0xb5,0x50,0x1b,0xe0,0x20,0x7f,0x92,0x33,0x88,0x97,0x4a,0x07,0x0c,0x9e,0x5f,0xeb,0xaa,0xf2,0x74,0x8d,0x17,0x80,0x06,0x29,0xf1,0xe0,0x71,0xfb,0xfd,0x71,0xd8,0xff,0xf8,0x21,0x71,0x04,0x87,0x01,0xc1,0xa1,0xff,0x83,0xe7,0xf0,0xff,0xc1,0x51,0xe4,0xdd,0x1b,0x07,0xc2,0x63,0xf6,0x0f,0x9f,0xeb,0x5f,0x02,0x77,0x8a,0xc4,0xa3,0x17,0xc8,0x44,0x8c,0x34,0x20,0x71,0xfe,0x99,0x04,0x88,0x40,0x01,0xc3,0x47,0xf0,0x93,0x0f,0xf4,0x28,0x0e,0x3a,0xad,0x50,0x39,0x30,0x1f,0x18,0x3d,0x0e,0x31,0xff,0x3d,0x0c,0x02,0xa8,0x03,0x20,0x01,0x7e,0x3f,0xf8,0x09,0x06,0x33,0xfe,0x1b,0x50,}; const uint8_t *_I_DFU_128x50[] = {_I_DFU_128x50_0}; -const uint8_t _I_ButtonLeftSmall_3x5_0[] = {0x00,0x04,0x06,0x07,0x06,0x04,}; -const uint8_t *_I_ButtonLeftSmall_3x5[] = {_I_ButtonLeftSmall_3x5_0}; +const uint8_t _I_Warning_30x23_0[] = {0x01,0x00,0x47,0x00,0x80,0x70,0x00,0x65,0xe0,0x80,0x80,0xc7,0xe1,0x03,0x01,0xaf,0xe2,0x0e,0x03,0x19,0xe4,0x3c,0x06,0xb3,0xe8,0xf8,0x0c,0x67,0xf3,0xf0,0x1a,0x60,0x27,0xf7,0xf1,0x50,0xcf,0xff,0xe0,0x34,0xf0,0x00,0xc6,0x03,0xf0,0x01,0x8c,0x0c,0x06,0x7f,0x80,0x18,0xc1,0xff,0x9f,0xff,0xfc,0x3c,0x06,0x7f,0xe0,0x58,0xc7,0xff,0xe0,0x31,0x00,0x88,0x00,0x67,0xff,0xe0,0x18,0xc7,0xc0,}; +const uint8_t *_I_Warning_30x23[] = {_I_Warning_30x23_0}; -const uint8_t _I_ButtonRightSmall_3x5_0[] = {0x00,0x01,0x03,0x07,0x03,0x01,}; -const uint8_t *_I_ButtonRightSmall_3x5[] = {_I_ButtonRightSmall_3x5_0}; +const uint8_t _I_ButtonDown_7x4_0[] = {0x00,0x7F,0x3E,0x1C,0x08,}; +const uint8_t *_I_ButtonDown_7x4[] = {_I_ButtonDown_7x4_0}; const uint8_t _I_ButtonRight_4x7_0[] = {0x00,0x01,0x03,0x07,0x0F,0x07,0x03,0x01,}; const uint8_t *_I_ButtonRight_4x7[] = {_I_ButtonRight_4x7_0}; -const uint8_t _I_Warning_30x23_0[] = {0x01,0x00,0x47,0x00,0x80,0x70,0x00,0x65,0xe0,0x80,0x80,0xc7,0xe1,0x03,0x01,0xaf,0xe2,0x0e,0x03,0x19,0xe4,0x3c,0x06,0xb3,0xe8,0xf8,0x0c,0x67,0xf3,0xf0,0x1a,0x60,0x27,0xf7,0xf1,0x50,0xcf,0xff,0xe0,0x34,0xf0,0x00,0xc6,0x03,0xf0,0x01,0x8c,0x0c,0x06,0x7f,0x80,0x18,0xc1,0xff,0x9f,0xff,0xfc,0x3c,0x06,0x7f,0xe0,0x58,0xc7,0xff,0xe0,0x31,0x00,0x88,0x00,0x67,0xff,0xe0,0x18,0xc7,0xc0,}; -const uint8_t *_I_Warning_30x23[] = {_I_Warning_30x23_0}; +const uint8_t _I_ButtonCenter_7x7_0[] = {0x00,0x1C,0x22,0x5D,0x5D,0x5D,0x22,0x1C,}; +const uint8_t *_I_ButtonCenter_7x7[] = {_I_ButtonCenter_7x7_0}; + +const uint8_t _I_ButtonUp_7x4_0[] = {0x00,0x08,0x1C,0x3E,0x7F,}; +const uint8_t *_I_ButtonUp_7x4[] = {_I_ButtonUp_7x4_0}; + +const uint8_t _I_DolphinOkay_41x43_0[] = {0x01,0x00,0xa0,0x00,0x00,0x0f,0x82,0x3e,0x05,0x38,0xf7,0x80,0x08,0x58,0x08,0x0c,0x02,0x0e,0x05,0x1b,0x00,0x08,0x63,0x00,0x21,0x88,0x00,0x86,0x40,0x02,0x18,0x40,0x08,0x68,0x00,0x21,0x82,0x06,0x88,0x0a,0xf0,0x21,0x39,0x09,0x84,0x02,0x20,0x57,0x09,0x98,0x15,0x67,0xc0,0x54,0xbe,0x81,0x4f,0x01,0xfe,0x02,0x9d,0x03,0xc4,0x20,0x10,0x29,0x7c,0x80,0xa9,0xfe,0x02,0xac,0x14,0x0a,0x77,0xc8,0x58,0x8c,0xf0,0x11,0x51,0x79,0xff,0x61,0x44,0x93,0x81,0x02,0xc4,0x9e,0x60,0xb2,0xf0,0xa0,0x46,0x0c,0x17,0x14,0x99,0x1a,0x07,0x80,0x59,0x49,0x82,0x21,0xc0,0xa4,0x82,0x24,0xb9,0x20,0x88,0x1c,0x47,0xc2,0x07,0x11,0x54,0xa0,0x60,0x53,0xb8,0x0a,0x4b,0xf3,0x03,0x87,0x81,0x4a,0x0d,0xfc,0x1a,0x98,0x68,0xb8,0x01,0x51,0x13,0x15,0xe0,0x82,0x7f,0x8d,0x78,0x38,0xbf,0xff,0xfa,0xb8,0x60,0xbf,0x1b,0xf9,0x50,0x14,0xea,0xe7,0x02,0x02,0x8e,0xac,0x94,0x40,}; +const uint8_t *_I_DolphinOkay_41x43[] = {_I_DolphinOkay_41x43_0}; + +const uint8_t _I_DolphinFirstStart4_67x53_0[] = {0x01,0x00,0x1f,0x01,0x00,0x17,0xc3,0xfe,0x08,0x68,0x74,0x02,0x0e,0x07,0x4c,0x04,0x06,0x01,0x18,0x04,0x25,0x00,0x04,0x36,0x00,0x42,0x48,0x02,0x88,0x00,0x28,0x80,0x0c,0xa0,0x40,0x83,0x84,0x00,0xca,0x08,0x08,0x30,0x21,0x83,0x0c,0x2c,0x81,0xe3,0x04,0x20,0xc0,0x80,0x02,0x31,0x32,0x11,0x02,0x27,0x00,0x5d,0x40,0x45,0x87,0x90,0x3e,0x7c,0x00,0x43,0x84,0x4e,0x60,0x43,0x30,0x89,0x82,0x12,0x80,0x15,0x20,0x40,0x99,0xc8,0x22,0x7b,0x88,0x10,0x20,0x82,0x27,0x7c,0x82,0x9d,0x48,0x22,0x5f,0x0d,0xfc,0x08,0x10,0x41,0x12,0xf8,0x57,0xc2,0x28,0x30,0x1e,0x07,0x9e,0x06,0x87,0x25,0x79,0xc4,0x20,0x40,0x83,0x21,0x14,0x22,0x08,0x08,0x38,0x2a,0xb8,0xd9,0x47,0x0a,0x14,0x09,0xf0,0x54,0x47,0x1f,0x81,0x82,0x1a,0xde,0x8e,0x33,0xd1,0xc7,0x81,0x0f,0x0e,0x45,0x18,0x20,0xa1,0xe6,0xf2,0x10,0x89,0xa0,0x70,0x11,0x00,0x41,0x46,0x03,0x86,0x55,0x10,0x40,0xc1,0x82,0x25,0x20,0x04,0x11,0x94,0x80,0x43,0x10,0x84,0x01,0x46,0xc0,0xbd,0x38,0x40,0x20,0x8f,0x49,0x08,0xc4,0x1c,0xc8,0x22,0x50,0x38,0x20,0x20,0x86,0xe4,0x83,0x10,0x41,0x8b,0x87,0xf9,0x03,0x81,0xc0,0x81,0x05,0x81,0xc0,0x40,0xf3,0x90,0x60,0x41,0x70,0x2c,0x17,0x01,0xc0,0xc1,0x41,0x05,0x30,0x98,0x43,0x04,0x65,0x01,0x04,0x0c,0x32,0x38,0x91,0x18,0x04,0x14,0x10,0x38,0x18,0x1e,0xac,0x7c,0x41,0x11,0x88,0x5f,0xfc,0x17,0x55,0xa9,0x82,0x06,0x05,0xbc,0x85,0x02,0x08,0xc6,0x32,0x0f,0xe5,0x5e,0x1a,0x08,0x5c,0x06,0xaa,0x34,0x08,0x4a,0x06,0x02,0xab,0x75,0xf0,0x4f,0xc1,0x05,0x80,0x08,0x8e,0xab,0x7f,0xea,0x04,0x11,0x80,0x6a,0xa0,0x02,0x03,0x08,}; +const uint8_t *_I_DolphinFirstStart4_67x53[] = {_I_DolphinFirstStart4_67x53_0}; const uint8_t _I_DolphinFirstStart2_59x51_0[] = {0x01,0x00,0x2e,0x01,0x00,0x1f,0xfe,0x06,0x05,0x3f,0xc7,0xfe,0x01,0x1c,0x03,0x16,0x02,0xaf,0x0f,0x80,0x58,0x01,0xc7,0xaa,0x80,0x82,0xc4,0x0e,0x55,0x6b,0x28,0x10,0x81,0x45,0xab,0x8d,0x01,0xca,0x04,0x1a,0x1a,0xac,0x1c,0x0e,0x50,0x48,0x06,0xc0,0x3c,0x40,0x01,0x84,0x40,0x2b,0x15,0x51,0xd9,0xc4,0x20,0x1a,0xc9,0x50,0x1c,0xe4,0x02,0xe1,0x8a,0x81,0xd7,0x55,0x0a,0x03,0x9d,0x02,0x01,0x5c,0x82,0x81,0xd7,0xc0,0x3a,0x10,0x3a,0x12,0x88,0xc8,0x60,0x11,0x07,0xa0,0x1c,0x68,0x00,0xf6,0xe0,0x22,0x50,0x0e,0x36,0x00,0x7b,0x68,0x00,0x83,0xa0,0x11,0x08,0x1c,0x6a,0x03,0x42,0x44,0x1e,0xc0,0x28,0x50,0x61,0xf9,0x56,0x00,0xe3,0x60,0x40,0x88,0x1c,0x75,0x01,0x42,0x07,0x9d,0x50,0x5e,0x4b,0x01,0x37,0x8e,0xb0,0x0e,0x51,0xd8,0x04,0xc2,0x01,0xd4,0x5d,0x1c,0x02,0x30,0x7f,0x14,0x99,0x5c,0x20,0x11,0x48,0x07,0x58,0x0e,0x20,0x81,0xd0,0x23,0x04,0x1e,0x30,0x80,0x38,0xd4,0x11,0x82,0x0f,0x18,0x40,0xb0,0xb0,0x50,0x3d,0x58,0x1c,0x52,0x85,0xf1,0x83,0x75,0x58,0x64,0x49,0x1a,0xfc,0x17,0x57,0x01,0x88,0x25,0x0b,0x55,0x02,0xaa,0xc0,0x64,0x14,0x08,0x1e,0x02,0xaa,0x1f,0x18,0x0f,0x00,0xbe,0x20,0xf1,0x80,0x82,0x46,0x01,0x03,0x82,0xe0,0x04,0xa3,0xab,0x46,0x0e,0x32,0x15,0x80,0xb5,0x40,0x2a,0xa4,0x21,0x98,0x43,0x70,0x13,0x58,0x04,0xac,0xa4,0x3c,0x08,0xd6,0x02,0x35,0x00,0x8a,0xcd,0x06,0xa3,0x1d,0xa0,0x24,0x46,0x57,0xe8,0x26,0x8c,0xdb,0x80,0x84,0x18,0xad,0x42,0x07,0x5f,0xbf,0xb9,0x8a,0x17,0x80,0xff,0x6a,0xb0,0x46,0x91,0x07,0x88,0xc4,0x4a,0x43,0x1f,0x07,0x92,0xc4,0x49,0x82,0x9b,0x25,0x98,0xc0,0x28,0xa0,0x73,0x1f,0x0b,0x50,0x81,0xea,0x07,0x40,0x7b,0xac,0x44,0x0e,0xa0,}; const uint8_t *_I_DolphinFirstStart2_59x51[] = {_I_DolphinFirstStart2_59x51_0}; @@ -363,125 +369,125 @@ const uint8_t *_I_DolphinFirstStart2_59x51[] = {_I_DolphinFirstStart2_59x51_0}; const uint8_t _I_DolphinFirstStart5_54x49_0[] = {0x01,0x00,0x0b,0x01,0x00,0x0f,0xf2,0xfe,0x06,0x48,0x1e,0x02,0x06,0x05,0x2e,0x00,0x08,0x61,0x80,0x62,0x98,0x00,0x86,0x20,0x06,0x28,0x40,0x08,0x64,0x00,0x62,0x82,0x00,0x86,0x80,0x06,0x28,0x14,0x72,0x01,0x80,0x03,0x14,0x06,0x44,0x03,0x20,0x49,0x00,0xc4,0x0c,0x61,0x13,0x81,0x07,0x90,0x0c,0xff,0xa8,0x18,0xcc,0xe0,0x10,0x78,0x60,0x18,0xc9,0xe3,0x10,0x03,0x0e,0x02,0x02,0x4f,0x19,0x00,0x18,0x78,0x10,0x12,0x78,0xc8,0x0a,0xc3,0xf8,0x80,0xc1,0x80,0xc5,0xe0,0xff,0x8f,0x47,0xe1,0x27,0x03,0x0d,0xfc,0x80,0x3b,0xc9,0x74,0x43,0x81,0x0f,0xb0,0x40,0x2b,0xd2,0xd3,0x71,0x07,0x87,0x5f,0x16,0x84,0x54,0x23,0xe3,0x21,0xab,0xc5,0x61,0x1a,0x82,0xf0,0xf0,0x35,0x70,0xa8,0x45,0x50,0x2a,0x3e,0x0a,0xac,0x1e,0x11,0x28,0x03,0x0f,0xc3,0xfe,0x06,0x19,0xa0,0x18,0x6f,0x9f,0x08,0x7c,0x22,0x30,0x06,0x1d,0xfc,0x3e,0x21,0x08,0x00,0x8f,0x01,0x7a,0x31,0x08,0x24,0x42,0x21,0xf0,0x5e,0x08,0x18,0x44,0xe3,0x0f,0x59,0x92,0xb4,0x96,0x66,0x06,0x58,0x10,0x19,0x60,0x20,0x64,0x46,0x08,0x19,0x27,0x00,0x65,0x9f,0x81,0x93,0xd1,0x2b,0x03,0x17,0x82,0x3f,0x50,0x9a,0x81,0x87,0x51,0x1e,0xf0,0x68,0x69,0x40,0x61,0xea,0x9d,0x86,0x1d,0x45,0x80,0x61,0x2d,0x48,0xc2,0x67,0x8d,0x12,0x3a,0x06,0x19,0x02,0x88,0x74,0x4b,0x21,0x03,0x1d,0x08,0xca,0x21,0x41,0x06,0x93,0xe8,0xa1,0x85,0x31,0xe9,0x24,0x48,0x20,0x30,0x1b,0x10,0x18,0x77,0x8f,0xa1,0x80,0xcc,0x40,0xc3,0x56,0x0b,0x8c,0x0a,0x22,0xba,0x12,0x88,0x81,0x84,}; const uint8_t *_I_DolphinFirstStart5_54x49[] = {_I_DolphinFirstStart5_54x49_0}; +const uint8_t _I_DolphinFirstStart0_70x53_0[] = {0x01,0x00,0x5a,0x01,0x80,0x60,0x3f,0xf7,0xf0,0x42,0xf8,0x01,0x43,0x07,0x04,0x24,0x72,0x01,0xc0,0x9d,0x82,0x13,0xff,0xff,0xbd,0x70,0x20,0x20,0x72,0xe0,0x40,0x2a,0x11,0xdb,0x00,0x6c,0xec,0x10,0x0d,0x44,0x3a,0x71,0x0e,0x04,0x14,0x42,0x01,0x54,0x86,0xd3,0x27,0x02,0x44,0xd4,0x41,0xb0,0xf2,0x10,0x42,0x55,0x38,0x71,0x1b,0x10,0x18,0xa0,0x41,0x11,0xb1,0xc8,0x28,0x98,0x09,0xfc,0x00,0x72,0x35,0x49,0x8d,0x0b,0xc1,0x70,0xf0,0x10,0x4b,0x51,0x11,0xc2,0x6c,0x0a,0xa3,0x03,0x80,0x7f,0xbf,0xf3,0x08,0x46,0x60,0x90,0x30,0x60,0x50,0xd8,0x2c,0x11,0x0c,0x71,0x5c,0x60,0xf8,0x0f,0xcf,0x3f,0x81,0x80,0xa1,0x9e,0x86,0x0f,0xc0,0x82,0x64,0x30,0x3e,0x09,0x84,0x03,0xf1,0x03,0xa0,0x40,0xa4,0x18,0x39,0xfc,0x20,0x52,0x30,0x19,0x07,0xc6,0x8e,0x4a,0x18,0x22,0x74,0x60,0x1a,0x0f,0xc6,0x3c,0x60,0x5c,0x05,0x28,0xe4,0x3f,0x99,0xf8,0x22,0x28,0x7e,0x05,0x91,0xa8,0x7f,0x23,0xf0,0x59,0x00,0xac,0x63,0xe0,0x81,0xcf,0x4f,0xe0,0xb1,0x81,0x58,0xc3,0xc1,0x08,0x24,0x1f,0xf9,0x68,0x6a,0x1f,0xe9,0xff,0x16,0x02,0x34,0x13,0x50,0x82,0x0a,0xea,0x60,0x1f,0xf9,0xf0,0x41,0x05,0x1d,0x30,0x09,0x18,0x60,0x15,0xa3,0xe8,0x83,0x47,0xe0,0xec,0x2c,0xaf,0xf2,0x0e,0x08,0x1f,0xc1,0x18,0x60,0x1a,0xaf,0xc2,0x6c,0x89,0x62,0x03,0x19,0xad,0xe5,0x70,0x44,0x62,0x80,0x5a,0xa1,0x4f,0x63,0x23,0x0c,0x7a,0xaa,0x4d,0x11,0xe9,0x00,0x06,0x73,0xaa,0x25,0x0a,0x78,0xaf,0x90,0x09,0x25,0x54,0x56,0x5f,0x04,0x30,0xc0,0x64,0x7a,0xa1,0x11,0x7e,0x20,0x18,0x0f,0x3c,0x82,0xaa,0x04,0x18,0x0d,0xf8,0x16,0x33,0xe8,0x84,0xa8,0x08,0x3c,0x33,0x00,0xf0,0x20,0x71,0x08,0xa9,0x38,0x86,0x62,0x62,0x18,0x40,0x44,0x80,0x09,0x04,0x08,0x90,0x01,0x20,0x41,0x17,0x22,0x90,0x01,0x3e,0x00,0x76,0x80,0x1d,0x48,0x00,0x8d,0x91,0x00,0x34,0xf8,0x20,0xe2,0xa7,0x9c,0x06,0x5c,0x11,0x02,0x28,0x5d,0x91,0x35,0x48,0xaf,0xf8,0x04,0x3f,0xf9,0x88,0x20,0x01,}; +const uint8_t *_I_DolphinFirstStart0_70x53[] = {_I_DolphinFirstStart0_70x53_0}; + const uint8_t _I_DolphinFirstStart6_58x54_0[] = {0x01,0x00,0x21,0x01,0x00,0x0f,0xf2,0x7e,0x06,0x4c,0x04,0x0f,0x81,0x03,0x03,0x9d,0x80,0x04,0x30,0xc0,0x39,0xc6,0x00,0x43,0x30,0x03,0x9c,0x10,0x04,0x34,0x00,0x39,0xc0,0x84,0x44,0x07,0x38,0x08,0x0d,0x41,0x68,0x13,0x70,0x39,0x08,0xd0,0x56,0xa1,0xd1,0x03,0x94,0x80,0x04,0x30,0x68,0x04,0x20,0x0e,0x84,0x91,0x03,0xa9,0x64,0x62,0x80,0x41,0x88,0x40,0x3f,0xc6,0xf1,0xfe,0x43,0xc0,0xe3,0x80,0xff,0xff,0xe0,0x3f,0xf8,0xf8,0x1c,0x78,0x18,0x1f,0xfe,0x0f,0x02,0x12,0x18,0x47,0x03,0x82,0x10,0x1e,0x08,0x1c,0xf5,0x60,0x71,0xd4,0x81,0xcf,0xab,0xff,0xd5,0xf5,0xc0,0xe3,0x04,0xe0,0x03,0x86,0xae,0x27,0x28,0x27,0x40,0x0e,0x21,0x91,0x03,0x96,0x80,0x0e,0x34,0x18,0x79,0x28,0x60,0x95,0x00,0x38,0xf8,0x20,0x27,0xd1,0x82,0x6a,0x03,0xc3,0x1c,0x39,0x94,0x0a,0xa1,0xc0,0xc5,0x2f,0xca,0x05,0x02,0x90,0x24,0x56,0x04,0x68,0x10,0x01,0x4f,0x80,0xea,0x5b,0x10,0x38,0x83,0x8d,0xa0,0x30,0x30,0x38,0xa3,0x09,0xc0,0x20,0xf2,0x03,0x90,0xc0,0x46,0xe2,0x91,0x2f,0x80,0xfc,0xe0,0x1e,0x08,0x02,0x54,0x47,0x62,0x27,0x2f,0xfb,0x14,0xdc,0xc6,0xb5,0x30,0x38,0x8b,0x05,0x6a,0x60,0x01,0x89,0x00,0xc8,0x16,0x50,0x29,0x10,0x1c,0x8d,0x25,0x05,0xa1,0x15,0xc9,0xfe,0x50,0xaa,0x08,0x10,0x67,0x01,0x22,0x8a,0xe0,0x60,0xe5,0xf2,0x07,0x8e,0xa8,0xb0,0x49,0xe1,0x00,0x0d,0xd4,0x68,0x5a,0x00,0x39,0x46,0x88,0x84,0x07,0x30,0xe8,0x81,0xc6,0x40,0x4d,0x11,0x91,0x17,0x06,0x40,0x65,0x11,0x51,0x01,0xc6,0x81,0x04,0x32,0x18,0x1e,0x92,0x64,0x00,0x11,0x68,0x81,0xd6,0xa0,0x07,0x16,0x22,0x6b,0x0a,0x82,0x07,0x3f,0x05,0x4d,0xdc,0x24,0x21,}; const uint8_t *_I_DolphinFirstStart6_58x54[] = {_I_DolphinFirstStart6_58x54_0}; -const uint8_t _I_Flipper_young_80x60_0[] = {0x01,0x00,0xa3,0x01,0x00,0x1e,0x03,0xff,0xff,0x87,0x82,0x57,0xf1,0x83,0x90,0xde,0x01,0x2b,0x0e,0x83,0x70,0xfb,0x10,0x10,0x41,0xf8,0x27,0x70,0xcc,0x34,0xc6,0x0e,0x09,0x3e,0x04,0x86,0x21,0x0c,0x90,0xc3,0x03,0xa9,0xe7,0xb0,0x46,0x2c,0x51,0x40,0x4a,0x63,0x38,0x31,0x0a,0x34,0x90,0x12,0x91,0x8e,0x3c,0xff,0x89,0x4c,0x04,0xa4,0x43,0xfd,0xf3,0xc3,0xf2,0x01,0x29,0xe0,0x2b,0x8e,0x72,0xa0,0x46,0x4b,0xe0,0x30,0xba,0x10,0x22,0xca,0x1c,0x0b,0x26,0x09,0x3c,0x04,0x0c,0x08,0x59,0xc8,0x21,0x64,0xc4,0x47,0x98,0x82,0x81,0x0a,0xe0,0x21,0x39,0x04,0x34,0x88,0x60,0x93,0xa0,0x45,0x4b,0x06,0xa3,0x40,0x48,0xfc,0x20,0xf0,0x82,0xa2,0x4d,0x60,0x11,0xe9,0xc2,0x19,0x64,0xd0,0x08,0x1f,0x80,0x7e,0x60,0x01,0x92,0x60,0x20,0x38,0x05,0x21,0x7c,0x3f,0xf0,0x1a,0xe6,0x00,0xe6,0x21,0x32,0x1a,0x0c,0x0e,0x91,0x80,0x8f,0xc0,0x06,0x25,0xcc,0xbf,0xc1,0xaa,0x10,0x0b,0xfc,0x02,0x60,0x2e,0x2c,0x04,0x32,0xc1,0x00,0xff,0x40,0x68,0x00,0x91,0x89,0xc0,0x21,0x20,0x51,0xfe,0x41,0xf0,0x00,0x91,0xc4,0xcf,0xe2,0x40,0x51,0xfc,0x0c,0x86,0x07,0x80,0xe2,0xdf,0xda,0x25,0xf0,0x9f,0xc0,0x21,0x98,0x0f,0x27,0xfd,0xa2,0x5e,0x01,0x90,0xc4,0x30,0x1e,0x2f,0xfc,0xa1,0x3a,0x45,0x41,0xb0,0x60,0x3e,0x5e,0x79,0x4a,0x10,0xbf,0xe2,0x61,0xc0,0x82,0x52,0x01,0xff,0x36,0x8e,0x3b,0xe5,0xff,0x04,0x9f,0xf8,0x78,0x3b,0x8f,0x97,0xf8,0x12,0x7f,0xc3,0x78,0xf8,0x3e,0x5f,0xc0,0x49,0xfe,0x08,0xc2,0x17,0x1f,0xcd,0xa5,0xac,0x5f,0x02,0x30,0xc0,0x30,0x5f,0xfd,0x23,0xbc,0xbc,0x1f,0xf0,0xc1,0x5f,0xaa,0x8e,0x52,0x28,0x10,0x10,0x6f,0x1b,0x28,0x57,0x81,0x66,0x25,0x01,0x80,0x4e,0x28,0x15,0x98,0xad,0xc3,0xfd,0xff,0xff,0x91,0x87,0xc1,0x80,0xd4,0xc2,0xb2,0x03,0xb1,0x5b,0x13,0x34,0x6a,0xf1,0x58,0x84,0x0e,0x1d,0x00,0x23,0x14,0x0f,0x55,0x0a,0x88,0x67,0x0d,0x83,0x7c,0x04,0x8c,0x0a,0xa9,0x15,0x90,0x7c,0x07,0x23,0xf8,0x80,0xc1,0xa0,0xda,0x88,0x54,0x82,0x00,0x2f,0x1f,0xe4,0x3c,0x7a,0x35,0x08,0xab,0x20,0x7f,0x03,0xc1,0x2d,0x96,0x82,0x14,0xce,0x20,0x02,0x04,0xc6,0x00,0x60,0x20,0x01,0x84,0xc4,0x6a,0x21,0x36,0x3b,0x8c,0xf0,0x3c,0xc8,0x02,0x1b,0x88,0x01,0xe1,0x80,0x98,0x2d,0x10,0x01,0xb0,0x05,0xa1,0x00,0x3d,0xf8,0x13,0x17,0x81,0x47,0x80,0x0b,0xc0,0x28,0x8e,0x02,0xa4,0x81,0x2c,0xf0,0x20,0x01,0x00,}; -const uint8_t *_I_Flipper_young_80x60[] = {_I_Flipper_young_80x60_0}; - -const uint8_t _I_DolphinFirstStart8_56x51_0[] = {0x01,0x00,0xfd,0x00,0x00,0x17,0x83,0xff,0x01,0x03,0x1c,0x72,0x01,0x06,0x03,0x1c,0x0e,0x01,0x18,0x02,0x96,0x00,0x04,0x36,0x00,0x31,0x50,0x01,0x24,0x1c,0x29,0x00,0x28,0xa0,0x40,0x21,0x88,0x01,0x8a,0x08,0x02,0x18,0x40,0x18,0x80,0x64,0x09,0x20,0x89,0x81,0x98,0x3c,0x42,0x63,0x03,0x30,0xcc,0x70,0x10,0x71,0xd9,0x01,0x86,0xc1,0x1c,0x03,0x24,0x42,0x7e,0x50,0x12,0x91,0x62,0x2f,0xf8,0x0e,0x00,0x18,0xb9,0x17,0x1c,0x04,0x83,0x02,0x06,0x1e,0x27,0xc4,0x54,0x20,0x62,0xf2,0x7c,0xe0,0x52,0x0c,0x10,0x88,0x7c,0x9f,0xf8,0x28,0x18,0x41,0xa5,0xff,0x85,0x48,0x30,0x80,0xd1,0xe4,0x5f,0xc1,0xa3,0x84,0x26,0x0f,0x23,0xfe,0x1b,0x18,0x44,0x16,0x01,0x90,0x81,0xc1,0x62,0x10,0x84,0xc0,0xf8,0x20,0x30,0x28,0x84,0x40,0x1a,0x25,0x11,0x82,0x42,0x22,0x11,0xf4,0xd9,0xc1,0x02,0x22,0xb2,0x38,0x14,0xc1,0x8e,0x90,0x14,0xc1,0xa2,0x86,0x02,0xc6,0x30,0x31,0x06,0x8c,0x0c,0x26,0x02,0x56,0x9d,0x04,0x0c,0x6a,0xa1,0x03,0x21,0x20,0x68,0x5f,0xe7,0xa9,0x00,0x86,0x85,0x01,0x8f,0xe0,0x08,0xe3,0x00,0xe1,0x02,0xc6,0xfe,0x16,0x23,0xe1,0x13,0x10,0xa4,0x82,0xb1,0x12,0x88,0x00,0xf0,0x91,0xe0,0x6a,0xfd,0x63,0xfc,0x08,0x78,0x18,0xb5,0x5e,0xad,0xfb,0x84,0xa0,0x95,0x48,0xad,0x54,0x4a,0x50,0x4d,0x44,0x6b,0x56,0x0d,0x28,0x45,0x42,0x6a,0x0d,0x38,0x46,0x02,0x55,0xaa,0x35,0x25,0x52,0xac,0x06,0x4b,0x04,0xa8,0x0c,0x94,0x03,0xa0,0x80,0x04,}; -const uint8_t *_I_DolphinFirstStart8_56x51[] = {_I_DolphinFirstStart8_56x51_0}; - const uint8_t _I_DolphinFirstStart1_59x53_0[] = {0x01,0x00,0x1e,0x01,0x00,0x0e,0x03,0xfe,0x07,0x5b,0x84,0x02,0x06,0x07,0x48,0x64,0x02,0x08,0x07,0x48,0x14,0x02,0x10,0x07,0x48,0x0c,0x03,0x21,0x3f,0x13,0x18,0x84,0xa8,0x00,0x75,0x8c,0x00,0xca,0x00,0x0b,0x28,0x20,0x1d,0xa0,0x59,0xe0,0x39,0x48,0x07,0x03,0x81,0xd5,0x81,0xd6,0x81,0x55,0x8c,0x01,0xc6,0x21,0x00,0x87,0x68,0x25,0x52,0x40,0x39,0x7c,0x21,0xf5,0x08,0xa8,0x1d,0x20,0xfa,0x88,0x70,0x1c,0xfd,0x10,0x3a,0xa4,0x1f,0x88,0x54,0x18,0x85,0x52,0x09,0xbe,0x81,0xc1,0x0c,0x83,0x10,0x94,0x40,0x39,0xf0,0x19,0x21,0xc8,0x62,0x12,0x0c,0x04,0x0e,0x0c,0x07,0x38,0x07,0x86,0x07,0x18,0x03,0x94,0xc2,0x01,0x9e,0x81,0xca,0x38,0x89,0x21,0x0f,0x0c,0x03,0xf9,0x27,0x13,0x94,0xd0,0xb6,0x70,0x20,0x38,0xda,0x80,0xe5,0x10,0x03,0x95,0x59,0x54,0x70,0x10,0x38,0xda,0xc0,0xc3,0xfe,0xc1,0xab,0x0b,0xaa,0x2a,0x1c,0x05,0x81,0x58,0x38,0x09,0xd0,0x5c,0xa3,0xe0,0x72,0x86,0xae,0x8d,0x40,0x34,0x06,0xa1,0xc0,0xc0,0xe3,0xc0,0x65,0x1c,0x19,0x58,0x29,0xe1,0x00,0x14,0x28,0x0a,0x26,0x61,0x00,0x15,0x58,0x0a,0x2e,0x34,0xd6,0x42,0x9e,0x6b,0x54,0x82,0x92,0x08,0x1e,0x63,0x41,0x1d,0x0a,0x88,0x60,0x1d,0x42,0x11,0x5c,0x01,0xe5,0x3c,0x03,0x97,0x30,0x0e,0x42,0x42,0x80,0xd0,0x82,0xe4,0x07,0x28,0x17,0x10,0x1e,0xb0,0x4a,0x20,0x3d,0x61,0x1a,0x80,0x79,0x0f,0x0a,0x21,0x70,0x07,0x90,0x1c,0xa4,0x1a,0x00,0x7a,0xd0,0x0e,0x42,0x34,0x20,0x10,0xe0,0x00,0xed,0x00,0xa1,0x82,0xc8,0xc6,0x74,0x40,0xd9,0x01,0xce,0x84,0x07,0x69,0x10,0xcc,0x80,0xe7,0x5c,0x03,0xb4,0xa8,0x96,0x40,0x73,0x8a,0x96,0xc8,0x0c,0x40,}; const uint8_t *_I_DolphinFirstStart1_59x53[] = {_I_DolphinFirstStart1_59x53_0}; -const uint8_t _I_DolphinOkay_41x43_0[] = {0x01,0x00,0xa0,0x00,0x00,0x0f,0x82,0x3e,0x05,0x38,0xf7,0x80,0x08,0x58,0x08,0x0c,0x02,0x0e,0x05,0x1b,0x00,0x08,0x63,0x00,0x21,0x88,0x00,0x86,0x40,0x02,0x18,0x40,0x08,0x68,0x00,0x21,0x82,0x06,0x88,0x0a,0xf0,0x21,0x39,0x09,0x84,0x02,0x20,0x57,0x09,0x98,0x15,0x67,0xc0,0x54,0xbe,0x81,0x4f,0x01,0xfe,0x02,0x9d,0x03,0xc4,0x20,0x10,0x29,0x7c,0x80,0xa9,0xfe,0x02,0xac,0x14,0x0a,0x77,0xc8,0x58,0x8c,0xf0,0x11,0x51,0x79,0xff,0x61,0x44,0x93,0x81,0x02,0xc4,0x9e,0x60,0xb2,0xf0,0xa0,0x46,0x0c,0x17,0x14,0x99,0x1a,0x07,0x80,0x59,0x49,0x82,0x21,0xc0,0xa4,0x82,0x24,0xb9,0x20,0x88,0x1c,0x47,0xc2,0x07,0x11,0x54,0xa0,0x60,0x53,0xb8,0x0a,0x4b,0xf3,0x03,0x87,0x81,0x4a,0x0d,0xfc,0x1a,0x98,0x68,0xb8,0x01,0x51,0x13,0x15,0xe0,0x82,0x7f,0x8d,0x78,0x38,0xbf,0xff,0xfa,0xb8,0x60,0xbf,0x1b,0xf9,0x50,0x14,0xea,0xe7,0x02,0x02,0x8e,0xac,0x94,0x40,}; -const uint8_t *_I_DolphinOkay_41x43[] = {_I_DolphinOkay_41x43_0}; - -const uint8_t _I_DolphinFirstStart3_57x48_0[] = {0x01,0x00,0x12,0x01,0x00,0x16,0x03,0xff,0x07,0x03,0xa5,0x82,0x01,0x38,0x03,0xa4,0x62,0x01,0xc0,0x03,0xa4,0x10,0x04,0x30,0x10,0x39,0xc0,0x80,0x48,0x0c,0x40,0x91,0x7e,0x20,0x60,0x72,0x84,0x02,0x8b,0x78,0x12,0x28,0x80,0x68,0x85,0x87,0x20,0x11,0x18,0x5c,0x80,0xe8,0x01,0x19,0xc5,0x00,0x0e,0x62,0xc1,0x9f,0x01,0xcb,0xe9,0x03,0x84,0x60,0x20,0xf8,0x00,0x38,0xd7,0x21,0xb1,0x0f,0x04,0x04,0x0e,0x5a,0x89,0xd4,0x83,0xc0,0x4b,0x3a,0xc5,0x54,0xcc,0x20,0x51,0x00,0x8e,0xc3,0x54,0x80,0x13,0xf8,0x81,0xc6,0xc1,0x55,0x01,0x8c,0x78,0x0e,0x30,0xee,0x06,0xaa,0x05,0xe0,0xae,0x01,0xc6,0x23,0x80,0xaa,0xc1,0x60,0x1a,0x90,0x38,0xc8,0x60,0x1a,0xb8,0x54,0x02,0xad,0x07,0x80,0xd0,0x40,0x83,0x15,0x80,0x7b,0x21,0x10,0x1c,0x0c,0x03,0x7f,0x2a,0x80,0x4d,0x00,0xe3,0x01,0xf8,0xf0,0x2a,0xf0,0x08,0x60,0x1c,0x60,0x41,0xd1,0xdf,0x1a,0x44,0x0e,0x50,0x68,0x05,0xe3,0x07,0x02,0x82,0x01,0xc6,0x19,0x00,0xf8,0x5f,0xe0,0x20,0x72,0xfa,0x40,0x7f,0xc2,0xb1,0x03,0x88,0x68,0x7f,0xf6,0xb4,0x28,0xc0,0x80,0xe3,0x88,0xaa,0xc7,0x40,0xe9,0x50,0xd5,0x41,0x94,0xa2,0x07,0x29,0x87,0x52,0x02,0x07,0x12,0x30,0xc1,0x22,0x16,0x86,0x29,0x01,0xca,0x30,0xf6,0x10,0x39,0xc2,0x23,0x10,0x6c,0x00,0x1d,0x3d,0x10,0x1b,0x02,0xe0,0x41,0x03,0x08,0x75,0x0c,0x60,0x0e,0x4f,0x11,0x0a,0x0c,0x18,0x0e,0x96,0x06,0x28,0x81,0xd3,0x01,0x1f,0x01,0x90,0x1c,0xdc,0xc2,0x01,0x15,0xd0,0x81,0xdc,0x4c,0x30,0x30,0x3f,0x00,0xc4,0x0e,0x30,0x20,0x3c,0x8c,0xc8,0x0f,0x2b,0x41,}; -const uint8_t *_I_DolphinFirstStart3_57x48[] = {_I_DolphinFirstStart3_57x48_0}; +const uint8_t _I_DolphinFirstStart8_56x51_0[] = {0x01,0x00,0xfd,0x00,0x00,0x17,0x83,0xff,0x01,0x03,0x1c,0x72,0x01,0x06,0x03,0x1c,0x0e,0x01,0x18,0x02,0x96,0x00,0x04,0x36,0x00,0x31,0x50,0x01,0x24,0x1c,0x29,0x00,0x28,0xa0,0x40,0x21,0x88,0x01,0x8a,0x08,0x02,0x18,0x40,0x18,0x80,0x64,0x09,0x20,0x89,0x81,0x98,0x3c,0x42,0x63,0x03,0x30,0xcc,0x70,0x10,0x71,0xd9,0x01,0x86,0xc1,0x1c,0x03,0x24,0x42,0x7e,0x50,0x12,0x91,0x62,0x2f,0xf8,0x0e,0x00,0x18,0xb9,0x17,0x1c,0x04,0x83,0x02,0x06,0x1e,0x27,0xc4,0x54,0x20,0x62,0xf2,0x7c,0xe0,0x52,0x0c,0x10,0x88,0x7c,0x9f,0xf8,0x28,0x18,0x41,0xa5,0xff,0x85,0x48,0x30,0x80,0xd1,0xe4,0x5f,0xc1,0xa3,0x84,0x26,0x0f,0x23,0xfe,0x1b,0x18,0x44,0x16,0x01,0x90,0x81,0xc1,0x62,0x10,0x84,0xc0,0xf8,0x20,0x30,0x28,0x84,0x40,0x1a,0x25,0x11,0x82,0x42,0x22,0x11,0xf4,0xd9,0xc1,0x02,0x22,0xb2,0x38,0x14,0xc1,0x8e,0x90,0x14,0xc1,0xa2,0x86,0x02,0xc6,0x30,0x31,0x06,0x8c,0x0c,0x26,0x02,0x56,0x9d,0x04,0x0c,0x6a,0xa1,0x03,0x21,0x20,0x68,0x5f,0xe7,0xa9,0x00,0x86,0x85,0x01,0x8f,0xe0,0x08,0xe3,0x00,0xe1,0x02,0xc6,0xfe,0x16,0x23,0xe1,0x13,0x10,0xa4,0x82,0xb1,0x12,0x88,0x00,0xf0,0x91,0xe0,0x6a,0xfd,0x63,0xfc,0x08,0x78,0x18,0xb5,0x5e,0xad,0xfb,0x84,0xa0,0x95,0x48,0xad,0x54,0x4a,0x50,0x4d,0x44,0x6b,0x56,0x0d,0x28,0x45,0x42,0x6a,0x0d,0x38,0x46,0x02,0x55,0xaa,0x35,0x25,0x52,0xac,0x06,0x4b,0x04,0xa8,0x0c,0x94,0x03,0xa0,0x80,0x04,}; +const uint8_t *_I_DolphinFirstStart8_56x51[] = {_I_DolphinFirstStart8_56x51_0}; const uint8_t _I_DolphinFirstStart7_61x51_0[] = {0x01,0x00,0x13,0x01,0x00,0x17,0x03,0xff,0x01,0x03,0xa4,0xe2,0x01,0x0e,0x03,0xa4,0x1a,0x01,0x30,0x03,0x1e,0x00,0x2a,0x3c,0x00,0x39,0xd0,0x00,0x65,0x03,0x01,0x94,0x80,0x06,0x50,0x40,0x19,0x44,0x00,0x65,0x08,0x01,0xb0,0x2c,0xe2,0x81,0xb6,0x86,0x0a,0xd8,0x7c,0x20,0x75,0x85,0x10,0xcc,0x06,0x50,0x50,0x3b,0x10,0xce,0x00,0x69,0x20,0x79,0x7c,0x20,0x20,0x71,0xc0,0x07,0xca,0xf1,0x02,0x81,0x01,0xc6,0x3a,0x07,0x1f,0xe4,0x10,0x0e,0x53,0xe0,0x38,0xe7,0xa0,0xa0,0x72,0xbb,0x81,0xca,0x12,0x68,0x1c,0x05,0x5c,0x0e,0x3f,0xe8,0xc8,0x1c,0xab,0xe0,0x72,0x94,0x81,0xda,0xb2,0x07,0x5f,0xe0,0x3d,0xbf,0x95,0x44,0x20,0x81,0xce,0xf1,0x2f,0x03,0x94,0xb8,0xae,0x51,0x00,0x39,0x47,0x60,0xd0,0x84,0x70,0x81,0xcb,0x44,0x9d,0x10,0x3a,0x58,0xce,0xe6,0x07,0x29,0x10,0x18,0xa0,0x50,0x88,0x76,0x02,0x22,0x07,0x49,0x8e,0x02,0x24,0x07,0x4e,0x0e,0x02,0x12,0x96,0x38,0x44,0x07,0x02,0x8f,0x1c,0x07,0x1c,0x4e,0x30,0x1c,0x10,0x3c,0x6c,0x13,0x80,0x38,0xc0,0xb0,0x80,0xf1,0x6e,0x90,0x1c,0x71,0x10,0xd7,0x49,0x81,0xc7,0x20,0x0f,0x17,0xe9,0x42,0x20,0x91,0x09,0xeb,0x24,0xe2,0x10,0x49,0x07,0x6f,0xff,0x80,0x56,0x88,0x1c,0xa2,0xae,0xd1,0x66,0x89,0xe0,0x68,0x11,0xb8,0x06,0xc0,0x2e,0x40,0x71,0x9a,0xc0,0x2b,0x00,0x73,0xc0,0x7a,0xe0,0x09,0x12,0x03,0x95,0x57,0xff,0x17,0x03,0x9c,0x03,0x57,0xaa,0x78,0x94,0x40,0xa6,0x35,0x5a,0xac,0x14,0x0e,0x9a,0xad,0x50,0xf8,0x41,0x05,0x00,0x83,0x55,0x14,0x06,0x07,0x18,0x54,0xa0,0x0e,0xb0,0x60,0x31,0xc0,0x00,}; const uint8_t *_I_DolphinFirstStart7_61x51[] = {_I_DolphinFirstStart7_61x51_0}; -const uint8_t _I_DolphinFirstStart0_70x53_0[] = {0x01,0x00,0x5a,0x01,0x80,0x60,0x3f,0xf7,0xf0,0x42,0xf8,0x01,0x43,0x07,0x04,0x24,0x72,0x01,0xc0,0x9d,0x82,0x13,0xff,0xff,0xbd,0x70,0x20,0x20,0x72,0xe0,0x40,0x2a,0x11,0xdb,0x00,0x6c,0xec,0x10,0x0d,0x44,0x3a,0x71,0x0e,0x04,0x14,0x42,0x01,0x54,0x86,0xd3,0x27,0x02,0x44,0xd4,0x41,0xb0,0xf2,0x10,0x42,0x55,0x38,0x71,0x1b,0x10,0x18,0xa0,0x41,0x11,0xb1,0xc8,0x28,0x98,0x09,0xfc,0x00,0x72,0x35,0x49,0x8d,0x0b,0xc1,0x70,0xf0,0x10,0x4b,0x51,0x11,0xc2,0x6c,0x0a,0xa3,0x03,0x80,0x7f,0xbf,0xf3,0x08,0x46,0x60,0x90,0x30,0x60,0x50,0xd8,0x2c,0x11,0x0c,0x71,0x5c,0x60,0xf8,0x0f,0xcf,0x3f,0x81,0x80,0xa1,0x9e,0x86,0x0f,0xc0,0x82,0x64,0x30,0x3e,0x09,0x84,0x03,0xf1,0x03,0xa0,0x40,0xa4,0x18,0x39,0xfc,0x20,0x52,0x30,0x19,0x07,0xc6,0x8e,0x4a,0x18,0x22,0x74,0x60,0x1a,0x0f,0xc6,0x3c,0x60,0x5c,0x05,0x28,0xe4,0x3f,0x99,0xf8,0x22,0x28,0x7e,0x05,0x91,0xa8,0x7f,0x23,0xf0,0x59,0x00,0xac,0x63,0xe0,0x81,0xcf,0x4f,0xe0,0xb1,0x81,0x58,0xc3,0xc1,0x08,0x24,0x1f,0xf9,0x68,0x6a,0x1f,0xe9,0xff,0x16,0x02,0x34,0x13,0x50,0x82,0x0a,0xea,0x60,0x1f,0xf9,0xf0,0x41,0x05,0x1d,0x30,0x09,0x18,0x60,0x15,0xa3,0xe8,0x83,0x47,0xe0,0xec,0x2c,0xaf,0xf2,0x0e,0x08,0x1f,0xc1,0x18,0x60,0x1a,0xaf,0xc2,0x6c,0x89,0x62,0x03,0x19,0xad,0xe5,0x70,0x44,0x62,0x80,0x5a,0xa1,0x4f,0x63,0x23,0x0c,0x7a,0xaa,0x4d,0x11,0xe9,0x00,0x06,0x73,0xaa,0x25,0x0a,0x78,0xaf,0x90,0x09,0x25,0x54,0x56,0x5f,0x04,0x30,0xc0,0x64,0x7a,0xa1,0x11,0x7e,0x20,0x18,0x0f,0x3c,0x82,0xaa,0x04,0x18,0x0d,0xf8,0x16,0x33,0xe8,0x84,0xa8,0x08,0x3c,0x33,0x00,0xf0,0x20,0x71,0x08,0xa9,0x38,0x86,0x62,0x62,0x18,0x40,0x44,0x80,0x09,0x04,0x08,0x90,0x01,0x20,0x41,0x17,0x22,0x90,0x01,0x3e,0x00,0x76,0x80,0x1d,0x48,0x00,0x8d,0x91,0x00,0x34,0xf8,0x20,0xe2,0xa7,0x9c,0x06,0x5c,0x11,0x02,0x28,0x5d,0x91,0x35,0x48,0xaf,0xf8,0x04,0x3f,0xf9,0x88,0x20,0x01,}; -const uint8_t *_I_DolphinFirstStart0_70x53[] = {_I_DolphinFirstStart0_70x53_0}; +const uint8_t _I_Flipper_young_80x60_0[] = {0x01,0x00,0xa3,0x01,0x00,0x1e,0x03,0xff,0xff,0x87,0x82,0x57,0xf1,0x83,0x90,0xde,0x01,0x2b,0x0e,0x83,0x70,0xfb,0x10,0x10,0x41,0xf8,0x27,0x70,0xcc,0x34,0xc6,0x0e,0x09,0x3e,0x04,0x86,0x21,0x0c,0x90,0xc3,0x03,0xa9,0xe7,0xb0,0x46,0x2c,0x51,0x40,0x4a,0x63,0x38,0x31,0x0a,0x34,0x90,0x12,0x91,0x8e,0x3c,0xff,0x89,0x4c,0x04,0xa4,0x43,0xfd,0xf3,0xc3,0xf2,0x01,0x29,0xe0,0x2b,0x8e,0x72,0xa0,0x46,0x4b,0xe0,0x30,0xba,0x10,0x22,0xca,0x1c,0x0b,0x26,0x09,0x3c,0x04,0x0c,0x08,0x59,0xc8,0x21,0x64,0xc4,0x47,0x98,0x82,0x81,0x0a,0xe0,0x21,0x39,0x04,0x34,0x88,0x60,0x93,0xa0,0x45,0x4b,0x06,0xa3,0x40,0x48,0xfc,0x20,0xf0,0x82,0xa2,0x4d,0x60,0x11,0xe9,0xc2,0x19,0x64,0xd0,0x08,0x1f,0x80,0x7e,0x60,0x01,0x92,0x60,0x20,0x38,0x05,0x21,0x7c,0x3f,0xf0,0x1a,0xe6,0x00,0xe6,0x21,0x32,0x1a,0x0c,0x0e,0x91,0x80,0x8f,0xc0,0x06,0x25,0xcc,0xbf,0xc1,0xaa,0x10,0x0b,0xfc,0x02,0x60,0x2e,0x2c,0x04,0x32,0xc1,0x00,0xff,0x40,0x68,0x00,0x91,0x89,0xc0,0x21,0x20,0x51,0xfe,0x41,0xf0,0x00,0x91,0xc4,0xcf,0xe2,0x40,0x51,0xfc,0x0c,0x86,0x07,0x80,0xe2,0xdf,0xda,0x25,0xf0,0x9f,0xc0,0x21,0x98,0x0f,0x27,0xfd,0xa2,0x5e,0x01,0x90,0xc4,0x30,0x1e,0x2f,0xfc,0xa1,0x3a,0x45,0x41,0xb0,0x60,0x3e,0x5e,0x79,0x4a,0x10,0xbf,0xe2,0x61,0xc0,0x82,0x52,0x01,0xff,0x36,0x8e,0x3b,0xe5,0xff,0x04,0x9f,0xf8,0x78,0x3b,0x8f,0x97,0xf8,0x12,0x7f,0xc3,0x78,0xf8,0x3e,0x5f,0xc0,0x49,0xfe,0x08,0xc2,0x17,0x1f,0xcd,0xa5,0xac,0x5f,0x02,0x30,0xc0,0x30,0x5f,0xfd,0x23,0xbc,0xbc,0x1f,0xf0,0xc1,0x5f,0xaa,0x8e,0x52,0x28,0x10,0x10,0x6f,0x1b,0x28,0x57,0x81,0x66,0x25,0x01,0x80,0x4e,0x28,0x15,0x98,0xad,0xc3,0xfd,0xff,0xff,0x91,0x87,0xc1,0x80,0xd4,0xc2,0xb2,0x03,0xb1,0x5b,0x13,0x34,0x6a,0xf1,0x58,0x84,0x0e,0x1d,0x00,0x23,0x14,0x0f,0x55,0x0a,0x88,0x67,0x0d,0x83,0x7c,0x04,0x8c,0x0a,0xa9,0x15,0x90,0x7c,0x07,0x23,0xf8,0x80,0xc1,0xa0,0xda,0x88,0x54,0x82,0x00,0x2f,0x1f,0xe4,0x3c,0x7a,0x35,0x08,0xab,0x20,0x7f,0x03,0xc1,0x2d,0x96,0x82,0x14,0xce,0x20,0x02,0x04,0xc6,0x00,0x60,0x20,0x01,0x84,0xc4,0x6a,0x21,0x36,0x3b,0x8c,0xf0,0x3c,0xc8,0x02,0x1b,0x88,0x01,0xe1,0x80,0x98,0x2d,0x10,0x01,0xb0,0x05,0xa1,0x00,0x3d,0xf8,0x13,0x17,0x81,0x47,0x80,0x0b,0xc0,0x28,0x8e,0x02,0xa4,0x81,0x2c,0xf0,0x20,0x01,0x00,}; +const uint8_t *_I_Flipper_young_80x60[] = {_I_Flipper_young_80x60_0}; -const uint8_t _I_DolphinFirstStart4_67x53_0[] = {0x01,0x00,0x1f,0x01,0x00,0x17,0xc3,0xfe,0x08,0x68,0x74,0x02,0x0e,0x07,0x4c,0x04,0x06,0x01,0x18,0x04,0x25,0x00,0x04,0x36,0x00,0x42,0x48,0x02,0x88,0x00,0x28,0x80,0x0c,0xa0,0x40,0x83,0x84,0x00,0xca,0x08,0x08,0x30,0x21,0x83,0x0c,0x2c,0x81,0xe3,0x04,0x20,0xc0,0x80,0x02,0x31,0x32,0x11,0x02,0x27,0x00,0x5d,0x40,0x45,0x87,0x90,0x3e,0x7c,0x00,0x43,0x84,0x4e,0x60,0x43,0x30,0x89,0x82,0x12,0x80,0x15,0x20,0x40,0x99,0xc8,0x22,0x7b,0x88,0x10,0x20,0x82,0x27,0x7c,0x82,0x9d,0x48,0x22,0x5f,0x0d,0xfc,0x08,0x10,0x41,0x12,0xf8,0x57,0xc2,0x28,0x30,0x1e,0x07,0x9e,0x06,0x87,0x25,0x79,0xc4,0x20,0x40,0x83,0x21,0x14,0x22,0x08,0x08,0x38,0x2a,0xb8,0xd9,0x47,0x0a,0x14,0x09,0xf0,0x54,0x47,0x1f,0x81,0x82,0x1a,0xde,0x8e,0x33,0xd1,0xc7,0x81,0x0f,0x0e,0x45,0x18,0x20,0xa1,0xe6,0xf2,0x10,0x89,0xa0,0x70,0x11,0x00,0x41,0x46,0x03,0x86,0x55,0x10,0x40,0xc1,0x82,0x25,0x20,0x04,0x11,0x94,0x80,0x43,0x10,0x84,0x01,0x46,0xc0,0xbd,0x38,0x40,0x20,0x8f,0x49,0x08,0xc4,0x1c,0xc8,0x22,0x50,0x38,0x20,0x20,0x86,0xe4,0x83,0x10,0x41,0x8b,0x87,0xf9,0x03,0x81,0xc0,0x81,0x05,0x81,0xc0,0x40,0xf3,0x90,0x60,0x41,0x70,0x2c,0x17,0x01,0xc0,0xc1,0x41,0x05,0x30,0x98,0x43,0x04,0x65,0x01,0x04,0x0c,0x32,0x38,0x91,0x18,0x04,0x14,0x10,0x38,0x18,0x1e,0xac,0x7c,0x41,0x11,0x88,0x5f,0xfc,0x17,0x55,0xa9,0x82,0x06,0x05,0xbc,0x85,0x02,0x08,0xc6,0x32,0x0f,0xe5,0x5e,0x1a,0x08,0x5c,0x06,0xaa,0x34,0x08,0x4a,0x06,0x02,0xab,0x75,0xf0,0x4f,0xc1,0x05,0x80,0x08,0x8e,0xab,0x7f,0xea,0x04,0x11,0x80,0x6a,0xa0,0x02,0x03,0x08,}; -const uint8_t *_I_DolphinFirstStart4_67x53[] = {_I_DolphinFirstStart4_67x53_0}; - -const uint8_t _I_ArrowUpEmpty_14x15_0[] = {0x01,0x00,0x18,0x00,0xe0,0x40,0x24,0x10,0x18,0x84,0x0a,0x11,0x04,0x82,0x42,0x20,0x51,0x08,0x0c,0x82,0x1f,0x3c,0x04,0x88,0x06,0x7f,0x10,0x70,}; -const uint8_t *_I_ArrowUpEmpty_14x15[] = {_I_ArrowUpEmpty_14x15_0}; +const uint8_t _I_DolphinFirstStart3_57x48_0[] = {0x01,0x00,0x12,0x01,0x00,0x16,0x03,0xff,0x07,0x03,0xa5,0x82,0x01,0x38,0x03,0xa4,0x62,0x01,0xc0,0x03,0xa4,0x10,0x04,0x30,0x10,0x39,0xc0,0x80,0x48,0x0c,0x40,0x91,0x7e,0x20,0x60,0x72,0x84,0x02,0x8b,0x78,0x12,0x28,0x80,0x68,0x85,0x87,0x20,0x11,0x18,0x5c,0x80,0xe8,0x01,0x19,0xc5,0x00,0x0e,0x62,0xc1,0x9f,0x01,0xcb,0xe9,0x03,0x84,0x60,0x20,0xf8,0x00,0x38,0xd7,0x21,0xb1,0x0f,0x04,0x04,0x0e,0x5a,0x89,0xd4,0x83,0xc0,0x4b,0x3a,0xc5,0x54,0xcc,0x20,0x51,0x00,0x8e,0xc3,0x54,0x80,0x13,0xf8,0x81,0xc6,0xc1,0x55,0x01,0x8c,0x78,0x0e,0x30,0xee,0x06,0xaa,0x05,0xe0,0xae,0x01,0xc6,0x23,0x80,0xaa,0xc1,0x60,0x1a,0x90,0x38,0xc8,0x60,0x1a,0xb8,0x54,0x02,0xad,0x07,0x80,0xd0,0x40,0x83,0x15,0x80,0x7b,0x21,0x10,0x1c,0x0c,0x03,0x7f,0x2a,0x80,0x4d,0x00,0xe3,0x01,0xf8,0xf0,0x2a,0xf0,0x08,0x60,0x1c,0x60,0x41,0xd1,0xdf,0x1a,0x44,0x0e,0x50,0x68,0x05,0xe3,0x07,0x02,0x82,0x01,0xc6,0x19,0x00,0xf8,0x5f,0xe0,0x20,0x72,0xfa,0x40,0x7f,0xc2,0xb1,0x03,0x88,0x68,0x7f,0xf6,0xb4,0x28,0xc0,0x80,0xe3,0x88,0xaa,0xc7,0x40,0xe9,0x50,0xd5,0x41,0x94,0xa2,0x07,0x29,0x87,0x52,0x02,0x07,0x12,0x30,0xc1,0x22,0x16,0x86,0x29,0x01,0xca,0x30,0xf6,0x10,0x39,0xc2,0x23,0x10,0x6c,0x00,0x1d,0x3d,0x10,0x1b,0x02,0xe0,0x41,0x03,0x08,0x75,0x0c,0x60,0x0e,0x4f,0x11,0x0a,0x0c,0x18,0x0e,0x96,0x06,0x28,0x81,0xd3,0x01,0x1f,0x01,0x90,0x1c,0xdc,0xc2,0x01,0x15,0xd0,0x81,0xdc,0x4c,0x30,0x30,0x3f,0x00,0xc4,0x0e,0x30,0x20,0x3c,0x8c,0xc8,0x0f,0x2b,0x41,}; +const uint8_t *_I_DolphinFirstStart3_57x48[] = {_I_DolphinFirstStart3_57x48_0}; const uint8_t _I_ArrowUpFilled_14x15_0[] = {0x00,0xC0,0x00,0x20,0x01,0xD0,0x02,0xE8,0x05,0xF4,0x0B,0xFA,0x17,0x61,0x21,0xAF,0x3D,0x68,0x05,0xA8,0x05,0x68,0x05,0xA8,0x05,0xE8,0x05,0x08,0x04,0xF8,0x07,}; const uint8_t *_I_ArrowUpFilled_14x15[] = {_I_ArrowUpFilled_14x15_0}; -const uint8_t _I_ArrowDownFilled_14x15_0[] = {0x00,0xF8,0x07,0x08,0x04,0xE8,0x05,0x68,0x05,0xA8,0x05,0x68,0x05,0xA8,0x05,0x6F,0x3D,0xA1,0x21,0xFA,0x17,0xF4,0x0B,0xE8,0x05,0xD0,0x02,0x20,0x01,0xC0,0x00,}; -const uint8_t *_I_ArrowDownFilled_14x15[] = {_I_ArrowDownFilled_14x15_0}; +const uint8_t _I_ArrowUpEmpty_14x15_0[] = {0x01,0x00,0x18,0x00,0xe0,0x40,0x24,0x10,0x18,0x84,0x0a,0x11,0x04,0x82,0x42,0x20,0x51,0x08,0x0c,0x82,0x1f,0x3c,0x04,0x88,0x06,0x7f,0x10,0x70,}; +const uint8_t *_I_ArrowUpEmpty_14x15[] = {_I_ArrowUpEmpty_14x15_0}; const uint8_t _I_ArrowDownEmpty_14x15_0[] = {0x01,0x00,0x17,0x00,0xfc,0x41,0xe1,0x10,0x40,0x0c,0xc3,0xe7,0x90,0x19,0x04,0x0a,0x20,0x08,0x10,0x48,0xc4,0x20,0x52,0x08,0x0f,0x02,0x00,}; const uint8_t *_I_ArrowDownEmpty_14x15[] = {_I_ArrowDownEmpty_14x15_0}; +const uint8_t _I_ArrowDownFilled_14x15_0[] = {0x00,0xF8,0x07,0x08,0x04,0xE8,0x05,0x68,0x05,0xA8,0x05,0x68,0x05,0xA8,0x05,0x6F,0x3D,0xA1,0x21,0xFA,0x17,0xF4,0x0B,0xE8,0x05,0xD0,0x02,0x20,0x01,0xC0,0x00,}; +const uint8_t *_I_ArrowDownFilled_14x15[] = {_I_ArrowDownFilled_14x15_0}; + const uint8_t _I_PassportBottom_128x17_0[] = {0x01,0x00,0x5e,0x00,0x96,0x01,0x97,0xe1,0xff,0x00,0x2e,0x3e,0x68,0x0f,0x5a,0xc5,0x54,0x00,0xb9,0x50,0xfb,0x6a,0x35,0x40,0x05,0xcd,0x4e,0x03,0xfd,0x30,0x0f,0xf8,0x7f,0xa0,0x81,0xfe,0xf9,0x1b,0xfb,0xf3,0x01,0x47,0x66,0x02,0x1b,0x03,0x07,0xe7,0x02,0x0b,0x02,0x07,0xe5,0x82,0x0b,0xf2,0x1c,0xb0,0x01,0x67,0xf0,0x5f,0xd0,0x3f,0x23,0xf0,0x9b,0xc9,0xe5,0x80,0x03,0xd5,0xc0,0x00,0x86,0x01,0xf3,0xe6,0x1e,0x58,0x00,0x36,0xa8,0x06,0xac,0x04,0x30,0x6c,0x30,0xee,0x60,0x1f,0xe0,0x10,0xff,0x0d,0xfb,0x00,}; const uint8_t *_I_PassportBottom_128x17[] = {_I_PassportBottom_128x17_0}; -const uint8_t _I_DoorLeft_70x55_0[] = {0x01,0x00,0x19,0x01,0x00,0x2c,0x32,0x01,0x03,0x04,0x2c,0x18,0x10,0xf0,0x40,0x47,0x82,0x06,0x81,0x03,0xff,0x80,0x08,0x1a,0x20,0x82,0x15,0x28,0x21,0x87,0x82,0x08,0x6f,0xc0,0xb1,0xe6,0x10,0x10,0x8b,0x46,0x20,0x43,0x55,0x8f,0x82,0x10,0x32,0x73,0x0a,0x09,0x89,0x6c,0x1e,0x09,0x00,0x18,0x60,0xf0,0x0c,0x84,0x93,0x82,0x03,0x18,0x0c,0x02,0x1d,0x00,0x90,0x52,0x70,0x50,0x1e,0x00,0x58,0x63,0x90,0x0a,0x06,0x4a,0x09,0x03,0xb0,0x02,0x06,0x70,0x62,0x49,0xf8,0x0c,0x66,0x3f,0xf0,0x41,0x63,0x04,0x43,0x00,0x99,0x60,0x00,0x85,0xc8,0x06,0x14,0xd0,0x80,0x3f,0xc8,0x0d,0xb8,0x10,0x70,0xf8,0x34,0x13,0x03,0x39,0x04,0x1c,0x42,0x19,0xf8,0xa0,0xc2,0x01,0x07,0xef,0x02,0x8c,0x80,0x10,0x9d,0x00,0x43,0xec,0x00,0xa3,0x10,0x04,0x25,0xce,0x19,0xfc,0x88,0x82,0x12,0x0c,0x35,0x10,0x42,0x4c,0xa1,0x90,0x3f,0xc0,0x21,0x22,0x39,0x82,0xc8,0x88,0xd2,0x11,0xf0,0x01,0x88,0xd5,0x18,0xe2,0x08,0x68,0x10,0x0c,0xa8,0x00,0x83,0x81,0xcc,0xd5,0xc3,0x80,0x84,0x82,0x0e,0xcc,0xc0,0x15,0x79,0x02,0x0b,0x98,0xf8,0x11,0x88,0x82,0x0f,0x31,0x19,0x02,0x08,0x2c,0x9f,0x6a,0x1d,0x20,0x41,0x31,0x4c,0x10,0x8d,0x73,0x04,0x23,0xa4,0xc4,0x6c,0xde,0x20,0x42,0xcc,0x01,0x07,0x07,0xff,0x80,0x06,0x3e,0x08,0x38,0x70,0x20,0xa1,0xe0,0x83,0x8e,0x01,0x0c,0xf0,0x73,0x80,0x43,0x70,0x05,0x08,0x00,0x2c,0x04,0xc4,0x46,0x53,0x09,0x98,0x24,0x80,0x65,0x80,0xb0,0xd9,0x84,0x65,0x32,0x06,0x17,0x0f,0x98,0x23,0x63,0xe1,0x88,0xc4,0x08,0x5f,0xc1,0x30,0x9d,0x84,0x4e,0x66,0x94,0x11,0x98,0x75,0x26,0x00,}; -const uint8_t *_I_DoorLeft_70x55[] = {_I_DoorLeft_70x55_0}; - -const uint8_t _I_DoorRight_70x55_0[] = {0x01,0x00,0x16,0x01,0x81,0xcc,0x01,0x0f,0x60,0x04,0x3f,0x00,0x10,0xf8,0x08,0x0c,0x02,0x05,0x01,0x84,0x02,0x06,0x26,0x0a,0x10,0x8a,0xcc,0xe0,0x1d,0x68,0xe0,0x18,0xab,0xd0,0x0b,0x18,0x10,0x46,0xe6,0x16,0x1e,0x18,0x10,0x46,0xe4,0x28,0x2c,0x98,0x14,0x68,0x00,0x21,0x1d,0x10,0x8c,0x40,0x02,0x0e,0x10,0xa1,0x08,0xc8,0x40,0x42,0x62,0x11,0x94,0x03,0xfd,0xff,0x00,0x0c,0xff,0x0c,0x08,0x28,0x60,0xe4,0xc0,0x85,0x00,0x83,0x00,0x87,0xf1,0x00,0x8c,0x02,0x0b,0x07,0x24,0x84,0xff,0x04,0xc7,0x80,0xa0,0xe4,0xa0,0x81,0x41,0x04,0x17,0x02,0x41,0x49,0x81,0x0e,0x10,0xb2,0xa0,0x82,0x0e,0x9f,0xfc,0x0a,0x62,0xf2,0xc0,0x03,0x92,0xf0,0x08,0x2d,0x78,0x20,0xff,0x02,0x01,0x08,0xae,0x60,0x64,0x38,0x0d,0xb0,0x8d,0x08,0x82,0x11,0x58,0xc4,0x13,0xc0,0x35,0x68,0x62,0x68,0x81,0x09,0x08,0x84,0x40,0x81,0x0d,0x18,0x69,0x10,0x47,0x44,0x66,0x5f,0x21,0xa9,0x29,0x94,0x10,0x2f,0x23,0x53,0x14,0x60,0x42,0x3c,0x08,0xfc,0x02,0x2c,0x62,0x23,0x58,0xd0,0x22,0x00,0x83,0x3e,0x98,0x44,0x43,0x46,0x22,0x30,0x89,0xce,0x01,0x0f,0x70,0x04,0x3f,0x81,0x8a,0x3c,0x21,0xaa,0x70,0x1a,0xe3,0x44,0x1a,0xa6,0x01,0xd2,0x38,0x90,0x8a,0x40,0x20,0xe5,0x96,0x80,0x43,0x81,0x06,0x6b,0x28,0x07,0xf3,0xfe,0x00,0x19,0xf9,0x34,0xc1,0x08,0x8f,0x20,0xf1,0x3e,0x16,0x00,0xa8,0x19,0x00,0x10,0x76,0x03,0xe2,0x3e,0x90,0x45,0x38,0x01,0x42,0x05,0x88,0x44,0x67,0x15,0x70,0x41,0x38,0x04,0x10,0x24,0x03,0x00,0x10,0x20,0x4a,0x46,0xe9,0x46,0xe1,0x04,0x50,0x66,0x40,0x85,0x19,0x98,0x00,0xc0,}; -const uint8_t *_I_DoorRight_70x55[] = {_I_DoorRight_70x55_0}; - const uint8_t _I_DoorLocked_10x56_0[] = {0x01,0x00,0x4e,0x00,0x86,0x40,0x25,0xb0,0x0b,0x6c,0x03,0x9b,0x00,0xc6,0xc0,0x65,0x90,0x10,0x3a,0xc3,0x20,0x31,0xc8,0x04,0xe2,0x01,0x70,0x80,0x78,0x20,0x1c,0x48,0x07,0x22,0x01,0xd0,0x00,0xf0,0x44,0x68,0x90,0x09,0x04,0x02,0x21,0x00,0x84,0x40,0x25,0x80,0x12,0x1e,0x88,0x14,0xc0,0x2e,0x0d,0x11,0xca,0xf8,0x60,0x1c,0x38,0x07,0x1a,0x05,0xcc,0x80,0x72,0x60,0x5c,0x38,0x10,0x1c,0xf9,0x10,0x2e,0x00,0x05,0x60,0x00,0x11,}; const uint8_t *_I_DoorLocked_10x56[] = {_I_DoorLocked_10x56_0}; +const uint8_t _I_DoorLeft_70x55_0[] = {0x01,0x00,0x19,0x01,0x00,0x2c,0x32,0x01,0x03,0x04,0x2c,0x18,0x10,0xf0,0x40,0x47,0x82,0x06,0x81,0x03,0xff,0x80,0x08,0x1a,0x20,0x82,0x15,0x28,0x21,0x87,0x82,0x08,0x6f,0xc0,0xb1,0xe6,0x10,0x10,0x8b,0x46,0x20,0x43,0x55,0x8f,0x82,0x10,0x32,0x73,0x0a,0x09,0x89,0x6c,0x1e,0x09,0x00,0x18,0x60,0xf0,0x0c,0x84,0x93,0x82,0x03,0x18,0x0c,0x02,0x1d,0x00,0x90,0x52,0x70,0x50,0x1e,0x00,0x58,0x63,0x90,0x0a,0x06,0x4a,0x09,0x03,0xb0,0x02,0x06,0x70,0x62,0x49,0xf8,0x0c,0x66,0x3f,0xf0,0x41,0x63,0x04,0x43,0x00,0x99,0x60,0x00,0x85,0xc8,0x06,0x14,0xd0,0x80,0x3f,0xc8,0x0d,0xb8,0x10,0x70,0xf8,0x34,0x13,0x03,0x39,0x04,0x1c,0x42,0x19,0xf8,0xa0,0xc2,0x01,0x07,0xef,0x02,0x8c,0x80,0x10,0x9d,0x00,0x43,0xec,0x00,0xa3,0x10,0x04,0x25,0xce,0x19,0xfc,0x88,0x82,0x12,0x0c,0x35,0x10,0x42,0x4c,0xa1,0x90,0x3f,0xc0,0x21,0x22,0x39,0x82,0xc8,0x88,0xd2,0x11,0xf0,0x01,0x88,0xd5,0x18,0xe2,0x08,0x68,0x10,0x0c,0xa8,0x00,0x83,0x81,0xcc,0xd5,0xc3,0x80,0x84,0x82,0x0e,0xcc,0xc0,0x15,0x79,0x02,0x0b,0x98,0xf8,0x11,0x88,0x82,0x0f,0x31,0x19,0x02,0x08,0x2c,0x9f,0x6a,0x1d,0x20,0x41,0x31,0x4c,0x10,0x8d,0x73,0x04,0x23,0xa4,0xc4,0x6c,0xde,0x20,0x42,0xcc,0x01,0x07,0x07,0xff,0x80,0x06,0x3e,0x08,0x38,0x70,0x20,0xa1,0xe0,0x83,0x8e,0x01,0x0c,0xf0,0x73,0x80,0x43,0x70,0x05,0x08,0x00,0x2c,0x04,0xc4,0x46,0x53,0x09,0x98,0x24,0x80,0x65,0x80,0xb0,0xd9,0x84,0x65,0x32,0x06,0x17,0x0f,0x98,0x23,0x63,0xe1,0x88,0xc4,0x08,0x5f,0xc1,0x30,0x9d,0x84,0x4e,0x66,0x94,0x11,0x98,0x75,0x26,0x00,}; +const uint8_t *_I_DoorLeft_70x55[] = {_I_DoorLeft_70x55_0}; + const uint8_t _I_PassportLeft_6x47_0[] = {0x01,0x00,0x1c,0x00,0x9e,0x40,0xa3,0x32,0x59,0x2c,0x66,0x03,0x01,0x82,0xc2,0x62,0x32,0x50,0x16,0xc8,0x60,0x30,0x28,0x24,0x32,0x39,0x3c,0x9e,0x4d,0x25,0x80,0x1a,}; const uint8_t *_I_PassportLeft_6x47[] = {_I_PassportLeft_6x47_0}; +const uint8_t _I_DoorRight_70x55_0[] = {0x01,0x00,0x16,0x01,0x81,0xcc,0x01,0x0f,0x60,0x04,0x3f,0x00,0x10,0xf8,0x08,0x0c,0x02,0x05,0x01,0x84,0x02,0x06,0x26,0x0a,0x10,0x8a,0xcc,0xe0,0x1d,0x68,0xe0,0x18,0xab,0xd0,0x0b,0x18,0x10,0x46,0xe6,0x16,0x1e,0x18,0x10,0x46,0xe4,0x28,0x2c,0x98,0x14,0x68,0x00,0x21,0x1d,0x10,0x8c,0x40,0x02,0x0e,0x10,0xa1,0x08,0xc8,0x40,0x42,0x62,0x11,0x94,0x03,0xfd,0xff,0x00,0x0c,0xff,0x0c,0x08,0x28,0x60,0xe4,0xc0,0x85,0x00,0x83,0x00,0x87,0xf1,0x00,0x8c,0x02,0x0b,0x07,0x24,0x84,0xff,0x04,0xc7,0x80,0xa0,0xe4,0xa0,0x81,0x41,0x04,0x17,0x02,0x41,0x49,0x81,0x0e,0x10,0xb2,0xa0,0x82,0x0e,0x9f,0xfc,0x0a,0x62,0xf2,0xc0,0x03,0x92,0xf0,0x08,0x2d,0x78,0x20,0xff,0x02,0x01,0x08,0xae,0x60,0x64,0x38,0x0d,0xb0,0x8d,0x08,0x82,0x11,0x58,0xc4,0x13,0xc0,0x35,0x68,0x62,0x68,0x81,0x09,0x08,0x84,0x40,0x81,0x0d,0x18,0x69,0x10,0x47,0x44,0x66,0x5f,0x21,0xa9,0x29,0x94,0x10,0x2f,0x23,0x53,0x14,0x60,0x42,0x3c,0x08,0xfc,0x02,0x2c,0x62,0x23,0x58,0xd0,0x22,0x00,0x83,0x3e,0x98,0x44,0x43,0x46,0x22,0x30,0x89,0xce,0x01,0x0f,0x70,0x04,0x3f,0x81,0x8a,0x3c,0x21,0xaa,0x70,0x1a,0xe3,0x44,0x1a,0xa6,0x01,0xd2,0x38,0x90,0x8a,0x40,0x20,0xe5,0x96,0x80,0x43,0x81,0x06,0x6b,0x28,0x07,0xf3,0xfe,0x00,0x19,0xf9,0x34,0xc1,0x08,0x8f,0x20,0xf1,0x3e,0x16,0x00,0xa8,0x19,0x00,0x10,0x76,0x03,0xe2,0x3e,0x90,0x45,0x38,0x01,0x42,0x05,0x88,0x44,0x67,0x15,0x70,0x41,0x38,0x04,0x10,0x24,0x03,0x00,0x10,0x20,0x4a,0x46,0xe9,0x46,0xe1,0x04,0x50,0x66,0x40,0x85,0x19,0x98,0x00,0xc0,}; +const uint8_t *_I_DoorRight_70x55[] = {_I_DoorRight_70x55_0}; + const uint8_t _I_LockPopup_100x49_0[] = {0x01,0x00,0x37,0x01,0xfc,0x7f,0xc0,0x13,0x01,0xfe,0x03,0x2a,0x07,0x06,0x12,0xd4,0x1a,0x06,0x0c,0xa8,0x60,0x33,0xe0,0x12,0x08,0x40,0x32,0x3f,0xd0,0x70,0x64,0xe0,0x20,0x31,0x8a,0x00,0x32,0x2c,0x10,0x0b,0x00,0x32,0x62,0x10,0x0c,0x06,0x00,0x19,0x00,0x82,0xc0,0x83,0x22,0x08,0x04,0x18,0x11,0x6a,0x01,0x25,0x02,0x84,0x83,0x1e,0x02,0x04,0x10,0xe1,0x03,0x1e,0x3c,0x0c,0x9c,0x1c,0x02,0x43,0x00,0x84,0x4f,0xc1,0x8f,0x80,0xaf,0x40,0x39,0x14,0x00,0x63,0xd0,0x36,0xf0,0x09,0xc6,0x00,0x18,0xd4,0x3a,0x06,0x9c,0x08,0x20,0xc9,0xdf,0xc0,0x20,0x7f,0x00,0x65,0x40,0x3f,0x80,0xc7,0xd0,0x10,0x06,0x01,0x7f,0x06,0x34,0x8e,0xa1,0x3d,0x80,0x70,0x0b,0x4f,0x23,0xd0,0x50,0xa0,0x1f,0x08,0x78,0x66,0x11,0xe3,0xfc,0x83,0x83,0x1e,0x40,0x0c,0x1f,0xfb,0xec,0x41,0x8c,0x03,0x1e,0x07,0x00,0x4d,0x10,0x0a,0x04,0xc0,0x9b,0x30,0x0c,0x1f,0xff,0xff,0x9f,0x06,0x3e,0x01,0x80,0x48,0xe7,0x99,0x83,0x0d,0x6a,0xe0,0xc4,0x90,0x03,0x1a,0x76,0x0c,0x38,0xe0,0x34,0x45,0x25,0x02,0x06,0x0d,0xe0,0x18,0x3c,0x08,0x19,0x40,0x78,0x00,0xc1,0x81,0xc3,0x27,0xf8,0x48,0x26,0x82,0x7d,0x00,0xfc,0x40,0xfc,0x10,0xfc,0x04,0xfc,0x18,0x30,0x28,0x7d,0x02,0x3f,0x00,0x98,0x41,0x38,0x31,0x08,0x25,0x0e,0x19,0x1f,0x81,0x42,0x70,0x11,0xa2,0x08,0xe2,0x30,0x72,0x08,0x76,0x0a,0x19,0x0f,0x85,0x42,0x60,0x11,0x51,0x78,0xc2,0x20,0x32,0x08,0x26,0x00,0x18,0x91,0x00,0x60,0x91,0x44,0x08,0x34,0x08,0x64,0x1f,0xe4,0x07,0x3f,0x84,0x0d,0x58,0x44,0x01,0x83,0xdc,0x60,0x43,0xe1,0x39,0xa9,0xd0,0x60,0x70,0x16,0x78,0xca,0x01,0x8f,0x83,0x3d,0x10,0x33,0x29,0x00,0xc7,0xa1,0x83,0x3f,0x10,0x0c,0x79,0x30,0x32,0xa0,0xdf,0xc7,0xa0,0x80,0x22,0x07,0xf8,0x06,0x54,0x04,}; const uint8_t *_I_LockPopup_100x49[] = {_I_LockPopup_100x49_0}; -const uint8_t _I_Down_hvr_25x27_0[] = {0x01,0x00,0x3a,0x00,0xfc,0x7f,0xe7,0xf0,0x0f,0xe7,0xfe,0xff,0x00,0xff,0x7f,0xff,0xf0,0x00,0x10,0xff,0xe0,0x20,0x3f,0x01,0x9c,0x3e,0x01,0xe0,0x01,0xa4,0x7e,0x01,0xf0,0x80,0x8b,0x47,0xf1,0x01,0x16,0x8f,0xf0,0x2e,0x23,0x11,0x01,0x88,0x04,0xf0,0x60,0x32,0xe3,0x80,0xcb,0xde,0x37,0xf0,0x1a,0x95,0xcc,0xbe,0x66,0x73,}; -const uint8_t *_I_Down_hvr_25x27[] = {_I_Down_hvr_25x27_0}; +const uint8_t _I_Mute_25x27_0[] = {0x01,0x00,0x51,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x20,0x31,0x81,0xc0,0x64,0x38,0x08,0xa4,0x06,0x83,0x40,0x86,0x40,0x70,0x32,0x08,0x20,0x3c,0x63,0xf0,0x60,0x38,0xc0,0xa0,0xa0,0x31,0xc2,0x02,0xc7,0x03,0x48,0x01,0x94,0xc0,0x06,0xc0,0xb3,0x09,0x98,0x6c,0x84,0x68,0x2b,0x21,0x99,0x8e,0xcc,0x86,0x64,0xb3,0x81,0x94,0xc6,0x03,0x06,0x80,0x70,0x20,0x1f,0xcf,0xfd,0xfc,0xce,0x80,}; +const uint8_t *_I_Mute_25x27[] = {_I_Mute_25x27_0}; -const uint8_t _I_Vol_down_hvr_25x27_0[] = {0x01,0x00,0x23,0x00,0xfc,0x7f,0xe7,0xf0,0x0f,0xe7,0xfe,0xff,0x00,0xff,0x7f,0xff,0xf0,0x00,0x10,0xff,0xe0,0x20,0x3f,0x01,0xf8,0xb4,0x7f,0x00,0x34,0x0b,0xf8,0x0f,0xc0,0x6e,0x57,0x32,0xf9,0x99,0xcc,}; -const uint8_t *_I_Vol_down_hvr_25x27[] = {_I_Vol_down_hvr_25x27_0}; - -const uint8_t _I_Down_25x27_0[] = {0x01,0x00,0x46,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x20,0x3f,0x01,0x9f,0xc7,0xff,0x1f,0x01,0xa7,0x87,0xff,0x0f,0x80,0xf0,0x7f,0xf0,0x78,0x0e,0x07,0xff,0x03,0x0b,0x8f,0xfc,0x04,0x30,0x1f,0xf0,0x7c,0xaf,0x80,0x32,0x9c,0x00,0xca,0x20,0x37,0xf0,0x18,0xc0,0xca,0x63,0x01,0x83,0x40,0x38,0x10,0x0f,0xe7,0xfe,0xfe,0x67,0x40,}; -const uint8_t *_I_Down_25x27[] = {_I_Down_25x27_0}; - -const uint8_t _I_Fill_marker_7x7_0[] = {0x00,0x1C,0x32,0x6F,0x5F,0x7F,0x3E,0x1C,}; -const uint8_t *_I_Fill_marker_7x7[] = {_I_Fill_marker_7x7_0}; - -const uint8_t _I_Vol_down_25x27_0[] = {0x01,0x00,0x2c,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x20,0x3f,0x01,0xff,0x07,0xff,0x07,0x01,0xa0,0x5f,0xc0,0x7e,0x03,0x38,0x19,0x4c,0x60,0x30,0x68,0x07,0x02,0x01,0xfc,0xff,0xdf,0xcc,0xe8,}; -const uint8_t *_I_Vol_down_25x27[] = {_I_Vol_down_25x27_0}; - -const uint8_t _I_Vol_up_25x27_0[] = {0x01,0x00,0x2f,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x20,0x38,0x88,0x00,0xfc,0x06,0xbc,0x1f,0xfc,0x1c,0x06,0x81,0x7f,0x01,0xc1,0x0e,0xa0,0x65,0x31,0x80,0xc1,0xa0,0x1c,0x08,0x07,0xf3,0xff,0x7f,0x33,0xa0,}; -const uint8_t *_I_Vol_up_25x27[] = {_I_Vol_up_25x27_0}; +const uint8_t _I_IrdaArrowUp_4x8_0[] = {0x00,0x18,0x3C,0x7E,0xFF,}; +const uint8_t *_I_IrdaArrowUp_4x8[] = {_I_IrdaArrowUp_4x8_0}; const uint8_t _I_Up_hvr_25x27_0[] = {0x01,0x00,0x39,0x00,0xfc,0x7f,0xe7,0xf0,0x0f,0xe7,0xfe,0xff,0x00,0xff,0x7f,0xff,0xf0,0x00,0x10,0xff,0xe0,0x20,0x3c,0xf7,0x80,0xcb,0x8e,0x03,0x2c,0x18,0x0c,0x80,0x26,0x25,0x18,0x08,0xa4,0x7f,0x90,0x11,0x88,0xfe,0x20,0x31,0xf8,0x07,0xc2,0x03,0x0f,0x80,0x78,0x00,0x68,0x37,0xf0,0x1d,0x95,0xcc,0xbe,0x66,0x73,}; const uint8_t *_I_Up_hvr_25x27[] = {_I_Up_hvr_25x27_0}; -const uint8_t _I_Vol_up_hvr_25x27_0[] = {0x01,0x00,0x28,0x00,0xfc,0x7f,0xe7,0xf0,0x0f,0xe7,0xfe,0xff,0x00,0xff,0x7f,0xff,0xf0,0x00,0x10,0xff,0xe0,0x20,0x38,0xf7,0x80,0xfc,0x06,0xa2,0xd1,0xfc,0x00,0xd0,0x2f,0xe0,0x38,0x21,0xd8,0x0c,0x8a,0xe6,0x5f,0x33,0x39,0x80,}; -const uint8_t *_I_Vol_up_hvr_25x27[] = {_I_Vol_up_hvr_25x27_0}; - -const uint8_t _I_IrdaLearnShort_128x31_0[] = {0x01,0x00,0x10,0x01,0x00,0x47,0xfb,0xfe,0x00,0x38,0x38,0x3e,0x20,0x20,0x54,0x84,0x03,0x9f,0xc0,0x06,0x58,0x80,0x3d,0xf2,0x00,0x65,0x90,0x03,0xde,0x90,0x06,0x5a,0x07,0xc0,0x8a,0x70,0x1a,0x04,0x02,0x51,0x80,0x03,0x94,0x02,0x3f,0x40,0x20,0x24,0x0b,0x01,0x00,0x92,0x70,0x35,0x40,0x01,0xe0,0xdf,0xf0,0x10,0x40,0x71,0x58,0x20,0x90,0x88,0x0c,0x4a,0x81,0x55,0x00,0x0f,0x87,0xf7,0x00,0x82,0x43,0x36,0x16,0xdc,0x9c,0x12,0x21,0x01,0x85,0x70,0x3f,0xc1,0xf1,0xf8,0xfc,0x60,0x20,0xf5,0x90,0x40,0xa1,0x34,0x08,0x18,0x7c,0x7e,0x24,0x91,0x07,0x8c,0xc0,0x5e,0x52,0x28,0x14,0x17,0x81,0x01,0x0f,0x8f,0xe7,0xe3,0x03,0x1f,0x8e,0x02,0xdb,0x03,0x8e,0x49,0x20,0x50,0x2e,0x04,0x72,0xbd,0x55,0xdc,0xeb,0xa0,0x7c,0x4f,0x68,0xbc,0x60,0x72,0x40,0x79,0x50,0x23,0x9a,0x6d,0x56,0x66,0x5c,0x0f,0x21,0x78,0x9b,0x04,0x1e,0x28,0x21,0x8e,0x5c,0x43,0xe6,0x2f,0x10,0xf9,0x0b,0xc7,0x04,0x99,0x18,0x06,0xe0,0x7e,0x56,0x32,0x78,0x8f,0xc4,0x08,0x32,0x20,0x79,0x48,0x2b,0x85,0xf2,0xf8,0x83,0xc4,0x5c,0x3f,0x03,0x78,0xd0,0x81,0xe3,0xc0,0xdf,0x9f,0xcb,0xf3,0x04,0xc6,0x7d,0xfb,0xdf,0x34,0x78,0xd0,0x45,0xe5,0x7e,0x4f,0x97,0xe2,0x09,0x80,0x07,0x88,0xbc,0x61,0x00,0xf3,0xd8,0x2f,0xcb,0xe0,0xcf,0x60,0x68,0xd0,0x30,0x15,0xfa,0xac,0x36,0x3f,0x60,0x77,0xb3,0x80,0x5d,0xe6,0x4b,0x20,0x03,0x03,0xc4,0x01,0xd0,0x10,0x7f,0x40,0x81,0xfc,0xa7,0x10,0x06,0x99,0xd0,0x01,0x51,0x00,0x7f,0x48,0x01,0xfd,0xc0,0x43,0x98,0x00,0x8e,0xfe,0x00,0xf0,}; -const uint8_t *_I_IrdaLearnShort_128x31[] = {_I_IrdaLearnShort_128x31_0}; - -const uint8_t _I_IrdaSend_128x64_0[] = {0x01,0x00,0xe2,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0xfe,0x04,0x0e,0x05,0x82,0xd7,0x81,0xca,0x21,0x08,0x01,0x8c,0x10,0x0e,0x54,0x00,0x20,0xe0,0xa4,0x00,0xfb,0xb2,0x4e,0xb0,0xfa,0x0e,0x74,0xc7,0x0f,0x3b,0xce,0x4e,0xec,0xf0,0xe1,0x79,0xe4,0xe9,0x58,0x2d,0x3d,0x4a,0x95,0x41,0x89,0x52,0x31,0x59,0x40,0xfa,0x64,0x01,0xe3,0xa0,0xa9,0x5e,0x81,0xe7,0xf4,0x07,0xcc,0x28,0x1e,0x71,0x40,0x7a,0x58,0x01,0xe4,0x3f,0x1c,0x0c,0x4f,0x11,0x0b,0xb3,0x83,0xcc,0x00,0x94,0x20,0x2a,0x03,0xa0,0x1e,0xd0,0x34,0xdf,0x80,0x3c,0x01,0xe0,0x0f,0x00,0x4c,0xf0,0x17,0x4c,0x81,0xa0,0x18,0x18,0x1f,0x39,0x90,0x6c,0x60,0x27,0x70,0xe9,0x3f,0x67,0x03,0x3c,0x80,0x83,0xde,0x81,0x4a,0x84,0xca,0x68,0xb8,0x2b,0xf0,0x3f,0x29,0x20,0xfe,0xa8,0xe0,0x85,0xf3,0x80,0xa5,0xc3,0xb8,0xf4,0xd8,0x11,0x3e,0x40,0x04,0x1b,0x23,0x7d,0x83,0xcd,0x1f,0x60,0x0f,0x00,0x78,0x03,0x7f,0x9f,0xf0,0x01,0xc0,0xc1,0xf1,0x04,0x02,0xa4,0x08,0x1f,0xe0,0xff,0x01,0x0f,0x00,0x70,0x9f,0xfe,0x20,0x10,0xe7,0xe0,0xf2,0x90,0x07,0xd7,0x89,0xdf,0xaa,0xd5,0x7b,0xa0,0xf3,0x8e,0x03,0xdb,0x54,0x00,0x29,0x70,0x3c,0xa2,0x40,0xf6,0xbf,0x87,0xc7,0xea,0x1f,0x12,0x30,0xc2,0x41,0xed,0xab,0x95,0x07,0xc6,0x75,0x02,0x10,0x0c,0x17,0xe0,0x47,0x18,0xff,0x82,0x07,0xc4,0xaf,0x8f,0xd2,0x43,0x80,0x82,0x56,0x01,0x03,0x35,0xfc,0x43,0xc7,0xe3,0x8a,0xc4,0x6a,0xa5,0x50,0x28,0x8d,0x02,0x05,0xa8,0x13,0x8c,0xaa,0xf9,0x1f,0xe2,0x5d,0xc2,0xc3,0x75,0x9f,0xe0,0xa1,0x14,0x08,0x0f,0x60,0x52,0x33,0x59,0xf4,0xf8,0x7e,0x32,0x2d,0x10,0xfc,0x70,0x58,0x89,0x04,0x06,0xd1,0xa0,0x0f,0x8f,0xfa,0x7e,0x3f,0x3e,0xa8,0x7c,0x69,0x1a,0x08,0x04,0xe2,0x80,0x1f,0x19,0xfd,0xf8,0xfe,0x92,0xa0,0x78,0xd0,0x20,0x19,0x8e,0x19,0xa8,0x7a,0xf7,0x51,0xfb,0x03,0xcb,0x11,0xc3,0xaa,0x4d,0x7a,0x76,0x51,0xf8,0x87,0xc8,0x7e,0x34,0x85,0xf0,0xe2,0x24,0x7a,0xe0,0xf9,0xaf,0xd0,0x9e,0x31,0x08,0x04,0x22,0x01,0x57,0x1f,0x9e,0xb8,0x7e,0x90,0x80,0x79,0x61,0x07,0xe2,0x5f,0x2f,0xfd,0xde,0xeb,0xf7,0x4f,0x8c,0x44,0x3a,0x30,0x8f,0xc0,0x7c,0x4f,0xe6,0x1f,0x29,0xda,0xbc,0x41,0xe5,0xc0,0xd7,0xa7,0xcd,0x8a,0x3d,0xdf,0xe8,0x7c,0x60,0x40,0xf2,0x80,0x55,0x97,0xe7,0xee,0x0f,0x0f,0xa9,0xfe,0x30,0x40,0x79,0x7c,0x05,0x43,0xe1,0x6f,0x88,0x7c,0x40,0x02,0x1f,0x18,0x01,0x3c,0x5d,0xe5,0x9f,0x80,0xbf,0xc4,0x1f,0x00,0x05,0x82,0x01,0x50,0x1e,0x28,0xf1,0x00,0x2c,0x90,0x1e,0xca,0xf1,0x00,0x2d,0x52,0x1e,0x0f,0x5c,0x00,0x7d,0xc1,0xed,0x00,0x25,0x08,0xff,0x00,0x46,0x00,0x3f,0xe1,0x7c,0xff,0xf0,0x30,0xc3,0xc0,0x3c,0x02,0x73,0xbc,0x00,0xcb,0xf0,0x18,0x4f,0xf8,0x3e,0x00,0x0c,0x0f,0xf0,}; -const uint8_t *_I_IrdaSend_128x64[] = {_I_IrdaSend_128x64_0}; - const uint8_t _I_DolphinReadingSuccess_59x63_0[] = {0x01,0x00,0x19,0x01,0x00,0x1d,0x00,0x0f,0xd2,0x00,0x21,0xe0,0x3f,0xf0,0xf9,0x00,0x40,0xee,0x00,0x11,0x88,0x04,0x0e,0x18,0x11,0x18,0x8c,0x40,0x0e,0x50,0x30,0x10,0xc0,0xa1,0x01,0xe2,0x05,0x14,0x12,0x08,0x33,0x58,0x44,0x08,0x66,0xa1,0xe3,0x01,0x9c,0x83,0x00,0x24,0x11,0x11,0x06,0xc4,0x76,0x20,0x75,0x15,0x99,0x48,0xc0,0xe9,0x0f,0x03,0x95,0xfc,0x86,0x3c,0x09,0x80,0x1c,0x7c,0x00,0x91,0x81,0x48,0x2f,0xc1,0x41,0x8c,0xc0,0x20,0x30,0x1c,0x87,0xfc,0x0e,0x30,0x70,0x70,0x81,0xc7,0xe6,0x07,0x18,0x08,0x1c,0xb9,0x1e,0x38,0x0f,0x02,0x01,0xf0,0x03,0xa0,0xa4,0x7f,0x90,0x30,0x38,0xff,0xe0,0x28,0x21,0xff,0x06,0x44,0x0e,0x46,0xe1,0x01,0x8c,0x03,0x34,0x2f,0x25,0x18,0x80,0xc7,0x2a,0x03,0x2e,0x01,0x3c,0x70,0x12,0xa2,0x39,0x78,0x27,0xe0,0x31,0xea,0x82,0xc4,0x6c,0x31,0xf0,0x78,0xea,0xb0,0x22,0x31,0xfc,0x1a,0xc6,0x01,0x55,0x25,0x88,0xf8,0x4b,0x02,0x1f,0x13,0xe1,0x7f,0x97,0x85,0x15,0x03,0x90,0xf8,0xa0,0x10,0xa1,0xb1,0x0e,0x88,0x00,0x7f,0x0f,0xc0,0x7c,0x57,0x27,0x3c,0xb0,0x7f,0x5f,0xa9,0x1f,0xc0,0x6a,0xc5,0x05,0xc0,0xf0,0x11,0x46,0xac,0x18,0x3f,0xf9,0x54,0x75,0x00,0x73,0x1f,0x0f,0xfe,0xfe,0xc6,0x30,0x01,0xbc,0x48,0x00,0x84,0x82,0x00,0x1b,0x64,0xc0,0x07,0x60,0x03,0xb4,0x70,0x0c,0xbf,0x82,0x31,0x01,0x8d,0x0c,0x40,0x02,0x37,0x08,0x1d,0x74,0x00,0x76,0xa0,0x01,0xdb,0x01,0xfe,0x85,0x8b,0x96,0xaa,0x9b,0x30,0x01,0x6a,0xa3,0x40,0x75,0xaa,0x03,0xdb,0x50,0xbb,0x30,0x01,0x54,0x24,0x25,0xe6,0x51,0x08,0x1f,0x68,0x00,0x7f,0x03,0xf2,0x79,0xc0,0xf4,}; const uint8_t *_I_DolphinReadingSuccess_59x63[] = {_I_DolphinReadingSuccess_59x63_0}; const uint8_t _I_Mute_hvr_25x27_0[] = {0x01,0x00,0x4a,0x00,0xfc,0x7f,0xe7,0xf0,0x0f,0xe7,0xfe,0xff,0x00,0xff,0x7f,0xff,0xf0,0x00,0x10,0xff,0xe0,0x20,0x21,0xfe,0x40,0x7b,0xf7,0xff,0x5c,0x07,0x7f,0xbf,0xf9,0xc0,0x6f,0xfd,0xff,0xd8,0x3c,0x7c,0x1f,0x90,0x38,0xff,0x7f,0x40,0x31,0xbd,0x82,0xc6,0xff,0xb7,0x01,0x97,0x3c,0x06,0xc0,0xb3,0x09,0x98,0x6c,0x84,0x68,0x2b,0x21,0x99,0x8e,0xcc,0x86,0x64,0xb5,0x01,0x89,0x5c,0xcb,0xe6,0x67,0x30,}; const uint8_t *_I_Mute_hvr_25x27[] = {_I_Mute_hvr_25x27_0}; -const uint8_t _I_Back_15x10_0[] = {0x00,0x04,0x00,0x06,0x00,0xFF,0x0F,0x06,0x10,0x04,0x20,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x10,0xFE,0x0F,}; -const uint8_t *_I_Back_15x10[] = {_I_Back_15x10_0}; +const uint8_t _I_Vol_down_25x27_0[] = {0x01,0x00,0x2c,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x20,0x3f,0x01,0xff,0x07,0xff,0x07,0x01,0xa0,0x5f,0xc0,0x7e,0x03,0x38,0x19,0x4c,0x60,0x30,0x68,0x07,0x02,0x01,0xfc,0xff,0xdf,0xcc,0xe8,}; +const uint8_t *_I_Vol_down_25x27[] = {_I_Vol_down_25x27_0}; -const uint8_t _I_Up_25x27_0[] = {0x01,0x00,0x44,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x20,0x3c,0x88,0x00,0xca,0x70,0x03,0x2b,0xe0,0x0c,0xbf,0xc0,0x32,0xff,0x80,0x87,0x03,0xff,0x81,0xc0,0x78,0x3f,0xf8,0x3c,0x07,0xc3,0xff,0x87,0xc0,0x7e,0x3f,0xf8,0xf8,0x0d,0x06,0xfe,0x03,0x78,0x19,0x4c,0x60,0x30,0x68,0x07,0x02,0x01,0xfc,0xff,0xdf,0xcc,0xe8,}; -const uint8_t *_I_Up_25x27[] = {_I_Up_25x27_0}; +const uint8_t _I_Down_25x27_0[] = {0x01,0x00,0x46,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x20,0x3f,0x01,0x9f,0xc7,0xff,0x1f,0x01,0xa7,0x87,0xff,0x0f,0x80,0xf0,0x7f,0xf0,0x78,0x0e,0x07,0xff,0x03,0x0b,0x8f,0xfc,0x04,0x30,0x1f,0xf0,0x7c,0xaf,0x80,0x32,0x9c,0x00,0xca,0x20,0x37,0xf0,0x18,0xc0,0xca,0x63,0x01,0x83,0x40,0x38,0x10,0x0f,0xe7,0xfe,0xfe,0x67,0x40,}; +const uint8_t *_I_Down_25x27[] = {_I_Down_25x27_0}; -const uint8_t _I_IrdaArrowUp_4x8_0[] = {0x00,0x18,0x3C,0x7E,0xFF,}; -const uint8_t *_I_IrdaArrowUp_4x8[] = {_I_IrdaArrowUp_4x8_0}; +const uint8_t _I_Power_hvr_25x27_0[] = {0x01,0x00,0x4b,0x00,0xfc,0x7f,0xe7,0xf0,0x0f,0xe7,0xfe,0xff,0x00,0xff,0x7f,0xff,0xf0,0x00,0x10,0xff,0xe0,0x3f,0xff,0x78,0x0c,0xb8,0xe0,0x35,0xbf,0xf1,0xbf,0x90,0x19,0xff,0x1b,0xf1,0x01,0x8f,0xf1,0xfe,0x30,0x1c,0xff,0x1f,0xe6,0x03,0x5f,0x78,0x0c,0xbf,0xe0,0x39,0x8f,0xff,0xc3,0x63,0x3f,0xff,0x08,0xc6,0xff,0x7c,0x15,0x89,0x04,0x7f,0xc0,0x31,0xc1,0x8e,0xc8,0x8e,0x60,0x36,0x2b,0x99,0x7c,0xcc,0xe6,}; +const uint8_t *_I_Power_hvr_25x27[] = {_I_Power_hvr_25x27_0}; -const uint8_t _I_Mute_25x27_0[] = {0x01,0x00,0x51,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x20,0x31,0x81,0xc0,0x64,0x38,0x08,0xa4,0x06,0x83,0x40,0x86,0x40,0x70,0x32,0x08,0x20,0x3c,0x63,0xf0,0x60,0x38,0xc0,0xa0,0xa0,0x31,0xc2,0x02,0xc7,0x03,0x48,0x01,0x94,0xc0,0x06,0xc0,0xb3,0x09,0x98,0x6c,0x84,0x68,0x2b,0x21,0x99,0x8e,0xcc,0x86,0x64,0xb3,0x81,0x94,0xc6,0x03,0x06,0x80,0x70,0x20,0x1f,0xcf,0xfd,0xfc,0xce,0x80,}; -const uint8_t *_I_Mute_25x27[] = {_I_Mute_25x27_0}; - -const uint8_t _I_Power_25x27_0[] = {0x01,0x00,0x54,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x30,0x18,0x80,0x0c,0xa7,0x00,0x35,0xc0,0xce,0x60,0x70,0x1e,0x0c,0xe6,0x0f,0x01,0xf0,0xce,0x21,0xd0,0x1b,0x0c,0xe2,0x18,0x03,0x58,0x80,0x0c,0xa0,0x00,0x39,0xf0,0xc0,0x03,0x63,0xc1,0x80,0x88,0xc7,0x03,0x83,0x15,0x8c,0x07,0xfe,0x02,0x18,0x0d,0xf0,0x76,0x44,0x73,0x01,0x94,0x0c,0xa6,0x30,0x18,0x34,0x03,0x81,0x00,0xfe,0x7f,0xef,0xe6,0x74,}; -const uint8_t *_I_Power_25x27[] = {_I_Power_25x27_0}; - -const uint8_t _I_IrdaSendShort_128x34_0[] = {0x01,0x00,0x42,0x01,0xfe,0x7f,0xc0,0x07,0x03,0x07,0xc4,0x10,0x0a,0x90,0x20,0x7f,0x83,0xfc,0x04,0x3c,0x01,0xc2,0x7f,0xf8,0x80,0x43,0x9f,0x83,0xca,0x40,0x1f,0x5e,0x27,0x7e,0xab,0x55,0xee,0x83,0xce,0x38,0x0f,0x6d,0x50,0x00,0xa5,0xc0,0xf2,0x89,0x03,0xda,0xfe,0x1f,0x1f,0xa8,0x7c,0x48,0xc3,0x09,0x07,0xb6,0xae,0x54,0x1f,0x19,0xd4,0x08,0x40,0x30,0x5f,0x81,0x1c,0x63,0xfe,0x08,0x1f,0x12,0xbe,0x3f,0x49,0x0e,0x02,0x09,0x58,0x04,0x0c,0xd7,0xf1,0x0f,0x1f,0x8e,0x2b,0x11,0xaa,0x95,0x40,0xa2,0x34,0x08,0x16,0xa0,0x4e,0x32,0xab,0xe4,0x7f,0x89,0x77,0x0b,0x0d,0xd6,0x7f,0x82,0x84,0x50,0x20,0x3d,0x81,0x48,0xcd,0x67,0xd3,0xe1,0xf8,0xc8,0xb4,0x43,0xf1,0xc1,0x62,0x24,0x10,0x1b,0x46,0x80,0x3e,0x3f,0xe9,0xf8,0xfc,0xfa,0xa1,0xf1,0xa4,0x68,0x20,0x13,0x8a,0x00,0x7c,0x67,0xf7,0xe3,0xfa,0x4a,0x81,0xe3,0x40,0x80,0x66,0x38,0x66,0xa1,0xeb,0xdd,0x47,0xec,0x0f,0x2c,0x47,0x0e,0xa9,0x35,0xe9,0xd9,0x47,0xe2,0x1f,0x21,0xf8,0xd2,0x17,0xc3,0x88,0x91,0xeb,0x83,0xe6,0xbf,0x42,0x78,0xc4,0x20,0x10,0x88,0x05,0x5c,0x7e,0x7a,0xe1,0xfa,0x42,0x01,0xe5,0x84,0x1f,0x89,0x7c,0xbf,0xf7,0x7b,0xaf,0xdd,0x3e,0x31,0x10,0xe8,0xc2,0x3f,0x01,0xf1,0x3f,0x98,0x7c,0xa7,0x6a,0xf1,0x07,0x97,0x03,0x5e,0x9f,0x36,0x28,0xf7,0x7f,0xa1,0xf1,0x81,0x03,0xca,0x01,0x56,0x5f,0x9f,0xb8,0x3c,0x3e,0xa7,0xf8,0xc1,0x01,0xe5,0xf0,0x15,0x0f,0x85,0xbe,0x21,0xf1,0x00,0x08,0x7c,0x60,0x04,0xf1,0x77,0x96,0x7e,0x02,0xff,0x10,0x7c,0x00,0x16,0x08,0x05,0x40,0x78,0xa3,0xc4,0x00,0xb2,0x40,0x7b,0x2b,0xc4,0x00,0xb5,0x48,0x78,0x3d,0x70,0x01,0xf7,0x07,0xb4,0x00,0x94,0x23,0xfc,0x01,0x18,0x00,0xff,0x85,0xf3,0xff,0xc0,0xc3,0x0f,0x00,0xf0,0x09,0xce,0xf0,0x03,0x2f,0xc0,0x61,0x3f,0xe0,0xf8,0x00,0x30,0x3f,0xc0,}; -const uint8_t *_I_IrdaSendShort_128x34[] = {_I_IrdaSendShort_128x34_0}; +const uint8_t _I_IrdaLearnShort_128x31_0[] = {0x01,0x00,0x10,0x01,0x00,0x47,0xfb,0xfe,0x00,0x38,0x38,0x3e,0x20,0x20,0x54,0x84,0x03,0x9f,0xc0,0x06,0x58,0x80,0x3d,0xf2,0x00,0x65,0x90,0x03,0xde,0x90,0x06,0x5a,0x07,0xc0,0x8a,0x70,0x1a,0x04,0x02,0x51,0x80,0x03,0x94,0x02,0x3f,0x40,0x20,0x24,0x0b,0x01,0x00,0x92,0x70,0x35,0x40,0x01,0xe0,0xdf,0xf0,0x10,0x40,0x71,0x58,0x20,0x90,0x88,0x0c,0x4a,0x81,0x55,0x00,0x0f,0x87,0xf7,0x00,0x82,0x43,0x36,0x16,0xdc,0x9c,0x12,0x21,0x01,0x85,0x70,0x3f,0xc1,0xf1,0xf8,0xfc,0x60,0x20,0xf5,0x90,0x40,0xa1,0x34,0x08,0x18,0x7c,0x7e,0x24,0x91,0x07,0x8c,0xc0,0x5e,0x52,0x28,0x14,0x17,0x81,0x01,0x0f,0x8f,0xe7,0xe3,0x03,0x1f,0x8e,0x02,0xdb,0x03,0x8e,0x49,0x20,0x50,0x2e,0x04,0x72,0xbd,0x55,0xdc,0xeb,0xa0,0x7c,0x4f,0x68,0xbc,0x60,0x72,0x40,0x79,0x50,0x23,0x9a,0x6d,0x56,0x66,0x5c,0x0f,0x21,0x78,0x9b,0x04,0x1e,0x28,0x21,0x8e,0x5c,0x43,0xe6,0x2f,0x10,0xf9,0x0b,0xc7,0x04,0x99,0x18,0x06,0xe0,0x7e,0x56,0x32,0x78,0x8f,0xc4,0x08,0x32,0x20,0x79,0x48,0x2b,0x85,0xf2,0xf8,0x83,0xc4,0x5c,0x3f,0x03,0x78,0xd0,0x81,0xe3,0xc0,0xdf,0x9f,0xcb,0xf3,0x04,0xc6,0x7d,0xfb,0xdf,0x34,0x78,0xd0,0x45,0xe5,0x7e,0x4f,0x97,0xe2,0x09,0x80,0x07,0x88,0xbc,0x61,0x00,0xf3,0xd8,0x2f,0xcb,0xe0,0xcf,0x60,0x68,0xd0,0x30,0x15,0xfa,0xac,0x36,0x3f,0x60,0x77,0xb3,0x80,0x5d,0xe6,0x4b,0x20,0x03,0x03,0xc4,0x01,0xd0,0x10,0x7f,0x40,0x81,0xfc,0xa7,0x10,0x06,0x99,0xd0,0x01,0x51,0x00,0x7f,0x48,0x01,0xfd,0xc0,0x43,0x98,0x00,0x8e,0xfe,0x00,0xf0,}; +const uint8_t *_I_IrdaLearnShort_128x31[] = {_I_IrdaLearnShort_128x31_0}; const uint8_t _I_IrdaArrowDown_4x8_0[] = {0x00,0xFF,0x7E,0x3C,0x18,}; const uint8_t *_I_IrdaArrowDown_4x8[] = {_I_IrdaArrowDown_4x8_0}; +const uint8_t _I_Vol_down_hvr_25x27_0[] = {0x01,0x00,0x23,0x00,0xfc,0x7f,0xe7,0xf0,0x0f,0xe7,0xfe,0xff,0x00,0xff,0x7f,0xff,0xf0,0x00,0x10,0xff,0xe0,0x20,0x3f,0x01,0xf8,0xb4,0x7f,0x00,0x34,0x0b,0xf8,0x0f,0xc0,0x6e,0x57,0x32,0xf9,0x99,0xcc,}; +const uint8_t *_I_Vol_down_hvr_25x27[] = {_I_Vol_down_hvr_25x27_0}; + const uint8_t _I_IrdaLearn_128x64_0[] = {0x01,0x00,0xcc,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0xf0,0x07,0x80,0x3f,0x01,0x07,0x82,0x41,0x21,0x20,0x73,0x00,0x8e,0x82,0x0f,0x00,0xa0,0x01,0x46,0x11,0x00,0x07,0xc0,0x28,0x41,0xe5,0xc8,0xba,0x63,0xa7,0x70,0x6b,0x3d,0xbb,0x99,0x19,0xee,0x68,0x71,0x16,0x3f,0x70,0x3c,0x64,0xf9,0x58,0x25,0x26,0x13,0x91,0xc9,0x64,0xa4,0x99,0x2d,0x06,0x1f,0x29,0x42,0x07,0x8c,0x80,0x1e,0x50,0xff,0x88,0x3c,0x67,0x80,0xf1,0xc1,0x03,0xde,0x03,0x11,0x07,0x8c,0x10,0x1e,0x38,0x40,0x79,0xf0,0x32,0x80,0xf1,0x83,0x58,0x72,0x58,0xc8,0xc6,0x73,0x40,0x3f,0x10,0x78,0x9e,0xf1,0x17,0xe9,0xcf,0x00,0x78,0x03,0xc0,0x1e,0x00,0xf0,0x02,0x44,0x18,0xa3,0x80,0x82,0x32,0x06,0x44,0x0f,0xf0,0x73,0x5d,0xe3,0x92,0x7e,0xcf,0x06,0x3b,0xc3,0xa4,0xdd,0xfc,0xc8,0x35,0xca,0x44,0xa5,0x34,0x5c,0x16,0x92,0x89,0x4a,0x91,0x4a,0x60,0x20,0xf7,0xa4,0x83,0xc6,0x8e,0x0f,0xba,0x88,0x3c,0x68,0x00,0xf7,0x80,0x65,0xe3,0x9c,0x7a,0x6e,0x0a,0x49,0xc3,0xb8,0xc8,0xa4,0xc0,0xf5,0x00,0x08,0x1d,0xc0,0x0e,0x0f,0xf0,0x07,0x80,0x3c,0x01,0xe0,0x0f,0x00,0x2f,0xfb,0xfe,0x00,0x38,0x39,0x97,0xa1,0x00,0xe7,0xf0,0x3b,0x1c,0x00,0xd9,0x00,0x32,0xc8,0x01,0xef,0x48,0x03,0x2d,0x03,0xe0,0x45,0x38,0x0d,0x02,0x01,0x28,0xc0,0x01,0xca,0x01,0x1f,0xa0,0x10,0x12,0x05,0x80,0x80,0x49,0x38,0x1a,0xa0,0x00,0xf0,0x6f,0xf8,0x08,0x20,0x38,0xac,0x10,0x48,0x44,0x06,0x25,0x40,0xaa,0x80,0x07,0xc3,0xfb,0x80,0x41,0x21,0x9b,0x0b,0x6e,0x4e,0x09,0x10,0x80,0xc2,0xb8,0x1f,0xe0,0xf8,0xfc,0x7e,0x30,0x10,0x7a,0xc8,0x20,0x50,0x9a,0x04,0x0c,0x3e,0x3f,0x12,0x48,0x83,0xc6,0x60,0x2f,0x29,0x14,0x0a,0x0b,0xc0,0x80,0x87,0xc7,0xf3,0xf1,0x81,0x8f,0xc7,0x01,0x6d,0x81,0xc7,0x24,0x90,0x28,0x17,0x02,0x39,0x5e,0xaa,0xee,0x75,0xd0,0x3e,0x27,0xb4,0x5e,0x30,0x39,0x20,0x3c,0xa8,0x11,0xcd,0x36,0xab,0x33,0x2e,0x07,0x90,0xbc,0x4d,0x82,0x0f,0x14,0x10,0xc7,0x2e,0x21,0xf3,0x17,0x88,0x7c,0x85,0xe3,0x82,0x4c,0x8c,0x03,0x70,0x3f,0x2b,0x19,0x3c,0x47,0xe2,0x04,0x19,0x10,0x3c,0xa4,0x15,0xc2,0xf9,0x7c,0x41,0xe2,0x2e,0x1f,0x81,0xbc,0x68,0x40,0xf1,0xe0,0x6f,0xcf,0xe5,0xf9,0x82,0x63,0x3e,0xfd,0xef,0x9a,0x3c,0x68,0x22,0xf2,0xbf,0x27,0xcb,0xf1,0x04,0xc0,0x03,0xc4,0x5e,0x30,0x80,0x79,0xec,0x17,0xe5,0xf0,0x67,0xb0,0x34,0x68,0x18,0x0a,0xfd,0x56,0x1b,0x1f,0xb0,0x3b,0xd9,0xc0,0x2e,0xf3,0x25,0x90,0x01,0x81,0xe2,0x00,0xe8,0x08,0x3f,0xa0,0x40,0xfe,0x53,0x88,0x03,0x4c,0xe8,0x00,0xa8,0x80,0x3f,0xa4,0x00,0xfe,0xe0,0x21,0xcc,0x00,0x47,0x7f,0x00,0x78,}; const uint8_t *_I_IrdaLearn_128x64[] = {_I_IrdaLearn_128x64_0}; -const uint8_t _I_Power_hvr_25x27_0[] = {0x01,0x00,0x4b,0x00,0xfc,0x7f,0xe7,0xf0,0x0f,0xe7,0xfe,0xff,0x00,0xff,0x7f,0xff,0xf0,0x00,0x10,0xff,0xe0,0x3f,0xff,0x78,0x0c,0xb8,0xe0,0x35,0xbf,0xf1,0xbf,0x90,0x19,0xff,0x1b,0xf1,0x01,0x8f,0xf1,0xfe,0x30,0x1c,0xff,0x1f,0xe6,0x03,0x5f,0x78,0x0c,0xbf,0xe0,0x39,0x8f,0xff,0xc3,0x63,0x3f,0xff,0x08,0xc6,0xff,0x7c,0x15,0x89,0x04,0x7f,0xc0,0x31,0xc1,0x8e,0xc8,0x8e,0x60,0x36,0x2b,0x99,0x7c,0xcc,0xe6,}; -const uint8_t *_I_Power_hvr_25x27[] = {_I_Power_hvr_25x27_0}; +const uint8_t _I_Down_hvr_25x27_0[] = {0x01,0x00,0x3a,0x00,0xfc,0x7f,0xe7,0xf0,0x0f,0xe7,0xfe,0xff,0x00,0xff,0x7f,0xff,0xf0,0x00,0x10,0xff,0xe0,0x20,0x3f,0x01,0x9c,0x3e,0x01,0xe0,0x01,0xa4,0x7e,0x01,0xf0,0x80,0x8b,0x47,0xf1,0x01,0x16,0x8f,0xf0,0x2e,0x23,0x11,0x01,0x88,0x04,0xf0,0x60,0x32,0xe3,0x80,0xcb,0xde,0x37,0xf0,0x1a,0x95,0xcc,0xbe,0x66,0x73,}; +const uint8_t *_I_Down_hvr_25x27[] = {_I_Down_hvr_25x27_0}; + +const uint8_t _I_Fill_marker_7x7_0[] = {0x00,0x1C,0x32,0x6F,0x5F,0x7F,0x3E,0x1C,}; +const uint8_t *_I_Fill_marker_7x7[] = {_I_Fill_marker_7x7_0}; + +const uint8_t _I_Power_25x27_0[] = {0x01,0x00,0x54,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x30,0x18,0x80,0x0c,0xa7,0x00,0x35,0xc0,0xce,0x60,0x70,0x1e,0x0c,0xe6,0x0f,0x01,0xf0,0xce,0x21,0xd0,0x1b,0x0c,0xe2,0x18,0x03,0x58,0x80,0x0c,0xa0,0x00,0x39,0xf0,0xc0,0x03,0x63,0xc1,0x80,0x88,0xc7,0x03,0x83,0x15,0x8c,0x07,0xfe,0x02,0x18,0x0d,0xf0,0x76,0x44,0x73,0x01,0x94,0x0c,0xa6,0x30,0x18,0x34,0x03,0x81,0x00,0xfe,0x7f,0xef,0xe6,0x74,}; +const uint8_t *_I_Power_25x27[] = {_I_Power_25x27_0}; + +const uint8_t _I_Vol_up_25x27_0[] = {0x01,0x00,0x2f,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x20,0x38,0x88,0x00,0xfc,0x06,0xbc,0x1f,0xfc,0x1c,0x06,0x81,0x7f,0x01,0xc1,0x0e,0xa0,0x65,0x31,0x80,0xc1,0xa0,0x1c,0x08,0x07,0xf3,0xff,0x7f,0x33,0xa0,}; +const uint8_t *_I_Vol_up_25x27[] = {_I_Vol_up_25x27_0}; + +const uint8_t _I_Up_25x27_0[] = {0x01,0x00,0x44,0x00,0xfc,0x7f,0xe7,0xf0,0x08,0x24,0x02,0x81,0x00,0x81,0x40,0x30,0x10,0x08,0x08,0x38,0x60,0x20,0x3c,0x88,0x00,0xca,0x70,0x03,0x2b,0xe0,0x0c,0xbf,0xc0,0x32,0xff,0x80,0x87,0x03,0xff,0x81,0xc0,0x78,0x3f,0xf8,0x3c,0x07,0xc3,0xff,0x87,0xc0,0x7e,0x3f,0xf8,0xf8,0x0d,0x06,0xfe,0x03,0x78,0x19,0x4c,0x60,0x30,0x68,0x07,0x02,0x01,0xfc,0xff,0xdf,0xcc,0xe8,}; +const uint8_t *_I_Up_25x27[] = {_I_Up_25x27_0}; + +const uint8_t _I_Back_15x10_0[] = {0x00,0x04,0x00,0x06,0x00,0xFF,0x0F,0x06,0x10,0x04,0x20,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x10,0xFE,0x0F,}; +const uint8_t *_I_Back_15x10[] = {_I_Back_15x10_0}; + +const uint8_t _I_IrdaSend_128x64_0[] = {0x01,0x00,0xe2,0x01,0x00,0x78,0x03,0xc0,0x1e,0x00,0xfe,0x04,0x0e,0x05,0x82,0xd7,0x81,0xca,0x21,0x08,0x01,0x8c,0x10,0x0e,0x54,0x00,0x20,0xe0,0xa4,0x00,0xfb,0xb2,0x4e,0xb0,0xfa,0x0e,0x74,0xc7,0x0f,0x3b,0xce,0x4e,0xec,0xf0,0xe1,0x79,0xe4,0xe9,0x58,0x2d,0x3d,0x4a,0x95,0x41,0x89,0x52,0x31,0x59,0x40,0xfa,0x64,0x01,0xe3,0xa0,0xa9,0x5e,0x81,0xe7,0xf4,0x07,0xcc,0x28,0x1e,0x71,0x40,0x7a,0x58,0x01,0xe4,0x3f,0x1c,0x0c,0x4f,0x11,0x0b,0xb3,0x83,0xcc,0x00,0x94,0x20,0x2a,0x03,0xa0,0x1e,0xd0,0x34,0xdf,0x80,0x3c,0x01,0xe0,0x0f,0x00,0x4c,0xf0,0x17,0x4c,0x81,0xa0,0x18,0x18,0x1f,0x39,0x90,0x6c,0x60,0x27,0x70,0xe9,0x3f,0x67,0x03,0x3c,0x80,0x83,0xde,0x81,0x4a,0x84,0xca,0x68,0xb8,0x2b,0xf0,0x3f,0x29,0x20,0xfe,0xa8,0xe0,0x85,0xf3,0x80,0xa5,0xc3,0xb8,0xf4,0xd8,0x11,0x3e,0x40,0x04,0x1b,0x23,0x7d,0x83,0xcd,0x1f,0x60,0x0f,0x00,0x78,0x03,0x7f,0x9f,0xf0,0x01,0xc0,0xc1,0xf1,0x04,0x02,0xa4,0x08,0x1f,0xe0,0xff,0x01,0x0f,0x00,0x70,0x9f,0xfe,0x20,0x10,0xe7,0xe0,0xf2,0x90,0x07,0xd7,0x89,0xdf,0xaa,0xd5,0x7b,0xa0,0xf3,0x8e,0x03,0xdb,0x54,0x00,0x29,0x70,0x3c,0xa2,0x40,0xf6,0xbf,0x87,0xc7,0xea,0x1f,0x12,0x30,0xc2,0x41,0xed,0xab,0x95,0x07,0xc6,0x75,0x02,0x10,0x0c,0x17,0xe0,0x47,0x18,0xff,0x82,0x07,0xc4,0xaf,0x8f,0xd2,0x43,0x80,0x82,0x56,0x01,0x03,0x35,0xfc,0x43,0xc7,0xe3,0x8a,0xc4,0x6a,0xa5,0x50,0x28,0x8d,0x02,0x05,0xa8,0x13,0x8c,0xaa,0xf9,0x1f,0xe2,0x5d,0xc2,0xc3,0x75,0x9f,0xe0,0xa1,0x14,0x08,0x0f,0x60,0x52,0x33,0x59,0xf4,0xf8,0x7e,0x32,0x2d,0x10,0xfc,0x70,0x58,0x89,0x04,0x06,0xd1,0xa0,0x0f,0x8f,0xfa,0x7e,0x3f,0x3e,0xa8,0x7c,0x69,0x1a,0x08,0x04,0xe2,0x80,0x1f,0x19,0xfd,0xf8,0xfe,0x92,0xa0,0x78,0xd0,0x20,0x19,0x8e,0x19,0xa8,0x7a,0xf7,0x51,0xfb,0x03,0xcb,0x11,0xc3,0xaa,0x4d,0x7a,0x76,0x51,0xf8,0x87,0xc8,0x7e,0x34,0x85,0xf0,0xe2,0x24,0x7a,0xe0,0xf9,0xaf,0xd0,0x9e,0x31,0x08,0x04,0x22,0x01,0x57,0x1f,0x9e,0xb8,0x7e,0x90,0x80,0x79,0x61,0x07,0xe2,0x5f,0x2f,0xfd,0xde,0xeb,0xf7,0x4f,0x8c,0x44,0x3a,0x30,0x8f,0xc0,0x7c,0x4f,0xe6,0x1f,0x29,0xda,0xbc,0x41,0xe5,0xc0,0xd7,0xa7,0xcd,0x8a,0x3d,0xdf,0xe8,0x7c,0x60,0x40,0xf2,0x80,0x55,0x97,0xe7,0xee,0x0f,0x0f,0xa9,0xfe,0x30,0x40,0x79,0x7c,0x05,0x43,0xe1,0x6f,0x88,0x7c,0x40,0x02,0x1f,0x18,0x01,0x3c,0x5d,0xe5,0x9f,0x80,0xbf,0xc4,0x1f,0x00,0x05,0x82,0x01,0x50,0x1e,0x28,0xf1,0x00,0x2c,0x90,0x1e,0xca,0xf1,0x00,0x2d,0x52,0x1e,0x0f,0x5c,0x00,0x7d,0xc1,0xed,0x00,0x25,0x08,0xff,0x00,0x46,0x00,0x3f,0xe1,0x7c,0xff,0xf0,0x30,0xc3,0xc0,0x3c,0x02,0x73,0xbc,0x00,0xcb,0xf0,0x18,0x4f,0xf8,0x3e,0x00,0x0c,0x0f,0xf0,}; +const uint8_t *_I_IrdaSend_128x64[] = {_I_IrdaSend_128x64_0}; + +const uint8_t _I_IrdaSendShort_128x34_0[] = {0x01,0x00,0x42,0x01,0xfe,0x7f,0xc0,0x07,0x03,0x07,0xc4,0x10,0x0a,0x90,0x20,0x7f,0x83,0xfc,0x04,0x3c,0x01,0xc2,0x7f,0xf8,0x80,0x43,0x9f,0x83,0xca,0x40,0x1f,0x5e,0x27,0x7e,0xab,0x55,0xee,0x83,0xce,0x38,0x0f,0x6d,0x50,0x00,0xa5,0xc0,0xf2,0x89,0x03,0xda,0xfe,0x1f,0x1f,0xa8,0x7c,0x48,0xc3,0x09,0x07,0xb6,0xae,0x54,0x1f,0x19,0xd4,0x08,0x40,0x30,0x5f,0x81,0x1c,0x63,0xfe,0x08,0x1f,0x12,0xbe,0x3f,0x49,0x0e,0x02,0x09,0x58,0x04,0x0c,0xd7,0xf1,0x0f,0x1f,0x8e,0x2b,0x11,0xaa,0x95,0x40,0xa2,0x34,0x08,0x16,0xa0,0x4e,0x32,0xab,0xe4,0x7f,0x89,0x77,0x0b,0x0d,0xd6,0x7f,0x82,0x84,0x50,0x20,0x3d,0x81,0x48,0xcd,0x67,0xd3,0xe1,0xf8,0xc8,0xb4,0x43,0xf1,0xc1,0x62,0x24,0x10,0x1b,0x46,0x80,0x3e,0x3f,0xe9,0xf8,0xfc,0xfa,0xa1,0xf1,0xa4,0x68,0x20,0x13,0x8a,0x00,0x7c,0x67,0xf7,0xe3,0xfa,0x4a,0x81,0xe3,0x40,0x80,0x66,0x38,0x66,0xa1,0xeb,0xdd,0x47,0xec,0x0f,0x2c,0x47,0x0e,0xa9,0x35,0xe9,0xd9,0x47,0xe2,0x1f,0x21,0xf8,0xd2,0x17,0xc3,0x88,0x91,0xeb,0x83,0xe6,0xbf,0x42,0x78,0xc4,0x20,0x10,0x88,0x05,0x5c,0x7e,0x7a,0xe1,0xfa,0x42,0x01,0xe5,0x84,0x1f,0x89,0x7c,0xbf,0xf7,0x7b,0xaf,0xdd,0x3e,0x31,0x10,0xe8,0xc2,0x3f,0x01,0xf1,0x3f,0x98,0x7c,0xa7,0x6a,0xf1,0x07,0x97,0x03,0x5e,0x9f,0x36,0x28,0xf7,0x7f,0xa1,0xf1,0x81,0x03,0xca,0x01,0x56,0x5f,0x9f,0xb8,0x3c,0x3e,0xa7,0xf8,0xc1,0x01,0xe5,0xf0,0x15,0x0f,0x85,0xbe,0x21,0xf1,0x00,0x08,0x7c,0x60,0x04,0xf1,0x77,0x96,0x7e,0x02,0xff,0x10,0x7c,0x00,0x16,0x08,0x05,0x40,0x78,0xa3,0xc4,0x00,0xb2,0x40,0x7b,0x2b,0xc4,0x00,0xb5,0x48,0x78,0x3d,0x70,0x01,0xf7,0x07,0xb4,0x00,0x94,0x23,0xfc,0x01,0x18,0x00,0xff,0x85,0xf3,0xff,0xc0,0xc3,0x0f,0x00,0xf0,0x09,0xce,0xf0,0x03,0x2f,0xc0,0x61,0x3f,0xe0,0xf8,0x00,0x30,0x3f,0xc0,}; +const uint8_t *_I_IrdaSendShort_128x34[] = {_I_IrdaSendShort_128x34_0}; + +const uint8_t _I_Vol_up_hvr_25x27_0[] = {0x01,0x00,0x28,0x00,0xfc,0x7f,0xe7,0xf0,0x0f,0xe7,0xfe,0xff,0x00,0xff,0x7f,0xff,0xf0,0x00,0x10,0xff,0xe0,0x20,0x38,0xf7,0x80,0xfc,0x06,0xa2,0xd1,0xfc,0x00,0xd0,0x2f,0xe0,0x38,0x21,0xd8,0x0c,0x8a,0xe6,0x5f,0x33,0x39,0x80,}; +const uint8_t *_I_Vol_up_hvr_25x27[] = {_I_Vol_up_hvr_25x27_0}; + +const uint8_t _I_KeySave_24x11_0[] = {0x01,0x00,0x1e,0x00,0xff,0x7f,0xff,0xf0,0x18,0x06,0x00,0x04,0x53,0x1c,0xbe,0x33,0x13,0x94,0xc9,0x64,0x72,0x99,0xed,0x0e,0x53,0x05,0x19,0xb3,0xe3,0x02,0x8a,0x1d,0x1b,0xf8,}; +const uint8_t *_I_KeySave_24x11[] = {_I_KeySave_24x11_0}; + +const uint8_t _I_KeyBackspaceSelected_16x9_0[] = {0x00,0xFE,0x7F,0xFF,0xFF,0xEF,0xFF,0xE7,0xFF,0x03,0xC0,0xE7,0xFF,0xEF,0xFF,0xFF,0xFF,0xFE,0x7F,}; +const uint8_t *_I_KeyBackspaceSelected_16x9[] = {_I_KeyBackspaceSelected_16x9_0}; const uint8_t _I_KeySaveSelected_24x11_0[] = {0x01,0x00,0x1a,0x00,0xff,0x7f,0xc0,0x0d,0xcf,0xb4,0x7c,0xee,0xf6,0xbf,0x6d,0xbe,0xd7,0xe1,0xaf,0xda,0xff,0xbe,0x7c,0xc7,0xcc,0x28,0xa1,0xd1,0xbf,0x80,}; const uint8_t *_I_KeySaveSelected_24x11[] = {_I_KeySaveSelected_24x11_0}; @@ -489,12 +495,6 @@ const uint8_t *_I_KeySaveSelected_24x11[] = {_I_KeySaveSelected_24x11_0}; const uint8_t _I_KeyBackspace_16x9_0[] = {0x00,0xFE,0x7F,0x01,0x80,0x11,0x80,0x19,0x80,0xFD,0xBF,0x19,0x80,0x11,0x80,0x01,0x80,0xFE,0x7F,}; const uint8_t *_I_KeyBackspace_16x9[] = {_I_KeyBackspace_16x9_0}; -const uint8_t _I_KeyBackspaceSelected_16x9_0[] = {0x00,0xFE,0x7F,0xFF,0xFF,0xEF,0xFF,0xE7,0xFF,0x03,0xC0,0xE7,0xFF,0xEF,0xFF,0xFF,0xFF,0xFE,0x7F,}; -const uint8_t *_I_KeyBackspaceSelected_16x9[] = {_I_KeyBackspaceSelected_16x9_0}; - -const uint8_t _I_KeySave_24x11_0[] = {0x01,0x00,0x1e,0x00,0xff,0x7f,0xff,0xf0,0x18,0x06,0x00,0x04,0x53,0x1c,0xbe,0x33,0x13,0x94,0xc9,0x64,0x72,0x99,0xed,0x0e,0x53,0x05,0x19,0xb3,0xe3,0x02,0x8a,0x1d,0x1b,0xf8,}; -const uint8_t *_I_KeySave_24x11[] = {_I_KeySave_24x11_0}; - const uint8_t _A_125khz_14_0[] = {0x00,0x80,0x07,0x00,0x08,0x00,0x13,0x00,0x24,0x0E,0x28,0x71,0x28,0x85,0x21,0x01,0x02,0x62,0x02,0x92,0x02,0x92,0x02,0x64,0x02,0x04,0x01,0xF8,0x00,}; const uint8_t _A_125khz_14_1[] = {0x00,0x80,0x07,0x00,0x08,0x00,0x10,0x00,0x20,0x0E,0x20,0x71,0x20,0x85,0x21,0x01,0x02,0x62,0x02,0x92,0x02,0x92,0x02,0x64,0x02,0x04,0x01,0xF8,0x00,}; const uint8_t _A_125khz_14_2[] = {0x01,0x00,0x17,0x00,0x00,0x3c,0x3a,0x01,0x71,0x80,0x61,0x60,0x30,0x18,0x15,0x8a,0x05,0x92,0x00,0x95,0x92,0x05,0x04,0x80,0xfe,0x20,0x00,}; @@ -650,45 +650,78 @@ const uint8_t *_I_Detailed_chip_17x13[] = {_I_Detailed_chip_17x13_0}; const uint8_t _I_Medium_chip_22x21_0[] = {0x01,0x00,0x35,0x00,0xfe,0x7f,0xe1,0xf0,0x28,0x04,0x43,0xf3,0xff,0x93,0xe1,0x6a,0x52,0x8e,0x2f,0xfe,0x51,0x25,0x80,0x4a,0x72,0xb6,0x79,0x55,0x76,0xc1,0x2e,0xaa,0xc0,0x25,0x51,0xdc,0x00,0x14,0x70,0x00,0x56,0xae,0x81,0x47,0x2b,0x7d,0x95,0x07,0x48,0x46,0x42,0x92,0x17,0x90,0xd4,0x87,0x64,}; const uint8_t *_I_Medium_chip_22x21[] = {_I_Medium_chip_22x21_0}; -const uint8_t _I_BatteryBody_52x28_0[] = {0x01,0x00,0x45,0x00,0xe0,0x7f,0x3f,0xe0,0x02,0x87,0xf0,0x21,0xe0,0xc3,0x84,0x50,0x39,0xbf,0xff,0x27,0xfe,0xf3,0x09,0xe0,0x42,0x81,0xab,0x0d,0x03,0x1c,0x2b,0xfc,0x0d,0x48,0x55,0xdc,0x1a,0x90,0x8f,0x18,0x6d,0x41,0xaa,0x1b,0x71,0x4b,0x0d,0xd4,0x1b,0xe0,0xdf,0x1b,0xd5,0xfc,0x1a,0xa5,0x36,0x06,0xac,0x20,0xa7,0xe0,0xdc,0xa5,0x7c,0x7c,0xb7,0xff,0xb4,0x21,0x5c,0xcb,0xc6,}; -const uint8_t *_I_BatteryBody_52x28[] = {_I_BatteryBody_52x28_0}; +const uint8_t _I_passport_happy1_46x49_0[] = {0x01,0x00,0x09,0x01,0xff,0x7f,0xc0,0x05,0x1f,0x02,0x1f,0xfe,0x7f,0xff,0x87,0xe0,0x00,0xa7,0xf1,0xbf,0x85,0x04,0x0a,0x30,0xec,0x07,0xe4,0x0a,0x37,0xf8,0x0c,0x03,0xec,0x05,0x1d,0xf8,0x98,0x7d,0x00,0x51,0xaf,0x81,0x47,0xa0,0x05,0x19,0x78,0x14,0xa0,0x73,0xf8,0xb8,0x14,0x74,0x1f,0xc9,0xf0,0x14,0xa4,0x10,0x39,0xec,0x2c,0x0a,0x3c,0x08,0x04,0xe8,0x0a,0x52,0x00,0x28,0xc1,0x7c,0x10,0x08,0x87,0x82,0x77,0x05,0xfc,0x40,0xe1,0x1f,0x80,0x28,0xff,0x20,0x70,0x4f,0xe4,0xf6,0x07,0xfe,0x80,0xc0,0xbf,0xd3,0xe8,0x1e,0x7a,0x0f,0x00,0xbf,0xcf,0xe0,0x74,0xe8,0x46,0x03,0x7e,0x05,0x19,0x70,0xbc,0x7b,0xe0,0x51,0x8a,0x40,0x3c,0x1e,0xf0,0x28,0xc4,0x20,0x1f,0x0f,0xb8,0x14,0xff,0x1f,0xb9,0xf9,0xa8,0x60,0x3f,0xcf,0xc8,0x14,0xff,0xde,0x70,0x29,0x61,0xb0,0xf9,0xf0,0x29,0x12,0x06,0xfd,0x3e,0x02,0x8f,0x82,0x0f,0xf8,0x9c,0x81,0x44,0x80,0x3e,0x09,0xb8,0x14,0x94,0x43,0x2b,0x80,0xcc,0x20,0xc0,0x71,0x94,0x40,0x69,0x10,0x90,0x29,0xe2,0x21,0x00,0x51,0x9b,0x01,0x4f,0xc0,0x23,0x1c,0x24,0x43,0xf5,0x1f,0x17,0x88,0x14,0x7e,0x1e,0x31,0xd8,0xe0,0xa4,0x18,0x02,0x99,0x01,0x46,0x01,0xfa,0x02,0x8e,0x06,0x80,0x05,0x6f,0xa4,0xff,0x03,0x80,0xc0,0x01,0x4a,0x82,0x04,0x18,0x08,0x14,0xb8,0x10,0x18,0x0f,0xa2,0x7f,0x21,0x02,0x8c,0x08,0x0a,0x31,0x10,0x28,0xc1,0x3a,0x13,0xf8,0x6f,0x82,0x07,0x18,0x02,0x8c,0x0c,0x0a,0x3e,0x0d,0x00,0xbc,0x7e,0x0b,0x31,0xb3,0xcf,0xff,0xdf,0xf0,0x01,0x47,0xc0,}; +const uint8_t *_I_passport_happy1_46x49[] = {_I_passport_happy1_46x49_0}; -const uint8_t _I_FaceCharging_29x14_0[] = {0x01,0x00,0x28,0x00,0xa0,0x00,0x86,0x05,0x60,0x01,0x8c,0x0e,0x61,0x00,0xc0,0x40,0x63,0x10,0x0e,0x04,0x03,0xf9,0x00,0xf0,0x41,0xc0,0x66,0x13,0xb8,0x40,0x94,0xc0,0x07,0x04,0x82,0x00,0xc6,0x11,0x02,0x01,0x8f,0xc2,0x03,0x00,}; -const uint8_t *_I_FaceCharging_29x14[] = {_I_FaceCharging_29x14_0}; +const uint8_t _I_passport_bad3_46x49_0[] = {0x01,0x00,0x07,0x01,0xff,0x7f,0xc0,0x05,0x1f,0x02,0x1f,0xfe,0x7e,0x02,0x18,0x0f,0xc0,0x0a,0x57,0xff,0xf7,0xbc,0x0a,0x59,0xf8,0x0f,0x40,0x0a,0x56,0xf8,0x04,0xe0,0x0a,0x51,0x78,0x07,0x1b,0xfc,0x05,0x18,0x5c,0x02,0x03,0xfd,0x02,0x8c,0x37,0x01,0x00,0xfd,0x01,0x46,0x15,0x40,0x80,0x7d,0x27,0xf7,0xf8,0x48,0x14,0xf7,0xf0,0x80,0x28,0xfa,0x00,0xa5,0x20,0x80,0x72,0x27,0xf5,0xf8,0x80,0x14,0x76,0x00,0x52,0x9f,0xc0,0x2f,0xd3,0xf9,0x7e,0x82,0x81,0xc0,0xc8,0xcf,0xa5,0xf6,0x0d,0x3c,0xe3,0x20,0x05,0x1d,0x05,0x32,0x4b,0xa0,0x9f,0x45,0xec,0x11,0xc9,0x18,0x14,0xe6,0x94,0x10,0x29,0xd7,0x00,0xa9,0x62,0x02,0x9f,0x02,0x83,0x41,0x11,0x88,0x14,0x77,0xf2,0x00,0x29,0x48,0x39,0x92,0x7a,0x84,0xfe,0x27,0x10,0x9c,0x7e,0x2f,0xf3,0xf8,0xea,0x78,0x68,0x18,0x09,0xf4,0x7c,0x0a,0x27,0x21,0x9e,0xc6,0xd5,0x65,0x01,0x9d,0x44,0xe0,0x10,0xe8,0x04,0x0a,0x69,0x63,0x80,0x4c,0x60,0x10,0x49,0xa6,0x0e,0x03,0xc0,0x80,0x42,0x25,0x10,0x38,0x34,0x02,0x06,0x05,0x28,0x44,0x02,0x19,0x10,0x02,0x8c,0x42,0x01,0x30,0xf8,0x4b,0xe0,0x71,0x48,0x07,0x02,0x3f,0x2c,0x05,0x8e,0x02,0x03,0x00,0x94,0x43,0xc2,0x22,0x30,0x19,0xa5,0xc4,0x0a,0x3f,0xc8,0x04,0xef,0x02,0x3c,0x16,0xe8,0xcf,0x60,0x31,0xc0,0xe8,0xdf,0xe7,0xd0,0x1b,0x01,0x34,0x77,0xf3,0xf8,0x08,0x88,0xb7,0x80,0x51,0x80,0x10,0x87,0x40,0x05,0x22,0x10,0xd8,0x00,0xa5,0x0a,0x05,0x88,0x74,0x41,0x64,0x05,0x7f,0xf7,0xfc,0x00,0x51,0xf0,}; +const uint8_t *_I_passport_bad3_46x49[] = {_I_passport_bad3_46x49_0}; + +const uint8_t _I_passport_okay2_46x49_0[] = {0x01,0x00,0xe5,0x00,0xff,0x7f,0xc0,0x05,0x1f,0x02,0x1f,0xfe,0x7e,0x02,0x1b,0xfe,0x00,0x0a,0x78,0x7b,0xff,0xf0,0x0a,0x57,0x9c,0x77,0x8c,0x0a,0x37,0xfc,0x34,0x07,0x38,0x05,0x1d,0xfd,0x06,0x01,0x60,0x02,0x8d,0x7e,0x41,0x00,0xc0,0x4f,0xbf,0xf2,0xf8,0x80,0xd0,0x67,0xbf,0xf8,0xb8,0x14,0xa7,0x40,0x51,0x84,0x01,0x4e,0x17,0x0c,0x02,0x8c,0xd3,0xff,0x05,0x82,0x01,0x5e,0x51,0xff,0x81,0x40,0xbf,0x10,0x30,0x29,0xc1,0x20,0x93,0x00,0x29,0x7c,0xa1,0x20,0x51,0xff,0x40,0xfd,0x31,0x39,0x85,0xfe,0x03,0x1c,0x8a,0xc4,0xe4,0x17,0xf8,0x2f,0x83,0x2b,0x17,0x90,0x6f,0xf0,0x90,0x0f,0xa8,0x16,0xbc,0xa0,0x52,0x84,0x40,0x61,0x51,0x20,0x29,0xfd,0xa3,0xe0,0x52,0x80,0x46,0xa1,0x02,0x91,0x80,0xf8,0x21,0x31,0x00,0x28,0xe0,0x63,0xf0,0x80,0x28,0xff,0xef,0xca,0xc2,0x90,0x4f,0xe0,0x68,0x21,0x02,0x8f,0x7c,0x12,0x20,0x52,0x97,0x81,0x52,0x2e,0x05,0x1a,0x00,0x14,0x61,0x61,0xb2,0x00,0x8c,0x14,0x0a,0x31,0x80,0x2a,0x41,0x80,0xa7,0xc0,0x80,0x81,0x47,0xcb,0x03,0x9e,0x06,0x4a,0x37,0xfc,0x1b,0x08,0xa5,0x00,0xa4,0x35,0x20,0x29,0x10,0x47,0xc1,0x0f,0x26,0x93,0x90,0x43,0x02,0x59,0x1f,0x07,0xfc,0x22,0x5f,0xff,0x7c,0x7c,0x0a,0x81,0x61,0x02,0x98,0xe8,0x40,0xa4,0x2a,0x39,0x07,0xf8,0x46,0x20,0x01,0x8f,0x80,}; +const uint8_t *_I_passport_okay2_46x49[] = {_I_passport_okay2_46x49_0}; + +const uint8_t _I_passport_bad2_46x49_0[] = {0x01,0x00,0xee,0x00,0xff,0x7f,0xc0,0x05,0x1f,0x02,0x1f,0xfe,0x7e,0x02,0x18,0x0f,0xe0,0x0a,0x57,0xff,0xf7,0x9c,0x0a,0x59,0xf8,0x0e,0x60,0x0a,0x5e,0xf8,0xfd,0x83,0xfc,0x05,0x18,0xbd,0x83,0x01,0xfd,0x02,0x8c,0x2f,0x01,0x01,0xfd,0x01,0x46,0x0b,0x00,0x81,0x7d,0x00,0xa3,0x02,0x80,0x41,0x3d,0x13,0xfb,0xfc,0x04,0x0a,0x3d,0x09,0xfe,0xfc,0x88,0x30,0x80,0x2a,0xea,0xa7,0xf5,0xf8,0x04,0x7e,0xa1,0xb5,0x02,0x8f,0x02,0xc1,0xb8,0xbf,0x4f,0xe5,0xf2,0x0e,0x07,0x53,0x03,0x3e,0x02,0x8e,0x9e,0x75,0x80,0x02,0x8e,0x42,0x9d,0x05,0xd1,0x4f,0xa2,0xf5,0x08,0xf4,0x0c,0x0a,0x73,0x69,0x08,0x14,0xab,0x17,0xe0,0x29,0xd4,0x2f,0x80,0x53,0xcc,0x50,0x24,0x22,0x31,0x8b,0xfc,0x08,0x62,0x05,0x29,0x07,0x32,0x0f,0x40,0x9f,0xc5,0xe2,0x13,0x8f,0xc5,0xfe,0x7f,0x1b,0x4f,0x90,0x44,0x40,0xa7,0x00,0x9e,0x81,0x52,0x75,0x1d,0x80,0x43,0x80,0xa3,0x34,0x86,0xc0,0x26,0x20,0x54,0xe0,0x01,0x46,0x51,0x0b,0x01,0x8c,0x0c,0x0a,0x90,0xc0,0x2a,0x4c,0x3e,0x12,0xb0,0x28,0xcc,0x38,0x10,0xf9,0x64,0x24,0x3a,0x29,0xd1,0x94,0x01,0x47,0x00,0x30,0x19,0xa0,0x14,0x60,0x1f,0xd8,0x04,0xec,0x0a,0x5f,0xaf,0xfc,0xf4,0x0a,0x5f,0x4b,0xfc,0xf8,0x0a,0x5a,0x8d,0xfc,0xfc,0x0a,0x54,0x00,0x2a,0x60,0x37,0x40,0x53,0x80,0x2e,0x44,0x0a,0x7a,0x00,0x2e,0x7f,0xbf,0xe0,0x02,0x8f,0x80,}; +const uint8_t *_I_passport_bad2_46x49[] = {_I_passport_bad2_46x49_0}; + +const uint8_t _I_passport_okay3_46x49_0[] = {0x01,0x00,0x06,0x01,0xff,0x7f,0xc0,0x05,0x1f,0x02,0x1f,0xfe,0x7e,0x02,0x2c,0x00,0x14,0xfb,0xf7,0xff,0xe0,0x14,0xa4,0xf8,0x0f,0x18,0x14,0xaf,0x30,0x0c,0xe0,0x14,0x6f,0xf8,0x68,0x05,0xa0,0x0a,0x3b,0xf8,0x0c,0x07,0x11,0x3e,0xff,0xd7,0xe0,0x10,0x28,0x44,0xf7,0xff,0x2f,0x02,0x8c,0x12,0x75,0xff,0x8b,0xc0,0x20,0x80,0x52,0x85,0x81,0x4a,0x68,0x05,0x28,0x44,0x08,0x0a,0x30,0x50,0x29,0x4a,0x00,0xa5,0xfc,0x81,0x81,0x4e,0x05,0x06,0x98,0x01,0x4b,0xf3,0x04,0x02,0x8f,0xfb,0x07,0x04,0x84,0xcc,0x2f,0xf0,0x1c,0xee,0x2a,0x15,0x28,0x02,0x8f,0x86,0xe4,0x05,0x1d,0xfe,0x03,0x01,0x52,0x02,0xa0,0x2c,0x64,0x80,0x52,0xc5,0x43,0x80,0xa7,0x07,0x87,0x81,0x4a,0x01,0xff,0x83,0xc8,0xb7,0xf0,0x08,0x0c,0x3a,0x09,0x22,0x14,0x94,0x16,0x11,0x21,0xbf,0xe0,0x6f,0xf0,0x40,0x28,0xff,0xef,0xd1,0x45,0x60,0xc8,0x67,0xf0,0x38,0x58,0x7c,0x64,0x5d,0xfe,0x04,0x18,0x0a,0x33,0xc9,0x7e,0x82,0x03,0x40,0x80,0x48,0x22,0xf5,0x08,0x00,0x14,0xa1,0x60,0x51,0x90,0x40,0x26,0x10,0x59,0x44,0x02,0x21,0x00,0x94,0x01,0x4a,0x1d,0x00,0x92,0x01,0x47,0x81,0x01,0x02,0x8f,0x96,0x57,0x3c,0x1a,0x8c,0x8a,0x36,0x8d,0x10,0x29,0x2b,0x04,0x00,0x52,0x15,0xc0,0x80,0x07,0x00,0x41,0x18,0x07,0x82,0x1f,0x80,0x92,0x37,0x88,0x30,0x32,0x9f,0xff,0x83,0xfe,0x12,0x19,0x97,0xff,0xdf,0x1f,0x02,0x8c,0x90,0x0a,0x30,0xf0,0x28,0xae,0x47,0xde,0x3a,0x12,0x68,0xb8,0xc8,0x00,0x32,0x0f,0xf0,0x8c,0x40,0x03,0x1f,}; +const uint8_t *_I_passport_okay3_46x49[] = {_I_passport_okay3_46x49_0}; + +const uint8_t _I_passport_bottom_128x18_0[] = {0x01,0x00,0x54,0x00,0x99,0x01,0x97,0xf1,0xff,0x00,0x2e,0x1c,0x1e,0xdf,0xc0,0x7b,0x63,0xe6,0xc0,0xfe,0x9e,0x03,0xfa,0x70,0x0f,0xe9,0x80,0x7f,0xc1,0xfd,0x04,0x37,0xf7,0xc9,0x1d,0xb8,0x08,0x4c,0x04,0x1f,0xb0,0x58,0x10,0x3f,0x38,0x00,0xfe,0xb0,0x41,0x7e,0x44,0x96,0x00,0x2c,0xfe,0x0b,0xfa,0x07,0xe4,0x7e,0x13,0x79,0x1d,0xce,0x02,0x03,0xc0,0x80,0x7c,0xf9,0x83,0xb9,0x80,0x40,0xc0,0x43,0x06,0xc3,0x0e,0xe6,0x01,0xfe,0x01,0x0f,0xf2,0x06,0x90,0xd0,}; +const uint8_t *_I_passport_bottom_128x18[] = {_I_passport_bottom_128x18_0}; + +const uint8_t _I_passport_bad1_46x49_0[] = {0x01,0x00,0xd2,0x00,0xff,0x7f,0xc0,0x05,0x1f,0x02,0x1f,0xfe,0x7e,0x02,0x18,0x0f,0xe0,0x0a,0x57,0xff,0xf7,0x9c,0x0a,0x59,0xf8,0x0e,0x60,0x0a,0x56,0xf8,0x05,0x83,0xfc,0x05,0x18,0xbc,0x03,0x01,0xfd,0x02,0x8c,0x2c,0x5a,0x3f,0xa0,0x28,0xc1,0x40,0xa3,0xf4,0x02,0x8c,0x08,0x0a,0x77,0xf8,0x08,0x14,0x7d,0x13,0xfd,0xf9,0x14,0x80,0xab,0xd0,0x9f,0xd7,0xe0,0x10,0x60,0x2a,0x42,0x20,0x1a,0x09,0xfc,0xbe,0x01,0x10,0x02,0xa5,0x9c,0x0a,0x78,0x0e,0x74,0x04,0x0a,0x31,0x7a,0x06,0x7a,0x06,0x05,0x39,0xb0,0x44,0x80,0xa3,0x7e,0x02,0xa5,0xf0,0x0a,0x78,0x0a,0x00,0x14,0xf8,0x13,0xf0,0x29,0xc8,0x07,0x66,0x70,0x11,0xd8,0xea,0xa7,0xf1,0xb2,0x99,0x4c,0x00,0xa9,0xc0,0x9f,0x01,0x4e,0x01,0x3d,0x02,0x8c,0x38,0x0a,0x33,0xa8,0x6c,0x02,0x62,0x05,0x19,0xa0,0x14,0x78,0x00,0x51,0x94,0x01,0x46,0x01,0x03,0x02,0xa4,0x30,0x0a,0x2a,0x02,0x98,0x7c,0x25,0x60,0x52,0xe0,0x43,0xe5,0x80,0x51,0xc0,0x27,0x46,0x51,0x09,0x05,0x88,0xc0,0x66,0x80,0x52,0xfe,0x40,0x27,0x60,0x52,0xf8,0x7f,0xe7,0xa0,0x52,0xe0,0x5f,0xe7,0xc0,0x52,0x80,0x6f,0xe7,0xe0,0x53,0xde,0x01,0x50,0xe2,0x20,0x5f,0x02,0xbf,0xfb,0xfe,0x00,0x28,0xf8,}; +const uint8_t *_I_passport_bad1_46x49[] = {_I_passport_bad1_46x49_0}; + +const uint8_t _I_passport_happy3_46x49_0[] = {0x01,0x00,0x23,0x01,0xff,0x7f,0xc0,0x05,0x1f,0x02,0x1f,0xfe,0x7f,0xff,0x81,0xe0,0x00,0xa7,0xfc,0xbf,0xff,0x00,0xa3,0x7f,0x85,0xe0,0x3e,0x60,0x51,0xdf,0xc1,0x38,0x1e,0xc0,0x28,0xd7,0xe0,0x52,0x0e,0x98,0x14,0x65,0xf0,0x28,0x86,0x92,0x1f,0x3f,0x8b,0xc0,0xa1,0x14,0x8f,0x9c,0xfa,0x2f,0x04,0x84,0x64,0x21,0x93,0xd8,0x5f,0xf2,0x6b,0xa0,0x81,0xce,0xa1,0x70,0x2a,0x37,0x82,0x05,0x34,0x82,0xfe,0x70,0x92,0x08,0x24,0xd3,0x1b,0x04,0x82,0xc4,0x7d,0x13,0x7c,0xbf,0xca,0x0b,0x0d,0xfc,0x4e,0xf4,0x7f,0xa8,0x2c,0x0f,0xf9,0x3d,0xe1,0xe7,0xa0,0xf0,0x1f,0xf4,0xfb,0x07,0x8e,0xe3,0xc0,0x2f,0xf3,0xfc,0x0d,0xd2,0x71,0x80,0xdf,0x81,0x46,0x73,0x00,0xe0,0x77,0xe7,0xf0,0x18,0x9c,0x03,0xc1,0xef,0x02,0x8c,0x7a,0x01,0xf0,0xfb,0x81,0x46,0x21,0x00,0xfc,0x7e,0xe7,0xf0,0x38,0x04,0x07,0xf9,0xf9,0x9f,0xc1,0x40,0xa3,0xfe,0xf3,0xcf,0xe1,0x30,0x0c,0x36,0x1f,0x3f,0x3f,0x88,0x85,0x86,0x07,0x7e,0x9f,0x48,0x45,0x03,0x07,0xfc,0x4c,0x68,0x2a,0xa1,0xbf,0xf8,0x25,0xf4,0x30,0x28,0xa8,0x86,0x57,0x47,0x98,0x41,0x80,0xe3,0x28,0x96,0xd2,0x04,0xa2,0x05,0x18,0xce,0x22,0x10,0x05,0x19,0xb4,0xc4,0x0a,0x5e,0x09,0xcd,0x87,0x09,0x10,0xfd,0x47,0xe7,0xdc,0x10,0x28,0xfc,0x3c,0x66,0x51,0xc1,0x48,0x30,0x05,0x31,0x02,0x94,0x03,0xf4,0x05,0x1c,0x0d,0x00,0x0a,0xdf,0x40,0x28,0xe0,0x30,0x00,0x52,0xa0,0x81,0x06,0x02,0x05,0x2e,0x04,0x06,0x03,0xe8,0x9f,0xc8,0x40,0xa3,0x02,0x02,0x8c,0x44,0x0a,0x30,0x4e,0x84,0xfe,0x1b,0xe0,0x81,0xc6,0x00,0xa3,0x03,0x02,0x8f,0x83,0x40,0x95,0x1f,0x84,0x1e,0x01,0x67,0x9f,0xff,0xbf,0xe0,0x02,0x8f,0x80,}; +const uint8_t *_I_passport_happy3_46x49[] = {_I_passport_happy3_46x49_0}; + +const uint8_t _I_passport_happy2_46x49_0[] = {0x01,0x00,0x16,0x01,0xff,0x7f,0xc0,0x05,0x1f,0x02,0x1f,0xfe,0x7f,0xff,0x87,0xe0,0x00,0xa7,0xf1,0xbf,0x85,0x04,0x0a,0x30,0xec,0x07,0x84,0x0a,0x37,0xf8,0x0c,0x03,0xbe,0x05,0x1d,0xfc,0xfb,0x81,0xa0,0x02,0x8f,0x7f,0x83,0x21,0xa4,0x43,0xe7,0xf2,0xf8,0x06,0x4a,0xa1,0xf3,0x9f,0x45,0xe0,0x10,0xcc,0x8c,0x32,0x7b,0x17,0xb8,0x42,0x30,0x50,0x39,0xd4,0x2f,0x19,0x25,0xe1,0x40,0x26,0x90,0xb8,0x15,0x1a,0x40,0x05,0x18,0x2f,0x86,0x89,0x18,0xf0,0x4d,0xe0,0xbf,0x98,0x2c,0x13,0xf1,0x3b,0xc2,0xff,0x20,0xb0,0x2f,0xe4,0xf7,0x07,0xfe,0x82,0xc0,0x7f,0xd3,0xec,0x1e,0x7b,0x8f,0x00,0xbf,0xcf,0xf0,0x74,0xc9,0xc6,0x03,0x7f,0x3f,0x81,0xc8,0x60,0x1c,0x0e,0xf8,0x14,0x62,0xd0,0x0f,0x07,0xbc,0x0a,0x31,0x88,0x07,0xc3,0xee,0x05,0x18,0x84,0x03,0xf1,0xfb,0x9f,0x9a,0x86,0x03,0xfc,0xfc,0x81,0x4f,0xfd,0xe7,0x02,0x96,0x1b,0x0f,0x9f,0x02,0x97,0xe2,0x07,0x7e,0x9f,0x01,0x47,0xc1,0x07,0xfc,0x4c,0x40,0xa2,0x40,0x1f,0x04,0xbc,0x0a,0x4a,0x21,0x95,0xc0,0x66,0x10,0x60,0x38,0xca,0x20,0x34,0x88,0x48,0x14,0xf1,0x10,0x80,0x28,0xcd,0x80,0xa7,0xe0,0x9c,0xc0,0x70,0x91,0x0f,0xd4,0x7c,0x5e,0x20,0x51,0xf8,0x78,0xc7,0x63,0x82,0x90,0x60,0x0a,0x64,0x05,0x18,0x07,0xe8,0x0a,0x38,0x1a,0x00,0x15,0xbe,0x93,0xfc,0x0e,0x03,0x00,0x05,0x2a,0x08,0x10,0x60,0x20,0x52,0xe0,0x40,0x60,0x3e,0x89,0xfc,0x84,0x0a,0x30,0x20,0x28,0xc4,0x40,0xa3,0x04,0xe8,0x4f,0xe1,0xbe,0x04,0x88,0x81,0x46,0x06,0x05,0x1f,0x06,0x80,0x5e,0x3f,0x08,0x3c,0x02,0xcf,0x3f,0xff,0x7f,0xc0,0x05,0x1f,}; +const uint8_t *_I_passport_happy2_46x49[] = {_I_passport_happy2_46x49_0}; + +const uint8_t _I_passport_okay1_46x49_0[] = {0x01,0x00,0xcc,0x00,0xff,0x7f,0xc0,0x05,0x1f,0x02,0x1f,0xfe,0x7e,0x02,0x1b,0xfc,0x00,0x0a,0x78,0xff,0xff,0xe0,0x0a,0x57,0x38,0x07,0x9c,0x0a,0x50,0xc8,0x06,0x60,0x0a,0x37,0xf8,0x1c,0x02,0xc0,0x05,0x1d,0xf8,0xb4,0x70,0x13,0xef,0xfd,0x7c,0x68,0x53,0xdf,0xfc,0xbc,0x0a,0x53,0xaf,0xfc,0x5c,0x0b,0x13,0x4f,0xfc,0x2c,0x0b,0x12,0x8f,0xfc,0x14,0x0a,0xdf,0x08,0x0c,0xc3,0xff,0x02,0x80,0x7a,0x20,0x60,0x53,0xfa,0x41,0xc0,0xa7,0x12,0x87,0xc8,0x00,0xa5,0x92,0x02,0xa7,0xc8,0x0b,0x5e,0x28,0x58,0x14,0xe0,0x90,0xc0,0x29,0xfa,0x20,0xe0,0x51,0x1d,0x8c,0x42,0x10,0x05,0x38,0x44,0x40,0x0a,0x38,0x58,0x78,0x30,0x40,0xa3,0x7d,0x29,0x94,0x82,0xff,0x06,0x02,0x9e,0x7e,0x02,0x88,0x10,0x28,0xdb,0xd1,0xc4,0x05,0x13,0xe1,0x50,0x00,0xa2,0x76,0x29,0x00,0x15,0x22,0x00,0x51,0x3e,0x14,0x38,0x0a,0x7c,0x01,0x28,0xc8,0x3c,0xb0,0xf9,0xe0,0x64,0xa3,0x7f,0x05,0xf8,0x8a,0x50,0x0a,0x4b,0x83,0x02,0x8f,0x7e,0x01,0xe0,0x2a,0x0c,0x81,0xbc,0x41,0x81,0x2c,0x8f,0x83,0xfe,0x11,0x2f,0xff,0xbe,0x3e,0x05,0x40,0xb0,0x81,0x4c,0x74,0x20,0x52,0x15,0x1c,0x83,0xfc,0x23,0x10,0x00,0xc7,0xc0,}; +const uint8_t *_I_passport_okay1_46x49[] = {_I_passport_okay1_46x49_0}; + +const uint8_t _I_passport_left_6x46_0[] = {0x01,0x00,0x1b,0x00,0x9e,0x40,0xa3,0x32,0x59,0x2c,0x66,0x03,0x01,0x82,0xc2,0x62,0x32,0x50,0x16,0xc8,0x60,0x30,0x28,0x34,0x3a,0x3d,0x3e,0x9d,0x4c,0x80,0x14,}; +const uint8_t *_I_passport_left_6x46[] = {_I_passport_left_6x46_0}; const uint8_t _I_Health_16x16_0[] = {0x01,0x00,0x12,0x00,0x00,0x2f,0x02,0x03,0x40,0x00,0x95,0xe2,0x1f,0x08,0x84,0x00,0xc4,0x12,0x60,0xf1,0x0c,0xb8,}; const uint8_t *_I_Health_16x16[] = {_I_Health_16x16_0}; +const uint8_t _I_FaceCharging_29x14_0[] = {0x01,0x00,0x28,0x00,0xa0,0x00,0x86,0x05,0x60,0x01,0x8c,0x0e,0x61,0x00,0xc0,0x40,0x63,0x10,0x0e,0x04,0x03,0xf9,0x00,0xf0,0x41,0xc0,0x66,0x13,0xb8,0x40,0x94,0xc0,0x07,0x04,0x82,0x00,0xc6,0x11,0x02,0x01,0x8f,0xc2,0x03,0x00,}; +const uint8_t *_I_FaceCharging_29x14[] = {_I_FaceCharging_29x14_0}; + +const uint8_t _I_BatteryBody_52x28_0[] = {0x01,0x00,0x45,0x00,0xe0,0x7f,0x3f,0xe0,0x02,0x87,0xf0,0x21,0xe0,0xc3,0x84,0x50,0x39,0xbf,0xff,0x27,0xfe,0xf3,0x09,0xe0,0x42,0x81,0xab,0x0d,0x03,0x1c,0x2b,0xfc,0x0d,0x48,0x55,0xdc,0x1a,0x90,0x8f,0x18,0x6d,0x41,0xaa,0x1b,0x71,0x4b,0x0d,0xd4,0x1b,0xe0,0xdf,0x1b,0xd5,0xfc,0x1a,0xa5,0x36,0x06,0xac,0x20,0xa7,0xe0,0xdc,0xa5,0x7c,0x7c,0xb7,0xff,0xb4,0x21,0x5c,0xcb,0xc6,}; +const uint8_t *_I_BatteryBody_52x28[] = {_I_BatteryBody_52x28_0}; + +const uint8_t _I_Voltage_16x16_0[] = {0x01,0x00,0x1a,0x00,0x00,0x24,0x0a,0x01,0x03,0xc0,0x40,0x78,0x10,0x1f,0x04,0x03,0xe1,0x07,0xc0,0x40,0xc0,0xe3,0xc0,0x80,0x58,0x20,0x12,0x00,0xd3,0x00,}; +const uint8_t *_I_Voltage_16x16[] = {_I_Voltage_16x16_0}; + const uint8_t _I_Temperature_16x16_0[] = {0x01,0x00,0x12,0x00,0x00,0x1e,0x02,0x01,0x40,0x80,0x80,0x66,0x41,0x02,0xf0,0x40,0xc0,0x23,0xc0,0x80,0x86,0xd4,}; const uint8_t *_I_Temperature_16x16[] = {_I_Temperature_16x16_0}; +const uint8_t _I_FaceNopower_29x14_0[] = {0x01,0x00,0x24,0x00,0x00,0x1f,0x02,0x01,0x60,0x01,0xa7,0x80,0x02,0x57,0xe0,0x48,0xc3,0xe7,0xd0,0x0c,0x04,0x3c,0x39,0x1f,0x88,0x18,0x0c,0x61,0x90,0x60,0x18,0xff,0x82,0x44,0x03,0x38,0x74,0x38,0x2c,0x80,}; +const uint8_t *_I_FaceNopower_29x14[] = {_I_FaceNopower_29x14_0}; + +const uint8_t _I_FaceNormal_29x14_0[] = {0x01,0x00,0x1e,0x00,0x00,0x1c,0xf2,0x01,0x80,0x83,0xd7,0xa0,0x1c,0x08,0x5d,0xf8,0x06,0x30,0xf0,0x1b,0x84,0xcc,0x41,0x10,0x88,0x10,0x0e,0x62,0x10,0x10,0x18,0xf8,0x00,0x42,}; +const uint8_t *_I_FaceNormal_29x14[] = {_I_FaceNormal_29x14_0}; + const uint8_t _I_Battery_16x16_0[] = {0x01,0x00,0x12,0x00,0x00,0x1e,0x02,0x03,0xc0,0x81,0xc8,0x20,0x80,0x11,0xd0,0x41,0x40,0x72,0x11,0x10,0xda,0x80,}; const uint8_t *_I_Battery_16x16[] = {_I_Battery_16x16_0}; const uint8_t _I_FaceConfused_29x14_0[] = {0x01,0x00,0x30,0x00,0xc0,0x00,0x46,0x1f,0x38,0x80,0xd0,0x22,0x14,0x48,0x0c,0x82,0x0f,0x52,0x80,0xe8,0x21,0x14,0xa0,0x18,0xc2,0xa6,0x59,0x19,0x24,0x27,0x09,0x48,0xa1,0x41,0x2f,0x12,0x4c,0x0c,0x0c,0x51,0x1f,0xc8,0x78,0x0c,0x7f,0xd1,0xf0,0x18,0xc3,0xa3,0x00,0x74,}; const uint8_t *_I_FaceConfused_29x14[] = {_I_FaceConfused_29x14_0}; -const uint8_t _I_FaceNormal_29x14_0[] = {0x01,0x00,0x1e,0x00,0x00,0x1c,0xf2,0x01,0x80,0x83,0xd7,0xa0,0x1c,0x08,0x5d,0xf8,0x06,0x30,0xf0,0x1b,0x84,0xcc,0x41,0x10,0x88,0x10,0x0e,0x62,0x10,0x10,0x18,0xf8,0x00,0x42,}; -const uint8_t *_I_FaceNormal_29x14[] = {_I_FaceNormal_29x14_0}; +const uint8_t _I_RFIDDolphinSuccess_108x57_0[] = {0x01,0x00,0xe7,0x01,0x00,0x0f,0x03,0xff,0x1f,0x06,0xd4,0xe2,0x01,0xe0,0x06,0xd4,0x18,0x04,0x30,0x30,0x64,0x60,0x20,0x20,0x31,0x86,0x03,0x62,0x80,0x03,0x28,0x80,0x36,0x24,0x00,0x36,0x00,0x28,0x5c,0xc3,0xe6,0x00,0x58,0x40,0xec,0xc1,0xb1,0x04,0x02,0x19,0x24,0x80,0x0b,0x02,0x02,0x40,0x37,0xc4,0x8c,0x2e,0x40,0x6f,0x93,0x8b,0x81,0x07,0x06,0xdc,0xc2,0x38,0x66,0x50,0x6a,0xe2,0x27,0xe0,0xd2,0xfc,0x08,0x09,0x0c,0x9c,0x4b,0x98,0x34,0xa0,0xe1,0xd5,0x06,0x8f,0x92,0xc2,0x05,0x1e,0x42,0xe1,0x81,0xa3,0xe2,0xf0,0xbc,0x4c,0x1a,0xff,0x2f,0x9b,0x80,0xd8,0xca,0x05,0x1f,0x97,0xfd,0xf8,0x60,0xd2,0x01,0x1e,0x00,0x1a,0x5c,0x00,0x08,0xc9,0xc1,0xab,0x40,0xf9,0x83,0x46,0x61,0x00,0xd8,0x4a,0x81,0xab,0xa0,0xf3,0x5f,0xc6,0x05,0x58,0x8a,0xa4,0x09,0x76,0x21,0xb1,0xf2,0x83,0x4f,0x5d,0x1a,0x01,0x8c,0x90,0x1a,0x31,0x0d,0x07,0xa9,0x16,0x50,0x0a,0xac,0x34,0xba,0x42,0xa1,0x88,0x50,0x23,0xaa,0x72,0xe0,0x6a,0xa1,0x4a,0x32,0x39,0x88,0x6c,0x60,0xc7,0x82,0xb0,0x55,0x60,0xa2,0x92,0x80,0xc0,0x43,0x63,0x03,0x25,0x96,0xe3,0x54,0x33,0x18,0xc4,0x90,0x22,0x21,0x81,0x81,0x03,0x4a,0xa9,0x55,0x7a,0x17,0xf3,0x82,0x9f,0x6d,0x5e,0xa9,0xb6,0x50,0x38,0x70,0x35,0x70,0x15,0x5a,0xa9,0xb8,0xa3,0x46,0x12,0x06,0x9f,0x83,0x54,0x8a,0x28,0x80,0x34,0xfc,0x08,0x93,0xaa,0xc7,0x40,0x83,0x83,0x81,0xd3,0xa1,0xd1,0x08,0x84,0x0c,0x24,0x3f,0xed,0x54,0x18,0x26,0x50,0x20,0xd9,0x42,0x21,0x90,0x4c,0x07,0xff,0xae,0x52,0x20,0x6a,0xc4,0x23,0x1f,0x88,0x3f,0xf0,0x1a,0x45,0x31,0xe7,0x03,0x4a,0x41,0xe0,0x69,0x0f,0xc2,0x1e,0x0d,0x19,0x80,0x48,0xa2,0x10,0xc5,0x68,0xdf,0x0a,0x82,0xb9,0x28,0x22,0x2c,0xe3,0x0a,0xd1,0x2b,0x0f,0x00,0x3c,0x22,0x91,0x53,0x9c,0x50,0x1a,0x30,0x08,0x39,0x1c,0x60,0x6d,0x12,0x3d,0x8c,0xc2,0x51,0x00,0x17,0x0c,0xe2,0x01,0xff,0x83,0x84,0xc6,0x40,0xb0,0x19,0x84,0xd0,0x1a,0x5c,0x08,0x1f,0xf8,0x8c,0x50,0x43,0x08,0xce,0x2d,0x06,0x71,0x5f,0x17,0xfe,0x12,0xdf,0x20,0x69,0x55,0x01,0xa6,0x00,0x18,0x40,0xa4,0x80,0x63,0x3c,0xb5,0x03,0x56,0x08,0x8b,0x20,0x10,0xcf,0x03,0x62,0x08,0x20,0x00,0x94,0xc6,0x01,0x70,0x01,0x0c,0xe8,0x36,0x20,0xd3,0xe0,0x00,0xcb,0x10,0x02,0x19,0xf3,0x9c,0x41,0xa3,0x15,0x31,0x90,0x00,0x70,0xc0,0x21,0xdd,0x86,0xc4,0x78,0x3e,0xa3,0x71,0xe0,0x30,0x20,0x31,0xbe,0x86,0xc4,0x1a,0x35,0x40,0x20,0x8d,0x89,0x28,0x5b,0xa0,0xd9,0xea,0x3d,0x44,0x42,0x87,0x83,0x48,0x36,0x49,0xe1,0xa0,0x75,0x67,0x8d,0x41,0x54,0x14,0x03,0xf5,0x2a,0x06,0x96,0x03,0x54,0xc4,0x14,0xd0,0x83,0x4a,0xfb,0x35,0x06,0x90,0x38,0x4e,0x46,0xb4,0x10,0xd9,0x81,0x49,0x72,0x40,0x01,0x0a,0x95,0xd4,0x36,0x20,0xd7,0x55,0x10,}; +const uint8_t *_I_RFIDDolphinSuccess_108x57[] = {_I_RFIDDolphinSuccess_108x57_0}; -const uint8_t _I_Voltage_16x16_0[] = {0x01,0x00,0x1a,0x00,0x00,0x24,0x0a,0x01,0x03,0xc0,0x40,0x78,0x10,0x1f,0x04,0x03,0xe1,0x07,0xc0,0x40,0xc0,0xe3,0xc0,0x80,0x58,0x20,0x12,0x00,0xd3,0x00,}; -const uint8_t *_I_Voltage_16x16[] = {_I_Voltage_16x16_0}; - -const uint8_t _I_FaceNopower_29x14_0[] = {0x01,0x00,0x24,0x00,0x00,0x1f,0x02,0x01,0x60,0x01,0xa7,0x80,0x02,0x57,0xe0,0x48,0xc3,0xe7,0xd0,0x0c,0x04,0x3c,0x39,0x1f,0x88,0x18,0x0c,0x61,0x90,0x60,0x18,0xff,0x82,0x44,0x03,0x38,0x74,0x38,0x2c,0x80,}; -const uint8_t *_I_FaceNopower_29x14[] = {_I_FaceNopower_29x14_0}; +const uint8_t _I_RFIDBigChip_37x36_0[] = {0x01,0x00,0x6e,0x00,0x83,0x01,0x0f,0xcd,0xff,0x00,0x0c,0x1e,0x24,0x08,0x28,0x47,0x24,0x12,0x51,0x39,0x28,0x24,0xa2,0x91,0x5e,0x07,0xab,0xfe,0x04,0x1c,0x04,0xaa,0x01,0x15,0x02,0x28,0x4c,0x81,0x2c,0x04,0x4e,0x05,0xfc,0x08,0x35,0x59,0x06,0x02,0x81,0x15,0xca,0xe4,0x26,0xf2,0x10,0x70,0xd7,0x66,0x11,0x70,0x70,0xd4,0x20,0x14,0x10,0x70,0xc7,0x68,0x13,0x70,0x70,0xd4,0x28,0x10,0x10,0x4a,0x84,0xc6,0x80,0x13,0x10,0xe8,0xd0,0x03,0xa2,0x27,0x19,0xf0,0x9c,0x46,0x28,0x3b,0x42,0xcf,0x96,0x6a,0xd4,0x13,0x6f,0x2a,0x2c,0xa2,0x90,0x54,0x59,0xfe,0x52,0xa7,0x02,0x4f,0x9f,0xf1,0x52,0x60,}; +const uint8_t *_I_RFIDBigChip_37x36[] = {_I_RFIDBigChip_37x36_0}; const uint8_t _I_RFIDDolphinSend_97x61_0[] = {0x01,0x00,0x8d,0x01,0x00,0x0f,0xfa,0x3e,0x04,0x2a,0x00,0x2d,0x78,0x10,0x1f,0x04,0x04,0x0a,0x38,0x00,0x62,0xcc,0x00,0x43,0x06,0x06,0x44,0x30,0x04,0x31,0x80,0x31,0x07,0x48,0x00,0x50,0x20,0x10,0xc8,0x01,0x64,0x0c,0x1d,0x04,0x28,0x24,0x83,0xd2,0x81,0x04,0xc4,0x18,0x42,0xc3,0x01,0x90,0x30,0xbe,0x05,0x51,0x29,0xa0,0x74,0x60,0x80,0xc1,0x84,0x0b,0x44,0x5e,0x43,0x73,0x82,0x41,0x20,0x1e,0x4a,0x68,0x31,0x27,0x90,0x48,0x84,0x20,0x18,0x31,0x7e,0x64,0x06,0x20,0x0c,0x2a,0x14,0x12,0x40,0x0c,0x28,0xa0,0xc4,0x41,0x87,0x81,0x17,0x08,0x30,0xa0,0xfd,0x08,0x0c,0x20,0xfc,0x38,0x08,0xc4,0x24,0x32,0x95,0x02,0x18,0xc2,0x61,0x18,0x09,0x20,0x31,0x03,0x25,0x84,0x1d,0x88,0x30,0x62,0x21,0x96,0xe2,0x44,0x22,0x00,0xc2,0x26,0xa0,0x64,0x68,0x80,0xc4,0x33,0x9e,0x92,0x9f,0x00,0xa3,0x48,0x24,0x00,0xc4,0x40,0xa4,0xa8,0x18,0xa9,0xb5,0x9b,0x48,0x28,0x05,0xa1,0x06,0x22,0xd4,0xa3,0x7e,0x05,0x98,0xe0,0x4f,0x22,0xcf,0x58,0x6f,0x80,0x10,0x34,0x24,0x31,0x3a,0x52,0x0f,0xe0,0x03,0x0c,0xf1,0xee,0x2d,0x63,0x00,0x0c,0x0f,0xe0,0x13,0x28,0xa0,0x31,0xa0,0x3f,0x08,0x18,0x10,0x45,0xa2,0xe3,0x40,0x00,0xf4,0x3f,0xe1,0xa1,0x84,0x02,0x94,0x18,0xb0,0xc0,0x63,0xc6,0x3f,0xe0,0x31,0x87,0x03,0x1e,0x11,0x3c,0x80,0x47,0xc1,0x90,0x56,0x1b,0x06,0x01,0xc0,0x20,0x06,0x17,0x88,0xf8,0x60,0xa0,0xc7,0x31,0x8a,0x58,0x60,0xe1,0x99,0x00,0x08,0x9a,0x01,0x06,0xd9,0x10,0x03,0x1f,0x44,0x19,0x43,0xc3,0x40,0xc4,0x2c,0x19,0x58,0x08,0x29,0xa0,0x60,0x0c,0xf2,0x00,0x27,0x02,0x05,0x20,0x06,0x4d,0x02,0x0b,0xc0,0x02,0x08,0x3c,0x80,0x09,0xa0,0x39,0x0a,0xd4,0x41,0x8f,0x50,0x05,0x09,0xa4,0x5b,0x4d,0x00,0xd8,0x23,0xc4,0x96,0x20,0xc7,0xac,0x40,0x2d,0x53,0x00,0x64,0x6b,0x20,0x1d,0x4a,0x08,0x32,0x2a,0x90,0x0d,0x46,0x0e,0x02,0x0c,0x79,0x51,0x08,0x61,0xf0,0x20,0x63,0xc5,0x4b,0x83,0x1e,0xfe,0x57,0xd3,0x51,0x40,0xbe,0xc0,0x08,0x42,0x00,0x53,0x30,0xe8,0x3f,0x50,0x14,0x73,0x80,0x0b,0xeb,0x07,0x61,0x40,0x00,0x7d,0x5f,0xf8,0x38,0x32,0x7a,0x03,0xf7,0x55,0xa6,0x78,0x19,0x54,0x0c,0xa8,0x32,0xa0,0x19,0xa0,0x65,0xc4,0x0b,0xe2,0x00,0x98,0x40,0x33,0xc1,0x92,0xfa,0x10,0x67,0x80,0x08,}; const uint8_t *_I_RFIDDolphinSend_97x61[] = {_I_RFIDDolphinSend_97x61_0}; -const uint8_t _I_RFIDDolphinSuccess_108x57_0[] = {0x01,0x00,0xe7,0x01,0x00,0x0f,0x03,0xff,0x1f,0x06,0xd4,0xe2,0x01,0xe0,0x06,0xd4,0x18,0x04,0x30,0x30,0x64,0x60,0x20,0x20,0x31,0x86,0x03,0x62,0x80,0x03,0x28,0x80,0x36,0x24,0x00,0x36,0x00,0x28,0x5c,0xc3,0xe6,0x00,0x58,0x40,0xec,0xc1,0xb1,0x04,0x02,0x19,0x24,0x80,0x0b,0x02,0x02,0x40,0x37,0xc4,0x8c,0x2e,0x40,0x6f,0x93,0x8b,0x81,0x07,0x06,0xdc,0xc2,0x38,0x66,0x50,0x6a,0xe2,0x27,0xe0,0xd2,0xfc,0x08,0x09,0x0c,0x9c,0x4b,0x98,0x34,0xa0,0xe1,0xd5,0x06,0x8f,0x92,0xc2,0x05,0x1e,0x42,0xe1,0x81,0xa3,0xe2,0xf0,0xbc,0x4c,0x1a,0xff,0x2f,0x9b,0x80,0xd8,0xca,0x05,0x1f,0x97,0xfd,0xf8,0x60,0xd2,0x01,0x1e,0x00,0x1a,0x5c,0x00,0x08,0xc9,0xc1,0xab,0x40,0xf9,0x83,0x46,0x61,0x00,0xd8,0x4a,0x81,0xab,0xa0,0xf3,0x5f,0xc6,0x05,0x58,0x8a,0xa4,0x09,0x76,0x21,0xb1,0xf2,0x83,0x4f,0x5d,0x1a,0x01,0x8c,0x90,0x1a,0x31,0x0d,0x07,0xa9,0x16,0x50,0x0a,0xac,0x34,0xba,0x42,0xa1,0x88,0x50,0x23,0xaa,0x72,0xe0,0x6a,0xa1,0x4a,0x32,0x39,0x88,0x6c,0x60,0xc7,0x82,0xb0,0x55,0x60,0xa2,0x92,0x80,0xc0,0x43,0x63,0x03,0x25,0x96,0xe3,0x54,0x33,0x18,0xc4,0x90,0x22,0x21,0x81,0x81,0x03,0x4a,0xa9,0x55,0x7a,0x17,0xf3,0x82,0x9f,0x6d,0x5e,0xa9,0xb6,0x50,0x38,0x70,0x35,0x70,0x15,0x5a,0xa9,0xb8,0xa3,0x46,0x12,0x06,0x9f,0x83,0x54,0x8a,0x28,0x80,0x34,0xfc,0x08,0x93,0xaa,0xc7,0x40,0x83,0x83,0x81,0xd3,0xa1,0xd1,0x08,0x84,0x0c,0x24,0x3f,0xed,0x54,0x18,0x26,0x50,0x20,0xd9,0x42,0x21,0x90,0x4c,0x07,0xff,0xae,0x52,0x20,0x6a,0xc4,0x23,0x1f,0x88,0x3f,0xf0,0x1a,0x45,0x31,0xe7,0x03,0x4a,0x41,0xe0,0x69,0x0f,0xc2,0x1e,0x0d,0x19,0x80,0x48,0xa2,0x10,0xc5,0x68,0xdf,0x0a,0x82,0xb9,0x28,0x22,0x2c,0xe3,0x0a,0xd1,0x2b,0x0f,0x00,0x3c,0x22,0x91,0x53,0x9c,0x50,0x1a,0x30,0x08,0x39,0x1c,0x60,0x6d,0x12,0x3d,0x8c,0xc2,0x51,0x00,0x17,0x0c,0xe2,0x01,0xff,0x83,0x84,0xc6,0x40,0xb0,0x19,0x84,0xd0,0x1a,0x5c,0x08,0x1f,0xf8,0x8c,0x50,0x43,0x08,0xce,0x2d,0x06,0x71,0x5f,0x17,0xfe,0x12,0xdf,0x20,0x69,0x55,0x01,0xa6,0x00,0x18,0x40,0xa4,0x80,0x63,0x3c,0xb5,0x03,0x56,0x08,0x8b,0x20,0x10,0xcf,0x03,0x62,0x08,0x20,0x00,0x94,0xc6,0x01,0x70,0x01,0x0c,0xe8,0x36,0x20,0xd3,0xe0,0x00,0xcb,0x10,0x02,0x19,0xf3,0x9c,0x41,0xa3,0x15,0x31,0x90,0x00,0x70,0xc0,0x21,0xdd,0x86,0xc4,0x78,0x3e,0xa3,0x71,0xe0,0x30,0x20,0x31,0xbe,0x86,0xc4,0x1a,0x35,0x40,0x20,0x8d,0x89,0x28,0x5b,0xa0,0xd9,0xea,0x3d,0x44,0x42,0x87,0x83,0x48,0x36,0x49,0xe1,0xa0,0x75,0x67,0x8d,0x41,0x54,0x14,0x03,0xf5,0x2a,0x06,0x96,0x03,0x54,0xc4,0x14,0xd0,0x83,0x4a,0xfb,0x35,0x06,0x90,0x38,0x4e,0x46,0xb4,0x10,0xd9,0x81,0x49,0x72,0x40,0x01,0x0a,0x95,0xd4,0x36,0x20,0xd7,0x55,0x10,}; -const uint8_t *_I_RFIDDolphinSuccess_108x57[] = {_I_RFIDDolphinSuccess_108x57_0}; - const uint8_t _I_RFIDDolphinReceive_97x61_0[] = {0x01,0x00,0x87,0x01,0x00,0x0f,0xfa,0x3e,0x04,0x28,0x08,0x2d,0x78,0x10,0x1f,0x00,0x24,0x70,0x01,0x86,0x98,0x00,0x86,0x0c,0x0c,0x88,0x60,0x08,0x63,0x10,0x0a,0x00,0x31,0xa0,0x40,0x21,0x90,0x03,0x04,0x1a,0x5a,0x08,0x50,0xe9,0x01,0x23,0x20,0x07,0x88,0x30,0xc5,0xa6,0x03,0x10,0x61,0xfc,0x0a,0xa2,0x2d,0x48,0x0c,0x82,0x20,0x04,0x18,0x40,0x40,0x42,0x44,0x37,0x28,0x80,0x30,0xbc,0x94,0xd0,0x62,0x4f,0x20,0x91,0x08,0x44,0x12,0x01,0x17,0xe6,0x40,0x42,0x45,0x00,0xa1,0x03,0x08,0xa8,0x31,0x41,0x88,0x83,0x0f,0x03,0x08,0x06,0x1c,0x1f,0xa1,0x01,0x84,0x1f,0x8a,0x31,0x09,0x0c,0xa5,0x40,0x86,0x30,0x98,0x46,0x02,0x48,0x0c,0x40,0xc9,0x61,0x00,0xe2,0x0c,0x18,0x88,0x65,0xb8,0x85,0x51,0x06,0x21,0x34,0x83,0x23,0x44,0x06,0x29,0x1c,0xb4,0x94,0xf8,0x05,0x19,0x12,0x20,0xc2,0x40,0xb4,0xa8,0x18,0xa9,0xb5,0x9b,0x48,0x28,0x05,0xa1,0x06,0x22,0xd4,0xa3,0x7e,0x05,0x98,0xe0,0x62,0x0c,0xf6,0x86,0xf8,0x16,0x63,0x42,0x06,0x0b,0xa1,0x60,0xfe,0x06,0xe8,0xcf,0x23,0x0d,0x53,0x00,0x14,0x0f,0xe0,0xea,0x28,0xa0,0x31,0xa0,0x3f,0x08,0x18,0x10,0x45,0xa2,0x11,0x20,0x01,0xf4,0x3f,0xe0,0x81,0x84,0x02,0x94,0x18,0xb0,0xc0,0x63,0xc6,0x3f,0xe0,0x31,0x87,0x03,0x1e,0x11,0x3c,0x80,0x47,0xc1,0x91,0x18,0x80,0x58,0x30,0x0e,0x01,0x00,0x30,0xbc,0x47,0xc3,0x05,0x06,0x3c,0x52,0x00,0xe4,0x20,0xcc,0x80,0x04,0x4d,0x00,0x83,0x73,0x08,0x01,0x8f,0xa2,0x0c,0xa1,0xe1,0xa0,0x62,0x16,0x0c,0xac,0x04,0x14,0xd0,0x30,0x08,0x80,0x31,0xb8,0x10,0x27,0x89,0x03,0x1e,0x81,0x05,0xe0,0x01,0x04,0x1e,0x40,0x04,0xd0,0x1c,0x85,0x6a,0x20,0xc7,0xa8,0x02,0x84,0xd2,0x34,0x00,0x63,0x6c,0x11,0xe2,0x4b,0x10,0x63,0xd6,0x20,0x16,0xa9,0x80,0x32,0x35,0x90,0x0e,0xa5,0x04,0x19,0x15,0x48,0x06,0xa3,0x07,0x01,0x06,0x3c,0xa8,0x84,0x30,0xf8,0x10,0x31,0xe2,0xa5,0xc1,0x8f,0x7f,0x2b,0xe9,0xa8,0xa0,0x5f,0x60,0x04,0x21,0x00,0x29,0x98,0x74,0x1f,0xa8,0x0a,0x39,0xc0,0x05,0xf5,0x83,0xb0,0xa0,0x00,0x3e,0xaf,0xfc,0x1c,0x19,0x3d,0x01,0xfb,0xaa,0xd3,0x3c,0x0c,0xaa,0x06,0x54,0x19,0x50,0x0c,0xd0,0x32,0xe2,0x05,0xf1,0x00,0x4c,0x20,0x19,0xe0,0xc9,0x7d,0x08,0x33,0xc0,0x04,}; const uint8_t *_I_RFIDDolphinReceive_97x61[] = {_I_RFIDDolphinReceive_97x61_0}; -const uint8_t _I_RFIDBigChip_37x36_0[] = {0x01,0x00,0x6e,0x00,0x83,0x01,0x0f,0xcd,0xff,0x00,0x0c,0x1e,0x24,0x08,0x28,0x47,0x24,0x12,0x51,0x39,0x28,0x24,0xa2,0x91,0x5e,0x07,0xab,0xfe,0x04,0x1c,0x04,0xaa,0x01,0x15,0x02,0x28,0x4c,0x81,0x2c,0x04,0x4e,0x05,0xfc,0x08,0x35,0x59,0x06,0x02,0x81,0x15,0xca,0xe4,0x26,0xf2,0x10,0x70,0xd7,0x66,0x11,0x70,0x70,0xd4,0x20,0x14,0x10,0x70,0xc7,0x68,0x13,0x70,0x70,0xd4,0x28,0x10,0x10,0x4a,0x84,0xc6,0x80,0x13,0x10,0xe8,0xd0,0x03,0xa2,0x27,0x19,0xf0,0x9c,0x46,0x28,0x3b,0x42,0xcf,0x96,0x6a,0xd4,0x13,0x6f,0x2a,0x2c,0xa2,0x90,0x54,0x59,0xfe,0x52,0xa7,0x02,0x4f,0x9f,0xf1,0x52,0x60,}; -const uint8_t *_I_RFIDBigChip_37x36[] = {_I_RFIDBigChip_37x36_0}; - const uint8_t _I_SDQuestion_35x43_0[] = {0x01,0x00,0x67,0x00,0xf8,0x7f,0xc0,0x03,0x03,0xfc,0x01,0x0a,0x0f,0x38,0xa4,0xe4,0xa4,0x80,0x4f,0x0c,0x20,0x13,0xc0,0x9f,0x80,0x02,0x15,0xfe,0x00,0x04,0x29,0xfc,0x03,0xfd,0x07,0xfa,0x47,0xe7,0xdf,0xc8,0x3f,0xea,0x1f,0x7f,0xfc,0x41,0xff,0xb8,0xff,0xf8,0x10,0x7f,0xe0,0x4e,0xef,0x86,0x08,0x68,0x33,0xf1,0x10,0xff,0x3f,0xf1,0xf1,0x60,0x81,0x06,0x1e,0x36,0x10,0x20,0xe1,0xc0,0x87,0xc7,0x02,0x0f,0xd3,0xff,0xe3,0x02,0x0f,0xe8,0x08,0x7f,0xd0,0x21,0x89,0xc4,0x08,0x9f,0x70,0x21,0x9a,0x08,0x08,0xc1,0x89,0x02,0x20,0x62,0x40,0x8f,0xfe,0x68,0x98,}; const uint8_t *_I_SDQuestion_35x43[] = {_I_SDQuestion_35x43_0}; @@ -698,8 +731,11 @@ const uint8_t *_I_SDError_43x35[] = {_I_SDError_43x35_0}; const uint8_t _I_Cry_dolph_55x52_0[] = {0x01,0x00,0xe8,0x00,0x00,0x0f,0xe3,0xff,0x01,0x03,0x1f,0xfb,0xff,0x0f,0x02,0x96,0x02,0x0f,0x00,0x9f,0x01,0x8b,0xc0,0x12,0x1f,0x80,0x18,0xae,0x00,0x21,0xe0,0x07,0x0a,0x30,0x0a,0x28,0x18,0x08,0x61,0x80,0x62,0x83,0x00,0x90,0x14,0x61,0x02,0x0c,0x16,0x00,0x76,0x60,0x66,0x98,0x0b,0x04,0x90,0x60,0x66,0xb0,0x00,0x48,0x0d,0x21,0x21,0x03,0x30,0x74,0x40,0xd3,0x80,0x03,0x34,0x04,0xc0,0x52,0x00,0x32,0xc7,0xa0,0x18,0x80,0x31,0x80,0x07,0xe1,0x01,0x37,0x18,0x50,0x80,0xc2,0x92,0x10,0x31,0xe8,0x23,0xe9,0x63,0x86,0x54,0x3f,0xe0,0xe1,0x0d,0x96,0x83,0xfc,0x06,0x40,0x69,0x6c,0x3c,0x60,0xd2,0xfc,0xc0,0x60,0x58,0x48,0x0c,0x1b,0x81,0x08,0x14,0x9c,0x1a,0x81,0x04,0x03,0x46,0x80,0x0c,0x50,0x26,0x21,0xc1,0x94,0x26,0x14,0x27,0x8a,0x40,0xc0,0xc2,0xe7,0x26,0x40,0x81,0x86,0xc0,0x6b,0x28,0x64,0x0f,0x01,0x10,0x4e,0x14,0x60,0x0c,0x29,0x02,0x48,0x8b,0x5c,0x45,0x22,0x01,0x10,0x31,0x3a,0x4c,0x0c,0x34,0x06,0xf1,0xd8,0x00,0xc5,0x1a,0x64,0x94,0x0c,0xc0,0x37,0x52,0x20,0x81,0x84,0x26,0x3e,0x88,0x0c,0x38,0x28,0x54,0x0e,0xac,0x1f,0xe1,0x3f,0x06,0x96,0x82,0x7e,0x29,0x4a,0xaf,0xfd,0x76,0x30,0x3a,0x41,0x14,0x7f,0xd0,0xf8,0x78,0x18,0xaa,0x9f,0xd4,0xe0,0x83,0x4f,0xf5,0xf7,0x38,0x0b,0x9c,0x6a,0x1f,0x5b,0x5c,0x00,}; const uint8_t *_I_Cry_dolph_55x52[] = {_I_Cry_dolph_55x52_0}; -const uint8_t _I_Background_128x11_0[] = {0x01,0x00,0x70,0x00,0xff,0x40,0x40,0xc9,0xe0,0xff,0x80,0x06,0x1e,0x08,0x38,0x0c,0x0c,0x1e,0x93,0x00,0x19,0x46,0x01,0x07,0x7d,0x83,0x03,0xd2,0x31,0xff,0xdb,0xd5,0x66,0x20,0x83,0xc0,0xff,0x05,0x24,0x00,0x1c,0x78,0x28,0xbc,0x40,0x72,0xbf,0xcf,0x47,0xeb,0x40,0xdb,0x7a,0xbf,0xf0,0x40,0x39,0x60,0x28,0x3f,0xe0,0xa0,0xea,0x80,0x63,0x3f,0x0b,0x17,0xe4,0x3e,0x5a,0xbc,0xf9,0x99,0x70,0x1f,0x81,0x50,0xc0,0x80,0xe7,0x3e,0x1e,0x9d,0x57,0xfb,0x7f,0x23,0x15,0xb0,0x12,0x5b,0x5b,0x02,0x1d,0x8c,0xc3,0x80,0x24,0x9e,0x03,0x80,0x5e,0x40,0x00,0xa1,0x88,0x0e,0x98,0x00,0x7b,0x07,0x08,0xb2,0x44,0x41,}; -const uint8_t *_I_Background_128x11[] = {_I_Background_128x11_0}; +const uint8_t _I_BadUsb_9x8_0[] = {0x00,0x01,0x01,0xBB,0x01,0xFE,0x00,0xFE,0x00,0xD6,0x00,0xD6,0x00,0x7C,0x00,0x38,0x00,}; +const uint8_t *_I_BadUsb_9x8[] = {_I_BadUsb_9x8_0}; + +const uint8_t _I_PlaceholderR_30x13_0[] = {0x01,0x00,0x19,0x00,0xfe,0x7f,0xff,0xf0,0xf8,0x10,0x18,0x62,0x10,0x10,0x18,0xc8,0x00,0x7e,0x03,0xb8,0x18,0x0c,0x66,0x1f,0xe1,0x58,0xc7,0xc5,0xe6,}; +const uint8_t *_I_PlaceholderR_30x13[] = {_I_PlaceholderR_30x13_0}; const uint8_t _I_Lock_8x8_0[] = {0x00,0x3C,0x42,0x42,0xFF,0xFF,0xE7,0xFF,0xFF,}; const uint8_t *_I_Lock_8x8[] = {_I_Lock_8x8_0}; @@ -707,71 +743,68 @@ const uint8_t *_I_Lock_8x8[] = {_I_Lock_8x8_0}; const uint8_t _I_Battery_26x8_0[] = {0x01,0x00,0x13,0x00,0xff,0x7f,0xef,0xf0,0x08,0x0c,0x03,0x00,0x03,0x38,0x18,0x0c,0xa0,0x40,0x36,0x05,0x98,0x6d,0x00,}; const uint8_t *_I_Battery_26x8[] = {_I_Battery_26x8_0}; -const uint8_t _I_Battery_19x8_0[] = {0x01,0x00,0x0f,0x00,0xff,0x7f,0xe0,0x30,0x18,0x04,0x08,0x04,0x90,0x60,0x12,0x02,0xcc,0x28,0x40,}; -const uint8_t *_I_Battery_19x8[] = {_I_Battery_19x8_0}; - -const uint8_t _I_USBConnected_15x8_0[] = {0x00,0xF0,0x07,0x08,0x7C,0x04,0x44,0x07,0x54,0x07,0x54,0x04,0x44,0x08,0x7C,0xF0,0x07,}; -const uint8_t *_I_USBConnected_15x8[] = {_I_USBConnected_15x8_0}; - -const uint8_t _I_BadUsb_9x8_0[] = {0x00,0x01,0x01,0xBB,0x01,0xFE,0x00,0xFE,0x00,0xD6,0x00,0xD6,0x00,0x7C,0x00,0x38,0x00,}; -const uint8_t *_I_BadUsb_9x8[] = {_I_BadUsb_9x8_0}; - -const uint8_t _I_BT_Pair_9x8_0[] = {0x00,0x11,0x01,0x35,0x00,0x58,0x01,0x31,0x00,0x30,0x01,0x59,0x00,0x34,0x01,0x11,0x01,}; -const uint8_t *_I_BT_Pair_9x8[] = {_I_BT_Pair_9x8_0}; - const uint8_t _I_PlaceholderL_11x13_0[] = {0x01,0x00,0x10,0x00,0xfe,0x40,0x60,0x50,0x28,0x0c,0x10,0x03,0xb0,0x38,0x37,0xfe,0x07,0xfe,0x80,0x80,}; const uint8_t *_I_PlaceholderL_11x13[] = {_I_PlaceholderL_11x13_0}; -const uint8_t _I_SDcardFail_11x8_0[] = {0x00,0xFF,0x07,0xB7,0x07,0xFF,0x07,0x87,0x07,0x7B,0x07,0xFF,0x07,0xFF,0x07,0x67,0x00,}; -const uint8_t *_I_SDcardFail_11x8[] = {_I_SDcardFail_11x8_0}; - -const uint8_t _I_Bluetooth_5x8_0[] = {0x00,0x04,0x0D,0x16,0x0C,0x0C,0x16,0x0D,0x04,}; -const uint8_t *_I_Bluetooth_5x8[] = {_I_Bluetooth_5x8_0}; - -const uint8_t _I_PlaceholderR_30x13_0[] = {0x01,0x00,0x19,0x00,0xfe,0x7f,0xff,0xf0,0xf8,0x10,0x18,0x62,0x10,0x10,0x18,0xc8,0x00,0x7e,0x03,0xb8,0x18,0x0c,0x66,0x1f,0xe1,0x58,0xc7,0xc5,0xe6,}; -const uint8_t *_I_PlaceholderR_30x13[] = {_I_PlaceholderR_30x13_0}; +const uint8_t _I_Battery_19x8_0[] = {0x01,0x00,0x0f,0x00,0xff,0x7f,0xe0,0x30,0x18,0x04,0x08,0x04,0x90,0x60,0x12,0x02,0xcc,0x28,0x40,}; +const uint8_t *_I_Battery_19x8[] = {_I_Battery_19x8_0}; const uint8_t _I_SDcardMounted_11x8_0[] = {0x01,0x00,0x09,0x00,0xff,0xc1,0xff,0xf0,0x40,0x1c,0xd9,0xe0,0x00,}; const uint8_t *_I_SDcardMounted_11x8[] = {_I_SDcardMounted_11x8_0}; -const uint8_t _I_Quest_7x8_0[] = {0x00,0x1E,0x33,0x33,0x30,0x18,0x0C,0x00,0x0C,}; -const uint8_t *_I_Quest_7x8[] = {_I_Quest_7x8_0}; +const uint8_t _I_SDcardFail_11x8_0[] = {0x00,0xFF,0x07,0xB7,0x07,0xFF,0x07,0x87,0x07,0x7B,0x07,0xFF,0x07,0xFF,0x07,0x67,0x00,}; +const uint8_t *_I_SDcardFail_11x8[] = {_I_SDcardFail_11x8_0}; -const uint8_t _I_Lock_7x8_0[] = {0x00,0x1C,0x22,0x22,0x7F,0x7F,0x77,0x7F,0x3E,}; -const uint8_t *_I_Lock_7x8[] = {_I_Lock_7x8_0}; +const uint8_t _I_USBConnected_15x8_0[] = {0x00,0xF0,0x07,0x08,0x7C,0x04,0x44,0x07,0x54,0x07,0x54,0x04,0x44,0x08,0x7C,0xF0,0x07,}; +const uint8_t *_I_USBConnected_15x8[] = {_I_USBConnected_15x8_0}; + +const uint8_t _I_Bluetooth_5x8_0[] = {0x00,0x04,0x0D,0x16,0x0C,0x0C,0x16,0x0D,0x04,}; +const uint8_t *_I_Bluetooth_5x8[] = {_I_Bluetooth_5x8_0}; + +const uint8_t _I_BT_Pair_9x8_0[] = {0x00,0x11,0x01,0x35,0x00,0x58,0x01,0x31,0x00,0x30,0x01,0x59,0x00,0x34,0x01,0x11,0x01,}; +const uint8_t *_I_BT_Pair_9x8[] = {_I_BT_Pair_9x8_0}; + +const uint8_t _I_Background_128x11_0[] = {0x01,0x00,0x70,0x00,0xff,0x40,0x40,0xc9,0xe0,0xff,0x80,0x06,0x1e,0x08,0x38,0x0c,0x0c,0x1e,0x93,0x00,0x19,0x46,0x01,0x07,0x7d,0x83,0x03,0xd2,0x31,0xff,0xdb,0xd5,0x66,0x20,0x83,0xc0,0xff,0x05,0x24,0x00,0x1c,0x78,0x28,0xbc,0x40,0x72,0xbf,0xcf,0x47,0xeb,0x40,0xdb,0x7a,0xbf,0xf0,0x40,0x39,0x60,0x28,0x3f,0xe0,0xa0,0xea,0x80,0x63,0x3f,0x0b,0x17,0xe4,0x3e,0x5a,0xbc,0xf9,0x99,0x70,0x1f,0x81,0x50,0xc0,0x80,0xe7,0x3e,0x1e,0x9d,0x57,0xfb,0x7f,0x23,0x15,0xb0,0x12,0x5b,0x5b,0x02,0x1d,0x8c,0xc3,0x80,0x24,0x9e,0x03,0x80,0x5e,0x40,0x00,0xa1,0x88,0x0e,0x98,0x00,0x7b,0x07,0x08,0xb2,0x44,0x41,}; +const uint8_t *_I_Background_128x11[] = {_I_Background_128x11_0}; const uint8_t _I_Scanning_123x52_0[] = {0x01,0x00,0xd3,0x01,0x00,0x78,0x03,0xc0,0x1f,0x00,0xe0,0x7f,0xc1,0xfb,0xf0,0x80,0x41,0xc0,0xc7,0x03,0x07,0xbe,0xb2,0x07,0x18,0x07,0xc4,0x40,0x06,0x55,0x68,0x2d,0x80,0x0a,0x58,0x08,0x10,0x3c,0xe1,0x00,0x32,0xc0,0xc2,0xb0,0x00,0xf8,0x82,0x02,0x0a,0x01,0x15,0x80,0x40,0x40,0xc3,0x40,0x07,0xa0,0x10,0xa8,0x10,0x09,0xc0,0x19,0x01,0xe9,0x82,0x01,0x0c,0x82,0x01,0x74,0x13,0x1d,0x03,0x04,0x24,0x28,0x05,0x04,0x1e,0x76,0x80,0x79,0xc8,0x30,0x50,0x28,0x30,0x14,0x64,0x26,0x23,0xe8,0x78,0x21,0xe0,0xf4,0x85,0x43,0x30,0x12,0x03,0x00,0x83,0xc7,0x41,0x1c,0x3b,0x10,0x3c,0xe2,0x98,0x08,0x80,0xa4,0x61,0x1e,0x0e,0x9c,0x0c,0x1e,0x51,0x00,0x7a,0x95,0x46,0x11,0x90,0xd3,0xd0,0x24,0x80,0xfb,0xe4,0x5f,0xf0,0x92,0x80,0x79,0x61,0x01,0xe3,0xff,0x07,0x9e,0x22,0xcf,0x3e,0xc4,0x03,0xd3,0xf5,0xff,0x07,0xa5,0x12,0xc9,0x2e,0x07,0xa7,0xf3,0x5f,0xff,0x8a,0x93,0xce,0x89,0xe4,0x97,0xe2,0x25,0x40,0xf1,0x8c,0x75,0x3b,0xf1,0xf1,0xf8,0x9b,0xc8,0x1e,0x55,0x0f,0xfc,0x03,0xfd,0x1f,0xf6,0x4f,0xc9,0xe2,0x8f,0x3a,0x27,0x12,0x5f,0xea,0x68,0x0c,0x06,0x35,0xfc,0x2f,0x92,0xbc,0xf0,0x98,0x89,0x7c,0x75,0x8e,0x37,0xd8,0xf1,0x7c,0xa3,0x0c,0xf3,0xc3,0x47,0xf8,0xcb,0x81,0xc2,0x5f,0x62,0xc0,0xf2,0x77,0xa5,0x1b,0xeb,0xc3,0x6c,0x8d,0x12,0x03,0x22,0x07,0x8c,0x30,0x18,0x2d,0x82,0xc3,0xc2,0xaf,0x84,0x42,0x81,0xc8,0xb1,0x01,0xb2,0x4e,0x08,0x08,0x68,0xb0,0x50,0x20,0xdf,0xb4,0x90,0x3a,0x10,0x3d,0x19,0x05,0x86,0x1e,0x8f,0x03,0x03,0xa5,0x83,0xd0,0xa1,0x10,0x30,0x79,0x00,0x0a,0x0a,0x02,0x19,0x84,0x03,0xa5,0xff,0xc0,0x8a,0x88,0x00,0x81,0xe1,0x80,0x12,0x07,0xa5,0x1f,0xc0,0x03,0xde,0x0b,0x80,0x80,0x0a,0x47,0xa3,0x1f,0x80,0x42,0x43,0xf1,0xe1,0x80,0x60,0x3d,0x30,0xf8,0x04,0x48,0x3e,0xf0,0x08,0xf1,0x40,0x7d,0x00,0xf1,0x56,0x08,0xfe,0x20,0x17,0x0f,0x70,0x3c,0x55,0x82,0x00,0x58,0x38,0x0c,0xa7,0x9f,0x90,0x78,0x80,0x1c,0xec,0x5a,0xac,0xff,0xc0,0x1f,0x30,0x1a,0x05,0x57,0xfb,0x5f,0xf8,0x45,0xc3,0xf3,0x80,0xf5,0x7f,0xe7,0xfe,0x00,0x7c,0x87,0xc7,0xab,0xff,0x8f,0x83,0xea,0x05,0x80,0xd5,0x7f,0xe1,0xfe,0x08,0x98,0x7e,0x60,0x15,0x5a,0xac,0x0f,0xe1,0x15,0x0f,0xc9,0x78,0x75,0x50,0x0d,0x84,0x28,0x3f,0x55,0x4b,0xac,0x02,0xb1,0x0d,0x0f,0xd6,0xa0,0xf8,0x3a,0x85,0x29,0xaf,0xde,0xf8,0x04,0x1a,0xe2,0x54,0x83,0xf0,0x00,0x2d,0x70,0xd4,0x43,0xf2,0x00,0x2e,0xb8,0x3a,0x20,0x05,0x93,0xc0,0x5e,0xc1,0xf2,0x79,0x3e,0x04,0x7c,0x1f,0x32,0xa0,0x19,0x7c,0x1e,0x86,0x00,0x6a,0xa8,0x0c,0xbf,0x84,0xe9,0x4e,0x88,0x0c,0x85,0xd5,0x00,}; const uint8_t *_I_Scanning_123x52[] = {_I_Scanning_123x52_0}; -const uint8_t _I_MHz_25x11_0[] = {0x01,0x00,0x21,0x00,0xe1,0xe1,0xa0,0x30,0x0f,0x38,0x0c,0xbf,0xe0,0x34,0xfe,0xc0,0x7b,0x7f,0xe0,0x19,0xf0,0x60,0x1d,0xbc,0x35,0x84,0x36,0x53,0x10,0x19,0x46,0x40,0x64,0x13,0x10,0x19,0x80,}; -const uint8_t *_I_MHz_25x11[] = {_I_MHz_25x11_0}; +const uint8_t _I_Quest_7x8_0[] = {0x00,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[] = {0x00,0x1C,0x22,0x02,0x4F,0x67,0x73,0x79,0x3C,}; const uint8_t *_I_Unlock_7x8[] = {_I_Unlock_7x8_0}; -const uint8_t _I_iButtonKey_49x44_0[] = {0x01,0x00,0xb4,0x00,0x00,0x24,0xfc,0x0a,0x9c,0x0e,0x00,0x19,0x26,0x18,0x00,0x32,0x43,0x20,0x10,0x10,0x31,0xc0,0x80,0xc9,0x80,0x02,0x08,0x18,0xec,0x00,0x21,0x03,0x1c,0x40,0x1e,0x22,0x15,0xa0,0x08,0x56,0x40,0x06,0x30,0xc0,0x85,0x84,0x86,0x40,0x21,0x84,0x10,0xcc,0x04,0x30,0x40,0x31,0x02,0x88,0x3a,0x20,0x01,0x83,0x0d,0x94,0x06,0x26,0x03,0xf8,0x43,0xc5,0xe9,0x0c,0x11,0x08,0xbc,0xe0,0x64,0x21,0x23,0x09,0x38,0x80,0x22,0x28,0x20,0x58,0x99,0xc4,0x50,0x41,0xe1,0xc0,0x60,0xcc,0xab,0x47,0x21,0xa6,0x02,0x9e,0x06,0x22,0x70,0xf0,0x00,0xcb,0x40,0x03,0x18,0xb0,0x78,0x14,0xe0,0x32,0x58,0x28,0xa5,0x84,0xd0,0x51,0x80,0xc9,0x30,0x06,0xae,0x62,0x84,0x06,0x48,0x64,0x88,0x0c,0x90,0x29,0x08,0x19,0x30,0x31,0x13,0x71,0xb8,0xc4,0xea,0x70,0x6b,0xc5,0x01,0x4a,0x7f,0xc8,0x7c,0x81,0x4a,0x77,0x8a,0xac,0x45,0x4a,0x7f,0x08,0x54,0x39,0x4a,0x7e,0x0e,0xa9,0xf0,0xcb,0xe3,0x7f,0x6e,0x22,0x5c,0x59,0x44,0x00,0x28,0x7a,0xd4,0x40,0x07,0xf0,0x02,0xa0,}; -const uint8_t *_I_iButtonKey_49x44[] = {_I_iButtonKey_49x44_0}; +const uint8_t _I_MHz_25x11_0[] = {0x01,0x00,0x21,0x00,0xe1,0xe1,0xa0,0x30,0x0f,0x38,0x0c,0xbf,0xe0,0x34,0xfe,0xc0,0x7b,0x7f,0xe0,0x19,0xf0,0x60,0x1d,0xbc,0x35,0x84,0x36,0x53,0x10,0x19,0x46,0x40,0x64,0x13,0x10,0x19,0x80,}; +const uint8_t *_I_MHz_25x11[] = {_I_MHz_25x11_0}; -const uint8_t _I_DolphinExcited_64x63_0[] = {0x01,0x00,0x36,0x01,0x00,0x25,0x00,0x0f,0xd2,0x00,0x3b,0xe0,0x00,0xeb,0x10,0x0c,0x34,0x40,0x30,0xd0,0x88,0x80,0x1d,0xa1,0x00,0x42,0xfc,0x7f,0xc0,0x63,0x04,0x01,0x0e,0x02,0x0f,0x00,0x00,0x8c,0x08,0x0e,0x37,0x00,0x10,0xc6,0x20,0x10,0x10,0xd9,0x11,0x92,0x1c,0x1a,0x3e,0x00,0x04,0x42,0x02,0x1a,0x20,0xb0,0xce,0x00,0x64,0x07,0x20,0x59,0x16,0x50,0x36,0x45,0x94,0x84,0x78,0x20,0x60,0x75,0x8e,0x43,0x06,0x63,0x3c,0x33,0x94,0x0c,0xd2,0x5c,0x30,0x38,0xe4,0x08,0x43,0x10,0xc0,0x5e,0x06,0x22,0x53,0x1a,0x02,0x08,0x7f,0xd0,0x32,0xc1,0x50,0x21,0x14,0x0e,0x70,0x1c,0x46,0xe2,0x07,0x19,0x06,0x3c,0xdc,0x20,0x91,0xae,0x01,0xcc,0xbe,0x30,0x09,0xfc,0x12,0x41,0xff,0x83,0xcc,0x0a,0xa3,0x1f,0x03,0x99,0xe8,0x7c,0x10,0xf8,0x25,0xa0,0x5e,0x50,0x0f,0x84,0x1e,0x09,0x54,0x03,0x9f,0xf2,0x07,0x02,0xd5,0x11,0xca,0x01,0xfe,0x80,0xc0,0xaa,0x9f,0xf0,0x39,0x5f,0xd0,0x43,0xaa,0x83,0x41,0x92,0xc3,0x1f,0x03,0x8d,0x52,0x02,0x2e,0x25,0xc9,0x6a,0x99,0x46,0xa6,0x2a,0xa0,0x1c,0xaf,0xca,0x62,0x94,0x28,0xcb,0x7e,0x0f,0x15,0x71,0xf8,0x3c,0x22,0x71,0x03,0x8a,0x84,0x67,0x18,0x0f,0xac,0x1c,0x0e,0x38,0x08,0x0c,0x3e,0x01,0xae,0xbd,0x13,0x0c,0x0e,0x35,0x8e,0xa8,0x1c,0xb0,0x1f,0xf8,0x06,0x83,0xf4,0x27,0x38,0x07,0xff,0xff,0x8f,0x03,0xa0,0x4c,0x80,0xed,0x60,0x03,0xb4,0x60,0x0e,0xd0,0x60,0x3a,0x87,0x84,0x0e,0xb7,0xc2,0xfa,0x18,0x05,0x44,0x20,0x73,0xff,0xf7,0xce,0xe4,0x07,0x2d,0x52,0x2c,0x80,0xe7,0x54,0xea,0x81,0xd7,0x50,0x0f,0x7a,0xaa,0x3d,0x41,0xe2,0x07,0x5a,0x80,0x3c,0xa0,0x40,0x72,0xd0,0x6a,0x80,0xa2,0x07,0x3a,0x05,0x54,0x8e,0x20,0x73,0xc0,0x03,0xd8,0x60,0x30,0x40,0x3a,0xc0,0x00,0xee,0xea,0x10,0x3b,0x80,}; -const uint8_t *_I_DolphinExcited_64x63[] = {_I_DolphinExcited_64x63_0}; - -const uint8_t _I_DolphinWait_61x59_0[] = {0x01,0x00,0x56,0x01,0x00,0x17,0xfa,0x1e,0x06,0x4f,0x84,0x06,0xe0,0x07,0x48,0x64,0x03,0x01,0x01,0x03,0x9c,0x0c,0x04,0x30,0x60,0x31,0x70,0x00,0x65,0x08,0x01,0x94,0xc0,0x06,0x51,0x00,0x5b,0x48,0x00,0x65,0x04,0x01,0x95,0x00,0x82,0xd8,0x00,0x19,0x40,0x7e,0x00,0x75,0x1f,0x88,0xe0,0x88,0x02,0x1a,0x1f,0x94,0x14,0x0e,0xbf,0x98,0x58,0x5c,0x42,0x45,0x00,0x9e,0x99,0x87,0x01,0x02,0x11,0x94,0xf2,0x2e,0x03,0x18,0x39,0x28,0x70,0x1f,0xc0,0x3e,0x42,0x00,0xe5,0x80,0xff,0xdf,0xc0,0xe5,0xf8,0x85,0xd8,0x10,0x27,0x40,0xf9,0xc2,0x63,0x88,0x12,0x82,0x6a,0x20,0x50,0x41,0xe9,0x42,0x20,0x95,0x48,0x6e,0x0c,0xfa,0x9a,0xaf,0xf9,0x90,0xe2,0x10,0x2e,0xac,0xe0,0x0e,0x98,0x29,0x52,0x11,0x13,0x23,0x15,0x3e,0x20,0x3c,0x61,0x40,0x52,0xfc,0x4f,0xe2,0x10,0x38,0x68,0x1c,0xa0,0xfc,0x08,0xbe,0x04,0x1e,0x5e,0x01,0xb9,0x03,0xc5,0x60,0x24,0xf2,0x84,0x60,0x63,0x40,0x71,0x27,0x9c,0x0e,0x2b,0x04,0x6c,0xa4,0x06,0x15,0x08,0x6c,0x99,0x8c,0xa6,0x0f,0x81,0x00,0x0c,0x08,0xf0,0x3c,0x05,0x61,0xc0,0x40,0x86,0xd0,0x30,0x78,0x80,0x0c,0xc6,0x2b,0x92,0x00,0x0d,0x51,0xf0,0x2d,0x42,0x0a,0x8e,0xaa,0x34,0x0f,0x4a,0x85,0x55,0x6e,0x20,0xf3,0xd5,0x6a,0x84,0xa2,0x66,0x2a,0x05,0xf7,0xaa,0x07,0x18,0xaf,0xfb,0x7f,0xea,0xc1,0xef,0xc0,0xe3,0xea,0x80,0xf8,0x27,0xf0,0x0a,0xc0,0x1c,0x67,0xa2,0xd1,0xb1,0xc0,0x34,0x00,0x71,0x14,0x8f,0x00,0x98,0x34,0x02,0x69,0xd0,0x37,0x90,0x16,0xf1,0x00,0x06,0xe1,0x84,0x31,0x89,0x14,0xe9,0xdc,0x40,0x38,0xa4,0xc4,0x4c,0x3c,0x1f,0x88,0x8c,0x5b,0xc3,0x01,0xbc,0x40,0x3f,0xf0,0xf6,0x71,0x0c,0x0b,0xe0,0x07,0x3c,0x0a,0xf8,0xa3,0xf0,0x03,0xb8,0xd8,0x80,0xe8,0x87,0x1b,0xa8,0x1c,0x78,0x1f,0xf8,0x0e,0x7e,0x01,0x6a,0x03,0x94,0x0f,0xfd,0xa0,0x80,0x7d,0x49,0x04,0x4d,0x12,0xc0,0xfa,0x83,0x83,0xbe,0x26,0x8d,0x02,0x05,0xd5,0xff,0xff,0xeb,0xe9,0x31,0x90,0x40,0x80,}; -const uint8_t *_I_DolphinWait_61x59[] = {_I_DolphinWait_61x59_0}; - -const uint8_t _I_iButtonDolphinVerySuccess_108x52_0[] = {0x01,0x00,0xc2,0x01,0x00,0x0f,0xe2,0xfe,0x0d,0xb8,0x3e,0x02,0x06,0x0c,0x9f,0x00,0x08,0x61,0x80,0xd9,0x8c,0x00,0x86,0x60,0x0d,0x98,0x30,0x08,0x6a,0x00,0xd9,0x80,0x80,0x87,0x40,0x0c,0x8c,0x00,0x0c,0xa8,0x01,0x12,0x00,0x2d,0x00,0x22,0x70,0x20,0x6b,0xc8,0x02,0x26,0x62,0x88,0x80,0x6c,0xc9,0x24,0x0d,0x9a,0x07,0x17,0xfe,0x1d,0x68,0x40,0x6c,0xe7,0x48,0x04,0x28,0x10,0x34,0xe8,0x10,0xd1,0x11,0xc4,0x01,0xa5,0x04,0x06,0x96,0xa0,0xa6,0x24,0xc2,0x88,0x17,0x88,0x1a,0x7d,0x43,0x78,0x82,0x4a,0x40,0x03,0x20,0xb0,0xff,0x20,0x16,0xa3,0xb2,0x48,0x03,0xe4,0x0d,0x1f,0xfc,0x06,0x3a,0x0d,0x4a,0x00,0x34,0xf8,0x00,0xd1,0x37,0x0f,0x82,0x9e,0x95,0x58,0x17,0x83,0xff,0x81,0x1b,0x0f,0xf1,0xfe,0x71,0xe0,0x69,0x7c,0x3f,0xe0,0x82,0xff,0xcf,0xc0,0x85,0x61,0x80,0x43,0xb0,0x5f,0xa8,0x79,0xdc,0x81,0xa5,0x70,0xc0,0x68,0x3c,0x10,0x1a,0x17,0xd5,0x28,0x42,0xd1,0x8f,0x84,0x46,0x83,0xb0,0x8e,0x40,0x34,0x5f,0xa8,0x38,0x34,0x45,0xa2,0x0d,0x18,0x04,0x9b,0x50,0x03,0x1a,0x14,0x35,0x36,0x5f,0x8f,0xf8,0xb8,0xa4,0x19,0x40,0x18,0xe8,0xa0,0xca,0x22,0xfe,0x7f,0xc4,0x05,0x20,0xa5,0x80,0xc6,0x82,0xcb,0x3f,0xf3,0x44,0xfc,0x12,0x40,0x18,0xe8,0x51,0x82,0x52,0x28,0xfc,0x38,0x0a,0x3e,0x48,0x98,0x6c,0x8f,0x43,0x00,0xe0,0x63,0xe0,0x62,0xe2,0x91,0x90,0x0a,0x02,0x0d,0x2f,0x82,0x50,0x41,0xa3,0x80,0x90,0x41,0x04,0xc3,0x01,0xc0,0x83,0x46,0x71,0x30,0x06,0x95,0x82,0x21,0x02,0x6e,0x88,0x6c,0x43,0x83,0x1f,0x2f,0x88,0x34,0x62,0x00,0xd1,0x15,0x08,0x2c,0x60,0xcc,0x51,0x0f,0x08,0xcc,0x81,0xa2,0x12,0x10,0x68,0xc6,0x3f,0x06,0xc2,0x06,0x8e,0x02,0x16,0x41,0x20,0x10,0xf8,0x01,0x85,0x00,0x19,0x0d,0x82,0x18,0x07,0x20,0x81,0x00,0x0c,0x9c,0x31,0x08,0x42,0x74,0x81,0xab,0x80,0x03,0x0c,0x32,0x11,0x0b,0x06,0xb9,0xc0,0x43,0xa3,0x10,0x8b,0x83,0x5c,0xe0,0x20,0x81,0xc8,0x26,0x49,0x4c,0x40,0x02,0x86,0x0a,0xc5,0x22,0x32,0x50,0x6b,0x93,0x86,0xc0,0x0d,0x19,0x18,0x35,0x8c,0x84,0x79,0x1a,0x84,0x84,0x1a,0xdf,0xc2,0xe0,0x8a,0xc7,0x51,0x22,0x06,0xb5,0x5e,0x3f,0x00,0x77,0x0d,0x60,0x36,0xfa,0xa9,0xd7,0x00,0x08,0x3a,0xc9,0x02,0x48,0xc0,0x05,0x54,0xba,0x98,0x8a,0xa8,0xf1,0x20,0x6a,0x6a,0x3d,0x43,0x61,0x80,0x4a,0x81,0xaf,0x40,0xea,0x8d,0x86,0x01,0x56,0x06,0x93,0x60,0x80,0x05,0xea,0x01,0x94,0xac,0x1b,0x11,0x80,0x19,0x45,0x41,0x44,0x0d,0x58,0x33,0x18,0xa1,0x4f,0xf3,0x06,0x1f,0x01,0x76,0x58,0x00,0xd9,0x83,0x52,0x7c,0x11,0x38,0x51,0x40,0x80,}; -const uint8_t *_I_iButtonDolphinVerySuccess_108x52[] = {_I_iButtonDolphinVerySuccess_108x52_0}; +const uint8_t _I_Lock_7x8_0[] = {0x00,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[] = {0x01,0x00,0x21,0x02,0x00,0x1e,0x02,0x06,0x0e,0xcb,0x04,0x10,0x1d,0x91,0x88,0x40,0x3b,0x20,0xc0,0xec,0xc0,0x40,0x62,0x03,0xac,0x80,0x03,0xb2,0x31,0x00,0x90,0x03,0xae,0x5e,0x0e,0xcf,0xc4,0x56,0x01,0x40,0x07,0x56,0xbe,0x14,0x0e,0x2f,0xf1,0x5e,0x2a,0xa1,0xd1,0xc0,0x7c,0x3f,0xf0,0x70,0x73,0x70,0x35,0x41,0xd1,0xc0,0x7f,0xff,0xf0,0xf0,0x73,0x50,0x03,0xa4,0x0d,0x10,0x74,0x07,0x46,0x55,0xe0,0x07,0x10,0xb1,0xc3,0xa3,0x55,0xfe,0x03,0x88,0x94,0xe1,0xd1,0xd5,0x03,0x4a,0x3e,0x59,0x9e,0xaf,0xfe,0xff,0x05,0x60,0x4e,0xab,0xf5,0xff,0x95,0xb4,0xa4,0x3a,0x3f,0xd0,0xe0,0xfa,0x20,0x20,0xf8,0xd5,0xff,0xb5,0xf0,0x0f,0x88,0x3a,0x6a,0xbf,0xf8,0xaf,0x82,0x6f,0x03,0x07,0x47,0xaf,0xff,0x0a,0xfe,0x5f,0xc1,0xd3,0xf6,0xbf,0xe0,0x7f,0xfe,0xf0,0x73,0x41,0x00,0x43,0xfa,0xd7,0xf8,0x27,0xfe,0xe0,0x73,0x40,0x80,0x43,0xfe,0xab,0xfe,0x21,0xfc,0xe5,0x9b,0x05,0x48,0xea,0x3f,0xc8,0xfa,0xc4,0x66,0x07,0x44,0x0e,0x8f,0x00,0xb0,0x2b,0x31,0x07,0x0f,0x00,0x1c,0x72,0x00,0x70,0xf8,0x37,0xe5,0x81,0xff,0x89,0x08,0xf2,0x71,0x80,0x20,0xfe,0x2b,0xf0,0x5f,0xc0,0x38,0xc8,0xa5,0x60,0xc3,0x00,0xc7,0xf9,0xaf,0x81,0x2d,0x04,0x34,0x40,0xe1,0x98,0x47,0x68,0x04,0x92,0xab,0xc0,0x7e,0xb7,0xf7,0x39,0x03,0x85,0x8e,0x24,0xf1,0xc0,0x7f,0xf5,0x78,0x0f,0x53,0xb4,0xbc,0x1f,0xb8,0x1a,0x0c,0x61,0xc5,0x82,0xab,0xc0,0x3e,0xa3,0xa2,0xfc,0x07,0x46,0x09,0x60,0x19,0x8f,0x80,0xec,0x38,0x08,0x52,0x6c,0xb8,0xdc,0x28,0x7c,0x10,0x2a,0x5f,0x0f,0xfc,0x5a,0x01,0x05,0x1a,0x8e,0x02,0x02,0x1d,0x1f,0x81,0xa8,0xbe,0x13,0xf8,0x52,0x2c,0x8c,0x62,0x77,0x42,0x11,0x40,0xe0,0xca,0x93,0x8e,0x03,0x8a,0x30,0x10,0x48,0x54,0x03,0x04,0xbb,0x2c,0x00,0x0c,0x64,0x80,0xe4,0x0e,0x88,0x38,0x7c,0x10,0x04,0x09,0x48,0x83,0xac,0x1b,0x18,0xf3,0x44,0xc1,0xca,0x1d,0x15,0x40,0x8e,0x05,0x02,0x20,0xe6,0x24,0x12,0x8c,0x8b,0x05,0x21,0x07,0x24,0x14,0x08,0x73,0x80,0x19,0x78,0x43,0xb2,0xff,0x15,0x30,0xc4,0x01,0x26,0x8f,0x14,0x61,0xa9,0x8a,0x09,0x10,0x02,0x12,0x1c,0x80,0x84,0xaf,0x10,0x71,0xaa,0xc4,0x00,0x3b,0x04,0xea,0x24,0x48,0x1c,0xbd,0x8f,0xf8,0x00,0x67,0xf0,0x09,0x40,0x20,0x61,0x00,0xe4,0xf6,0x07,0x4b,0xc1,0x1f,0x07,0x14,0x40,0x1c,0x9d,0x66,0x79,0x24,0xc6,0xa0,0x0e,0x32,0x51,0xfa,0xce,0xe7,0x50,0x07,0x1c,0x80,0x30,0x58,0x0e,0xa2,0xcc,0xa0,0x19,0x00,0x71,0x42,0x13,0x27,0x40,0xf5,0x45,0x41,0xc5,0x08,0xb0,0x80,0xc6,0x18,0xf2,0x28,0x04,0x83,0xe8,0x58,0x10,0x30,0xc2,0x2c,0x40,0x91,0x89,0x3c,0x88,0x62,0x21,0xd2,0xff,0x03,0x87,0xc8,0x12,0x19,0x08,0x39,0x3e,0x83,0xb2,0x4a,0x0e,0xa2,0x0d,0xc0,0xe0,0x50,0x06,0xa7,0xe8,0x2c,0x94,0xc2,0x09,0x50,0x8c,0xce,0x20,0x34,0x70,0x71,0x41,0x3e,0x85,0xe2,0xe0,0x41,0x38,0x1e,0x28,0x3c,0x19,0xc8,0x70,0x4f,0xc1,0xdc,0xe0,0x74,0x01,0xd8,0xc6,0x24,0x00,0x82,0x81,0x7c,0x12,0xa6,0x7e,0x10,0x28,0xd8,0x22,0x00,0xe3,0xfc,0x34,0x53,0x00,0x23,0x1c,0x04,0x44,0x0e,0x50,0x10,0xeb,0x17,0xca,0x1c,0x07,0x20,}; const uint8_t *_I_DolphinMafia_115x62[] = {_I_DolphinMafia_115x62_0}; -const uint8_t _I_DolphinNice_96x59_0[] = {0x01,0x00,0x8a,0x01,0x00,0x37,0xfa,0x3e,0x0a,0x8f,0x04,0x04,0x02,0x20,0xb7,0x8c,0x00,0x86,0x1c,0x0b,0x78,0x20,0x08,0x66,0x00,0xb7,0x81,0x00,0x86,0x80,0x0b,0x71,0x61,0x60,0x01,0x4c,0x07,0x41,0xe3,0x07,0xd0,0x4e,0x40,0xb8,0x1f,0x90,0x00,0xe4,0x00,0xba,0x88,0x01,0x0e,0x10,0x0a,0x48,0xf9,0x6c,0xbe,0x10,0x70,0x82,0x78,0x3c,0x15,0x82,0x18,0xc2,0x21,0x00,0xb4,0x02,0x0e,0xbc,0x86,0x30,0x48,0x80,0xd1,0x05,0x03,0x78,0x82,0xc0,0x3e,0x52,0x32,0x63,0x70,0x20,0x70,0x09,0xd4,0x98,0xb0,0xf0,0x60,0x58,0xc9,0xce,0x12,0x0b,0xbf,0xd4,0x9d,0x28,0x9e,0x24,0xa9,0x82,0xda,0x24,0x2d,0x10,0x00,0xfd,0x2a,0x60,0xb4,0x85,0x4e,0x00,0x85,0xf8,0xd4,0x82,0xd2,0x09,0xc0,0x12,0x14,0x12,0xad,0x81,0x29,0xa8,0x90,0xf5,0x01,0x75,0x80,0x46,0x00,0xa5,0x50,0x0b,0x90,0x1c,0x41,0x63,0x60,0x05,0x96,0xc0,0x2e,0x52,0x44,0x79,0x60,0x06,0x05,0x50,0x05,0x94,0x89,0x88,0x63,0x02,0x98,0x02,0xc7,0xc1,0x21,0x6a,0x98,0xa0,0x62,0x11,0x00,0x58,0xc6,0x02,0xe2,0xb8,0x21,0x80,0xc3,0x05,0x02,0x38,0x11,0x78,0xa5,0x0b,0x01,0x81,0x5a,0x88,0x2c,0x60,0x40,0xb1,0xc0,0x27,0x0a,0xfc,0x0f,0x28,0x04,0x06,0x50,0x05,0x18,0xa9,0x94,0xc1,0x67,0x48,0x02,0x8c,0xb8,0x16,0xf8,0x80,0x28,0xd6,0x16,0x86,0x0b,0x38,0x40,0xd4,0x76,0x0c,0xd4,0x05,0x94,0x10,0x9a,0x34,0x01,0x82,0x1f,0x06,0x05,0x02,0x98,0x01,0x47,0x54,0x18,0x35,0xc8,0xff,0x20,0x3c,0x00,0x58,0xd5,0x6a,0xa0,0xb3,0x81,0xa3,0x0a,0x0f,0x80,0xd5,0xea,0x81,0x67,0x07,0x46,0x14,0xe3,0xe1,0x55,0x18,0x18,0x2c,0x51,0x85,0xc0,0xef,0x85,0x8c,0x0c,0x30,0xf4,0x61,0x40,0x2d,0x46,0xb4,0x05,0x8b,0x04,0xb0,0x15,0x40,0x5a,0x50,0x23,0xe6,0x01,0x02,0x8c,0xa8,0x2e,0xb1,0xe5,0x40,0x81,0x46,0x6a,0x17,0x59,0xeb,0xe4,0xa8,0x11,0xa0,0x5a,0x68,0x27,0x4e,0xd3,0x59,0xad,0x82,0xfa,0xed,0x2a,0x04,0x28,0x2e,0xb7,0xa7,0x69,0xc3,0x42,0xeb,0xf5,0x1f,0x09,0x4c,0x42,0xed,0xea,0x01,0x8c,0x06,0x41,0x05,0x0b,0xbc,0x02,0x0d,0x80,0x83,0x05,0xe2,0x11,0x40,0x0b,0xb7,0x14,0x06,0x33,0x0c,0x83,0x89,0x02,0xe3,0xca,0x3d,0x95,0x01,0xe2,0x21,0x74,0xc2,0x81,0x0b,0x0e,0x17,0x6c,0x10,0x10,0xaf,0x09,0xe2,0x0b,0xbb,0xd0,0x42,0xeb,0x02,}; -const uint8_t *_I_DolphinNice_96x59[] = {_I_DolphinNice_96x59_0}; +const uint8_t _I_DolphinExcited_64x63_0[] = {0x01,0x00,0x36,0x01,0x00,0x25,0x00,0x0f,0xd2,0x00,0x3b,0xe0,0x00,0xeb,0x10,0x0c,0x34,0x40,0x30,0xd0,0x88,0x80,0x1d,0xa1,0x00,0x42,0xfc,0x7f,0xc0,0x63,0x04,0x01,0x0e,0x02,0x0f,0x00,0x00,0x8c,0x08,0x0e,0x37,0x00,0x10,0xc6,0x20,0x10,0x10,0xd9,0x11,0x92,0x1c,0x1a,0x3e,0x00,0x04,0x42,0x02,0x1a,0x20,0xb0,0xce,0x00,0x64,0x07,0x20,0x59,0x16,0x50,0x36,0x45,0x94,0x84,0x78,0x20,0x60,0x75,0x8e,0x43,0x06,0x63,0x3c,0x33,0x94,0x0c,0xd2,0x5c,0x30,0x38,0xe4,0x08,0x43,0x10,0xc0,0x5e,0x06,0x22,0x53,0x1a,0x02,0x08,0x7f,0xd0,0x32,0xc1,0x50,0x21,0x14,0x0e,0x70,0x1c,0x46,0xe2,0x07,0x19,0x06,0x3c,0xdc,0x20,0x91,0xae,0x01,0xcc,0xbe,0x30,0x09,0xfc,0x12,0x41,0xff,0x83,0xcc,0x0a,0xa3,0x1f,0x03,0x99,0xe8,0x7c,0x10,0xf8,0x25,0xa0,0x5e,0x50,0x0f,0x84,0x1e,0x09,0x54,0x03,0x9f,0xf2,0x07,0x02,0xd5,0x11,0xca,0x01,0xfe,0x80,0xc0,0xaa,0x9f,0xf0,0x39,0x5f,0xd0,0x43,0xaa,0x83,0x41,0x92,0xc3,0x1f,0x03,0x8d,0x52,0x02,0x2e,0x25,0xc9,0x6a,0x99,0x46,0xa6,0x2a,0xa0,0x1c,0xaf,0xca,0x62,0x94,0x28,0xcb,0x7e,0x0f,0x15,0x71,0xf8,0x3c,0x22,0x71,0x03,0x8a,0x84,0x67,0x18,0x0f,0xac,0x1c,0x0e,0x38,0x08,0x0c,0x3e,0x01,0xae,0xbd,0x13,0x0c,0x0e,0x35,0x8e,0xa8,0x1c,0xb0,0x1f,0xf8,0x06,0x83,0xf4,0x27,0x38,0x07,0xff,0xff,0x8f,0x03,0xa0,0x4c,0x80,0xed,0x60,0x03,0xb4,0x60,0x0e,0xd0,0x60,0x3a,0x87,0x84,0x0e,0xb7,0xc2,0xfa,0x18,0x05,0x44,0x20,0x73,0xff,0xf7,0xce,0xe4,0x07,0x2d,0x52,0x2c,0x80,0xe7,0x54,0xea,0x81,0xd7,0x50,0x0f,0x7a,0xaa,0x3d,0x41,0xe2,0x07,0x5a,0x80,0x3c,0xa0,0x40,0x72,0xd0,0x6a,0x80,0xa2,0x07,0x3a,0x05,0x54,0x8e,0x20,0x73,0xc0,0x03,0xd8,0x60,0x30,0x40,0x3a,0xc0,0x00,0xee,0xea,0x10,0x3b,0x80,}; +const uint8_t *_I_DolphinExcited_64x63[] = {_I_DolphinExcited_64x63_0}; const uint8_t _I_iButtonDolphinSuccess_109x60_0[] = {0x01,0x00,0xac,0x01,0x00,0x17,0xfe,0x1e,0x0c,0xaf,0x04,0x02,0xe0,0x0d,0xa8,0xf4,0x03,0x01,0x03,0x06,0x46,0x02,0x02,0x03,0x18,0xe0,0x36,0x2c,0x00,0x36,0x00,0x2c,0x40,0x3e,0x60,0xd8,0x84,0x01,0x0c,0x5a,0x40,0x05,0x82,0x01,0x0e,0x04,0x0d,0x70,0x42,0x04,0x90,0x49,0x02,0xe4,0x20,0x41,0x28,0xc0,0x07,0x40,0x06,0xf8,0x00,0xa4,0x00,0xd6,0x03,0xa8,0x37,0x44,0x2a,0x31,0x74,0xd3,0x83,0x57,0x80,0x0d,0xc7,0x18,0xa9,0xa8,0x36,0x2a,0x86,0x06,0x8d,0xfc,0x36,0x60,0xd7,0xc0,0x3b,0x8c,0x36,0xf0,0x4a,0x05,0xf9,0x6e,0x5e,0x06,0x23,0x41,0x24,0x1f,0xf6,0x01,0x74,0x01,0xb1,0xe3,0x82,0x81,0x47,0x40,0x0d,0x7c,0x87,0x8e,0x12,0x05,0x1a,0x84,0x0d,0xb6,0xa0,0xd2,0x85,0x86,0xc8,0x1a,0x50,0x40,0x69,0x40,0xb2,0x1f,0xf0,0x69,0x50,0x01,0xa5,0x08,0xfc,0x03,0x5f,0x60,0x0d,0x28,0x84,0x1a,0x07,0x18,0x06,0xaf,0x00,0x1a,0x3c,0x03,0xb8,0xc3,0x20,0xd0,0x28,0x87,0xfc,0x8a,0x50,0x08,0x78,0x08,0x70,0x77,0x0c,0x44,0x06,0x05,0x30,0xff,0x18,0x4a,0x01,0x30,0x01,0x0d,0x33,0x19,0x11,0x1b,0x8c,0xa2,0xf8,0x7d,0x27,0x71,0xd0,0x20,0x51,0x20,0x68,0xd5,0x00,0x42,0x0d,0x2c,0x00,0x08,0x64,0x10,0x19,0x20,0x28,0x75,0x07,0x53,0x3d,0x18,0x35,0x2a,0x9f,0xf4,0x9a,0x41,0x90,0x23,0x00,0x94,0x43,0xe0,0x5e,0xae,0x03,0x9d,0xb4,0xe0,0xd1,0x0d,0x8c,0xd0,0x52,0xb1,0x00,0xd9,0x83,0x46,0x34,0x45,0x41,0xa8,0x9f,0x86,0x01,0x14,0x05,0x08,0x08,0x81,0xa6,0x62,0x10,0x68,0xe5,0x20,0x70,0x41,0x80,0x80,0x10,0xc4,0x34,0x48,0x04,0x2a,0x38,0x0d,0x99,0x16,0x02,0x1a,0xd5,0x10,0x6c,0x5e,0x2e,0x0b,0xa1,0x4b,0x0a,0x60,0xc1,0xa7,0x84,0xfc,0x58,0x01,0xb5,0x02,0x82,0xb4,0xc4,0x16,0x22,0xa5,0x06,0x96,0x19,0x20,0x20,0xd7,0x30,0x8c,0x0f,0x08,0x05,0x10,0x68,0xa1,0x44,0x1a,0x98,0x08,0x14,0x11,0x28,0x21,0x91,0x1d,0x8f,0x83,0xfe,0x07,0x1b,0x00,0x34,0x61,0x00,0xd3,0x1d,0x8c,0x7a,0x01,0x7e,0x80,0x56,0x30,0x06,0xb1,0x4a,0x08,0xd4,0xbf,0xc1,0x31,0xc0,0x7f,0xe8,0xf0,0x08,0x3c,0x40,0x1a,0x80,0x04,0x5a,0x8c,0x10,0x80,0x40,0xd7,0x05,0x08,0x36,0xc0,0xe2,0x0d,0xb8,0x30,0x34,0x45,0x82,0x0d,0x72,0x49,0x03,0x5a,0x41,0x55,0xf8,0x7f,0xff,0xe8,0x72,0x06,0xae,0x03,0xf4,0x0c,0x1d,0xf8,0x18,0x60,0x40,0xd2,0x4b,0x9f,0xd0,0x1a,0x35,0x71,0x48,0xc0,0x95,0x42,0x0d,0x4d,0x50,0x70,0x75,0x40,0xd1,0x80,0x83,0x5a,0xa1,0x55,0x00,0x0c,0x05,0xa4,0x20,0xd2,}; const uint8_t *_I_iButtonDolphinSuccess_109x60[] = {_I_iButtonDolphinSuccess_109x60_0}; -const Icon I_Certification2_119x30 = {.width=119,.height=30,.frame_count=1,.frame_rate=0,.frames=_I_Certification2_119x30}; +const uint8_t _I_iButtonDolphinVerySuccess_108x52_0[] = {0x01,0x00,0xc2,0x01,0x00,0x0f,0xe2,0xfe,0x0d,0xb8,0x3e,0x02,0x06,0x0c,0x9f,0x00,0x08,0x61,0x80,0xd9,0x8c,0x00,0x86,0x60,0x0d,0x98,0x30,0x08,0x6a,0x00,0xd9,0x80,0x80,0x87,0x40,0x0c,0x8c,0x00,0x0c,0xa8,0x01,0x12,0x00,0x2d,0x00,0x22,0x70,0x20,0x6b,0xc8,0x02,0x26,0x62,0x88,0x80,0x6c,0xc9,0x24,0x0d,0x9a,0x07,0x17,0xfe,0x1d,0x68,0x40,0x6c,0xe7,0x48,0x04,0x28,0x10,0x34,0xe8,0x10,0xd1,0x11,0xc4,0x01,0xa5,0x04,0x06,0x96,0xa0,0xa6,0x24,0xc2,0x88,0x17,0x88,0x1a,0x7d,0x43,0x78,0x82,0x4a,0x40,0x03,0x20,0xb0,0xff,0x20,0x16,0xa3,0xb2,0x48,0x03,0xe4,0x0d,0x1f,0xfc,0x06,0x3a,0x0d,0x4a,0x00,0x34,0xf8,0x00,0xd1,0x37,0x0f,0x82,0x9e,0x95,0x58,0x17,0x83,0xff,0x81,0x1b,0x0f,0xf1,0xfe,0x71,0xe0,0x69,0x7c,0x3f,0xe0,0x82,0xff,0xcf,0xc0,0x85,0x61,0x80,0x43,0xb0,0x5f,0xa8,0x79,0xdc,0x81,0xa5,0x70,0xc0,0x68,0x3c,0x10,0x1a,0x17,0xd5,0x28,0x42,0xd1,0x8f,0x84,0x46,0x83,0xb0,0x8e,0x40,0x34,0x5f,0xa8,0x38,0x34,0x45,0xa2,0x0d,0x18,0x04,0x9b,0x50,0x03,0x1a,0x14,0x35,0x36,0x5f,0x8f,0xf8,0xb8,0xa4,0x19,0x40,0x18,0xe8,0xa0,0xca,0x22,0xfe,0x7f,0xc4,0x05,0x20,0xa5,0x80,0xc6,0x82,0xcb,0x3f,0xf3,0x44,0xfc,0x12,0x40,0x18,0xe8,0x51,0x82,0x52,0x28,0xfc,0x38,0x0a,0x3e,0x48,0x98,0x6c,0x8f,0x43,0x00,0xe0,0x63,0xe0,0x62,0xe2,0x91,0x90,0x0a,0x02,0x0d,0x2f,0x82,0x50,0x41,0xa3,0x80,0x90,0x41,0x04,0xc3,0x01,0xc0,0x83,0x46,0x71,0x30,0x06,0x95,0x82,0x21,0x02,0x6e,0x88,0x6c,0x43,0x83,0x1f,0x2f,0x88,0x34,0x62,0x00,0xd1,0x15,0x08,0x2c,0x60,0xcc,0x51,0x0f,0x08,0xcc,0x81,0xa2,0x12,0x10,0x68,0xc6,0x3f,0x06,0xc2,0x06,0x8e,0x02,0x16,0x41,0x20,0x10,0xf8,0x01,0x85,0x00,0x19,0x0d,0x82,0x18,0x07,0x20,0x81,0x00,0x0c,0x9c,0x31,0x08,0x42,0x74,0x81,0xab,0x80,0x03,0x0c,0x32,0x11,0x0b,0x06,0xb9,0xc0,0x43,0xa3,0x10,0x8b,0x83,0x5c,0xe0,0x20,0x81,0xc8,0x26,0x49,0x4c,0x40,0x02,0x86,0x0a,0xc5,0x22,0x32,0x50,0x6b,0x93,0x86,0xc0,0x0d,0x19,0x18,0x35,0x8c,0x84,0x79,0x1a,0x84,0x84,0x1a,0xdf,0xc2,0xe0,0x8a,0xc7,0x51,0x22,0x06,0xb5,0x5e,0x3f,0x00,0x77,0x0d,0x60,0x36,0xfa,0xa9,0xd7,0x00,0x08,0x3a,0xc9,0x02,0x48,0xc0,0x05,0x54,0xba,0x98,0x8a,0xa8,0xf1,0x20,0x6a,0x6a,0x3d,0x43,0x61,0x80,0x4a,0x81,0xaf,0x40,0xea,0x8d,0x86,0x01,0x56,0x06,0x93,0x60,0x80,0x05,0xea,0x01,0x94,0xac,0x1b,0x11,0x80,0x19,0x45,0x41,0x44,0x0d,0x58,0x33,0x18,0xa1,0x4f,0xf3,0x06,0x1f,0x01,0x76,0x58,0x00,0xd9,0x83,0x52,0x7c,0x11,0x38,0x51,0x40,0x80,}; +const uint8_t *_I_iButtonDolphinVerySuccess_108x52[] = {_I_iButtonDolphinVerySuccess_108x52_0}; + +const uint8_t _I_iButtonKey_49x44_0[] = {0x01,0x00,0xb4,0x00,0x00,0x24,0xfc,0x0a,0x9c,0x0e,0x00,0x19,0x26,0x18,0x00,0x32,0x43,0x20,0x10,0x10,0x31,0xc0,0x80,0xc9,0x80,0x02,0x08,0x18,0xec,0x00,0x21,0x03,0x1c,0x40,0x1e,0x22,0x15,0xa0,0x08,0x56,0x40,0x06,0x30,0xc0,0x85,0x84,0x86,0x40,0x21,0x84,0x10,0xcc,0x04,0x30,0x40,0x31,0x02,0x88,0x3a,0x20,0x01,0x83,0x0d,0x94,0x06,0x26,0x03,0xf8,0x43,0xc5,0xe9,0x0c,0x11,0x08,0xbc,0xe0,0x64,0x21,0x23,0x09,0x38,0x80,0x22,0x28,0x20,0x58,0x99,0xc4,0x50,0x41,0xe1,0xc0,0x60,0xcc,0xab,0x47,0x21,0xa6,0x02,0x9e,0x06,0x22,0x70,0xf0,0x00,0xcb,0x40,0x03,0x18,0xb0,0x78,0x14,0xe0,0x32,0x58,0x28,0xa5,0x84,0xd0,0x51,0x80,0xc9,0x30,0x06,0xae,0x62,0x84,0x06,0x48,0x64,0x88,0x0c,0x90,0x29,0x08,0x19,0x30,0x31,0x13,0x71,0xb8,0xc4,0xea,0x70,0x6b,0xc5,0x01,0x4a,0x7f,0xc8,0x7c,0x81,0x4a,0x77,0x8a,0xac,0x45,0x4a,0x7f,0x08,0x54,0x39,0x4a,0x7e,0x0e,0xa9,0xf0,0xcb,0xe3,0x7f,0x6e,0x22,0x5c,0x59,0x44,0x00,0x28,0x7a,0xd4,0x40,0x07,0xf0,0x02,0xa0,}; +const uint8_t *_I_iButtonKey_49x44[] = {_I_iButtonKey_49x44_0}; + +const uint8_t _I_DolphinNice_96x59_0[] = {0x01,0x00,0x8a,0x01,0x00,0x37,0xfa,0x3e,0x0a,0x8f,0x04,0x04,0x02,0x20,0xb7,0x8c,0x00,0x86,0x1c,0x0b,0x78,0x20,0x08,0x66,0x00,0xb7,0x81,0x00,0x86,0x80,0x0b,0x71,0x61,0x60,0x01,0x4c,0x07,0x41,0xe3,0x07,0xd0,0x4e,0x40,0xb8,0x1f,0x90,0x00,0xe4,0x00,0xba,0x88,0x01,0x0e,0x10,0x0a,0x48,0xf9,0x6c,0xbe,0x10,0x70,0x82,0x78,0x3c,0x15,0x82,0x18,0xc2,0x21,0x00,0xb4,0x02,0x0e,0xbc,0x86,0x30,0x48,0x80,0xd1,0x05,0x03,0x78,0x82,0xc0,0x3e,0x52,0x32,0x63,0x70,0x20,0x70,0x09,0xd4,0x98,0xb0,0xf0,0x60,0x58,0xc9,0xce,0x12,0x0b,0xbf,0xd4,0x9d,0x28,0x9e,0x24,0xa9,0x82,0xda,0x24,0x2d,0x10,0x00,0xfd,0x2a,0x60,0xb4,0x85,0x4e,0x00,0x85,0xf8,0xd4,0x82,0xd2,0x09,0xc0,0x12,0x14,0x12,0xad,0x81,0x29,0xa8,0x90,0xf5,0x01,0x75,0x80,0x46,0x00,0xa5,0x50,0x0b,0x90,0x1c,0x41,0x63,0x60,0x05,0x96,0xc0,0x2e,0x52,0x44,0x79,0x60,0x06,0x05,0x50,0x05,0x94,0x89,0x88,0x63,0x02,0x98,0x02,0xc7,0xc1,0x21,0x6a,0x98,0xa0,0x62,0x11,0x00,0x58,0xc6,0x02,0xe2,0xb8,0x21,0x80,0xc3,0x05,0x02,0x38,0x11,0x78,0xa5,0x0b,0x01,0x81,0x5a,0x88,0x2c,0x60,0x40,0xb1,0xc0,0x27,0x0a,0xfc,0x0f,0x28,0x04,0x06,0x50,0x05,0x18,0xa9,0x94,0xc1,0x67,0x48,0x02,0x8c,0xb8,0x16,0xf8,0x80,0x28,0xd6,0x16,0x86,0x0b,0x38,0x40,0xd4,0x76,0x0c,0xd4,0x05,0x94,0x10,0x9a,0x34,0x01,0x82,0x1f,0x06,0x05,0x02,0x98,0x01,0x47,0x54,0x18,0x35,0xc8,0xff,0x20,0x3c,0x00,0x58,0xd5,0x6a,0xa0,0xb3,0x81,0xa3,0x0a,0x0f,0x80,0xd5,0xea,0x81,0x67,0x07,0x46,0x14,0xe3,0xe1,0x55,0x18,0x18,0x2c,0x51,0x85,0xc0,0xef,0x85,0x8c,0x0c,0x30,0xf4,0x61,0x40,0x2d,0x46,0xb4,0x05,0x8b,0x04,0xb0,0x15,0x40,0x5a,0x50,0x23,0xe6,0x01,0x02,0x8c,0xa8,0x2e,0xb1,0xe5,0x40,0x81,0x46,0x6a,0x17,0x59,0xeb,0xe4,0xa8,0x11,0xa0,0x5a,0x68,0x27,0x4e,0xd3,0x59,0xad,0x82,0xfa,0xed,0x2a,0x04,0x28,0x2e,0xb7,0xa7,0x69,0xc3,0x42,0xeb,0xf5,0x1f,0x09,0x4c,0x42,0xed,0xea,0x01,0x8c,0x06,0x41,0x05,0x0b,0xbc,0x02,0x0d,0x80,0x83,0x05,0xe2,0x11,0x40,0x0b,0xb7,0x14,0x06,0x33,0x0c,0x83,0x89,0x02,0xe3,0xca,0x3d,0x95,0x01,0xe2,0x21,0x74,0xc2,0x81,0x0b,0x0e,0x17,0x6c,0x10,0x10,0xaf,0x09,0xe2,0x0b,0xbb,0xd0,0x42,0xeb,0x02,}; +const uint8_t *_I_DolphinNice_96x59[] = {_I_DolphinNice_96x59_0}; + +const uint8_t _I_DolphinWait_61x59_0[] = {0x01,0x00,0x56,0x01,0x00,0x17,0xfa,0x1e,0x06,0x4f,0x84,0x06,0xe0,0x07,0x48,0x64,0x03,0x01,0x01,0x03,0x9c,0x0c,0x04,0x30,0x60,0x31,0x70,0x00,0x65,0x08,0x01,0x94,0xc0,0x06,0x51,0x00,0x5b,0x48,0x00,0x65,0x04,0x01,0x95,0x00,0x82,0xd8,0x00,0x19,0x40,0x7e,0x00,0x75,0x1f,0x88,0xe0,0x88,0x02,0x1a,0x1f,0x94,0x14,0x0e,0xbf,0x98,0x58,0x5c,0x42,0x45,0x00,0x9e,0x99,0x87,0x01,0x02,0x11,0x94,0xf2,0x2e,0x03,0x18,0x39,0x28,0x70,0x1f,0xc0,0x3e,0x42,0x00,0xe5,0x80,0xff,0xdf,0xc0,0xe5,0xf8,0x85,0xd8,0x10,0x27,0x40,0xf9,0xc2,0x63,0x88,0x12,0x82,0x6a,0x20,0x50,0x41,0xe9,0x42,0x20,0x95,0x48,0x6e,0x0c,0xfa,0x9a,0xaf,0xf9,0x90,0xe2,0x10,0x2e,0xac,0xe0,0x0e,0x98,0x29,0x52,0x11,0x13,0x23,0x15,0x3e,0x20,0x3c,0x61,0x40,0x52,0xfc,0x4f,0xe2,0x10,0x38,0x68,0x1c,0xa0,0xfc,0x08,0xbe,0x04,0x1e,0x5e,0x01,0xb9,0x03,0xc5,0x60,0x24,0xf2,0x84,0x60,0x63,0x40,0x71,0x27,0x9c,0x0e,0x2b,0x04,0x6c,0xa4,0x06,0x15,0x08,0x6c,0x99,0x8c,0xa6,0x0f,0x81,0x00,0x0c,0x08,0xf0,0x3c,0x05,0x61,0xc0,0x40,0x86,0xd0,0x30,0x78,0x80,0x0c,0xc6,0x2b,0x92,0x00,0x0d,0x51,0xf0,0x2d,0x42,0x0a,0x8e,0xaa,0x34,0x0f,0x4a,0x85,0x55,0x6e,0x20,0xf3,0xd5,0x6a,0x84,0xa2,0x66,0x2a,0x05,0xf7,0xaa,0x07,0x18,0xaf,0xfb,0x7f,0xea,0xc1,0xef,0xc0,0xe3,0xea,0x80,0xf8,0x27,0xf0,0x0a,0xc0,0x1c,0x67,0xa2,0xd1,0xb1,0xc0,0x34,0x00,0x71,0x14,0x8f,0x00,0x98,0x34,0x02,0x69,0xd0,0x37,0x90,0x16,0xf1,0x00,0x06,0xe1,0x84,0x31,0x89,0x14,0xe9,0xdc,0x40,0x38,0xa4,0xc4,0x4c,0x3c,0x1f,0x88,0x8c,0x5b,0xc3,0x01,0xbc,0x40,0x3f,0xf0,0xf6,0x71,0x0c,0x0b,0xe0,0x07,0x3c,0x0a,0xf8,0xa3,0xf0,0x03,0xb8,0xd8,0x80,0xe8,0x87,0x1b,0xa8,0x1c,0x78,0x1f,0xf8,0x0e,0x7e,0x01,0x6a,0x03,0x94,0x0f,0xfd,0xa0,0x80,0x7d,0x49,0x04,0x4d,0x12,0xc0,0xfa,0x83,0x83,0xbe,0x26,0x8d,0x02,0x05,0xd5,0xff,0xff,0xeb,0xe9,0x31,0x90,0x40,0x80,}; +const uint8_t *_I_DolphinWait_61x59[] = {_I_DolphinWait_61x59_0}; + const Icon I_Certification1_103x23 = {.width=103,.height=23,.frame_count=1,.frame_rate=0,.frames=_I_Certification1_103x23}; +const Icon I_Certification2_119x30 = {.width=119,.height=30,.frame_count=1,.frame_rate=0,.frames=_I_Certification2_119x30}; const Icon A_BadBattery_128x51 = {.width=128,.height=51,.frame_count=2,.frame_rate=2,.frames=_A_BadBattery_128x51}; const Icon A_BoxActive_128x51 = {.width=128,.height=51,.frame_count=2,.frame_rate=2,.frames=_A_BoxActive_128x51}; const Icon A_Box_128x51 = {.width=128,.height=51,.frame_count=4,.frame_rate=2,.frames=_A_Box_128x51}; @@ -805,20 +838,20 @@ const Icon A_Level3HijackActive_128x51 = {.width=128,.height=51,.frame_count=2,. const Icon A_Level3Hijack_128x51 = {.width=128,.height=51,.frame_count=3,.frame_rate=2,.frames=_A_Level3Hijack_128x51}; const Icon A_Level3LabActive_128x51 = {.width=128,.height=51,.frame_count=2,.frame_rate=2,.frames=_A_Level3LabActive_128x51}; const Icon A_Level3Lab_128x51 = {.width=128,.height=51,.frame_count=3,.frame_rate=2,.frames=_A_Level3Lab_128x51}; -const Icon I_LevelUp2_04 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_04}; -const Icon I_LevelUp2_03 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_03}; const Icon I_LevelUp2_07 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_07}; -const Icon I_LevelUp2_05 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_05}; -const Icon I_LevelUp2_02 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_02}; const Icon I_LevelUp2_06 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_06}; +const Icon I_LevelUp2_04 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_04}; +const Icon I_LevelUp2_05 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_05}; const Icon I_LevelUp2_01 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_01}; -const Icon I_LevelUp3_07 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_07}; -const Icon I_LevelUp3_02 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_02}; -const Icon I_LevelUp3_04 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_04}; +const Icon I_LevelUp2_02 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_02}; +const Icon I_LevelUp2_03 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp2_03}; const Icon I_LevelUp3_05 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_05}; -const Icon I_LevelUp3_01 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_01}; -const Icon I_LevelUp3_03 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_03}; +const Icon I_LevelUp3_04 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_04}; const Icon I_LevelUp3_06 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_06}; +const Icon I_LevelUp3_07 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_07}; +const Icon I_LevelUp3_03 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_03}; +const Icon I_LevelUp3_02 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_02}; +const Icon I_LevelUp3_01 = {.width=128,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_LevelUp3_01}; const Icon A_LevelUpPending_128x51 = {.width=128,.height=51,.frame_count=2,.frame_rate=2,.frames=_A_LevelUpPending_128x51}; const Icon A_NoSdCard_128x51 = {.width=128,.height=51,.frame_count=2,.frame_rate=2,.frames=_A_NoSdCard_128x51}; const Icon A_SleepActive_128x52 = {.width=128,.height=52,.frame_count=5,.frame_rate=2,.frames=_A_SleepActive_128x52}; @@ -827,79 +860,79 @@ const Icon A_TvActive_128x52 = {.width=128,.height=52,.frame_count=6,.frame_rate const Icon A_Tv_128x52 = {.width=128,.height=52,.frame_count=6,.frame_rate=2,.frames=_A_Tv_128x52}; const Icon A_WavesActive_128x52 = {.width=128,.height=52,.frame_count=7,.frame_rate=2,.frames=_A_WavesActive_128x52}; const Icon A_Waves_128x52 = {.width=128,.height=52,.frame_count=2,.frame_rate=2,.frames=_A_Waves_128x52}; +const Icon I_dir_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_dir_10px}; +const Icon I_Nfc_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_Nfc_10px}; const Icon I_sub1_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_sub1_10px}; const Icon I_ir_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_ir_10px}; -const Icon I_unknown_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_unknown_10px}; const Icon I_ibutt_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_ibutt_10px}; -const Icon I_Nfc_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_Nfc_10px}; +const Icon I_unknown_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_unknown_10px}; const Icon I_ble_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_ble_10px}; const Icon I_125_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_125_10px}; -const Icon I_dir_10px = {.width=10,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_dir_10px}; const Icon I_BLE_Pairing_128x64 = {.width=128,.height=64,.frame_count=1,.frame_rate=0,.frames=_I_BLE_Pairing_128x64}; +const Icon I_UsbTree_48x22 = {.width=48,.height=22,.frame_count=1,.frame_rate=0,.frames=_I_UsbTree_48x22}; +const Icon I_EviWaiting2_18x21 = {.width=18,.height=21,.frame_count=1,.frame_rate=0,.frames=_I_EviWaiting2_18x21}; +const Icon I_Clock_18x18 = {.width=18,.height=18,.frame_count=1,.frame_rate=0,.frames=_I_Clock_18x18}; +const Icon I_Smile_18x18 = {.width=18,.height=18,.frame_count=1,.frame_rate=0,.frames=_I_Smile_18x18}; +const Icon I_EviSmile1_18x21 = {.width=18,.height=21,.frame_count=1,.frame_rate=0,.frames=_I_EviSmile1_18x21}; +const Icon I_Percent_10x14 = {.width=10,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_Percent_10x14}; +const Icon I_Error_18x18 = {.width=18,.height=18,.frame_count=1,.frame_rate=0,.frames=_I_Error_18x18}; const Icon I_EviWaiting1_18x21 = {.width=18,.height=21,.frame_count=1,.frame_rate=0,.frames=_I_EviWaiting1_18x21}; const Icon I_EviSmile2_18x21 = {.width=18,.height=21,.frame_count=1,.frame_rate=0,.frames=_I_EviSmile2_18x21}; -const Icon I_Error_18x18 = {.width=18,.height=18,.frame_count=1,.frame_rate=0,.frames=_I_Error_18x18}; -const Icon I_Percent_10x14 = {.width=10,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_Percent_10x14}; -const Icon I_EviSmile1_18x21 = {.width=18,.height=21,.frame_count=1,.frame_rate=0,.frames=_I_EviSmile1_18x21}; -const Icon I_EviWaiting2_18x21 = {.width=18,.height=21,.frame_count=1,.frame_rate=0,.frames=_I_EviWaiting2_18x21}; -const Icon I_UsbTree_48x22 = {.width=48,.height=22,.frame_count=1,.frame_rate=0,.frames=_I_UsbTree_48x22}; -const Icon I_Smile_18x18 = {.width=18,.height=18,.frame_count=1,.frame_rate=0,.frames=_I_Smile_18x18}; -const Icon I_Clock_18x18 = {.width=18,.height=18,.frame_count=1,.frame_rate=0,.frames=_I_Clock_18x18}; -const Icon I_ButtonDown_7x4 = {.width=7,.height=4,.frame_count=1,.frame_rate=0,.frames=_I_ButtonDown_7x4}; -const Icon I_ButtonCenter_7x7 = {.width=7,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_ButtonCenter_7x7}; -const Icon I_ButtonLeft_4x7 = {.width=4,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_ButtonLeft_4x7}; -const Icon I_ButtonUp_7x4 = {.width=7,.height=4,.frame_count=1,.frame_rate=0,.frames=_I_ButtonUp_7x4}; -const Icon I_DFU_128x50 = {.width=128,.height=50,.frame_count=1,.frame_rate=0,.frames=_I_DFU_128x50}; -const Icon I_ButtonLeftSmall_3x5 = {.width=3,.height=5,.frame_count=1,.frame_rate=0,.frames=_I_ButtonLeftSmall_3x5}; const Icon I_ButtonRightSmall_3x5 = {.width=3,.height=5,.frame_count=1,.frame_rate=0,.frames=_I_ButtonRightSmall_3x5}; -const Icon I_ButtonRight_4x7 = {.width=4,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_ButtonRight_4x7}; +const Icon I_ButtonLeft_4x7 = {.width=4,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_ButtonLeft_4x7}; +const Icon I_ButtonLeftSmall_3x5 = {.width=3,.height=5,.frame_count=1,.frame_rate=0,.frames=_I_ButtonLeftSmall_3x5}; +const Icon I_DFU_128x50 = {.width=128,.height=50,.frame_count=1,.frame_rate=0,.frames=_I_DFU_128x50}; const Icon I_Warning_30x23 = {.width=30,.height=23,.frame_count=1,.frame_rate=0,.frames=_I_Warning_30x23}; +const Icon I_ButtonDown_7x4 = {.width=7,.height=4,.frame_count=1,.frame_rate=0,.frames=_I_ButtonDown_7x4}; +const Icon I_ButtonRight_4x7 = {.width=4,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_ButtonRight_4x7}; +const Icon I_ButtonCenter_7x7 = {.width=7,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_ButtonCenter_7x7}; +const Icon I_ButtonUp_7x4 = {.width=7,.height=4,.frame_count=1,.frame_rate=0,.frames=_I_ButtonUp_7x4}; +const Icon I_DolphinOkay_41x43 = {.width=41,.height=43,.frame_count=1,.frame_rate=0,.frames=_I_DolphinOkay_41x43}; +const Icon I_DolphinFirstStart4_67x53 = {.width=67,.height=53,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart4_67x53}; const Icon I_DolphinFirstStart2_59x51 = {.width=59,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart2_59x51}; const Icon I_DolphinFirstStart5_54x49 = {.width=54,.height=49,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart5_54x49}; -const Icon I_DolphinFirstStart6_58x54 = {.width=58,.height=54,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart6_58x54}; -const Icon I_Flipper_young_80x60 = {.width=80,.height=60,.frame_count=1,.frame_rate=0,.frames=_I_Flipper_young_80x60}; -const Icon I_DolphinFirstStart8_56x51 = {.width=56,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart8_56x51}; -const Icon I_DolphinFirstStart1_59x53 = {.width=59,.height=53,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart1_59x53}; -const Icon I_DolphinOkay_41x43 = {.width=41,.height=43,.frame_count=1,.frame_rate=0,.frames=_I_DolphinOkay_41x43}; -const Icon I_DolphinFirstStart3_57x48 = {.width=57,.height=48,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart3_57x48}; -const Icon I_DolphinFirstStart7_61x51 = {.width=61,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart7_61x51}; const Icon I_DolphinFirstStart0_70x53 = {.width=70,.height=53,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart0_70x53}; -const Icon I_DolphinFirstStart4_67x53 = {.width=67,.height=53,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart4_67x53}; -const Icon I_ArrowUpEmpty_14x15 = {.width=14,.height=15,.frame_count=1,.frame_rate=0,.frames=_I_ArrowUpEmpty_14x15}; +const Icon I_DolphinFirstStart6_58x54 = {.width=58,.height=54,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart6_58x54}; +const Icon I_DolphinFirstStart1_59x53 = {.width=59,.height=53,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart1_59x53}; +const Icon I_DolphinFirstStart8_56x51 = {.width=56,.height=51,.frame_count=1,.frame_rate=0,.frames=_I_DolphinFirstStart8_56x51}; +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_ArrowUpFilled_14x15 = {.width=14,.height=15,.frame_count=1,.frame_rate=0,.frames=_I_ArrowUpFilled_14x15}; -const Icon I_ArrowDownFilled_14x15 = {.width=14,.height=15,.frame_count=1,.frame_rate=0,.frames=_I_ArrowDownFilled_14x15}; +const Icon I_ArrowUpEmpty_14x15 = {.width=14,.height=15,.frame_count=1,.frame_rate=0,.frames=_I_ArrowUpEmpty_14x15}; const Icon I_ArrowDownEmpty_14x15 = {.width=14,.height=15,.frame_count=1,.frame_rate=0,.frames=_I_ArrowDownEmpty_14x15}; +const Icon I_ArrowDownFilled_14x15 = {.width=14,.height=15,.frame_count=1,.frame_rate=0,.frames=_I_ArrowDownFilled_14x15}; const Icon I_PassportBottom_128x17 = {.width=128,.height=17,.frame_count=1,.frame_rate=0,.frames=_I_PassportBottom_128x17}; -const Icon I_DoorLeft_70x55 = {.width=70,.height=55,.frame_count=1,.frame_rate=0,.frames=_I_DoorLeft_70x55}; -const Icon I_DoorRight_70x55 = {.width=70,.height=55,.frame_count=1,.frame_rate=0,.frames=_I_DoorRight_70x55}; const Icon I_DoorLocked_10x56 = {.width=10,.height=56,.frame_count=1,.frame_rate=0,.frames=_I_DoorLocked_10x56}; +const Icon I_DoorLeft_70x55 = {.width=70,.height=55,.frame_count=1,.frame_rate=0,.frames=_I_DoorLeft_70x55}; const Icon I_PassportLeft_6x47 = {.width=6,.height=47,.frame_count=1,.frame_rate=0,.frames=_I_PassportLeft_6x47}; +const Icon I_DoorRight_70x55 = {.width=70,.height=55,.frame_count=1,.frame_rate=0,.frames=_I_DoorRight_70x55}; const Icon I_LockPopup_100x49 = {.width=100,.height=49,.frame_count=1,.frame_rate=0,.frames=_I_LockPopup_100x49}; -const Icon I_Down_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Down_hvr_25x27}; -const Icon I_Vol_down_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_down_hvr_25x27}; -const Icon I_Down_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Down_25x27}; -const Icon I_Fill_marker_7x7 = {.width=7,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_Fill_marker_7x7}; -const Icon I_Vol_down_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_down_25x27}; -const Icon I_Vol_up_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_up_25x27}; +const Icon I_Mute_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Mute_25x27}; +const Icon I_IrdaArrowUp_4x8 = {.width=8,.height=4,.frame_count=1,.frame_rate=0,.frames=_I_IrdaArrowUp_4x8}; const Icon I_Up_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Up_hvr_25x27}; -const Icon I_Vol_up_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_up_hvr_25x27}; -const Icon I_IrdaLearnShort_128x31 = {.width=128,.height=31,.frame_count=1,.frame_rate=0,.frames=_I_IrdaLearnShort_128x31}; -const Icon I_IrdaSend_128x64 = {.width=128,.height=64,.frame_count=1,.frame_rate=0,.frames=_I_IrdaSend_128x64}; const Icon I_DolphinReadingSuccess_59x63 = {.width=59,.height=63,.frame_count=1,.frame_rate=0,.frames=_I_DolphinReadingSuccess_59x63}; const Icon I_Mute_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Mute_hvr_25x27}; -const Icon I_Back_15x10 = {.width=15,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_Back_15x10}; -const Icon I_Up_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Up_25x27}; -const Icon I_IrdaArrowUp_4x8 = {.width=8,.height=4,.frame_count=1,.frame_rate=0,.frames=_I_IrdaArrowUp_4x8}; -const Icon I_Mute_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Mute_25x27}; -const Icon I_Power_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Power_25x27}; -const Icon I_IrdaSendShort_128x34 = {.width=128,.height=34,.frame_count=1,.frame_rate=0,.frames=_I_IrdaSendShort_128x34}; -const Icon I_IrdaArrowDown_4x8 = {.width=8,.height=4,.frame_count=1,.frame_rate=0,.frames=_I_IrdaArrowDown_4x8}; -const Icon I_IrdaLearn_128x64 = {.width=128,.height=64,.frame_count=1,.frame_rate=0,.frames=_I_IrdaLearn_128x64}; +const Icon I_Vol_down_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_down_25x27}; +const Icon I_Down_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Down_25x27}; const Icon I_Power_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Power_hvr_25x27}; +const Icon I_IrdaLearnShort_128x31 = {.width=128,.height=31,.frame_count=1,.frame_rate=0,.frames=_I_IrdaLearnShort_128x31}; +const Icon I_IrdaArrowDown_4x8 = {.width=8,.height=4,.frame_count=1,.frame_rate=0,.frames=_I_IrdaArrowDown_4x8}; +const Icon I_Vol_down_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_down_hvr_25x27}; +const Icon I_IrdaLearn_128x64 = {.width=128,.height=64,.frame_count=1,.frame_rate=0,.frames=_I_IrdaLearn_128x64}; +const Icon I_Down_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Down_hvr_25x27}; +const Icon I_Fill_marker_7x7 = {.width=7,.height=7,.frame_count=1,.frame_rate=0,.frames=_I_Fill_marker_7x7}; +const Icon I_Power_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Power_25x27}; +const Icon I_Vol_up_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_up_25x27}; +const Icon I_Up_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Up_25x27}; +const Icon I_Back_15x10 = {.width=15,.height=10,.frame_count=1,.frame_rate=0,.frames=_I_Back_15x10}; +const Icon I_IrdaSend_128x64 = {.width=128,.height=64,.frame_count=1,.frame_rate=0,.frames=_I_IrdaSend_128x64}; +const Icon I_IrdaSendShort_128x34 = {.width=128,.height=34,.frame_count=1,.frame_rate=0,.frames=_I_IrdaSendShort_128x34}; +const Icon I_Vol_up_hvr_25x27 = {.width=25,.height=27,.frame_count=1,.frame_rate=0,.frames=_I_Vol_up_hvr_25x27}; +const Icon I_KeySave_24x11 = {.width=24,.height=11,.frame_count=1,.frame_rate=0,.frames=_I_KeySave_24x11}; +const Icon I_KeyBackspaceSelected_16x9 = {.width=16,.height=9,.frame_count=1,.frame_rate=0,.frames=_I_KeyBackspaceSelected_16x9}; const Icon I_KeySaveSelected_24x11 = {.width=24,.height=11,.frame_count=1,.frame_rate=0,.frames=_I_KeySaveSelected_24x11}; const Icon I_KeyBackspace_16x9 = {.width=16,.height=9,.frame_count=1,.frame_rate=0,.frames=_I_KeyBackspace_16x9}; -const Icon I_KeyBackspaceSelected_16x9 = {.width=16,.height=9,.frame_count=1,.frame_rate=0,.frames=_I_KeyBackspaceSelected_16x9}; -const Icon I_KeySave_24x11 = {.width=24,.height=11,.frame_count=1,.frame_rate=0,.frames=_I_KeySave_24x11}; const Icon A_125khz_14 = {.width=14,.height=14,.frame_count=4,.frame_rate=3,.frames=_A_125khz_14}; const Icon A_BadUsb_14 = {.width=14,.height=14,.frame_count=11,.frame_rate=3,.frames=_A_BadUsb_14}; const Icon A_Bluetooth_14 = {.width=14,.height=14,.frame_count=6,.frame_rate=3,.frames=_A_Bluetooth_14}; @@ -919,44 +952,55 @@ const Icon A_U2F_14 = {.width=14,.height=14,.frame_count=4,.frame_rate=3,.frames const Icon A_iButton_14 = {.width=14,.height=14,.frame_count=7,.frame_rate=3,.frames=_A_iButton_14}; const Icon I_Detailed_chip_17x13 = {.width=17,.height=13,.frame_count=1,.frame_rate=0,.frames=_I_Detailed_chip_17x13}; const Icon I_Medium_chip_22x21 = {.width=22,.height=21,.frame_count=1,.frame_rate=0,.frames=_I_Medium_chip_22x21}; -const Icon I_BatteryBody_52x28 = {.width=52,.height=28,.frame_count=1,.frame_rate=0,.frames=_I_BatteryBody_52x28}; -const Icon I_FaceCharging_29x14 = {.width=29,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_FaceCharging_29x14}; +const Icon I_passport_happy1_46x49 = {.width=46,.height=49,.frame_count=1,.frame_rate=0,.frames=_I_passport_happy1_46x49}; +const Icon I_passport_bad3_46x49 = {.width=46,.height=49,.frame_count=1,.frame_rate=0,.frames=_I_passport_bad3_46x49}; +const Icon I_passport_okay2_46x49 = {.width=46,.height=49,.frame_count=1,.frame_rate=0,.frames=_I_passport_okay2_46x49}; +const Icon I_passport_bad2_46x49 = {.width=46,.height=49,.frame_count=1,.frame_rate=0,.frames=_I_passport_bad2_46x49}; +const Icon I_passport_okay3_46x49 = {.width=46,.height=49,.frame_count=1,.frame_rate=0,.frames=_I_passport_okay3_46x49}; +const Icon I_passport_bottom_128x18 = {.width=128,.height=18,.frame_count=1,.frame_rate=0,.frames=_I_passport_bottom_128x18}; +const Icon I_passport_bad1_46x49 = {.width=46,.height=49,.frame_count=1,.frame_rate=0,.frames=_I_passport_bad1_46x49}; +const Icon I_passport_happy3_46x49 = {.width=46,.height=49,.frame_count=1,.frame_rate=0,.frames=_I_passport_happy3_46x49}; +const Icon I_passport_happy2_46x49 = {.width=46,.height=49,.frame_count=1,.frame_rate=0,.frames=_I_passport_happy2_46x49}; +const Icon I_passport_okay1_46x49 = {.width=46,.height=49,.frame_count=1,.frame_rate=0,.frames=_I_passport_okay1_46x49}; +const Icon I_passport_left_6x46 = {.width=6,.height=46,.frame_count=1,.frame_rate=0,.frames=_I_passport_left_6x46}; const Icon I_Health_16x16 = {.width=16,.height=16,.frame_count=1,.frame_rate=0,.frames=_I_Health_16x16}; +const Icon I_FaceCharging_29x14 = {.width=29,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_FaceCharging_29x14}; +const Icon I_BatteryBody_52x28 = {.width=52,.height=28,.frame_count=1,.frame_rate=0,.frames=_I_BatteryBody_52x28}; +const Icon I_Voltage_16x16 = {.width=16,.height=16,.frame_count=1,.frame_rate=0,.frames=_I_Voltage_16x16}; const Icon I_Temperature_16x16 = {.width=16,.height=16,.frame_count=1,.frame_rate=0,.frames=_I_Temperature_16x16}; +const Icon I_FaceNopower_29x14 = {.width=29,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_FaceNopower_29x14}; +const Icon I_FaceNormal_29x14 = {.width=29,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_FaceNormal_29x14}; const Icon I_Battery_16x16 = {.width=16,.height=16,.frame_count=1,.frame_rate=0,.frames=_I_Battery_16x16}; const Icon I_FaceConfused_29x14 = {.width=29,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_FaceConfused_29x14}; -const Icon I_FaceNormal_29x14 = {.width=29,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_FaceNormal_29x14}; -const Icon I_Voltage_16x16 = {.width=16,.height=16,.frame_count=1,.frame_rate=0,.frames=_I_Voltage_16x16}; -const Icon I_FaceNopower_29x14 = {.width=29,.height=14,.frame_count=1,.frame_rate=0,.frames=_I_FaceNopower_29x14}; -const Icon I_RFIDDolphinSend_97x61 = {.width=97,.height=61,.frame_count=1,.frame_rate=0,.frames=_I_RFIDDolphinSend_97x61}; const Icon I_RFIDDolphinSuccess_108x57 = {.width=108,.height=57,.frame_count=1,.frame_rate=0,.frames=_I_RFIDDolphinSuccess_108x57}; -const Icon I_RFIDDolphinReceive_97x61 = {.width=97,.height=61,.frame_count=1,.frame_rate=0,.frames=_I_RFIDDolphinReceive_97x61}; const Icon I_RFIDBigChip_37x36 = {.width=37,.height=36,.frame_count=1,.frame_rate=0,.frames=_I_RFIDBigChip_37x36}; +const Icon I_RFIDDolphinSend_97x61 = {.width=97,.height=61,.frame_count=1,.frame_rate=0,.frames=_I_RFIDDolphinSend_97x61}; +const Icon I_RFIDDolphinReceive_97x61 = {.width=97,.height=61,.frame_count=1,.frame_rate=0,.frames=_I_RFIDDolphinReceive_97x61}; const Icon I_SDQuestion_35x43 = {.width=35,.height=43,.frame_count=1,.frame_rate=0,.frames=_I_SDQuestion_35x43}; const Icon I_SDError_43x35 = {.width=43,.height=35,.frame_count=1,.frame_rate=0,.frames=_I_SDError_43x35}; const Icon I_Cry_dolph_55x52 = {.width=55,.height=52,.frame_count=1,.frame_rate=0,.frames=_I_Cry_dolph_55x52}; -const Icon I_Background_128x11 = {.width=128,.height=11,.frame_count=1,.frame_rate=0,.frames=_I_Background_128x11}; +const Icon I_BadUsb_9x8 = {.width=9,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_BadUsb_9x8}; +const Icon I_PlaceholderR_30x13 = {.width=30,.height=13,.frame_count=1,.frame_rate=0,.frames=_I_PlaceholderR_30x13}; const Icon I_Lock_8x8 = {.width=8,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Lock_8x8}; const Icon I_Battery_26x8 = {.width=26,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Battery_26x8}; -const Icon I_Battery_19x8 = {.width=19,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Battery_19x8}; -const Icon I_USBConnected_15x8 = {.width=15,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_USBConnected_15x8}; -const Icon I_BadUsb_9x8 = {.width=9,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_BadUsb_9x8}; -const Icon I_BT_Pair_9x8 = {.width=9,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_BT_Pair_9x8}; const Icon I_PlaceholderL_11x13 = {.width=11,.height=13,.frame_count=1,.frame_rate=0,.frames=_I_PlaceholderL_11x13}; -const Icon I_SDcardFail_11x8 = {.width=11,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_SDcardFail_11x8}; -const Icon I_Bluetooth_5x8 = {.width=5,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Bluetooth_5x8}; -const Icon I_PlaceholderR_30x13 = {.width=30,.height=13,.frame_count=1,.frame_rate=0,.frames=_I_PlaceholderR_30x13}; +const Icon I_Battery_19x8 = {.width=19,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Battery_19x8}; const Icon I_SDcardMounted_11x8 = {.width=11,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_SDcardMounted_11x8}; -const Icon I_Quest_7x8 = {.width=7,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Quest_7x8}; -const Icon I_Lock_7x8 = {.width=7,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_Lock_7x8}; +const Icon I_SDcardFail_11x8 = {.width=11,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_SDcardFail_11x8}; +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_BT_Pair_9x8 = {.width=9,.height=8,.frame_count=1,.frame_rate=0,.frames=_I_BT_Pair_9x8}; +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_MHz_25x11 = {.width=25,.height=11,.frame_count=1,.frame_rate=0,.frames=_I_MHz_25x11}; +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_iButtonKey_49x44 = {.width=49,.height=44,.frame_count=1,.frame_rate=0,.frames=_I_iButtonKey_49x44}; -const Icon I_DolphinExcited_64x63 = {.width=64,.height=63,.frame_count=1,.frame_rate=0,.frames=_I_DolphinExcited_64x63}; -const Icon I_DolphinWait_61x59 = {.width=61,.height=59,.frame_count=1,.frame_rate=0,.frames=_I_DolphinWait_61x59}; -const Icon I_iButtonDolphinVerySuccess_108x52 = {.width=108,.height=52,.frame_count=1,.frame_rate=0,.frames=_I_iButtonDolphinVerySuccess_108x52}; +const Icon I_MHz_25x11 = {.width=25,.height=11,.frame_count=1,.frame_rate=0,.frames=_I_MHz_25x11}; +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_DolphinNice_96x59 = {.width=96,.height=59,.frame_count=1,.frame_rate=0,.frames=_I_DolphinNice_96x59}; +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}; +const Icon I_iButtonDolphinVerySuccess_108x52 = {.width=108,.height=52,.frame_count=1,.frame_rate=0,.frames=_I_iButtonDolphinVerySuccess_108x52}; +const Icon I_iButtonKey_49x44 = {.width=49,.height=44,.frame_count=1,.frame_rate=0,.frames=_I_iButtonKey_49x44}; +const Icon I_DolphinNice_96x59 = {.width=96,.height=59,.frame_count=1,.frame_rate=0,.frames=_I_DolphinNice_96x59}; +const Icon I_DolphinWait_61x59 = {.width=61,.height=59,.frame_count=1,.frame_rate=0,.frames=_I_DolphinWait_61x59}; diff --git a/assets/compiled/assets_icons.h b/assets/compiled/assets_icons.h index 6d05a531..7ae01304 100644 --- a/assets/compiled/assets_icons.h +++ b/assets/compiled/assets_icons.h @@ -1,8 +1,8 @@ #pragma once #include -extern const Icon I_Certification2_119x30; extern const Icon I_Certification1_103x23; +extern const Icon I_Certification2_119x30; extern const Icon A_BadBattery_128x51; extern const Icon A_BoxActive_128x51; extern const Icon A_Box_128x51; @@ -36,20 +36,20 @@ extern const Icon A_Level3HijackActive_128x51; extern const Icon A_Level3Hijack_128x51; extern const Icon A_Level3LabActive_128x51; extern const Icon A_Level3Lab_128x51; -extern const Icon I_LevelUp2_04; -extern const Icon I_LevelUp2_03; extern const Icon I_LevelUp2_07; -extern const Icon I_LevelUp2_05; -extern const Icon I_LevelUp2_02; extern const Icon I_LevelUp2_06; +extern const Icon I_LevelUp2_04; +extern const Icon I_LevelUp2_05; extern const Icon I_LevelUp2_01; -extern const Icon I_LevelUp3_07; -extern const Icon I_LevelUp3_02; -extern const Icon I_LevelUp3_04; +extern const Icon I_LevelUp2_02; +extern const Icon I_LevelUp2_03; extern const Icon I_LevelUp3_05; -extern const Icon I_LevelUp3_01; -extern const Icon I_LevelUp3_03; +extern const Icon I_LevelUp3_04; extern const Icon I_LevelUp3_06; +extern const Icon I_LevelUp3_07; +extern const Icon I_LevelUp3_03; +extern const Icon I_LevelUp3_02; +extern const Icon I_LevelUp3_01; extern const Icon A_LevelUpPending_128x51; extern const Icon A_NoSdCard_128x51; extern const Icon A_SleepActive_128x52; @@ -58,79 +58,79 @@ extern const Icon A_TvActive_128x52; extern const Icon A_Tv_128x52; extern const Icon A_WavesActive_128x52; extern const Icon A_Waves_128x52; +extern const Icon I_dir_10px; +extern const Icon I_Nfc_10px; extern const Icon I_sub1_10px; extern const Icon I_ir_10px; -extern const Icon I_unknown_10px; extern const Icon I_ibutt_10px; -extern const Icon I_Nfc_10px; +extern const Icon I_unknown_10px; extern const Icon I_ble_10px; extern const Icon I_125_10px; -extern const Icon I_dir_10px; extern const Icon I_BLE_Pairing_128x64; +extern const Icon I_UsbTree_48x22; +extern const Icon I_EviWaiting2_18x21; +extern const Icon I_Clock_18x18; +extern const Icon I_Smile_18x18; +extern const Icon I_EviSmile1_18x21; +extern const Icon I_Percent_10x14; +extern const Icon I_Error_18x18; extern const Icon I_EviWaiting1_18x21; extern const Icon I_EviSmile2_18x21; -extern const Icon I_Error_18x18; -extern const Icon I_Percent_10x14; -extern const Icon I_EviSmile1_18x21; -extern const Icon I_EviWaiting2_18x21; -extern const Icon I_UsbTree_48x22; -extern const Icon I_Smile_18x18; -extern const Icon I_Clock_18x18; -extern const Icon I_ButtonDown_7x4; -extern const Icon I_ButtonCenter_7x7; -extern const Icon I_ButtonLeft_4x7; -extern const Icon I_ButtonUp_7x4; -extern const Icon I_DFU_128x50; -extern const Icon I_ButtonLeftSmall_3x5; extern const Icon I_ButtonRightSmall_3x5; -extern const Icon I_ButtonRight_4x7; +extern const Icon I_ButtonLeft_4x7; +extern const Icon I_ButtonLeftSmall_3x5; +extern const Icon I_DFU_128x50; extern const Icon I_Warning_30x23; +extern const Icon I_ButtonDown_7x4; +extern const Icon I_ButtonRight_4x7; +extern const Icon I_ButtonCenter_7x7; +extern const Icon I_ButtonUp_7x4; +extern const Icon I_DolphinOkay_41x43; +extern const Icon I_DolphinFirstStart4_67x53; extern const Icon I_DolphinFirstStart2_59x51; extern const Icon I_DolphinFirstStart5_54x49; -extern const Icon I_DolphinFirstStart6_58x54; -extern const Icon I_Flipper_young_80x60; -extern const Icon I_DolphinFirstStart8_56x51; -extern const Icon I_DolphinFirstStart1_59x53; -extern const Icon I_DolphinOkay_41x43; -extern const Icon I_DolphinFirstStart3_57x48; -extern const Icon I_DolphinFirstStart7_61x51; extern const Icon I_DolphinFirstStart0_70x53; -extern const Icon I_DolphinFirstStart4_67x53; -extern const Icon I_ArrowUpEmpty_14x15; +extern const Icon I_DolphinFirstStart6_58x54; +extern const Icon I_DolphinFirstStart1_59x53; +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_ArrowUpFilled_14x15; -extern const Icon I_ArrowDownFilled_14x15; +extern const Icon I_ArrowUpEmpty_14x15; extern const Icon I_ArrowDownEmpty_14x15; +extern const Icon I_ArrowDownFilled_14x15; extern const Icon I_PassportBottom_128x17; -extern const Icon I_DoorLeft_70x55; -extern const Icon I_DoorRight_70x55; extern const Icon I_DoorLocked_10x56; +extern const Icon I_DoorLeft_70x55; extern const Icon I_PassportLeft_6x47; +extern const Icon I_DoorRight_70x55; extern const Icon I_LockPopup_100x49; -extern const Icon I_Down_hvr_25x27; -extern const Icon I_Vol_down_hvr_25x27; -extern const Icon I_Down_25x27; -extern const Icon I_Fill_marker_7x7; -extern const Icon I_Vol_down_25x27; -extern const Icon I_Vol_up_25x27; +extern const Icon I_Mute_25x27; +extern const Icon I_IrdaArrowUp_4x8; extern const Icon I_Up_hvr_25x27; -extern const Icon I_Vol_up_hvr_25x27; -extern const Icon I_IrdaLearnShort_128x31; -extern const Icon I_IrdaSend_128x64; extern const Icon I_DolphinReadingSuccess_59x63; extern const Icon I_Mute_hvr_25x27; -extern const Icon I_Back_15x10; -extern const Icon I_Up_25x27; -extern const Icon I_IrdaArrowUp_4x8; -extern const Icon I_Mute_25x27; -extern const Icon I_Power_25x27; -extern const Icon I_IrdaSendShort_128x34; -extern const Icon I_IrdaArrowDown_4x8; -extern const Icon I_IrdaLearn_128x64; +extern const Icon I_Vol_down_25x27; +extern const Icon I_Down_25x27; extern const Icon I_Power_hvr_25x27; +extern const Icon I_IrdaLearnShort_128x31; +extern const Icon I_IrdaArrowDown_4x8; +extern const Icon I_Vol_down_hvr_25x27; +extern const Icon I_IrdaLearn_128x64; +extern const Icon I_Down_hvr_25x27; +extern const Icon I_Fill_marker_7x7; +extern const Icon I_Power_25x27; +extern const Icon I_Vol_up_25x27; +extern const Icon I_Up_25x27; +extern const Icon I_Back_15x10; +extern const Icon I_IrdaSend_128x64; +extern const Icon I_IrdaSendShort_128x34; +extern const Icon I_Vol_up_hvr_25x27; +extern const Icon I_KeySave_24x11; +extern const Icon I_KeyBackspaceSelected_16x9; extern const Icon I_KeySaveSelected_24x11; extern const Icon I_KeyBackspace_16x9; -extern const Icon I_KeyBackspaceSelected_16x9; -extern const Icon I_KeySave_24x11; extern const Icon A_125khz_14; extern const Icon A_BadUsb_14; extern const Icon A_Bluetooth_14; @@ -150,43 +150,54 @@ extern const Icon A_U2F_14; extern const Icon A_iButton_14; extern const Icon I_Detailed_chip_17x13; extern const Icon I_Medium_chip_22x21; -extern const Icon I_BatteryBody_52x28; -extern const Icon I_FaceCharging_29x14; +extern const Icon I_passport_happy1_46x49; +extern const Icon I_passport_bad3_46x49; +extern const Icon I_passport_okay2_46x49; +extern const Icon I_passport_bad2_46x49; +extern const Icon I_passport_okay3_46x49; +extern const Icon I_passport_bottom_128x18; +extern const Icon I_passport_bad1_46x49; +extern const Icon I_passport_happy3_46x49; +extern const Icon I_passport_happy2_46x49; +extern const Icon I_passport_okay1_46x49; +extern const Icon I_passport_left_6x46; extern const Icon I_Health_16x16; +extern const Icon I_FaceCharging_29x14; +extern const Icon I_BatteryBody_52x28; +extern const Icon I_Voltage_16x16; extern const Icon I_Temperature_16x16; +extern const Icon I_FaceNopower_29x14; +extern const Icon I_FaceNormal_29x14; extern const Icon I_Battery_16x16; extern const Icon I_FaceConfused_29x14; -extern const Icon I_FaceNormal_29x14; -extern const Icon I_Voltage_16x16; -extern const Icon I_FaceNopower_29x14; -extern const Icon I_RFIDDolphinSend_97x61; extern const Icon I_RFIDDolphinSuccess_108x57; -extern const Icon I_RFIDDolphinReceive_97x61; extern const Icon I_RFIDBigChip_37x36; +extern const Icon I_RFIDDolphinSend_97x61; +extern const Icon I_RFIDDolphinReceive_97x61; extern const Icon I_SDQuestion_35x43; extern const Icon I_SDError_43x35; extern const Icon I_Cry_dolph_55x52; -extern const Icon I_Background_128x11; +extern const Icon I_BadUsb_9x8; +extern const Icon I_PlaceholderR_30x13; extern const Icon I_Lock_8x8; extern const Icon I_Battery_26x8; -extern const Icon I_Battery_19x8; -extern const Icon I_USBConnected_15x8; -extern const Icon I_BadUsb_9x8; -extern const Icon I_BT_Pair_9x8; extern const Icon I_PlaceholderL_11x13; -extern const Icon I_SDcardFail_11x8; -extern const Icon I_Bluetooth_5x8; -extern const Icon I_PlaceholderR_30x13; +extern const Icon I_Battery_19x8; extern const Icon I_SDcardMounted_11x8; -extern const Icon I_Quest_7x8; -extern const Icon I_Lock_7x8; +extern const Icon I_SDcardFail_11x8; +extern const Icon I_USBConnected_15x8; +extern const Icon I_Bluetooth_5x8; +extern const Icon I_BT_Pair_9x8; +extern const Icon I_Background_128x11; extern const Icon I_Scanning_123x52; -extern const Icon I_MHz_25x11; +extern const Icon I_Quest_7x8; extern const Icon I_Unlock_7x8; -extern const Icon I_iButtonKey_49x44; -extern const Icon I_DolphinExcited_64x63; -extern const Icon I_DolphinWait_61x59; -extern const Icon I_iButtonDolphinVerySuccess_108x52; +extern const Icon I_MHz_25x11; +extern const Icon I_Lock_7x8; extern const Icon I_DolphinMafia_115x62; -extern const Icon I_DolphinNice_96x59; +extern const Icon I_DolphinExcited_64x63; extern const Icon I_iButtonDolphinSuccess_109x60; +extern const Icon I_iButtonDolphinVerySuccess_108x52; +extern const Icon I_iButtonKey_49x44; +extern const Icon I_DolphinNice_96x59; +extern const Icon I_DolphinWait_61x59; diff --git a/assets/icons/Passport/passport_bad1_46x49.png b/assets/icons/Passport/passport_bad1_46x49.png new file mode 100644 index 0000000000000000000000000000000000000000..9b0e7c74ef20cfdf8b046d7597bd857ff786e56d GIT binary patch literal 1237 zcmaJ=Z*0_L7_S);hC)R2gM1*RGe(I0-(IiHx@EiGxf5<&ZYN$s!f4;V-8HxVq3yW4 ziQ<%?@&Sx4>I}#SgC=5#5n;eI8=xRjqeh*H(WnV(3>rTeLEMM=cDI{+SZLBd@B8%m zJ^-dcM0Sb0$$m zB^snkxjdfo0*Ff#O9F;ra7m_2-OzzyJb-fy$I^^IvjWL53NI^yfX_b!3Ky7`QqVH< z!O%@5%2DJiG+nJ$sVYx-!2r$5vP?4^&2c2MAj7&F={3>~+nOFU7=pm|BinQF*rRTE zLy<}#s*M~RKbKo@?1uA|LN%jnx=*tdLpx5K*qn7372y9g7PStGbsy3N7)XT~bQqGwBT1-Na_yFw$KBo3U*admfv- zDOO1ZP>;Nz=y`+9G02y_$P3G!k8?c5;P>ZrV7swqecYu+(i#lxozTn#o`cVoS+N(P zkT9WP2&maIXK|z;h=7!3QzRub0WBseaJ+@mZ{W=v%Ga1vq(N!;O*RT(B}+_z1gW#o zB3W7B$)o`wsY{HQv_#1ic!r=6MLM3G8z!l#LgN`97Zw9u7FG+oXrBVKIM1~0I)IjL zX?{~NJv%##jt`&v@^K`-&T3u7+P7a#Z(MnvS+?Z!v6=oex#GtcZl8pQavRh;cARaU zI(x2X_xm5cz2&LHJxiv3;wNsK`n$zCjlKNnsh?L{|F%AHdF15UBQLg3UwCc0Z~yVj zTVH5fdGFdc@49;W%E8gFzW2Lw{-4pAPuIWm#)+-_Z|NWZ{`cYu?ckx^cXx~(*?aW$ zefPch;k7-|^$kCSoV@DCcVB((@YBcAOW#uW?F3WnX72oL_>r0=_Zu{cW z(N{Wt`KI)TYi_&#m^FIfOn>Fp&Nbr~N7jv>zjkrgRrRk`+p*18S}Gm&PbN`TWB0r7@oLNYcQw}#-;%?Odn!uXXn1NGwwDdducXilkH|T3sRc7oXHN^otex` zx|<+gYM{iXSQ}A_6)Dn|`cV5&MN!i>u~u!cO@*R~lwP10iV7+ejJTf3W@8^h2WHMW z|M|cF|Nh&Ir@FV))vm8a5Tq{A5lzF@4_|7n4}SOE9DEKg4Q?#!_L`bolx%>ssiq9j zL_rz=X&|X1L*IcAg80VtOxDdNyF|q-_$5!rUn*D-jUb`ck|imFz(r*+pc`TA_b*Oj zsIG>wJ}yZntq92J9iukr9qrC2ql1c|Vy&CeP)URa3c!`nQXy|RVkwL**%jg56B8J^ zq~Z>Su?nedGKEG=8=$oDEeAQQ#=HZn?T? zpq@oZHiz9X2B}tJC|JqliebZ9&J@fUQIafz@{>fN;03m%?YL?1KaEwjoy>>@h%|7_ zVOxO((Kb}UFnRZPXBk1k zC6459PE|OC=Y#+$D^)wI;Tb*{V50$=4Ymg|S27e( z^{qqS%UJ5ZSTSM)$u;eaY38eKkjj~^>Euicr5QhoKAn^l-S8wWUX?0AM}e*H0BYPe z3+PgsMST?t0TswH3yUq#8jZ6or{IF1ayYLBfJO#cn$ckR6});+`YL@2B`^%D%0^Tu zUgH8v0GBAB;grBKcu-aVF7YH6)Hq&c84@EPMZ)WxdpfBqg6-*TR|W$fRz?dLaGq>9 zIQw7fc?AyLnp9UNRxX#}_W9`_Uq+CcM-$PuOlkhaJ9G8Z=p&KIa#;^Qu&uV`_(MOx z-gw!?$2OjN()aN#!o((qUVBD;Fx$UpYHfd0XU)a0YfKzf6rOfXRcytG#ws-q!wyIYd^)Aa|e~?ZxbMHO( zobP<+HBWaY+c(tQQG+1JhWO@43a(!GQrCIlclUh%18}+Bjb_{~Gw0?d8z3RolmQyo zr5=z1l3E=68Uzr;Gp?mGZYI$oDyHt0$~xYHZb54V3A7e0N$CeJDuW))2x5z~pJ1q_ z2C;4~K_;v)=+!ol*r019nN~*n6+y*X??VFx5d!GImC%AdU^rqSh%MoYa93L+BC!H&ILn!WIU@>^MNnRn(Dia)OWKZ`0{_!kRoh7yEkLAzV-DF0 zEJ&`gY7CQibw_1I$VPn7)?ihnfrzOL>A-N~kstYg#DHcuBM=At{3xdkwyy^ov($CUN4u)T`SFcE4rB9&*hGA9N zhziB$IG^IfB?{zlN?;k>FDn3-c#`wyI9_EL5+fi*qTD%GbW&9W+q1k~84P$>87*MI zd9vZ)@P{U!fJ3*gvm+fXl}d2?(A=r*2(o5lJQ7M5zJ2AT_}b6V^`7a{=!f+aKwW#{ zK#*+ubL{$0C$8n$k^m}!+ z4aqGxKUFwYO9kHiYvbahk39Cg+BCCo%lQ|M%n6$g@0tAQ^Oob^{JwL>IUGgu*GwPc zUM;p;E48 fV|H=hUc`f(xyf_n$$93k^1mt`O-5$gvSa@Nx4y<4 literal 0 HcmV?d00001 diff --git a/assets/icons/Passport/passport_bottom_128x18.png b/assets/icons/Passport/passport_bottom_128x18.png new file mode 100644 index 0000000000000000000000000000000000000000..691ed8b4ad994daeacf0ac0d3966affc2a30fce7 GIT binary patch literal 1149 zcmaJ=PiP!f7@ss!N@y;g+S0;f0-}&N^XA{q&X6@GJG*wFo2Hu;bLgRO-n>bs$^3EV z#oYu=q822Iw1@U0cqr|mrO-d8f<4r>f)olZ6-4Vnu@y0*f*$mg_$Hf;J%kL*eD8hp z{l4$_{aYCyd%eH!K%XE8{k6kRgUe<9zPP8Ce=m-`bc2iitTM?aVxP5eN`(EK}^Fc zAeVIgY=<`;O|5DLMK6wyC`zSV)Qzg6jhJOat5&M&Xct?HGKM2UyRicvdlQRx#M(IG*i}!T5B{;%qujfT~Fdyj;g5h;q#in2(&EEfTmZVJ}T;}=JWJBc<;ILb>@_7cp6EUjZGBOHwvTxu|j>QSh@y_ zE};;c$SC@T>FF90WlmAfC+E3I>ZTWl0n7@o3$UJ?Q+4_XB?PI-XR*}2c`OuAyb(`{GTw%Km&hNQ*0oN34HT$q{C zZ6Q8TQ^1fkv059z0vhqf*nm-M)D$&qFfnR0)`Utz;zQ8{1>vC}F{@a{rYiZhC@mK|dAe$4-atf|t_)=vd_NP9j)I2c94*x7`zGVrY;#IP&rQ3aTU-4&N8Bg zD;&w;oUU=2z==GmYDGKi;W=L91*U;!BMtQw)fkJgTwG@Ag&4=g8{>3C5u336K(RGY z^ld`lt61uxSSjWKC2+j7N!wabnwk_vyvVjgzCV{_?}o(;wDa zlZQTir*r$psSP*X>iJU_zweoT?c<+zz4>qD^{bTQRNT6@=jPUuIiq#zcnzPbyfb_} z^yS~u`T4HJ#L}Z@k9CM!4t7@kzWec+*{)k3{Bxl^^KCm@_f>x6*Zd!Ul}`R#``rot zvzGCA$KfNUf4ckRm5J`Wxnu5j^X!u&$>B$uYitx%6rNHagjluO2sA~8L5mM&=dm-pJCklnyW7Xw?z-8ow1|+-+_|%zwDWLg z*4=JQ4T2E_{h_2)G0`ZMkTi{u5Qw0Lw#J|dQHh8c!L(6Iq@h|9+oV|Uw%y7P!Xz{I z-gD1)&Uaq3Cmw4kSy8?M!?2P_V>p3U4|IFeIR98utqxMUo{T%Nuc)W*Lg+D25|xTJ#Dc$Ki_)f!x`O zDkj49i_Xv~NOZWaB~nx-lksG{9@9=yj35XU%~C8&A`Q~%He4x78qWHHg)nr0ty!*S z8hGBKB%5hBNFb^UG3Zt_x@6dJ7Bhu%Mr9?7VmvgZ>-oUuwH-GB|EFWHw{0D zm3rIM@%c21+AS#f6e!CaDz?C?EXi>^AO%6;Nx$NQDjnchuZqH7z$-VUZ=p|-1chN0 z*oc7ftGo~RNQr?e$q1a649EbIlAq=SD(_b~FHKO0B9-r)n>wi=LhYH~E)51cER7a4 z&^*~_aK^uDI){etu6T2@Zfd*YjtfxXp%eGRQg&lXYD z>C^k^p0%q=)2sVF6f4_;?|fQ5nD}e+WMi(s`rs$KPR)#LId=cV_R~+^*cMxxJJdgV zw0&8_+g)6A`PQ$~Hy$Y)&plLe;h6CKop*03e)#I^J9|&;h*gA2hyRHmn118qjZ-DT zYs5z{4S%Iqzp~Og+&k7g_(c1f%Bs?t%uxEZ{r1o=vmcyD_N6DLe{8kRrvkelywvq; z`Q^g{dk0@NX5Y;``_suk`^t}iYXe6{)aRPFZu@fLk9C(o@0F3?Ce_;EL2>Mdvm3V0 z_HUjky{>&ex-K?+CR4f6soHSh^7(%sEv3pv->1q>-LVRrpo*u*!||g0KP*xg3lG+| Gzx*E~RoOxS literal 0 HcmV?d00001 diff --git a/assets/icons/Passport/passport_happy3_46x49.png b/assets/icons/Passport/passport_happy3_46x49.png new file mode 100644 index 0000000000000000000000000000000000000000..7aef17674336e71cb1cdf323c1fb039e0e627d33 GIT binary patch literal 1348 zcmaJ>eQXnD7{7&~lejEf6dZ`TCJQE*5i}V=Gtg{i3Pxj)$VR4uj%5Br(2>QcxJ9tO-PXw;3zyuz@B6&Z z?|FXD*S*$I_h|8o)hiGLDGt_15x6?wOBF4H-?y&BYT;6D`y1`erf#QY3m{(2Q~(-` z%S|8xWUYP2H^7Y`%eswdqum$|iK-cQ$T=NHCZ2?71aWW5BxN-QY*YbFM#6(l4~<}` zp?R>UxG)(``arW$(_w+l9d%K)Bc=)(wrL~k&WO-J9N03NiMJ$DV#b5b*%jeFCnhj- zPQ{LSuz6CA;Re)aS^(u86t0paiSmL&lNDK2lnp3N(iB0m1jXVcDKdh{vgpEtL3fs> zixDZX;0&HTShH;>MS@7D(~dObFs&wn5(I%DX@aJ4sDY>26Skbe6RGui3ld1FmXWj# zGlAwT%8J=)doW0KK8AQQ99}e>NG)Uv=8VY5NrG~aL_D4gY)(66N5KCymefu~+mnEZ zfRx#4sjwjW`aBpW@Ai&zija+1ZyB&Ea*JfDt#OdBgOUe>HxA9vM4bc*$0-`F0Gh{H zMo@8?BRQPYR8HkN!AUA=-p*2ZUSj9~!%3{G+DlP>pNr)J66584924*d=;}N+m`K@j zLIru>2K2pv_1zXL`Ya&ZrWG~KmV6sDG@G`WYBrN7%{WN(p|GqPiJYV|SEc!&C14qC zKnqxA9Gy$EXe>d&sR2b{VX*~Tr*W3$R9p}=4(Bx|&`B3dGdc`^9{kf_iiuqr*cMf-r|D(OMvukwvy8`o1`tw&u9$(pU5#95~ z%oTI>8uxp$)MLN!$|u8Ts>&uiuO7ZWBpiL98lP5}6NArIJQJ=spqB+Br+<8N>Vw_S z_Y<{yCf_|@e7Vx~+0Lm4rC5)>;nUic6RxqR?aGg??}}}We<5Oh`o+G7&-IS&?LRe} z-r_uRFyy2dJyS4Wz?o~hpirfB!b{SC`cogKU3Sa;{l$NW9Rh4&#f XzZTxR@26EIx&KcmkDlB-hOF=!v8?;5Sw{!P^&I!WElc3#UoyM|F z;!wi5jnoel?#*H5`w1qSlmVA+1W{T1{r;l}0S( zRfXIFW;+qXeHdlaLj;FrBn=W4#1Y65u^Vr*vdF0patM<~;}kf`PAbJ~Ciih7D-x2! zFi-5*I%6&RpT@b?S$ij;a*Jm1c1n0d{OO@HFW$w0azoC>UQGku6};udWILo0t2x;Ccg- zAj&l}d6x!BJ2VaMQLmQ9Avi9x9h^g<=uy|zd9y9mSD~&O1X`A7K+`KyAC+`f^LhFM zfA38B26M_aJdI??#wLpC8%0utSfM^tEM0>omr#gJWR!fv^mGl0GN&l#lXGU0hAKXu z`SEly_~mr9XvFs^<%{$7>7N>3y0PYRyLxnV#E-W>AKvHUM%`Ix_rJUA>+7Qha3B=G z*#5}1pIh%HM!$?7eiFVeO?Ba3Qh5II^{a>9E&0XLfeRTaUY)U2p03Ze3ShNk+zwl zw#s=f@2Am_-8~kdO=GMcw%0W5z(ElpYfi-twOWdr^Q+-=tY#^4&LkR6 zQFT(~e1S}R0U{NKry<92q@pq=FaR`+XGwt*c$Sk`UZOcp6ID%;$oYrD;R4grih6cF z7`~;bp(ye-maSH+OjTsOV36fiRb@GW6$Bbv(BY^Xfg0_Gs~aA46vDvvBinPy*ds8! zktjuBs`VTkKc8Q4?1uA|!Zl-Sz-M`eV;v_>Y|c82is*kDi&}@JQ6I5I6nY~8#0{}l zH^8`f_YV{sVm4Y|VB@ZUitfP?2f0yBPf_>}W7?)>ambKm!=w!)D6}N1kOnd*)3OO= zsK{!9GhoBdVt7$WCL}%4DJ8p-JfBG?B{{2$ol063vze^W)xhT5Faj<_jo3DhJ&#rI zi`CKr0+AP#Jg?FigTjy(dEt=flY+=_%f@tCN>v;2?^3~@QYj7HVgN+7x#gY>+K?5FH zG_Oh`oire#fx^j2OIA!tf8DB<9c!Bp4m?~u^x&a`cYi-{^R3IP zPPoVV65n0W$8J3}03V&W+H_+b^T@7We|i6jJKg_Srwr=$%B4R#Km9N*^^dcUU%vR^ zl{b6-?3!s#7Ux3KipP+Z}O#J;?kG)wF^K0UD(|>{@Sg# zvv-qQaz}42@A+oi2is>}bl*L5YU5{r{g!N<{OIYUyU+hS-T%N+VrsOhvhSTWpW-}; MT&7n)()IlKe@XVQIsgCw literal 0 HcmV?d00001 diff --git a/assets/icons/Passport/passport_okay2_46x49.png b/assets/icons/Passport/passport_okay2_46x49.png new file mode 100644 index 0000000000000000000000000000000000000000..34fd3767b92bc334f15e4e13811020c1e0211078 GIT binary patch literal 1281 zcmaJ>eP|nH7{9gXN~Cj8-Povj-o(x6YJvi`=jjO?tS0q zeSXjLd%kXOXGd$jZ>*tz1;sM_Qd!4eFl>lMknpC0Ehz)QLuJsfn-T2l$x|4r zs}byJHc2M!D9Gwv^_75cz!GpAYygr=OsBo+n6}plKXx;O?;LNd??=*HtZuz*QXG_H@fc z%N8Zs8uB6-q*{r=u#?F}!=}5CDVQ^&AlU@vCkewS2R5(mdMWTfjU~0+^so(x6mYE} zM}Y;=)>XkUd3SbHR)lPXryLztMaqemGGqYLONbE+-uP8r6*LmaEGw(H3}_B#0=$At zEXm@ms;~;j@5raV{)DohoSTw}2aWT-$McF_+7N=XP*o5hNlBs~I zZyowxz_NG53Q-40p5>%1D_3oU&aCBGZq~9;ARjzSX5S z@A;>FOUxLP5U06J+c1lS4&rqjjy=>tKRJ^ds_R>{c8{$}HYhrX*>`{7SxW0ObGYd=rz{>|;) zcDd&GWRr6A;8aunL+7upZ+znLY-x|L5bAlUr}giN1Mc~myY_rmr*V6W_KxGvY}@kA zrz^ML*p=RQVps7>VtDoM@An>K4i85A-!0{Cta)91@|#yO%V&g!>02KZH?Da5R9nNw zM=qSXxay1X?wu!p9KG=E>G9bk|C)onm&TrzuNNN}x&Gpx4SmR=iQ4_OTeDx5e@cm1 KhdAESxAQ++sKGP< literal 0 HcmV?d00001 diff --git a/assets/icons/Passport/passport_okay3_46x49.png b/assets/icons/Passport/passport_okay3_46x49.png new file mode 100644 index 0000000000000000000000000000000000000000..e65da5b0e586ab706b40263b637f0fd3647ac5d6 GIT binary patch literal 1304 zcmaJ=eQ4Zd7*FY#?Xc({wr<5?O#hgI`A#mEaJRF)-1W}xYPsFqxo)2Mc+-pRC25j+ z*P{+~I(14dBFvRBN2hbJDTpFM)qUugbz-}TilX~M+(1Ul>R)5DzSs8Z{wND1@AE!+ ze$VrJzFzO@Y;Rc8yaqv#hGarc!;^q7T~`agZ(r^0fX6yNmi0H=hF?@%fVAqi3eaRh z=>ch==!5+eAcP>bFPoXHpG|F&G`m136&s>da3C5%LXncAXuZHkRnTKvVQhN*IEI>f z7~9IHsFV{0c{5RV!RB&jMl1JfqK-v2qM?!m9Tb4Cprt~eP5w%}KSaz#yI=z@vg z8^#t%Wm8>f)OGRp)0DQsp_LBLoqZ-aU{**6eY2u#Bu1-gTZjFZb)f4 zz7!1J!dTw-9f>51#UfE;3ES-;YGU z4KZ4(U|7662dWrCHqsNW3A>{7$+k970G6MW!x;QS=%y|i6i|6y)o~Rt0?x6bhATY9 zCt(kQeA6&js6BX*w1Sa(rB7TZJgk#$$1&t%^-rp08LMsKz#7 z>?JIBN30Zef#Tb4#lx?BI(#Kl}VE zr>*Xj7oPuOCYk$s)Y#tsK*%~np8RyS?!L1%zI<}}!MWYx!_m5O^Oebw6XCJ(_ObK- zTzE2ZDn{m<55rd*dxnMr?}ze}_QjcOWc_;&d9i~N9qGpsZ_J!4w`@NTS~`yv?;ke? zhv>V?2d>v2-`~IQ&nd6F)duN|MblK>4PVZ`*vyPb!yT5yrS%35K zA7@kco=YdXx2-A%Zb=_}`+d*RzhdRBuUsVFjp#>D|NZ4t)}y$rkd*-G80G55pQ2+n{ literal 0 HcmV?d00001 From 03d7476e4fc5e86f48ef2db823d5c40b30cfa8f9 Mon Sep 17 00:00:00 2001 From: Anna Prosvetova Date: Tue, 7 Dec 2021 16:47:20 +0300 Subject: [PATCH 20/32] Rpc: StorageInfo, StorageRename, SystemReboot, SystemDeviceInfo (bonus: +FuriHalInfo) (#862) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Rpc: update protobuf sources * Rpc: rename Status to System * Rpc: implement StorageInfoRequest * Rpc: implement StorageRenameRequest * Rpc: implement SystemRebootRequest * FuriHal: introduce FuriHalInfo, refactor device_info * Rpc: implement DeviceInfoRequest * Rpc: use strdup where it suites the best. * Make: add do not page align data to linker flag. Co-authored-by: あく --- applications/cli/cli_commands.c | 156 +-------------- applications/rpc/rpc.c | 57 +++++- applications/rpc/rpc_i.h | 2 +- applications/rpc/rpc_status.c | 39 ---- applications/rpc/rpc_storage.c | 58 ++++++ applications/rpc/rpc_system.c | 118 +++++++++++ applications/tests/rpc/rpc_test.c | 127 ++++++++++-- assets/assets.mk | 2 +- assets/compiled/flipper.pb.h | 48 +++-- assets/compiled/storage.pb.c | 9 + assets/compiled/storage.pb.h | 51 +++++ assets/compiled/system.pb.c | 25 +++ assets/compiled/system.pb.h | 121 +++++++++++ assets/protobuf | 2 +- firmware/targets/f6/furi-hal/furi-hal-info.c | 189 ++++++++++++++++++ firmware/targets/f7/furi-hal/furi-hal-info.c | 189 ++++++++++++++++++ .../targets/furi-hal-include/furi-hal-info.h | 33 +++ firmware/targets/furi-hal-include/furi-hal.h | 1 + make/toolchain.mk | 2 +- 19 files changed, 1005 insertions(+), 224 deletions(-) delete mode 100644 applications/rpc/rpc_status.c create mode 100644 applications/rpc/rpc_system.c create mode 100644 assets/compiled/system.pb.c create mode 100644 assets/compiled/system.pb.h create mode 100644 firmware/targets/f6/furi-hal/furi-hal-info.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-info.c create mode 100644 firmware/targets/furi-hal-include/furi-hal-info.h diff --git a/applications/cli/cli_commands.c b/applications/cli/cli_commands.c index 4711b13d..c3e51656 100644 --- a/applications/cli/cli_commands.c +++ b/applications/cli/cli_commands.c @@ -1,166 +1,22 @@ #include "cli_commands.h" #include #include +#include #include #include #include #include -#include -#define ENCLAVE_SIGNATURE_KEY_SLOTS 10 -#define ENCLAVE_SIGNATURE_SIZE 16 - -static const uint8_t enclave_signature_iv[ENCLAVE_SIGNATURE_KEY_SLOTS][16] = { - {0xac, 0x5d, 0x68, 0xb8, 0x79, 0x74, 0xfc, 0x7f, 0x45, 0x02, 0x82, 0xf1, 0x48, 0x7e, 0x75, 0x8a}, - {0x38, 0xe6, 0x6a, 0x90, 0x5e, 0x5b, 0x8a, 0xa6, 0x70, 0x30, 0x04, 0x72, 0xc2, 0x42, 0xea, 0xaf}, - {0x73, 0xd5, 0x8e, 0xfb, 0x0f, 0x4b, 0xa9, 0x79, 0x0f, 0xde, 0x0e, 0x53, 0x44, 0x7d, 0xaa, 0xfd}, - {0x3c, 0x9a, 0xf4, 0x43, 0x2b, 0xfe, 0xea, 0xae, 0x8c, 0xc6, 0xd1, 0x60, 0xd2, 0x96, 0x64, 0xa9}, - {0x10, 0xac, 0x7b, 0x63, 0x03, 0x7f, 0x43, 0x18, 0xec, 0x9d, 0x9c, 0xc4, 0x01, 0xdc, 0x35, 0xa7}, - {0x26, 0x21, 0x64, 0xe6, 0xd0, 0xf2, 0x47, 0x49, 0xdc, 0x36, 0xcd, 0x68, 0x0c, 0x91, 0x03, 0x44}, - {0x7a, 0xbd, 0xce, 0x9c, 0x24, 0x7a, 0x2a, 0xb1, 0x3c, 0x4f, 0x5a, 0x7d, 0x80, 0x3e, 0xfc, 0x0d}, - {0xcd, 0xdd, 0xd3, 0x02, 0x85, 0x65, 0x43, 0x83, 0xf9, 0xac, 0x75, 0x2f, 0x21, 0xef, 0x28, 0x6b}, - {0xab, 0x73, 0x70, 0xe8, 0xe2, 0x56, 0x0f, 0x58, 0xab, 0x29, 0xa5, 0xb1, 0x13, 0x47, 0x5e, 0xe8}, - {0x4f, 0x3c, 0x43, 0x77, 0xde, 0xed, 0x79, 0xa1, 0x8d, 0x4c, 0x1f, 0xfd, 0xdb, 0x96, 0x87, 0x2e}, -}; - -static const uint8_t enclave_signature_input[ENCLAVE_SIGNATURE_KEY_SLOTS][ENCLAVE_SIGNATURE_SIZE] = { - {0x9f, 0x5c, 0xb1, 0x43, 0x17, 0x53, 0x18, 0x8c, 0x66, 0x3d, 0x39, 0x45, 0x90, 0x13, 0xa9, 0xde}, - {0xc5, 0x98, 0xe9, 0x17, 0xb8, 0x97, 0x9e, 0x03, 0x33, 0x14, 0x13, 0x8f, 0xce, 0x74, 0x0d, 0x54}, - {0x34, 0xba, 0x99, 0x59, 0x9f, 0x70, 0x67, 0xe9, 0x09, 0xee, 0x64, 0x0e, 0xb3, 0xba, 0xfb, 0x75}, - {0xdc, 0xfa, 0x6c, 0x9a, 0x6f, 0x0a, 0x3e, 0xdc, 0x42, 0xf6, 0xae, 0x0d, 0x3c, 0xf7, 0x83, 0xaf}, - {0xea, 0x2d, 0xe3, 0x1f, 0x02, 0x99, 0x1a, 0x7e, 0x6d, 0x93, 0x4c, 0xb5, 0x42, 0xf0, 0x7a, 0x9b}, - {0x53, 0x5e, 0x04, 0xa2, 0x49, 0xa0, 0x73, 0x49, 0x56, 0xb0, 0x88, 0x8c, 0x12, 0xa0, 0xe4, 0x18}, - {0x7d, 0xa7, 0xc5, 0x21, 0x7f, 0x12, 0x95, 0xdd, 0x4d, 0x77, 0x01, 0xfa, 0x71, 0x88, 0x2b, 0x7f}, - {0xdc, 0x9b, 0xc5, 0xa7, 0x6b, 0x84, 0x5c, 0x37, 0x7c, 0xec, 0x05, 0xa1, 0x9f, 0x91, 0x17, 0x3b}, - {0xea, 0xcf, 0xd9, 0x9b, 0x86, 0xcd, 0x2b, 0x43, 0x54, 0x45, 0x82, 0xc6, 0xfe, 0x73, 0x1a, 0x1a}, - {0x77, 0xb8, 0x1b, 0x90, 0xb4, 0xb7, 0x32, 0x76, 0x8f, 0x8a, 0x57, 0x06, 0xc7, 0xdd, 0x08, 0x90}, -}; - -static const uint8_t enclave_signature_expected[ENCLAVE_SIGNATURE_KEY_SLOTS][ENCLAVE_SIGNATURE_SIZE] = { - {0xe9, 0x9a, 0xce, 0xe9, 0x4d, 0xe1, 0x7f, 0x55, 0xcb, 0x8a, 0xbf, 0xf2, 0x4d, 0x98, 0x27, 0x67}, - {0x34, 0x27, 0xa7, 0xea, 0xa8, 0x98, 0x66, 0x9b, 0xed, 0x43, 0xd3, 0x93, 0xb5, 0xa2, 0x87, 0x8e}, - {0x6c, 0xf3, 0x01, 0x78, 0x53, 0x1b, 0x11, 0x32, 0xf0, 0x27, 0x2f, 0xe3, 0x7d, 0xa6, 0xe2, 0xfd}, - {0xdf, 0x7f, 0x37, 0x65, 0x2f, 0xdb, 0x7c, 0xcf, 0x5b, 0xb6, 0xe4, 0x9c, 0x63, 0xc5, 0x0f, 0xe0}, - {0x9b, 0x5c, 0xee, 0x44, 0x0e, 0xd1, 0xcb, 0x5f, 0x28, 0x9f, 0x12, 0x17, 0x59, 0x64, 0x40, 0xbb}, - {0x94, 0xc2, 0x09, 0x98, 0x62, 0xa7, 0x2b, 0x93, 0xed, 0x36, 0x1f, 0x10, 0xbc, 0x26, 0xbd, 0x41}, - {0x4d, 0xb2, 0x2b, 0xc5, 0x96, 0x47, 0x61, 0xf4, 0x16, 0xe0, 0x81, 0xc3, 0x8e, 0xb9, 0x9c, 0x9b}, - {0xc3, 0x6b, 0x83, 0x55, 0x90, 0x38, 0x0f, 0xea, 0xd1, 0x65, 0xbf, 0x32, 0x4f, 0x8e, 0x62, 0x5b}, - {0x8d, 0x5e, 0x27, 0xbc, 0x14, 0x4f, 0x08, 0xa8, 0x2b, 0x14, 0x89, 0x5e, 0xdf, 0x77, 0x04, 0x31}, - {0xc9, 0xf7, 0x03, 0xf1, 0x6c, 0x65, 0xad, 0x49, 0x74, 0xbe, 0x00, 0x54, 0xfd, 0xa6, 0x9c, 0x32}, -}; +void cli_command_device_info_callback(const char* key, const char* value, bool last, void* context) { + printf("%-24s: %s\r\n", key, value); +} /* * Device Info Command - * This command is intended to be used by humans and machines - * Keys and values format MUST NOT BE changed + * This command is intended to be used by humans */ void cli_command_device_info(Cli* cli, string_t args, void* context) { - // Device Info version - printf("device_info_major : %d\r\n", 2); - printf("device_info_minor : %d\r\n", 0); - // Model name - printf("hardware_model : %s\r\n", furi_hal_version_get_model_name()); - - // Unique ID - printf("hardware_uid : "); - const uint8_t* uid = furi_hal_version_uid(); - for(size_t i = 0; i < furi_hal_version_uid_size(); i++) { - printf("%02X", uid[i]); - } - printf("\r\n"); - - // OTP Revision - printf("hardware_otp_ver : %d\r\n", furi_hal_version_get_otp_version()); - printf("hardware_timestamp : %lu\r\n", furi_hal_version_get_hw_timestamp()); - - // Board Revision - printf("hardware_ver : %d\r\n", furi_hal_version_get_hw_version()); - printf("hardware_target : %d\r\n", furi_hal_version_get_hw_target()); - printf("hardware_body : %d\r\n", furi_hal_version_get_hw_body()); - printf("hardware_connect : %d\r\n", furi_hal_version_get_hw_connect()); - printf("hardware_display : %d\r\n", furi_hal_version_get_hw_display()); - - // Board Personification - printf("hardware_color : %d\r\n", furi_hal_version_get_hw_color()); - printf("hardware_region : %d\r\n", furi_hal_version_get_hw_region()); - const char* name = furi_hal_version_get_name_ptr(); - if(name) { - printf("hardware_name : %s\r\n", name); - } - - // Bootloader Version - const Version* bootloader_version = furi_hal_version_get_bootloader_version(); - if(bootloader_version) { - printf("bootloader_commit : %s\r\n", version_get_githash(bootloader_version)); - printf("bootloader_branch : %s\r\n", version_get_gitbranch(bootloader_version)); - printf("bootloader_branch_num : %s\r\n", version_get_gitbranchnum(bootloader_version)); - printf("bootloader_version : %s\r\n", version_get_version(bootloader_version)); - printf("bootloader_build_date : %s\r\n", version_get_builddate(bootloader_version)); - printf("bootloader_target : %d\r\n", version_get_target(bootloader_version)); - } - - // Firmware version - const Version* firmware_version = furi_hal_version_get_firmware_version(); - if(firmware_version) { - printf("firmware_commit : %s\r\n", version_get_githash(firmware_version)); - printf("firmware_branch : %s\r\n", version_get_gitbranch(firmware_version)); - printf("firmware_branch_num : %s\r\n", version_get_gitbranchnum(firmware_version)); - printf("firmware_version : %s\r\n", version_get_version(firmware_version)); - printf("firmware_build_date : %s\r\n", version_get_builddate(firmware_version)); - printf("firmware_target : %d\r\n", version_get_target(firmware_version)); - } - - WirelessFwInfo_t pWirelessInfo; - if(furi_hal_bt_is_alive() && SHCI_GetWirelessFwInfo(&pWirelessInfo) == SHCI_Success) { - printf("radio_alive : true\r\n"); - // FUS Info - printf("radio_fus_major : %d\r\n", pWirelessInfo.FusVersionMajor); - printf("radio_fus_minor : %d\r\n", pWirelessInfo.FusVersionMinor); - printf("radio_fus_sub : %d\r\n", pWirelessInfo.FusVersionSub); - printf("radio_fus_sram2b : %dK\r\n", pWirelessInfo.FusMemorySizeSram2B); - printf("radio_fus_sram2a : %dK\r\n", pWirelessInfo.FusMemorySizeSram2A); - printf("radio_fus_flash : %dK\r\n", pWirelessInfo.FusMemorySizeFlash * 4); - // Stack Info - printf("radio_stack_type : %d\r\n", pWirelessInfo.StackType); - printf("radio_stack_major : %d\r\n", pWirelessInfo.VersionMajor); - printf("radio_stack_minor : %d\r\n", pWirelessInfo.VersionMinor); - printf("radio_stack_sub : %d\r\n", pWirelessInfo.VersionSub); - printf("radio_stack_branch : %d\r\n", pWirelessInfo.VersionBranch); - printf("radio_stack_release : %d\r\n", pWirelessInfo.VersionReleaseType); - printf("radio_stack_sram2b : %dK\r\n", pWirelessInfo.MemorySizeSram2B); - printf("radio_stack_sram2a : %dK\r\n", pWirelessInfo.MemorySizeSram2A); - printf("radio_stack_sram1 : %dK\r\n", pWirelessInfo.MemorySizeSram1); - printf("radio_stack_flash : %dK\r\n", pWirelessInfo.MemorySizeFlash * 4); - // Mac address - printf("radio_ble_mac : "); - const uint8_t* ble_mac = furi_hal_version_get_ble_mac(); - for(size_t i = 0; i < 6; i++) { - printf("%02X", ble_mac[i]); - } - printf("\r\n"); - - // Signature verification - uint8_t buffer[ENCLAVE_SIGNATURE_SIZE]; - size_t enclave_valid_keys = 0; - for(size_t key_slot = 0; key_slot < ENCLAVE_SIGNATURE_KEY_SLOTS; key_slot++) { - if(furi_hal_crypto_store_load_key(key_slot + 1, enclave_signature_iv[key_slot])) { - if(furi_hal_crypto_encrypt( - enclave_signature_input[key_slot], buffer, ENCLAVE_SIGNATURE_SIZE)) { - enclave_valid_keys += memcmp( - buffer, - enclave_signature_expected[key_slot], - ENCLAVE_SIGNATURE_SIZE) == 0; - } - furi_hal_crypto_store_unload_key(key_slot + 1); - } - } - printf("enclave_valid_keys : %d\r\n", enclave_valid_keys); - printf( - "enclave_valid : %s\r\n", - (enclave_valid_keys == ENCLAVE_SIGNATURE_KEY_SLOTS) ? "true" : "false"); - } else { - printf("radio_alive : false\r\n"); - } + furi_hal_info_get(cli_command_device_info_callback, context); } void cli_command_help(Cli* cli, string_t args, void* context) { diff --git a/applications/rpc/rpc.c b/applications/rpc/rpc.c index fa39699f..449ab015 100644 --- a/applications/rpc/rpc.c +++ b/applications/rpc/rpc.c @@ -33,7 +33,7 @@ typedef struct { static RpcSystemCallbacks rpc_systems[] = { { - .alloc = rpc_system_status_alloc, + .alloc = rpc_system_system_alloc, .free = NULL, }, { @@ -203,12 +203,23 @@ void rpc_print_message(const PB_Main* message) { } break; } - case PB_Main_ping_request_tag: + case PB_Main_system_ping_request_tag: string_cat_printf(str, "\tping_request {\r\n"); break; - case PB_Main_ping_response_tag: + case PB_Main_system_ping_response_tag: string_cat_printf(str, "\tping_response {\r\n"); break; + case PB_Main_system_device_info_request_tag: + string_cat_printf(str, "\tdevice_info_request {\r\n"); + break; + case PB_Main_system_device_info_response_tag: + string_cat_printf(str, "\tdevice_info_response {\r\n"); + string_cat_printf( + str, + "\t\t%s: %s\r\n", + message->content.system_device_info_response.key, + message->content.system_device_info_response.value); + break; case PB_Main_storage_mkdir_request_tag: string_cat_printf(str, "\tmkdir {\r\n"); break; @@ -223,6 +234,38 @@ void rpc_print_message(const PB_Main* message) { case PB_Main_empty_tag: string_cat_printf(str, "\tempty {\r\n"); break; + case PB_Main_storage_info_request_tag: { + string_cat_printf(str, "\tinfo_request {\r\n"); + const char* path = message->content.storage_info_request.path; + if(path) { + string_cat_printf(str, "\t\tpath: %s\r\n", path); + } + break; + } + case PB_Main_storage_info_response_tag: { + string_cat_printf(str, "\tinfo_response {\r\n"); + string_cat_printf( + str, "\t\ttotal_space: %lu\r\n", message->content.storage_info_response.total_space); + string_cat_printf( + str, "\t\tfree_space: %lu\r\n", message->content.storage_info_response.free_space); + break; + } + case PB_Main_storage_stat_request_tag: { + string_cat_printf(str, "\tstat_request {\r\n"); + const char* path = message->content.storage_stat_request.path; + if(path) { + string_cat_printf(str, "\t\tpath: %s\r\n", path); + } + break; + } + case PB_Main_storage_stat_response_tag: { + string_cat_printf(str, "\tstat_response {\r\n"); + if(message->content.storage_stat_response.has_file) { + const PB_Storage_File* msg_file = &message->content.storage_stat_response.file; + rpc_sprintf_msg_file(str, "\t\t\t", msg_file, 1); + } + break; + } case PB_Main_storage_list_request_tag: { string_cat_printf(str, "\tlist_request {\r\n"); const char* path = message->content.storage_list_request.path; @@ -265,6 +308,14 @@ void rpc_print_message(const PB_Main* message) { rpc_sprintf_msg_file(str, "\t\t", msg_file, msg_file_count); break; } + case PB_Main_storage_rename_request_tag: { + string_cat_printf(str, "\trename_request {\r\n"); + string_cat_printf( + str, "\t\told_path: %s\r\n", message->content.storage_rename_request.old_path); + string_cat_printf( + str, "\t\tnew_path: %s\r\n", message->content.storage_rename_request.new_path); + break; + } case PB_Main_gui_start_screen_stream_request_tag: string_cat_printf(str, "\tstart_screen_stream {\r\n"); break; diff --git a/applications/rpc/rpc_i.h b/applications/rpc/rpc_i.h index 76df1e5a..2eee2c46 100644 --- a/applications/rpc/rpc_i.h +++ b/applications/rpc/rpc_i.h @@ -21,7 +21,7 @@ void rpc_send_and_release(Rpc* rpc, PB_Main* main_message); void rpc_send_and_release_empty(Rpc* rpc, uint32_t command_id, PB_CommandStatus status); void rpc_add_handler(Rpc* rpc, pb_size_t message_tag, RpcHandler* handler); -void* rpc_system_status_alloc(Rpc* rpc); +void* rpc_system_system_alloc(Rpc* rpc); void* rpc_system_storage_alloc(Rpc* rpc); void rpc_system_storage_free(void* ctx); void* rpc_system_app_alloc(Rpc* rpc); diff --git a/applications/rpc/rpc_status.c b/applications/rpc/rpc_status.c deleted file mode 100644 index 0c3fb56e..00000000 --- a/applications/rpc/rpc_status.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "flipper.pb.h" -#include "rpc_i.h" -#include "status.pb.h" - -void rpc_system_status_ping_process(const PB_Main* msg_request, void* context) { - if(msg_request->has_next) { - rpc_send_and_release_empty( - context, msg_request->command_id, PB_CommandStatus_ERROR_INVALID_PARAMETERS); - return; - } - - PB_Main msg_response = PB_Main_init_default; - msg_response.has_next = false; - msg_response.command_status = PB_CommandStatus_OK; - msg_response.command_id = msg_request->command_id; - msg_response.which_content = PB_Main_ping_response_tag; - - const PB_Status_PingRequest* request = &msg_request->content.ping_request; - PB_Status_PingResponse* response = &msg_response.content.ping_response; - if(request->data && (request->data->size > 0)) { - response->data = furi_alloc(PB_BYTES_ARRAY_T_ALLOCSIZE(request->data->size)); - memcpy(response->data->bytes, request->data->bytes, request->data->size); - response->data->size = request->data->size; - } - - rpc_send_and_release(context, &msg_response); -} - -void* rpc_system_status_alloc(Rpc* rpc) { - RpcHandler rpc_handler = { - .message_handler = rpc_system_status_ping_process, - .decode_submessage = NULL, - .context = rpc, - }; - - rpc_add_handler(rpc, PB_Main_ping_request_tag, &rpc_handler); - - return NULL; -} diff --git a/applications/rpc/rpc_storage.c b/applications/rpc/rpc_storage.c index 99844e5d..1fa7063d 100644 --- a/applications/rpc/rpc_storage.c +++ b/applications/rpc/rpc_storage.c @@ -96,6 +96,37 @@ static PB_CommandStatus rpc_system_storage_get_file_error(File* file) { return rpc_system_storage_get_error(storage_file_get_error(file)); } +static void rpc_system_storage_info_process(const PB_Main* request, void* context) { + furi_assert(request); + furi_assert(context); + furi_assert(request->which_content == PB_Main_storage_info_request_tag); + + RpcStorageSystem* rpc_storage = context; + rpc_system_storage_reset_state(rpc_storage, true); + + PB_Main* response = furi_alloc(sizeof(PB_Main)); + response->command_id = request->command_id; + + Storage* fs_api = furi_record_open("storage"); + + FS_Error error = storage_common_fs_info( + fs_api, + request->content.storage_info_request.path, + &response->content.storage_info_response.total_space, + &response->content.storage_info_response.free_space); + + response->command_status = rpc_system_storage_get_error(error); + if(error == FSE_OK) { + response->which_content = PB_Main_storage_info_response_tag; + } else { + response->which_content = PB_Main_empty_tag; + } + + rpc_send_and_release(rpc_storage->rpc, response); + free(response); + furi_record_close("storage"); +} + static void rpc_system_storage_stat_process(const PB_Main* request, void* context) { furi_assert(request); furi_assert(context); @@ -388,6 +419,7 @@ static void rpc_system_storage_mkdir_process(const PB_Main* request, void* conte } else { status = PB_CommandStatus_ERROR_INVALID_PARAMETERS; } + furi_record_close("storage"); rpc_send_and_release_empty(rpc_storage->rpc, request->command_id, status); } @@ -453,6 +485,26 @@ static void rpc_system_storage_md5sum_process(const PB_Main* request, void* cont furi_record_close("storage"); } +static void rpc_system_storage_rename_process(const PB_Main* request, void* context) { + furi_assert(request); + furi_assert(request->which_content == PB_Main_storage_rename_request_tag); + furi_assert(context); + RpcStorageSystem* rpc_storage = context; + PB_CommandStatus status; + rpc_system_storage_reset_state(rpc_storage, true); + + Storage* fs_api = furi_record_open("storage"); + + FS_Error error = storage_common_rename( + fs_api, + request->content.storage_rename_request.old_path, + request->content.storage_rename_request.new_path); + status = rpc_system_storage_get_error(error); + + furi_record_close("storage"); + rpc_send_and_release_empty(rpc_storage->rpc, request->command_id, status); +} + void* rpc_system_storage_alloc(Rpc* rpc) { furi_assert(rpc); @@ -467,6 +519,9 @@ void* rpc_system_storage_alloc(Rpc* rpc) { .context = rpc_storage, }; + rpc_handler.message_handler = rpc_system_storage_info_process; + rpc_add_handler(rpc, PB_Main_storage_info_request_tag, &rpc_handler); + rpc_handler.message_handler = rpc_system_storage_stat_process; rpc_add_handler(rpc, PB_Main_storage_stat_request_tag, &rpc_handler); @@ -488,6 +543,9 @@ void* rpc_system_storage_alloc(Rpc* rpc) { rpc_handler.message_handler = rpc_system_storage_md5sum_process; rpc_add_handler(rpc, PB_Main_storage_md5sum_request_tag, &rpc_handler); + rpc_handler.message_handler = rpc_system_storage_rename_process; + rpc_add_handler(rpc, PB_Main_storage_rename_request_tag, &rpc_handler); + return rpc_storage; } diff --git a/applications/rpc/rpc_system.c b/applications/rpc/rpc_system.c new file mode 100644 index 00000000..92a770ad --- /dev/null +++ b/applications/rpc/rpc_system.c @@ -0,0 +1,118 @@ +#include "flipper.pb.h" +#include "rpc_i.h" +#include "status.pb.h" + +#include +#include + +void rpc_system_system_ping_process(const PB_Main* msg_request, void* context) { + furi_assert(msg_request); + furi_assert(msg_request->which_content == PB_Main_system_ping_request_tag); + furi_assert(context); + Rpc* rpc = context; + + if(msg_request->has_next) { + rpc_send_and_release_empty( + rpc, msg_request->command_id, PB_CommandStatus_ERROR_INVALID_PARAMETERS); + return; + } + + PB_Main msg_response = PB_Main_init_default; + msg_response.has_next = false; + msg_response.command_status = PB_CommandStatus_OK; + msg_response.command_id = msg_request->command_id; + msg_response.which_content = PB_Main_system_ping_response_tag; + + const PB_System_PingRequest* request = &msg_request->content.system_ping_request; + PB_System_PingResponse* response = &msg_response.content.system_ping_response; + if(request->data && (request->data->size > 0)) { + response->data = furi_alloc(PB_BYTES_ARRAY_T_ALLOCSIZE(request->data->size)); + memcpy(response->data->bytes, request->data->bytes, request->data->size); + response->data->size = request->data->size; + } + + rpc_send_and_release(rpc, &msg_response); +} + +void rpc_system_system_reboot_process(const PB_Main* request, void* context) { + furi_assert(request); + furi_assert(request->which_content == PB_Main_system_reboot_request_tag); + furi_assert(context); + Rpc* rpc = context; + + const int mode = request->content.system_reboot_request.mode; + + if(mode == PB_System_RebootRequest_RebootMode_OS) { + power_reboot(PowerBootModeNormal); + } else if(mode == PB_System_RebootRequest_RebootMode_DFU) { + power_reboot(PowerBootModeDfu); + } else { + rpc_send_and_release_empty( + rpc, request->command_id, PB_CommandStatus_ERROR_INVALID_PARAMETERS); + } +} + +typedef struct { + Rpc* rpc; + PB_Main* response; +} RpcSystemSystemDeviceInfoContext; + +void rpc_system_system_device_info_callback( + const char* key, + const char* value, + bool last, + void* context) { + furi_assert(key); + furi_assert(value); + furi_assert(context); + RpcSystemSystemDeviceInfoContext* ctx = context; + + char* str_key = strdup(key); + char* str_value = strdup(value); + + ctx->response->has_next = !last; + ctx->response->content.system_device_info_response.key = str_key; + ctx->response->content.system_device_info_response.value = str_value; + + rpc_send_and_release(ctx->rpc, ctx->response); +} + +void rpc_system_system_device_info_process(const PB_Main* request, void* context) { + furi_assert(request); + furi_assert(request->which_content == PB_Main_system_device_info_request_tag); + furi_assert(context); + Rpc* rpc = context; + + PB_Main* response = furi_alloc(sizeof(PB_Main)); + response->command_id = request->command_id; + response->which_content = PB_Main_system_device_info_response_tag; + response->command_status = PB_CommandStatus_OK; + + RpcSystemSystemDeviceInfoContext device_info_context = { + .rpc = rpc, + .response = response, + }; + + furi_hal_info_get(rpc_system_system_device_info_callback, &device_info_context); + + free(response); +} + +void* rpc_system_system_alloc(Rpc* rpc) { + RpcHandler rpc_handler = { + .message_handler = NULL, + .decode_submessage = NULL, + .context = rpc, + }; + + rpc_handler.message_handler = rpc_system_system_ping_process; + rpc_add_handler(rpc, PB_Main_system_ping_request_tag, &rpc_handler); + + rpc_handler.message_handler = rpc_system_system_reboot_process; + rpc_add_handler(rpc, PB_Main_system_reboot_request_tag, &rpc_handler); + + rpc_handler.message_handler = rpc_system_system_device_info_process; + rpc_add_handler(rpc, PB_Main_system_device_info_request_tag, &rpc_handler); + + return NULL; +} diff --git a/applications/tests/rpc/rpc_test.c b/applications/tests/rpc/rpc_test.c index dbe1a324..599ca266 100644 --- a/applications/tests/rpc/rpc_test.c +++ b/applications/tests/rpc/rpc_test.c @@ -196,8 +196,8 @@ static void test_rpc_add_ping_to_list(MsgList_t msg_list, bool request, uint32_t response->command_status = PB_CommandStatus_OK; response->cb_content.funcs.encode = NULL; response->has_next = false; - response->which_content = (request == PING_REQUEST) ? PB_Main_ping_request_tag : - PB_Main_ping_response_tag; + response->which_content = (request == PING_REQUEST) ? PB_Main_system_ping_request_tag : + PB_Main_system_ping_response_tag; } static void test_rpc_create_simple_message( @@ -209,8 +209,7 @@ static void test_rpc_create_simple_message( char* str_copy = NULL; if(str) { - str_copy = furi_alloc(strlen(str) + 1); - strcpy(str_copy, str); + str_copy = strdup(str); } message->command_id = command_id; message->command_status = PB_CommandStatus_OK; @@ -218,6 +217,9 @@ static void test_rpc_create_simple_message( message->which_content = tag; message->has_next = false; switch(tag) { + case PB_Main_storage_info_request_tag: + message->content.storage_info_request.path = str_copy; + break; case PB_Main_storage_stat_request_tag: message->content.storage_stat_request.path = str_copy; break; @@ -268,9 +270,7 @@ static void test_rpc_add_read_or_write_to_list( request->command_status = PB_CommandStatus_OK; if(write == WRITE_REQUEST) { - size_t path_size = strlen(path) + 1; - request->content.storage_write_request.path = furi_alloc(path_size); - strncpy(request->content.storage_write_request.path, path, path_size); + request->content.storage_write_request.path = strdup(path); request->which_content = PB_Main_storage_write_request_tag; request->content.storage_write_request.has_file = true; msg_file = &request->content.storage_write_request.file; @@ -353,10 +353,10 @@ static void test_rpc_compare_messages(PB_Main* result, PB_Main* expected) { switch(result->which_content) { case PB_Main_empty_tag: - case PB_Main_ping_response_tag: + case PB_Main_system_ping_response_tag: /* nothing to check */ break; - case PB_Main_ping_request_tag: + case PB_Main_system_ping_request_tag: case PB_Main_storage_list_request_tag: case PB_Main_storage_read_request_tag: case PB_Main_storage_write_request_tag: @@ -372,6 +372,15 @@ static void test_rpc_compare_messages(PB_Main* result, PB_Main* expected) { mu_check(result_locked == expected_locked); break; } + case PB_Main_storage_info_response_tag: { + uint64_t result_total_space = result->content.storage_info_response.total_space; + uint64_t expected_total_space = expected->content.storage_info_response.total_space; + mu_check(result_total_space == expected_total_space); + + uint64_t result_free_space = result->content.storage_info_response.free_space; + uint64_t expected_free_space = expected->content.storage_info_response.free_space; + mu_check(result_free_space == expected_free_space); + } break; case PB_Main_storage_stat_response_tag: { bool result_has_msg_file = result->content.storage_stat_response.has_file; bool expected_has_msg_file = expected->content.storage_stat_response.has_file; @@ -701,6 +710,38 @@ static void test_create_file(const char* path, size_t size) { furi_check(test_is_exists(path)); } +static void test_rpc_storage_info_run(const char* path, uint32_t command_id) { + PB_Main request; + MsgList_t expected_msg_list; + MsgList_init(expected_msg_list); + + test_rpc_create_simple_message(&request, PB_Main_storage_info_request_tag, path, command_id); + + PB_Main* response = MsgList_push_new(expected_msg_list); + response->command_id = command_id; + + Storage* fs_api = furi_record_open("storage"); + + FS_Error error = storage_common_fs_info( + fs_api, + path, + &response->content.storage_info_response.total_space, + &response->content.storage_info_response.free_space); + + response->command_status = rpc_system_storage_get_error(error); + if(error == FSE_OK) { + response->which_content = PB_Main_storage_info_response_tag; + } else { + response->which_content = PB_Main_empty_tag; + } + + test_rpc_encode_and_feed_one(&request); + test_rpc_decode_and_compare(expected_msg_list); + + pb_release(&PB_Main_msg, &request); + test_rpc_free_msg_list(expected_msg_list); +} + static void test_rpc_storage_stat_run(const char* path, uint32_t command_id) { PB_Main request; MsgList_t expected_msg_list; @@ -735,6 +776,12 @@ static void test_rpc_storage_stat_run(const char* path, uint32_t command_id) { test_rpc_free_msg_list(expected_msg_list); } +MU_TEST(test_storage_info) { + test_rpc_storage_info_run("/any", ++command_id); + test_rpc_storage_info_run("/int", ++command_id); + test_rpc_storage_info_run("/ext", ++command_id); +} + #define TEST_DIR_STAT_NAME TEST_DIR "stat_dir" #define TEST_DIR_STAT TEST_DIR_STAT_NAME "/" MU_TEST(test_storage_stat) { @@ -928,7 +975,7 @@ MU_TEST(test_storage_interrupt_continuous_another_system) { .command_status = PB_CommandStatus_OK, .cb_content.funcs.encode = NULL, .has_next = false, - .which_content = PB_Main_ping_request_tag, + .which_content = PB_Main_system_ping_request_tag, }; MsgList_it_t it; @@ -1162,6 +1209,54 @@ MU_TEST(test_storage_md5sum) { test_storage_md5sum_run(TEST_DIR "file2.txt", ++command_id, md5sum2, PB_CommandStatus_OK); } +static void test_rpc_storage_rename_run( + const char* old_path, + const char* new_path, + uint32_t command_id, + PB_CommandStatus status) { + PB_Main request; + MsgList_t expected_msg_list; + MsgList_init(expected_msg_list); + + char* str_old_path = strdup(old_path); + char* str_new_path = strdup(new_path); + + request.command_id = command_id; + request.command_status = PB_CommandStatus_OK; + request.cb_content.funcs.encode = NULL; + request.which_content = PB_Main_storage_rename_request_tag; + request.has_next = false; + request.content.storage_rename_request.old_path = str_old_path; + request.content.storage_rename_request.new_path = str_new_path; + + test_rpc_add_empty_to_list(expected_msg_list, status, command_id); + + test_rpc_encode_and_feed_one(&request); + test_rpc_decode_and_compare(expected_msg_list); + + pb_release(&PB_Main_msg, &request); + test_rpc_free_msg_list(expected_msg_list); +} + +MU_TEST(test_storage_rename) { + test_rpc_storage_rename_run( + NULL, NULL, ++command_id, PB_CommandStatus_ERROR_STORAGE_INVALID_NAME); + + furi_check(!test_is_exists(TEST_DIR "empty.txt")); + test_create_file(TEST_DIR "empty.txt", 0); + test_rpc_storage_rename_run( + TEST_DIR "empty.txt", TEST_DIR "empty2.txt", ++command_id, PB_CommandStatus_OK); + mu_check(!test_is_exists(TEST_DIR "empty.txt")); + mu_check(test_is_exists(TEST_DIR "empty2.txt")); + + furi_check(!test_is_exists(TEST_DIR "dir1")); + test_create_dir(TEST_DIR "dir1"); + test_rpc_storage_rename_run( + TEST_DIR "dir1", TEST_DIR "dir2", ++command_id, PB_CommandStatus_OK); + mu_check(!test_is_exists(TEST_DIR "dir1")); + mu_check(test_is_exists(TEST_DIR "dir2")); +} + MU_TEST(test_ping) { MsgList_t input_msg_list; MsgList_init(input_msg_list); @@ -1196,7 +1291,7 @@ MU_TEST(test_ping) { // 3) test for one push of several packets // 4) test for fill buffer till end (great varint) and close connection -MU_TEST_SUITE(test_rpc_status) { +MU_TEST_SUITE(test_rpc_system) { MU_SUITE_CONFIGURE(&test_rpc_setup, &test_rpc_teardown); MU_RUN_TEST(test_ping); @@ -1205,6 +1300,7 @@ MU_TEST_SUITE(test_rpc_status) { MU_TEST_SUITE(test_rpc_storage) { MU_SUITE_CONFIGURE(&test_rpc_storage_setup, &test_rpc_storage_teardown); + MU_RUN_TEST(test_storage_info); MU_RUN_TEST(test_storage_stat); MU_RUN_TEST(test_storage_list); MU_RUN_TEST(test_storage_read); @@ -1214,6 +1310,7 @@ MU_TEST_SUITE(test_rpc_storage) { MU_RUN_TEST(test_storage_delete_recursive); MU_RUN_TEST(test_storage_mkdir); MU_RUN_TEST(test_storage_md5sum); + MU_RUN_TEST(test_storage_rename); MU_RUN_TEST(test_storage_interrupt_continuous_same_system); MU_RUN_TEST(test_storage_interrupt_continuous_another_system); } @@ -1230,16 +1327,14 @@ static void test_app_create_request( request->has_next = false; if(app_name) { - char* msg_app_name = furi_alloc(strlen(app_name) + 1); - strcpy(msg_app_name, app_name); + char* msg_app_name = strdup(app_name); request->content.app_start_request.name = msg_app_name; } else { request->content.app_start_request.name = NULL; } if(app_args) { - char* msg_app_args = furi_alloc(strlen(app_args) + 1); - strcpy(msg_app_args, app_args); + char* msg_app_args = strdup(app_args); request->content.app_start_request.args = msg_app_args; } else { request->content.app_start_request.args = NULL; @@ -1339,7 +1434,7 @@ int run_minunit_test_rpc() { MU_RUN_SUITE(test_rpc_storage); } - MU_RUN_SUITE(test_rpc_status); + MU_RUN_SUITE(test_rpc_system); MU_RUN_SUITE(test_rpc_app); return MU_EXIT_CODE; diff --git a/assets/assets.mk b/assets/assets.mk index 8430702e..bed20ea7 100644 --- a/assets/assets.mk +++ b/assets/assets.mk @@ -13,7 +13,7 @@ PROTOBUF_SOURCES := $(shell find $(PROTOBUF_SOURCE_DIR) -type f -iname '*.proto #PROTOBUF_FILENAMES := $(notdir $(PROTOBUF)) PROTOBUF_FILENAMES := $(notdir $(addsuffix .pb.c,$(basename $(PROTOBUF_SOURCES)))) PROTOBUF := $(addprefix $(PROTOBUF_COMPILED_DIR)/,$(PROTOBUF_FILENAMES)) -PROTOBUF_CFLAGS += -DPB_ENABLE_MALLOC -DPB_WITHOUT_64BIT +PROTOBUF_CFLAGS += -DPB_ENABLE_MALLOC CFLAGS += -I$(ASSETS_COMPILED_DIR) $(PROTOBUF_CFLAGS) C_SOURCES += $(wildcard $(ASSETS_COMPILED_DIR)/*.c) diff --git a/assets/compiled/flipper.pb.h b/assets/compiled/flipper.pb.h index f164c8da..7599e3c5 100644 --- a/assets/compiled/flipper.pb.h +++ b/assets/compiled/flipper.pb.h @@ -5,7 +5,7 @@ #define PB_PB_FLIPPER_PB_H_INCLUDED #include #include "storage.pb.h" -#include "status.pb.h" +#include "system.pb.h" #include "application.pb.h" #include "gui.pb.h" @@ -62,8 +62,8 @@ typedef struct _PB_Main { pb_size_t which_content; union { PB_Empty empty; - PB_Status_PingRequest ping_request; - PB_Status_PingResponse ping_response; + PB_System_PingRequest system_ping_request; + PB_System_PingResponse system_ping_response; PB_Storage_ListRequest storage_list_request; PB_Storage_ListResponse storage_list_response; PB_Storage_ReadRequest storage_read_request; @@ -85,6 +85,12 @@ typedef struct _PB_Main { PB_Storage_StatResponse storage_stat_response; PB_Gui_StartVirtualDisplayRequest gui_start_virtual_display_request; PB_Gui_StopVirtualDisplayRequest gui_stop_virtual_display_request; + PB_Storage_InfoRequest storage_info_request; + PB_Storage_InfoResponse storage_info_response; + PB_Storage_RenameRequest storage_rename_request; + PB_System_RebootRequest system_reboot_request; + PB_System_DeviceInfoRequest system_device_info_request; + PB_System_DeviceInfoResponse system_device_info_response; } content; } PB_Main; @@ -112,8 +118,8 @@ extern "C" { #define PB_Main_command_status_tag 2 #define PB_Main_has_next_tag 3 #define PB_Main_empty_tag 4 -#define PB_Main_ping_request_tag 5 -#define PB_Main_ping_response_tag 6 +#define PB_Main_system_ping_request_tag 5 +#define PB_Main_system_ping_response_tag 6 #define PB_Main_storage_list_request_tag 7 #define PB_Main_storage_list_response_tag 8 #define PB_Main_storage_read_request_tag 9 @@ -135,6 +141,12 @@ extern "C" { #define PB_Main_storage_stat_response_tag 25 #define PB_Main_gui_start_virtual_display_request_tag 26 #define PB_Main_gui_stop_virtual_display_request_tag 27 +#define PB_Main_storage_info_request_tag 28 +#define PB_Main_storage_info_response_tag 29 +#define PB_Main_storage_rename_request_tag 30 +#define PB_Main_system_reboot_request_tag 31 +#define PB_Main_system_device_info_request_tag 32 +#define PB_Main_system_device_info_response_tag 33 /* Struct field encoding specification for nanopb */ #define PB_Empty_FIELDLIST(X, a) \ @@ -152,8 +164,8 @@ X(a, STATIC, SINGULAR, UINT32, command_id, 1) \ X(a, STATIC, SINGULAR, UENUM, command_status, 2) \ X(a, STATIC, SINGULAR, BOOL, has_next, 3) \ X(a, STATIC, ONEOF, MSG_W_CB, (content,empty,content.empty), 4) \ -X(a, STATIC, ONEOF, MSG_W_CB, (content,ping_request,content.ping_request), 5) \ -X(a, STATIC, ONEOF, MSG_W_CB, (content,ping_response,content.ping_response), 6) \ +X(a, STATIC, ONEOF, MSG_W_CB, (content,system_ping_request,content.system_ping_request), 5) \ +X(a, STATIC, ONEOF, MSG_W_CB, (content,system_ping_response,content.system_ping_response), 6) \ X(a, STATIC, ONEOF, MSG_W_CB, (content,storage_list_request,content.storage_list_request), 7) \ X(a, STATIC, ONEOF, MSG_W_CB, (content,storage_list_response,content.storage_list_response), 8) \ X(a, STATIC, ONEOF, MSG_W_CB, (content,storage_read_request,content.storage_read_request), 9) \ @@ -174,12 +186,18 @@ X(a, STATIC, ONEOF, MSG_W_CB, (content,gui_send_input_event_request,content X(a, STATIC, ONEOF, MSG_W_CB, (content,storage_stat_request,content.storage_stat_request), 24) \ X(a, STATIC, ONEOF, MSG_W_CB, (content,storage_stat_response,content.storage_stat_response), 25) \ X(a, STATIC, ONEOF, MSG_W_CB, (content,gui_start_virtual_display_request,content.gui_start_virtual_display_request), 26) \ -X(a, STATIC, ONEOF, MSG_W_CB, (content,gui_stop_virtual_display_request,content.gui_stop_virtual_display_request), 27) +X(a, STATIC, ONEOF, MSG_W_CB, (content,gui_stop_virtual_display_request,content.gui_stop_virtual_display_request), 27) \ +X(a, STATIC, ONEOF, MSG_W_CB, (content,storage_info_request,content.storage_info_request), 28) \ +X(a, STATIC, ONEOF, MSG_W_CB, (content,storage_info_response,content.storage_info_response), 29) \ +X(a, STATIC, ONEOF, MSG_W_CB, (content,storage_rename_request,content.storage_rename_request), 30) \ +X(a, STATIC, ONEOF, MSG_W_CB, (content,system_reboot_request,content.system_reboot_request), 31) \ +X(a, STATIC, ONEOF, MSG_W_CB, (content,system_device_info_request,content.system_device_info_request), 32) \ +X(a, STATIC, ONEOF, MSG_W_CB, (content,system_device_info_response,content.system_device_info_response), 33) #define PB_Main_CALLBACK NULL #define PB_Main_DEFAULT NULL #define PB_Main_content_empty_MSGTYPE PB_Empty -#define PB_Main_content_ping_request_MSGTYPE PB_Status_PingRequest -#define PB_Main_content_ping_response_MSGTYPE PB_Status_PingResponse +#define PB_Main_content_system_ping_request_MSGTYPE PB_System_PingRequest +#define PB_Main_content_system_ping_response_MSGTYPE PB_System_PingResponse #define PB_Main_content_storage_list_request_MSGTYPE PB_Storage_ListRequest #define PB_Main_content_storage_list_response_MSGTYPE PB_Storage_ListResponse #define PB_Main_content_storage_read_request_MSGTYPE PB_Storage_ReadRequest @@ -201,6 +219,12 @@ X(a, STATIC, ONEOF, MSG_W_CB, (content,gui_stop_virtual_display_request,con #define PB_Main_content_storage_stat_response_MSGTYPE PB_Storage_StatResponse #define PB_Main_content_gui_start_virtual_display_request_MSGTYPE PB_Gui_StartVirtualDisplayRequest #define PB_Main_content_gui_stop_virtual_display_request_MSGTYPE PB_Gui_StopVirtualDisplayRequest +#define PB_Main_content_storage_info_request_MSGTYPE PB_Storage_InfoRequest +#define PB_Main_content_storage_info_response_MSGTYPE PB_Storage_InfoResponse +#define PB_Main_content_storage_rename_request_MSGTYPE PB_Storage_RenameRequest +#define PB_Main_content_system_reboot_request_MSGTYPE PB_System_RebootRequest +#define PB_Main_content_system_device_info_request_MSGTYPE PB_System_DeviceInfoRequest +#define PB_Main_content_system_device_info_response_MSGTYPE PB_System_DeviceInfoResponse extern const pb_msgdesc_t PB_Empty_msg; extern const pb_msgdesc_t PB_StopSession_msg; @@ -214,9 +238,9 @@ extern const pb_msgdesc_t PB_Main_msg; /* Maximum encoded size of messages (where known) */ #define PB_Empty_size 0 #define PB_StopSession_size 0 -#if defined(PB_Status_PingRequest_size) && defined(PB_Status_PingResponse_size) && defined(PB_Storage_ListRequest_size) && defined(PB_Storage_ListResponse_size) && defined(PB_Storage_ReadRequest_size) && defined(PB_Storage_ReadResponse_size) && defined(PB_Storage_WriteRequest_size) && defined(PB_Storage_DeleteRequest_size) && defined(PB_Storage_MkdirRequest_size) && defined(PB_Storage_Md5sumRequest_size) && defined(PB_App_StartRequest_size) && defined(PB_Gui_ScreenFrame_size) && defined(PB_Storage_StatRequest_size) && defined(PB_Storage_StatResponse_size) +#if defined(PB_System_PingRequest_size) && defined(PB_System_PingResponse_size) && defined(PB_Storage_ListRequest_size) && defined(PB_Storage_ListResponse_size) && defined(PB_Storage_ReadRequest_size) && defined(PB_Storage_ReadResponse_size) && defined(PB_Storage_WriteRequest_size) && defined(PB_Storage_DeleteRequest_size) && defined(PB_Storage_MkdirRequest_size) && defined(PB_Storage_Md5sumRequest_size) && defined(PB_App_StartRequest_size) && defined(PB_Gui_ScreenFrame_size) && defined(PB_Storage_StatRequest_size) && defined(PB_Storage_StatResponse_size) && defined(PB_Storage_InfoRequest_size) && defined(PB_Storage_RenameRequest_size) && defined(PB_System_DeviceInfoResponse_size) #define PB_Main_size (10 + sizeof(union PB_Main_content_size_union)) -union PB_Main_content_size_union {char f5[(6 + PB_Status_PingRequest_size)]; char f6[(6 + PB_Status_PingResponse_size)]; char f7[(6 + PB_Storage_ListRequest_size)]; char f8[(6 + PB_Storage_ListResponse_size)]; char f9[(6 + PB_Storage_ReadRequest_size)]; char f10[(6 + PB_Storage_ReadResponse_size)]; char f11[(6 + PB_Storage_WriteRequest_size)]; char f12[(6 + PB_Storage_DeleteRequest_size)]; char f13[(6 + PB_Storage_MkdirRequest_size)]; char f14[(6 + PB_Storage_Md5sumRequest_size)]; char f16[(7 + PB_App_StartRequest_size)]; char f22[(7 + PB_Gui_ScreenFrame_size)]; char f24[(7 + PB_Storage_StatRequest_size)]; char f25[(7 + PB_Storage_StatResponse_size)]; char f0[36];}; +union PB_Main_content_size_union {char f5[(6 + PB_System_PingRequest_size)]; char f6[(6 + PB_System_PingResponse_size)]; char f7[(6 + PB_Storage_ListRequest_size)]; char f8[(6 + PB_Storage_ListResponse_size)]; char f9[(6 + PB_Storage_ReadRequest_size)]; char f10[(6 + PB_Storage_ReadResponse_size)]; char f11[(6 + PB_Storage_WriteRequest_size)]; char f12[(6 + PB_Storage_DeleteRequest_size)]; char f13[(6 + PB_Storage_MkdirRequest_size)]; char f14[(6 + PB_Storage_Md5sumRequest_size)]; char f16[(7 + PB_App_StartRequest_size)]; char f22[(7 + PB_Gui_ScreenFrame_size)]; char f24[(7 + PB_Storage_StatRequest_size)]; char f25[(7 + PB_Storage_StatResponse_size)]; char f28[(7 + PB_Storage_InfoRequest_size)]; char f30[(7 + PB_Storage_RenameRequest_size)]; char f33[(7 + PB_System_DeviceInfoResponse_size)]; char f0[36];}; #endif #ifdef __cplusplus diff --git a/assets/compiled/storage.pb.c b/assets/compiled/storage.pb.c index 24577c23..9db544cb 100644 --- a/assets/compiled/storage.pb.c +++ b/assets/compiled/storage.pb.c @@ -9,6 +9,12 @@ PB_BIND(PB_Storage_File, PB_Storage_File, AUTO) +PB_BIND(PB_Storage_InfoRequest, PB_Storage_InfoRequest, AUTO) + + +PB_BIND(PB_Storage_InfoResponse, PB_Storage_InfoResponse, AUTO) + + PB_BIND(PB_Storage_StatRequest, PB_Storage_StatRequest, AUTO) @@ -42,5 +48,8 @@ PB_BIND(PB_Storage_Md5sumRequest, PB_Storage_Md5sumRequest, AUTO) PB_BIND(PB_Storage_Md5sumResponse, PB_Storage_Md5sumResponse, AUTO) +PB_BIND(PB_Storage_RenameRequest, PB_Storage_RenameRequest, AUTO) + + diff --git a/assets/compiled/storage.pb.h b/assets/compiled/storage.pb.h index 2e82a8de..8a86c937 100644 --- a/assets/compiled/storage.pb.h +++ b/assets/compiled/storage.pb.h @@ -16,6 +16,10 @@ typedef enum _PB_Storage_File_FileType { } PB_Storage_File_FileType; /* Struct definitions */ +typedef struct _PB_Storage_InfoRequest { + char *path; +} PB_Storage_InfoRequest; + typedef struct _PB_Storage_ListRequest { char *path; } PB_Storage_ListRequest; @@ -32,6 +36,11 @@ typedef struct _PB_Storage_ReadRequest { char *path; } PB_Storage_ReadRequest; +typedef struct _PB_Storage_RenameRequest { + char *old_path; + char *new_path; +} PB_Storage_RenameRequest; + typedef struct _PB_Storage_StatRequest { char *path; } PB_Storage_StatRequest; @@ -48,6 +57,11 @@ typedef struct _PB_Storage_File { pb_bytes_array_t *data; } PB_Storage_File; +typedef struct _PB_Storage_InfoResponse { + uint64_t total_space; + uint64_t free_space; +} PB_Storage_InfoResponse; + typedef struct _PB_Storage_Md5sumResponse { char md5sum[33]; } PB_Storage_Md5sumResponse; @@ -86,6 +100,8 @@ extern "C" { /* Initializer values for message structs */ #define PB_Storage_File_init_default {_PB_Storage_File_FileType_MIN, NULL, 0, NULL} +#define PB_Storage_InfoRequest_init_default {NULL} +#define PB_Storage_InfoResponse_init_default {0, 0} #define PB_Storage_StatRequest_init_default {NULL} #define PB_Storage_StatResponse_init_default {false, PB_Storage_File_init_default} #define PB_Storage_ListRequest_init_default {NULL} @@ -97,7 +113,10 @@ extern "C" { #define PB_Storage_MkdirRequest_init_default {NULL} #define PB_Storage_Md5sumRequest_init_default {NULL} #define PB_Storage_Md5sumResponse_init_default {""} +#define PB_Storage_RenameRequest_init_default {NULL, NULL} #define PB_Storage_File_init_zero {_PB_Storage_File_FileType_MIN, NULL, 0, NULL} +#define PB_Storage_InfoRequest_init_zero {NULL} +#define PB_Storage_InfoResponse_init_zero {0, 0} #define PB_Storage_StatRequest_init_zero {NULL} #define PB_Storage_StatResponse_init_zero {false, PB_Storage_File_init_zero} #define PB_Storage_ListRequest_init_zero {NULL} @@ -109,12 +128,16 @@ extern "C" { #define PB_Storage_MkdirRequest_init_zero {NULL} #define PB_Storage_Md5sumRequest_init_zero {NULL} #define PB_Storage_Md5sumResponse_init_zero {""} +#define PB_Storage_RenameRequest_init_zero {NULL, NULL} /* Field tags (for use in manual encoding/decoding) */ +#define PB_Storage_InfoRequest_path_tag 1 #define PB_Storage_ListRequest_path_tag 1 #define PB_Storage_Md5sumRequest_path_tag 1 #define PB_Storage_MkdirRequest_path_tag 1 #define PB_Storage_ReadRequest_path_tag 1 +#define PB_Storage_RenameRequest_old_path_tag 1 +#define PB_Storage_RenameRequest_new_path_tag 2 #define PB_Storage_StatRequest_path_tag 1 #define PB_Storage_DeleteRequest_path_tag 1 #define PB_Storage_DeleteRequest_recursive_tag 2 @@ -122,6 +145,8 @@ extern "C" { #define PB_Storage_File_name_tag 2 #define PB_Storage_File_size_tag 3 #define PB_Storage_File_data_tag 4 +#define PB_Storage_InfoResponse_total_space_tag 1 +#define PB_Storage_InfoResponse_free_space_tag 2 #define PB_Storage_Md5sumResponse_md5sum_tag 1 #define PB_Storage_ListResponse_file_tag 1 #define PB_Storage_ReadResponse_file_tag 1 @@ -138,6 +163,17 @@ X(a, POINTER, SINGULAR, BYTES, data, 4) #define PB_Storage_File_CALLBACK NULL #define PB_Storage_File_DEFAULT NULL +#define PB_Storage_InfoRequest_FIELDLIST(X, a) \ +X(a, POINTER, SINGULAR, STRING, path, 1) +#define PB_Storage_InfoRequest_CALLBACK NULL +#define PB_Storage_InfoRequest_DEFAULT NULL + +#define PB_Storage_InfoResponse_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UINT64, total_space, 1) \ +X(a, STATIC, SINGULAR, UINT64, free_space, 2) +#define PB_Storage_InfoResponse_CALLBACK NULL +#define PB_Storage_InfoResponse_DEFAULT NULL + #define PB_Storage_StatRequest_FIELDLIST(X, a) \ X(a, POINTER, SINGULAR, STRING, path, 1) #define PB_Storage_StatRequest_CALLBACK NULL @@ -199,7 +235,15 @@ X(a, STATIC, SINGULAR, STRING, md5sum, 1) #define PB_Storage_Md5sumResponse_CALLBACK NULL #define PB_Storage_Md5sumResponse_DEFAULT NULL +#define PB_Storage_RenameRequest_FIELDLIST(X, a) \ +X(a, POINTER, SINGULAR, STRING, old_path, 1) \ +X(a, POINTER, SINGULAR, STRING, new_path, 2) +#define PB_Storage_RenameRequest_CALLBACK NULL +#define PB_Storage_RenameRequest_DEFAULT NULL + extern const pb_msgdesc_t PB_Storage_File_msg; +extern const pb_msgdesc_t PB_Storage_InfoRequest_msg; +extern const pb_msgdesc_t PB_Storage_InfoResponse_msg; extern const pb_msgdesc_t PB_Storage_StatRequest_msg; extern const pb_msgdesc_t PB_Storage_StatResponse_msg; extern const pb_msgdesc_t PB_Storage_ListRequest_msg; @@ -211,9 +255,12 @@ extern const pb_msgdesc_t PB_Storage_DeleteRequest_msg; extern const pb_msgdesc_t PB_Storage_MkdirRequest_msg; extern const pb_msgdesc_t PB_Storage_Md5sumRequest_msg; extern const pb_msgdesc_t PB_Storage_Md5sumResponse_msg; +extern const pb_msgdesc_t PB_Storage_RenameRequest_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define PB_Storage_File_fields &PB_Storage_File_msg +#define PB_Storage_InfoRequest_fields &PB_Storage_InfoRequest_msg +#define PB_Storage_InfoResponse_fields &PB_Storage_InfoResponse_msg #define PB_Storage_StatRequest_fields &PB_Storage_StatRequest_msg #define PB_Storage_StatResponse_fields &PB_Storage_StatResponse_msg #define PB_Storage_ListRequest_fields &PB_Storage_ListRequest_msg @@ -225,9 +272,11 @@ extern const pb_msgdesc_t PB_Storage_Md5sumResponse_msg; #define PB_Storage_MkdirRequest_fields &PB_Storage_MkdirRequest_msg #define PB_Storage_Md5sumRequest_fields &PB_Storage_Md5sumRequest_msg #define PB_Storage_Md5sumResponse_fields &PB_Storage_Md5sumResponse_msg +#define PB_Storage_RenameRequest_fields &PB_Storage_RenameRequest_msg /* Maximum encoded size of messages (where known) */ /* PB_Storage_File_size depends on runtime parameters */ +/* PB_Storage_InfoRequest_size depends on runtime parameters */ /* PB_Storage_StatRequest_size depends on runtime parameters */ /* PB_Storage_StatResponse_size depends on runtime parameters */ /* PB_Storage_ListRequest_size depends on runtime parameters */ @@ -238,6 +287,8 @@ extern const pb_msgdesc_t PB_Storage_Md5sumResponse_msg; /* PB_Storage_DeleteRequest_size depends on runtime parameters */ /* PB_Storage_MkdirRequest_size depends on runtime parameters */ /* PB_Storage_Md5sumRequest_size depends on runtime parameters */ +/* PB_Storage_RenameRequest_size depends on runtime parameters */ +#define PB_Storage_InfoResponse_size 22 #define PB_Storage_Md5sumResponse_size 34 #ifdef __cplusplus diff --git a/assets/compiled/system.pb.c b/assets/compiled/system.pb.c new file mode 100644 index 00000000..128e1c08 --- /dev/null +++ b/assets/compiled/system.pb.c @@ -0,0 +1,25 @@ +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.4.5 */ + +#include "system.pb.h" +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +PB_BIND(PB_System_PingRequest, PB_System_PingRequest, AUTO) + + +PB_BIND(PB_System_PingResponse, PB_System_PingResponse, AUTO) + + +PB_BIND(PB_System_RebootRequest, PB_System_RebootRequest, AUTO) + + +PB_BIND(PB_System_DeviceInfoRequest, PB_System_DeviceInfoRequest, AUTO) + + +PB_BIND(PB_System_DeviceInfoResponse, PB_System_DeviceInfoResponse, AUTO) + + + + diff --git a/assets/compiled/system.pb.h b/assets/compiled/system.pb.h new file mode 100644 index 00000000..84120fc9 --- /dev/null +++ b/assets/compiled/system.pb.h @@ -0,0 +1,121 @@ +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.4.5 */ + +#ifndef PB_PB_SYSTEM_SYSTEM_PB_H_INCLUDED +#define PB_PB_SYSTEM_SYSTEM_PB_H_INCLUDED +#include + +#if PB_PROTO_HEADER_VERSION != 40 +#error Regenerate this file with the current version of nanopb generator. +#endif + +/* Enum definitions */ +typedef enum _PB_System_RebootRequest_RebootMode { + PB_System_RebootRequest_RebootMode_OS = 0, + PB_System_RebootRequest_RebootMode_DFU = 1 +} PB_System_RebootRequest_RebootMode; + +/* Struct definitions */ +typedef struct _PB_System_DeviceInfoRequest { + char dummy_field; +} PB_System_DeviceInfoRequest; + +typedef struct _PB_System_DeviceInfoResponse { + char *key; + char *value; +} PB_System_DeviceInfoResponse; + +typedef struct _PB_System_PingRequest { + pb_bytes_array_t *data; +} PB_System_PingRequest; + +typedef struct _PB_System_PingResponse { + pb_bytes_array_t *data; +} PB_System_PingResponse; + +typedef struct _PB_System_RebootRequest { + PB_System_RebootRequest_RebootMode mode; +} PB_System_RebootRequest; + + +/* Helper constants for enums */ +#define _PB_System_RebootRequest_RebootMode_MIN PB_System_RebootRequest_RebootMode_OS +#define _PB_System_RebootRequest_RebootMode_MAX PB_System_RebootRequest_RebootMode_DFU +#define _PB_System_RebootRequest_RebootMode_ARRAYSIZE ((PB_System_RebootRequest_RebootMode)(PB_System_RebootRequest_RebootMode_DFU+1)) + + +#ifdef __cplusplus +extern "C" { +#endif + +/* Initializer values for message structs */ +#define PB_System_PingRequest_init_default {NULL} +#define PB_System_PingResponse_init_default {NULL} +#define PB_System_RebootRequest_init_default {_PB_System_RebootRequest_RebootMode_MIN} +#define PB_System_DeviceInfoRequest_init_default {0} +#define PB_System_DeviceInfoResponse_init_default {NULL, NULL} +#define PB_System_PingRequest_init_zero {NULL} +#define PB_System_PingResponse_init_zero {NULL} +#define PB_System_RebootRequest_init_zero {_PB_System_RebootRequest_RebootMode_MIN} +#define PB_System_DeviceInfoRequest_init_zero {0} +#define PB_System_DeviceInfoResponse_init_zero {NULL, NULL} + +/* Field tags (for use in manual encoding/decoding) */ +#define PB_System_DeviceInfoResponse_key_tag 1 +#define PB_System_DeviceInfoResponse_value_tag 2 +#define PB_System_PingRequest_data_tag 1 +#define PB_System_PingResponse_data_tag 1 +#define PB_System_RebootRequest_mode_tag 1 + +/* Struct field encoding specification for nanopb */ +#define PB_System_PingRequest_FIELDLIST(X, a) \ +X(a, POINTER, SINGULAR, BYTES, data, 1) +#define PB_System_PingRequest_CALLBACK NULL +#define PB_System_PingRequest_DEFAULT NULL + +#define PB_System_PingResponse_FIELDLIST(X, a) \ +X(a, POINTER, SINGULAR, BYTES, data, 1) +#define PB_System_PingResponse_CALLBACK NULL +#define PB_System_PingResponse_DEFAULT NULL + +#define PB_System_RebootRequest_FIELDLIST(X, a) \ +X(a, STATIC, SINGULAR, UENUM, mode, 1) +#define PB_System_RebootRequest_CALLBACK NULL +#define PB_System_RebootRequest_DEFAULT NULL + +#define PB_System_DeviceInfoRequest_FIELDLIST(X, a) \ + +#define PB_System_DeviceInfoRequest_CALLBACK NULL +#define PB_System_DeviceInfoRequest_DEFAULT NULL + +#define PB_System_DeviceInfoResponse_FIELDLIST(X, a) \ +X(a, POINTER, SINGULAR, STRING, key, 1) \ +X(a, POINTER, SINGULAR, STRING, value, 2) +#define PB_System_DeviceInfoResponse_CALLBACK NULL +#define PB_System_DeviceInfoResponse_DEFAULT NULL + +extern const pb_msgdesc_t PB_System_PingRequest_msg; +extern const pb_msgdesc_t PB_System_PingResponse_msg; +extern const pb_msgdesc_t PB_System_RebootRequest_msg; +extern const pb_msgdesc_t PB_System_DeviceInfoRequest_msg; +extern const pb_msgdesc_t PB_System_DeviceInfoResponse_msg; + +/* Defines for backwards compatibility with code written before nanopb-0.4.0 */ +#define PB_System_PingRequest_fields &PB_System_PingRequest_msg +#define PB_System_PingResponse_fields &PB_System_PingResponse_msg +#define PB_System_RebootRequest_fields &PB_System_RebootRequest_msg +#define PB_System_DeviceInfoRequest_fields &PB_System_DeviceInfoRequest_msg +#define PB_System_DeviceInfoResponse_fields &PB_System_DeviceInfoResponse_msg + +/* Maximum encoded size of messages (where known) */ +/* PB_System_PingRequest_size depends on runtime parameters */ +/* PB_System_PingResponse_size depends on runtime parameters */ +/* PB_System_DeviceInfoResponse_size depends on runtime parameters */ +#define PB_System_DeviceInfoRequest_size 0 +#define PB_System_RebootRequest_size 2 + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/assets/protobuf b/assets/protobuf index 060aead1..5761a237 160000 --- a/assets/protobuf +++ b/assets/protobuf @@ -1 +1 @@ -Subproject commit 060aead10b80622975b14a077420354d26e0be38 +Subproject commit 5761a23786b4729303bfa49142effea51870e549 diff --git a/firmware/targets/f6/furi-hal/furi-hal-info.c b/firmware/targets/f6/furi-hal/furi-hal-info.c new file mode 100644 index 00000000..783a5113 --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-info.c @@ -0,0 +1,189 @@ +#include +#include +#include + +#define ENCLAVE_SIGNATURE_KEY_SLOTS 10 +#define ENCLAVE_SIGNATURE_SIZE 16 + +static const uint8_t enclave_signature_iv[ENCLAVE_SIGNATURE_KEY_SLOTS][16] = { + {0xac, 0x5d, 0x68, 0xb8, 0x79, 0x74, 0xfc, 0x7f, 0x45, 0x02, 0x82, 0xf1, 0x48, 0x7e, 0x75, 0x8a}, + {0x38, 0xe6, 0x6a, 0x90, 0x5e, 0x5b, 0x8a, 0xa6, 0x70, 0x30, 0x04, 0x72, 0xc2, 0x42, 0xea, 0xaf}, + {0x73, 0xd5, 0x8e, 0xfb, 0x0f, 0x4b, 0xa9, 0x79, 0x0f, 0xde, 0x0e, 0x53, 0x44, 0x7d, 0xaa, 0xfd}, + {0x3c, 0x9a, 0xf4, 0x43, 0x2b, 0xfe, 0xea, 0xae, 0x8c, 0xc6, 0xd1, 0x60, 0xd2, 0x96, 0x64, 0xa9}, + {0x10, 0xac, 0x7b, 0x63, 0x03, 0x7f, 0x43, 0x18, 0xec, 0x9d, 0x9c, 0xc4, 0x01, 0xdc, 0x35, 0xa7}, + {0x26, 0x21, 0x64, 0xe6, 0xd0, 0xf2, 0x47, 0x49, 0xdc, 0x36, 0xcd, 0x68, 0x0c, 0x91, 0x03, 0x44}, + {0x7a, 0xbd, 0xce, 0x9c, 0x24, 0x7a, 0x2a, 0xb1, 0x3c, 0x4f, 0x5a, 0x7d, 0x80, 0x3e, 0xfc, 0x0d}, + {0xcd, 0xdd, 0xd3, 0x02, 0x85, 0x65, 0x43, 0x83, 0xf9, 0xac, 0x75, 0x2f, 0x21, 0xef, 0x28, 0x6b}, + {0xab, 0x73, 0x70, 0xe8, 0xe2, 0x56, 0x0f, 0x58, 0xab, 0x29, 0xa5, 0xb1, 0x13, 0x47, 0x5e, 0xe8}, + {0x4f, 0x3c, 0x43, 0x77, 0xde, 0xed, 0x79, 0xa1, 0x8d, 0x4c, 0x1f, 0xfd, 0xdb, 0x96, 0x87, 0x2e}, +}; + +static const uint8_t enclave_signature_input[ENCLAVE_SIGNATURE_KEY_SLOTS][ENCLAVE_SIGNATURE_SIZE] = { + {0x9f, 0x5c, 0xb1, 0x43, 0x17, 0x53, 0x18, 0x8c, 0x66, 0x3d, 0x39, 0x45, 0x90, 0x13, 0xa9, 0xde}, + {0xc5, 0x98, 0xe9, 0x17, 0xb8, 0x97, 0x9e, 0x03, 0x33, 0x14, 0x13, 0x8f, 0xce, 0x74, 0x0d, 0x54}, + {0x34, 0xba, 0x99, 0x59, 0x9f, 0x70, 0x67, 0xe9, 0x09, 0xee, 0x64, 0x0e, 0xb3, 0xba, 0xfb, 0x75}, + {0xdc, 0xfa, 0x6c, 0x9a, 0x6f, 0x0a, 0x3e, 0xdc, 0x42, 0xf6, 0xae, 0x0d, 0x3c, 0xf7, 0x83, 0xaf}, + {0xea, 0x2d, 0xe3, 0x1f, 0x02, 0x99, 0x1a, 0x7e, 0x6d, 0x93, 0x4c, 0xb5, 0x42, 0xf0, 0x7a, 0x9b}, + {0x53, 0x5e, 0x04, 0xa2, 0x49, 0xa0, 0x73, 0x49, 0x56, 0xb0, 0x88, 0x8c, 0x12, 0xa0, 0xe4, 0x18}, + {0x7d, 0xa7, 0xc5, 0x21, 0x7f, 0x12, 0x95, 0xdd, 0x4d, 0x77, 0x01, 0xfa, 0x71, 0x88, 0x2b, 0x7f}, + {0xdc, 0x9b, 0xc5, 0xa7, 0x6b, 0x84, 0x5c, 0x37, 0x7c, 0xec, 0x05, 0xa1, 0x9f, 0x91, 0x17, 0x3b}, + {0xea, 0xcf, 0xd9, 0x9b, 0x86, 0xcd, 0x2b, 0x43, 0x54, 0x45, 0x82, 0xc6, 0xfe, 0x73, 0x1a, 0x1a}, + {0x77, 0xb8, 0x1b, 0x90, 0xb4, 0xb7, 0x32, 0x76, 0x8f, 0x8a, 0x57, 0x06, 0xc7, 0xdd, 0x08, 0x90}, +}; + +static const uint8_t enclave_signature_expected[ENCLAVE_SIGNATURE_KEY_SLOTS][ENCLAVE_SIGNATURE_SIZE] = { + {0xe9, 0x9a, 0xce, 0xe9, 0x4d, 0xe1, 0x7f, 0x55, 0xcb, 0x8a, 0xbf, 0xf2, 0x4d, 0x98, 0x27, 0x67}, + {0x34, 0x27, 0xa7, 0xea, 0xa8, 0x98, 0x66, 0x9b, 0xed, 0x43, 0xd3, 0x93, 0xb5, 0xa2, 0x87, 0x8e}, + {0x6c, 0xf3, 0x01, 0x78, 0x53, 0x1b, 0x11, 0x32, 0xf0, 0x27, 0x2f, 0xe3, 0x7d, 0xa6, 0xe2, 0xfd}, + {0xdf, 0x7f, 0x37, 0x65, 0x2f, 0xdb, 0x7c, 0xcf, 0x5b, 0xb6, 0xe4, 0x9c, 0x63, 0xc5, 0x0f, 0xe0}, + {0x9b, 0x5c, 0xee, 0x44, 0x0e, 0xd1, 0xcb, 0x5f, 0x28, 0x9f, 0x12, 0x17, 0x59, 0x64, 0x40, 0xbb}, + {0x94, 0xc2, 0x09, 0x98, 0x62, 0xa7, 0x2b, 0x93, 0xed, 0x36, 0x1f, 0x10, 0xbc, 0x26, 0xbd, 0x41}, + {0x4d, 0xb2, 0x2b, 0xc5, 0x96, 0x47, 0x61, 0xf4, 0x16, 0xe0, 0x81, 0xc3, 0x8e, 0xb9, 0x9c, 0x9b}, + {0xc3, 0x6b, 0x83, 0x55, 0x90, 0x38, 0x0f, 0xea, 0xd1, 0x65, 0xbf, 0x32, 0x4f, 0x8e, 0x62, 0x5b}, + {0x8d, 0x5e, 0x27, 0xbc, 0x14, 0x4f, 0x08, 0xa8, 0x2b, 0x14, 0x89, 0x5e, 0xdf, 0x77, 0x04, 0x31}, + {0xc9, 0xf7, 0x03, 0xf1, 0x6c, 0x65, 0xad, 0x49, 0x74, 0xbe, 0x00, 0x54, 0xfd, 0xa6, 0x9c, 0x32}, +}; + +void furi_hal_info_get(FuriHalInfoValueCallback out, void* context) { + string_t value; + string_init(value); + + // Device Info version + out("device_info_major", "2", false, context); + out("device_info_minor", "0", false, context); + + // Model name + out("hardware_model", furi_hal_version_get_model_name(), false, context); + + // Unique ID + string_reset(value); + const uint8_t* uid = furi_hal_version_uid(); + for(size_t i = 0; i < furi_hal_version_uid_size(); i++) { + string_cat_printf(value, "%02X", uid[i]); + } + out("hardware_uid", string_get_cstr(value), false, context); + + // OTP Revision + string_printf(value, "%d", furi_hal_version_get_otp_version()); + out("hardware_otp_ver", string_get_cstr(value), false, context); + string_printf(value, "%lu", furi_hal_version_get_hw_timestamp()); + out("hardware_timestamp", string_get_cstr(value), false, context); + + // Board Revision + string_printf(value, "%d", furi_hal_version_get_hw_version()); + out("hardware_ver", string_get_cstr(value), false, context); + string_printf(value, "%d", furi_hal_version_get_hw_target()); + out("hardware_target", string_get_cstr(value), false, context); + string_printf(value, "%d", furi_hal_version_get_hw_body()); + out("hardware_body", string_get_cstr(value), false, context); + string_printf(value, "%d", furi_hal_version_get_hw_connect()); + out("hardware_connect", string_get_cstr(value), false, context); + string_printf(value, "%d", furi_hal_version_get_hw_display()); + out("hardware_display", string_get_cstr(value), false, context); + + // Board Personification + string_printf(value, "%d", furi_hal_version_get_hw_color()); + out("hardware_color", string_get_cstr(value), false, context); + string_printf(value, "%d", furi_hal_version_get_hw_region()); + out("hardware_region", string_get_cstr(value), false, context); + const char* name = furi_hal_version_get_name_ptr(); + if(name) { + out("hardware_name", name, false, context); + } + + // Bootloader Version + const Version* bootloader_version = furi_hal_version_get_bootloader_version(); + if(bootloader_version) { + out("bootloader_commit", version_get_githash(bootloader_version), false, context); + out("bootloader_branch", version_get_gitbranch(bootloader_version), false, context); + out("bootloader_branch_num", version_get_gitbranchnum(bootloader_version), false, context); + out("bootloader_version", version_get_version(bootloader_version), false, context); + out("bootloader_build_date", version_get_builddate(bootloader_version), false, context); + string_printf(value, "%d", version_get_target(bootloader_version)); + out("bootloader_target", string_get_cstr(value), false, context); + } + + // Firmware version + const Version* firmware_version = furi_hal_version_get_firmware_version(); + if(firmware_version) { + out("firmware_commit", version_get_githash(firmware_version), false, context); + out("firmware_branch", version_get_gitbranch(firmware_version), false, context); + out("firmware_branch_num", version_get_gitbranchnum(firmware_version), false, context); + out("firmware_version", version_get_version(firmware_version), false, context); + out("firmware_build_date", version_get_builddate(firmware_version), false, context); + string_printf(value, "%d", version_get_target(firmware_version)); + out("firmware_target", string_get_cstr(value), false, context); + } + + WirelessFwInfo_t pWirelessInfo; + if(furi_hal_bt_is_alive() && SHCI_GetWirelessFwInfo(&pWirelessInfo) == SHCI_Success) { + out("radio_alive", "true", false, context); + + // FUS Info + string_printf(value, "%d", pWirelessInfo.FusVersionMajor); + out("radio_fus_major", string_get_cstr(value), false, context); + string_printf(value, "%d", pWirelessInfo.FusVersionMinor); + out("radio_fus_minor", string_get_cstr(value), false, context); + string_printf(value, "%d", pWirelessInfo.FusVersionSub); + out("radio_fus_sub", string_get_cstr(value), false, context); + string_printf(value, "%dK", pWirelessInfo.FusMemorySizeSram2B); + out("radio_fus_sram2b", string_get_cstr(value), false, context); + string_printf(value, "%dK", pWirelessInfo.FusMemorySizeSram2A); + out("radio_fus_sram2a", string_get_cstr(value), false, context); + string_printf(value, "%dK", pWirelessInfo.FusMemorySizeFlash * 4); + out("radio_fus_flash", string_get_cstr(value), false, context); + + // Stack Info + string_printf(value, "%d", pWirelessInfo.StackType); + out("radio_stack_type", string_get_cstr(value), false, context); + string_printf(value, "%d", pWirelessInfo.VersionMajor); + out("radio_stack_major", string_get_cstr(value), false, context); + string_printf(value, "%d", pWirelessInfo.VersionMinor); + out("radio_stack_minor", string_get_cstr(value), false, context); + string_printf(value, "%d", pWirelessInfo.VersionSub); + out("radio_stack_sub", string_get_cstr(value), false, context); + string_printf(value, "%d", pWirelessInfo.VersionBranch); + out("radio_stack_branch", string_get_cstr(value), false, context); + string_printf(value, "%d", pWirelessInfo.VersionReleaseType); + out("radio_stack_release", string_get_cstr(value), false, context); + string_printf(value, "%dK", pWirelessInfo.MemorySizeSram2B); + out("radio_stack_sram2b", string_get_cstr(value), false, context); + string_printf(value, "%dK", pWirelessInfo.MemorySizeSram2A); + out("radio_stack_sram2a", string_get_cstr(value), false, context); + string_printf(value, "%dK", pWirelessInfo.MemorySizeSram1); + out("radio_stack_sram1", string_get_cstr(value), false, context); + string_printf(value, "%dK", pWirelessInfo.MemorySizeFlash * 4); + out("radio_stack_flash", string_get_cstr(value), false, context); + + // Mac address + string_reset(value); + const uint8_t* ble_mac = furi_hal_version_get_ble_mac(); + for(size_t i = 0; i < 6; i++) { + string_cat_printf(value, "%02X", ble_mac[i]); + } + out("radio_ble_mac", string_get_cstr(value), false, context); + + // Signature verification + uint8_t buffer[ENCLAVE_SIGNATURE_SIZE]; + size_t enclave_valid_keys = 0; + for(size_t key_slot = 0; key_slot < ENCLAVE_SIGNATURE_KEY_SLOTS; key_slot++) { + if(furi_hal_crypto_store_load_key(key_slot + 1, enclave_signature_iv[key_slot])) { + if(furi_hal_crypto_encrypt( + enclave_signature_input[key_slot], buffer, ENCLAVE_SIGNATURE_SIZE)) { + enclave_valid_keys += memcmp( + buffer, + enclave_signature_expected[key_slot], + ENCLAVE_SIGNATURE_SIZE) == 0; + } + furi_hal_crypto_store_unload_key(key_slot + 1); + } + } + string_printf(value, "%d", enclave_valid_keys); + out("enclave_valid_keys", string_get_cstr(value), false, context); + out("enclave_valid", (enclave_valid_keys == ENCLAVE_SIGNATURE_KEY_SLOTS) ? "true" : "false", true, context); + } else { + out("radio_alive", "false", true, context); + } + + string_clear(value); +} \ No newline at end of file diff --git a/firmware/targets/f7/furi-hal/furi-hal-info.c b/firmware/targets/f7/furi-hal/furi-hal-info.c new file mode 100644 index 00000000..783a5113 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-info.c @@ -0,0 +1,189 @@ +#include +#include +#include + +#define ENCLAVE_SIGNATURE_KEY_SLOTS 10 +#define ENCLAVE_SIGNATURE_SIZE 16 + +static const uint8_t enclave_signature_iv[ENCLAVE_SIGNATURE_KEY_SLOTS][16] = { + {0xac, 0x5d, 0x68, 0xb8, 0x79, 0x74, 0xfc, 0x7f, 0x45, 0x02, 0x82, 0xf1, 0x48, 0x7e, 0x75, 0x8a}, + {0x38, 0xe6, 0x6a, 0x90, 0x5e, 0x5b, 0x8a, 0xa6, 0x70, 0x30, 0x04, 0x72, 0xc2, 0x42, 0xea, 0xaf}, + {0x73, 0xd5, 0x8e, 0xfb, 0x0f, 0x4b, 0xa9, 0x79, 0x0f, 0xde, 0x0e, 0x53, 0x44, 0x7d, 0xaa, 0xfd}, + {0x3c, 0x9a, 0xf4, 0x43, 0x2b, 0xfe, 0xea, 0xae, 0x8c, 0xc6, 0xd1, 0x60, 0xd2, 0x96, 0x64, 0xa9}, + {0x10, 0xac, 0x7b, 0x63, 0x03, 0x7f, 0x43, 0x18, 0xec, 0x9d, 0x9c, 0xc4, 0x01, 0xdc, 0x35, 0xa7}, + {0x26, 0x21, 0x64, 0xe6, 0xd0, 0xf2, 0x47, 0x49, 0xdc, 0x36, 0xcd, 0x68, 0x0c, 0x91, 0x03, 0x44}, + {0x7a, 0xbd, 0xce, 0x9c, 0x24, 0x7a, 0x2a, 0xb1, 0x3c, 0x4f, 0x5a, 0x7d, 0x80, 0x3e, 0xfc, 0x0d}, + {0xcd, 0xdd, 0xd3, 0x02, 0x85, 0x65, 0x43, 0x83, 0xf9, 0xac, 0x75, 0x2f, 0x21, 0xef, 0x28, 0x6b}, + {0xab, 0x73, 0x70, 0xe8, 0xe2, 0x56, 0x0f, 0x58, 0xab, 0x29, 0xa5, 0xb1, 0x13, 0x47, 0x5e, 0xe8}, + {0x4f, 0x3c, 0x43, 0x77, 0xde, 0xed, 0x79, 0xa1, 0x8d, 0x4c, 0x1f, 0xfd, 0xdb, 0x96, 0x87, 0x2e}, +}; + +static const uint8_t enclave_signature_input[ENCLAVE_SIGNATURE_KEY_SLOTS][ENCLAVE_SIGNATURE_SIZE] = { + {0x9f, 0x5c, 0xb1, 0x43, 0x17, 0x53, 0x18, 0x8c, 0x66, 0x3d, 0x39, 0x45, 0x90, 0x13, 0xa9, 0xde}, + {0xc5, 0x98, 0xe9, 0x17, 0xb8, 0x97, 0x9e, 0x03, 0x33, 0x14, 0x13, 0x8f, 0xce, 0x74, 0x0d, 0x54}, + {0x34, 0xba, 0x99, 0x59, 0x9f, 0x70, 0x67, 0xe9, 0x09, 0xee, 0x64, 0x0e, 0xb3, 0xba, 0xfb, 0x75}, + {0xdc, 0xfa, 0x6c, 0x9a, 0x6f, 0x0a, 0x3e, 0xdc, 0x42, 0xf6, 0xae, 0x0d, 0x3c, 0xf7, 0x83, 0xaf}, + {0xea, 0x2d, 0xe3, 0x1f, 0x02, 0x99, 0x1a, 0x7e, 0x6d, 0x93, 0x4c, 0xb5, 0x42, 0xf0, 0x7a, 0x9b}, + {0x53, 0x5e, 0x04, 0xa2, 0x49, 0xa0, 0x73, 0x49, 0x56, 0xb0, 0x88, 0x8c, 0x12, 0xa0, 0xe4, 0x18}, + {0x7d, 0xa7, 0xc5, 0x21, 0x7f, 0x12, 0x95, 0xdd, 0x4d, 0x77, 0x01, 0xfa, 0x71, 0x88, 0x2b, 0x7f}, + {0xdc, 0x9b, 0xc5, 0xa7, 0x6b, 0x84, 0x5c, 0x37, 0x7c, 0xec, 0x05, 0xa1, 0x9f, 0x91, 0x17, 0x3b}, + {0xea, 0xcf, 0xd9, 0x9b, 0x86, 0xcd, 0x2b, 0x43, 0x54, 0x45, 0x82, 0xc6, 0xfe, 0x73, 0x1a, 0x1a}, + {0x77, 0xb8, 0x1b, 0x90, 0xb4, 0xb7, 0x32, 0x76, 0x8f, 0x8a, 0x57, 0x06, 0xc7, 0xdd, 0x08, 0x90}, +}; + +static const uint8_t enclave_signature_expected[ENCLAVE_SIGNATURE_KEY_SLOTS][ENCLAVE_SIGNATURE_SIZE] = { + {0xe9, 0x9a, 0xce, 0xe9, 0x4d, 0xe1, 0x7f, 0x55, 0xcb, 0x8a, 0xbf, 0xf2, 0x4d, 0x98, 0x27, 0x67}, + {0x34, 0x27, 0xa7, 0xea, 0xa8, 0x98, 0x66, 0x9b, 0xed, 0x43, 0xd3, 0x93, 0xb5, 0xa2, 0x87, 0x8e}, + {0x6c, 0xf3, 0x01, 0x78, 0x53, 0x1b, 0x11, 0x32, 0xf0, 0x27, 0x2f, 0xe3, 0x7d, 0xa6, 0xe2, 0xfd}, + {0xdf, 0x7f, 0x37, 0x65, 0x2f, 0xdb, 0x7c, 0xcf, 0x5b, 0xb6, 0xe4, 0x9c, 0x63, 0xc5, 0x0f, 0xe0}, + {0x9b, 0x5c, 0xee, 0x44, 0x0e, 0xd1, 0xcb, 0x5f, 0x28, 0x9f, 0x12, 0x17, 0x59, 0x64, 0x40, 0xbb}, + {0x94, 0xc2, 0x09, 0x98, 0x62, 0xa7, 0x2b, 0x93, 0xed, 0x36, 0x1f, 0x10, 0xbc, 0x26, 0xbd, 0x41}, + {0x4d, 0xb2, 0x2b, 0xc5, 0x96, 0x47, 0x61, 0xf4, 0x16, 0xe0, 0x81, 0xc3, 0x8e, 0xb9, 0x9c, 0x9b}, + {0xc3, 0x6b, 0x83, 0x55, 0x90, 0x38, 0x0f, 0xea, 0xd1, 0x65, 0xbf, 0x32, 0x4f, 0x8e, 0x62, 0x5b}, + {0x8d, 0x5e, 0x27, 0xbc, 0x14, 0x4f, 0x08, 0xa8, 0x2b, 0x14, 0x89, 0x5e, 0xdf, 0x77, 0x04, 0x31}, + {0xc9, 0xf7, 0x03, 0xf1, 0x6c, 0x65, 0xad, 0x49, 0x74, 0xbe, 0x00, 0x54, 0xfd, 0xa6, 0x9c, 0x32}, +}; + +void furi_hal_info_get(FuriHalInfoValueCallback out, void* context) { + string_t value; + string_init(value); + + // Device Info version + out("device_info_major", "2", false, context); + out("device_info_minor", "0", false, context); + + // Model name + out("hardware_model", furi_hal_version_get_model_name(), false, context); + + // Unique ID + string_reset(value); + const uint8_t* uid = furi_hal_version_uid(); + for(size_t i = 0; i < furi_hal_version_uid_size(); i++) { + string_cat_printf(value, "%02X", uid[i]); + } + out("hardware_uid", string_get_cstr(value), false, context); + + // OTP Revision + string_printf(value, "%d", furi_hal_version_get_otp_version()); + out("hardware_otp_ver", string_get_cstr(value), false, context); + string_printf(value, "%lu", furi_hal_version_get_hw_timestamp()); + out("hardware_timestamp", string_get_cstr(value), false, context); + + // Board Revision + string_printf(value, "%d", furi_hal_version_get_hw_version()); + out("hardware_ver", string_get_cstr(value), false, context); + string_printf(value, "%d", furi_hal_version_get_hw_target()); + out("hardware_target", string_get_cstr(value), false, context); + string_printf(value, "%d", furi_hal_version_get_hw_body()); + out("hardware_body", string_get_cstr(value), false, context); + string_printf(value, "%d", furi_hal_version_get_hw_connect()); + out("hardware_connect", string_get_cstr(value), false, context); + string_printf(value, "%d", furi_hal_version_get_hw_display()); + out("hardware_display", string_get_cstr(value), false, context); + + // Board Personification + string_printf(value, "%d", furi_hal_version_get_hw_color()); + out("hardware_color", string_get_cstr(value), false, context); + string_printf(value, "%d", furi_hal_version_get_hw_region()); + out("hardware_region", string_get_cstr(value), false, context); + const char* name = furi_hal_version_get_name_ptr(); + if(name) { + out("hardware_name", name, false, context); + } + + // Bootloader Version + const Version* bootloader_version = furi_hal_version_get_bootloader_version(); + if(bootloader_version) { + out("bootloader_commit", version_get_githash(bootloader_version), false, context); + out("bootloader_branch", version_get_gitbranch(bootloader_version), false, context); + out("bootloader_branch_num", version_get_gitbranchnum(bootloader_version), false, context); + out("bootloader_version", version_get_version(bootloader_version), false, context); + out("bootloader_build_date", version_get_builddate(bootloader_version), false, context); + string_printf(value, "%d", version_get_target(bootloader_version)); + out("bootloader_target", string_get_cstr(value), false, context); + } + + // Firmware version + const Version* firmware_version = furi_hal_version_get_firmware_version(); + if(firmware_version) { + out("firmware_commit", version_get_githash(firmware_version), false, context); + out("firmware_branch", version_get_gitbranch(firmware_version), false, context); + out("firmware_branch_num", version_get_gitbranchnum(firmware_version), false, context); + out("firmware_version", version_get_version(firmware_version), false, context); + out("firmware_build_date", version_get_builddate(firmware_version), false, context); + string_printf(value, "%d", version_get_target(firmware_version)); + out("firmware_target", string_get_cstr(value), false, context); + } + + WirelessFwInfo_t pWirelessInfo; + if(furi_hal_bt_is_alive() && SHCI_GetWirelessFwInfo(&pWirelessInfo) == SHCI_Success) { + out("radio_alive", "true", false, context); + + // FUS Info + string_printf(value, "%d", pWirelessInfo.FusVersionMajor); + out("radio_fus_major", string_get_cstr(value), false, context); + string_printf(value, "%d", pWirelessInfo.FusVersionMinor); + out("radio_fus_minor", string_get_cstr(value), false, context); + string_printf(value, "%d", pWirelessInfo.FusVersionSub); + out("radio_fus_sub", string_get_cstr(value), false, context); + string_printf(value, "%dK", pWirelessInfo.FusMemorySizeSram2B); + out("radio_fus_sram2b", string_get_cstr(value), false, context); + string_printf(value, "%dK", pWirelessInfo.FusMemorySizeSram2A); + out("radio_fus_sram2a", string_get_cstr(value), false, context); + string_printf(value, "%dK", pWirelessInfo.FusMemorySizeFlash * 4); + out("radio_fus_flash", string_get_cstr(value), false, context); + + // Stack Info + string_printf(value, "%d", pWirelessInfo.StackType); + out("radio_stack_type", string_get_cstr(value), false, context); + string_printf(value, "%d", pWirelessInfo.VersionMajor); + out("radio_stack_major", string_get_cstr(value), false, context); + string_printf(value, "%d", pWirelessInfo.VersionMinor); + out("radio_stack_minor", string_get_cstr(value), false, context); + string_printf(value, "%d", pWirelessInfo.VersionSub); + out("radio_stack_sub", string_get_cstr(value), false, context); + string_printf(value, "%d", pWirelessInfo.VersionBranch); + out("radio_stack_branch", string_get_cstr(value), false, context); + string_printf(value, "%d", pWirelessInfo.VersionReleaseType); + out("radio_stack_release", string_get_cstr(value), false, context); + string_printf(value, "%dK", pWirelessInfo.MemorySizeSram2B); + out("radio_stack_sram2b", string_get_cstr(value), false, context); + string_printf(value, "%dK", pWirelessInfo.MemorySizeSram2A); + out("radio_stack_sram2a", string_get_cstr(value), false, context); + string_printf(value, "%dK", pWirelessInfo.MemorySizeSram1); + out("radio_stack_sram1", string_get_cstr(value), false, context); + string_printf(value, "%dK", pWirelessInfo.MemorySizeFlash * 4); + out("radio_stack_flash", string_get_cstr(value), false, context); + + // Mac address + string_reset(value); + const uint8_t* ble_mac = furi_hal_version_get_ble_mac(); + for(size_t i = 0; i < 6; i++) { + string_cat_printf(value, "%02X", ble_mac[i]); + } + out("radio_ble_mac", string_get_cstr(value), false, context); + + // Signature verification + uint8_t buffer[ENCLAVE_SIGNATURE_SIZE]; + size_t enclave_valid_keys = 0; + for(size_t key_slot = 0; key_slot < ENCLAVE_SIGNATURE_KEY_SLOTS; key_slot++) { + if(furi_hal_crypto_store_load_key(key_slot + 1, enclave_signature_iv[key_slot])) { + if(furi_hal_crypto_encrypt( + enclave_signature_input[key_slot], buffer, ENCLAVE_SIGNATURE_SIZE)) { + enclave_valid_keys += memcmp( + buffer, + enclave_signature_expected[key_slot], + ENCLAVE_SIGNATURE_SIZE) == 0; + } + furi_hal_crypto_store_unload_key(key_slot + 1); + } + } + string_printf(value, "%d", enclave_valid_keys); + out("enclave_valid_keys", string_get_cstr(value), false, context); + out("enclave_valid", (enclave_valid_keys == ENCLAVE_SIGNATURE_KEY_SLOTS) ? "true" : "false", true, context); + } else { + out("radio_alive", "false", true, context); + } + + string_clear(value); +} \ No newline at end of file diff --git a/firmware/targets/furi-hal-include/furi-hal-info.h b/firmware/targets/furi-hal-include/furi-hal-info.h new file mode 100644 index 00000000..adf9819b --- /dev/null +++ b/firmware/targets/furi-hal-include/furi-hal-info.h @@ -0,0 +1,33 @@ +/** + * @file furi-hal-info.h + * Device info HAL API + */ + +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Callback type called every time another key-value pair of device information is ready + * + * @param key[in] device information type identifier + * @param value[in] device information value + * @param last[in] whether the passed key-value pair is the last one + * @param context[in] to pass to callback + */ +typedef void (*FuriHalInfoValueCallback) (const char* key, const char* value, bool last, void* context); + +/** Get device information + * + * @param[in] callback callback to provide with new data + * @param[in] context context to pass to callback + */ +void furi_hal_info_get(FuriHalInfoValueCallback callback, void* context); + +#ifdef __cplusplus +} +#endif diff --git a/firmware/targets/furi-hal-include/furi-hal.h b/firmware/targets/furi-hal-include/furi-hal.h index 2357e7fe..4c223aab 100644 --- a/firmware/targets/furi-hal-include/furi-hal.h +++ b/firmware/targets/furi-hal-include/furi-hal.h @@ -38,6 +38,7 @@ template struct STOP_EXTERNING_ME {}; #include "furi-hal-usb-hid.h" #include "furi-hal-compress.h" #include "furi-hal-uart.h" +#include "furi-hal-info.h" /** Init furi-hal */ void furi_hal_init(); diff --git a/make/toolchain.mk b/make/toolchain.mk index 9b7368c2..3b3babf4 100644 --- a/make/toolchain.mk +++ b/make/toolchain.mk @@ -27,4 +27,4 @@ endif CFLAGS += -fdata-sections -ffunction-sections -fno-math-errno -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" CPPFLAGS += -fno-threadsafe-statics -fno-use-cxa-atexit -fno-exceptions -fno-rtti -LDFLAGS += -Wl,-Map=$(OBJ_DIR)/$(PROJECT).map,--cref -Wl,--gc-sections -Wl,--undefined=uxTopUsedPriority -u _printf_float \ No newline at end of file +LDFLAGS += -Wl,-Map=$(OBJ_DIR)/$(PROJECT).map,--cref -Wl,--gc-sections -Wl,--undefined=uxTopUsedPriority -u _printf_float -n \ No newline at end of file From f54ae2597e6a9a81f69356b417da8604182de35d Mon Sep 17 00:00:00 2001 From: hedger Date: Tue, 7 Dec 2021 17:17:08 +0300 Subject: [PATCH 21/32] Bootloader size optimizations (#873) --- .../targets/f6/furi-hal/furi-hal-version.c | 22 ------------------- bootloader/targets/f6/target.c | 4 +++- .../targets/f7/furi-hal/furi-hal-version.c | 22 ------------------- bootloader/targets/f7/target.c | 4 +++- firmware/targets/f6/target.mk | 4 ++-- firmware/targets/f7/target.mk | 4 ++-- make/toolchain.mk | 2 +- 7 files changed, 11 insertions(+), 51 deletions(-) diff --git a/bootloader/targets/f6/furi-hal/furi-hal-version.c b/bootloader/targets/f6/furi-hal/furi-hal-version.c index df6d61b0..1425cd6d 100644 --- a/bootloader/targets/f6/furi-hal/furi-hal-version.c +++ b/bootloader/targets/f6/furi-hal/furi-hal-version.c @@ -87,29 +87,7 @@ typedef struct { static FuriHalVersion furi_hal_version = {0}; static void furi_hal_version_set_name(const char* name) { - if(name != NULL) { - strlcpy(furi_hal_version.name, name, FURI_HAL_VERSION_ARRAY_NAME_LENGTH); - snprintf( - furi_hal_version.device_name, - FURI_HAL_VERSION_DEVICE_NAME_LENGTH, - "xFlipper %s", - furi_hal_version.name); - } else { - snprintf(furi_hal_version.device_name, FURI_HAL_VERSION_DEVICE_NAME_LENGTH, "xFlipper"); - } - furi_hal_version.device_name[0] = 0; - - // BLE Mac address - uint32_t udn = LL_FLASH_GetUDN(); - uint32_t company_id = LL_FLASH_GetSTCompanyID(); - uint32_t device_id = LL_FLASH_GetDeviceID(); - furi_hal_version.ble_mac[0] = (uint8_t)(udn & 0x000000FF); - furi_hal_version.ble_mac[1] = (uint8_t)((udn & 0x0000FF00) >> 8); - furi_hal_version.ble_mac[2] = (uint8_t)((udn & 0x00FF0000) >> 16); - furi_hal_version.ble_mac[3] = (uint8_t)device_id; - furi_hal_version.ble_mac[4] = (uint8_t)(company_id & 0x000000FF); - furi_hal_version.ble_mac[5] = (uint8_t)((company_id & 0x0000FF00) >> 8); } static void furi_hal_version_load_otp_default() { diff --git a/bootloader/targets/f6/target.c b/bootloader/targets/f6/target.c index df694edd..0240204c 100644 --- a/bootloader/targets/f6/target.c +++ b/bootloader/targets/f6/target.c @@ -194,10 +194,12 @@ void target_display_init() { // Create payload u8g2_ClearBuffer(&fb); u8g2_SetDrawColor(&fb, 0x01); - u8g2_SetFont(&fb, u8g2_font_helvB08_tf); u8g2_DrawXBM(&fb, 0, 64 - 50, 128, 50, I_DFU_128x50); +#ifndef SLIM_BOOTLOADER + u8g2_SetFont(&fb, u8g2_font_helvB08_tf); u8g2_DrawStr(&fb, 2, 8, "Update & Recovery Mode"); u8g2_DrawStr(&fb, 2, 21, "DFU started"); +#endif // Send buffer u8g2_SetPowerSave(&fb, 0); u8g2_SendBuffer(&fb); diff --git a/bootloader/targets/f7/furi-hal/furi-hal-version.c b/bootloader/targets/f7/furi-hal/furi-hal-version.c index df6d61b0..1425cd6d 100644 --- a/bootloader/targets/f7/furi-hal/furi-hal-version.c +++ b/bootloader/targets/f7/furi-hal/furi-hal-version.c @@ -87,29 +87,7 @@ typedef struct { static FuriHalVersion furi_hal_version = {0}; static void furi_hal_version_set_name(const char* name) { - if(name != NULL) { - strlcpy(furi_hal_version.name, name, FURI_HAL_VERSION_ARRAY_NAME_LENGTH); - snprintf( - furi_hal_version.device_name, - FURI_HAL_VERSION_DEVICE_NAME_LENGTH, - "xFlipper %s", - furi_hal_version.name); - } else { - snprintf(furi_hal_version.device_name, FURI_HAL_VERSION_DEVICE_NAME_LENGTH, "xFlipper"); - } - furi_hal_version.device_name[0] = 0; - - // BLE Mac address - uint32_t udn = LL_FLASH_GetUDN(); - uint32_t company_id = LL_FLASH_GetSTCompanyID(); - uint32_t device_id = LL_FLASH_GetDeviceID(); - furi_hal_version.ble_mac[0] = (uint8_t)(udn & 0x000000FF); - furi_hal_version.ble_mac[1] = (uint8_t)((udn & 0x0000FF00) >> 8); - furi_hal_version.ble_mac[2] = (uint8_t)((udn & 0x00FF0000) >> 16); - furi_hal_version.ble_mac[3] = (uint8_t)device_id; - furi_hal_version.ble_mac[4] = (uint8_t)(company_id & 0x000000FF); - furi_hal_version.ble_mac[5] = (uint8_t)((company_id & 0x0000FF00) >> 8); } static void furi_hal_version_load_otp_default() { diff --git a/bootloader/targets/f7/target.c b/bootloader/targets/f7/target.c index df694edd..0240204c 100644 --- a/bootloader/targets/f7/target.c +++ b/bootloader/targets/f7/target.c @@ -194,10 +194,12 @@ void target_display_init() { // Create payload u8g2_ClearBuffer(&fb); u8g2_SetDrawColor(&fb, 0x01); - u8g2_SetFont(&fb, u8g2_font_helvB08_tf); u8g2_DrawXBM(&fb, 0, 64 - 50, 128, 50, I_DFU_128x50); +#ifndef SLIM_BOOTLOADER + u8g2_SetFont(&fb, u8g2_font_helvB08_tf); u8g2_DrawStr(&fb, 2, 8, "Update & Recovery Mode"); u8g2_DrawStr(&fb, 2, 21, "DFU started"); +#endif // Send buffer u8g2_SetPowerSave(&fb, 0); u8g2_SendBuffer(&fb); diff --git a/firmware/targets/f6/target.mk b/firmware/targets/f6/target.mk index 85669e8d..cad7d33f 100644 --- a/firmware/targets/f6/target.mk +++ b/firmware/targets/f6/target.mk @@ -19,9 +19,9 @@ BOOT_CFLAGS = -DBOOT_ADDRESS=$(BOOT_ADDRESS) -DFW_ADDRESS=$(FW_ADDRESS) -DOS_OF MCU_FLAGS = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard CFLAGS += $(MCU_FLAGS) $(BOOT_CFLAGS) -DSTM32WB55xx -Wall -fdata-sections -ffunction-sections -LDFLAGS += $(MCU_FLAGS) -specs=nosys.specs -specs=nano.specs +LDFLAGS += $(MCU_FLAGS) -specs=nosys.specs -specs=nano.specs -u _printf_float -CPPFLAGS += -fno-rtti -fno-use-cxa-atexit -fno-exceptions +CPPFLAGS += -fno-rtti -fno-use-cxa-atexit -fno-exceptions LDFLAGS += -Wl,--start-group -lstdc++ -lsupc++ -Wl,--end-group HARDWARE_TARGET = 6 diff --git a/firmware/targets/f7/target.mk b/firmware/targets/f7/target.mk index d6b8cbfa..f54f3f25 100644 --- a/firmware/targets/f7/target.mk +++ b/firmware/targets/f7/target.mk @@ -19,9 +19,9 @@ BOOT_CFLAGS = -DBOOT_ADDRESS=$(BOOT_ADDRESS) -DFW_ADDRESS=$(FW_ADDRESS) -DOS_OF MCU_FLAGS = -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard CFLAGS += $(MCU_FLAGS) $(BOOT_CFLAGS) -DSTM32WB55xx -Wall -fdata-sections -ffunction-sections -LDFLAGS += $(MCU_FLAGS) -specs=nosys.specs -specs=nano.specs +LDFLAGS += $(MCU_FLAGS) -specs=nosys.specs -specs=nano.specs -u _printf_float -CPPFLAGS += -fno-rtti -fno-use-cxa-atexit -fno-exceptions +CPPFLAGS += -fno-rtti -fno-use-cxa-atexit -fno-exceptions LDFLAGS += -Wl,--start-group -lstdc++ -lsupc++ -Wl,--end-group HARDWARE_TARGET = 7 diff --git a/make/toolchain.mk b/make/toolchain.mk index 3b3babf4..75d0c370 100644 --- a/make/toolchain.mk +++ b/make/toolchain.mk @@ -27,4 +27,4 @@ endif CFLAGS += -fdata-sections -ffunction-sections -fno-math-errno -fstack-usage -MMD -MP -MF"$(@:%.o=%.d)" CPPFLAGS += -fno-threadsafe-statics -fno-use-cxa-atexit -fno-exceptions -fno-rtti -LDFLAGS += -Wl,-Map=$(OBJ_DIR)/$(PROJECT).map,--cref -Wl,--gc-sections -Wl,--undefined=uxTopUsedPriority -u _printf_float -n \ No newline at end of file +LDFLAGS += -Wl,-Map=$(OBJ_DIR)/$(PROJECT).map,--cref -Wl,--gc-sections -Wl,--undefined=uxTopUsedPriority -n \ No newline at end of file From 02ba5692e442545ea2beadce7fe8a8165ae7194c Mon Sep 17 00:00:00 2001 From: Oleg Kalachev Date: Tue, 7 Dec 2021 18:54:37 +0300 Subject: [PATCH 22/32] Specify vid and pid of device for upload target (#877) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- make/rules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/rules.mk b/make/rules.mk index ca6bcd86..70bf76be 100644 --- a/make/rules.mk +++ b/make/rules.mk @@ -77,7 +77,7 @@ $(OBJ_DIR)/flash: $(OBJ_DIR)/$(PROJECT).bin touch $@ $(OBJ_DIR)/upload: $(OBJ_DIR)/$(PROJECT).bin - dfu-util -D $(OBJ_DIR)/$(PROJECT).bin -a 0 -s $(FLASH_ADDRESS) $(DFU_OPTIONS) + dfu-util -d 0xdf11:0x0483 -D $(OBJ_DIR)/$(PROJECT).bin -a 0 -s $(FLASH_ADDRESS) $(DFU_OPTIONS) touch $@ flash: $(OBJ_DIR)/flash From 9708b30965c7cdbe2faafba1442855027f9a9ebb Mon Sep 17 00:00:00 2001 From: Oleg Kalachev Date: Tue, 7 Dec 2021 20:31:20 +0300 Subject: [PATCH 23/32] Fix pid and vid for dfu-util (#878) --- make/rules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/rules.mk b/make/rules.mk index 70bf76be..a212f09c 100644 --- a/make/rules.mk +++ b/make/rules.mk @@ -77,7 +77,7 @@ $(OBJ_DIR)/flash: $(OBJ_DIR)/$(PROJECT).bin touch $@ $(OBJ_DIR)/upload: $(OBJ_DIR)/$(PROJECT).bin - dfu-util -d 0xdf11:0x0483 -D $(OBJ_DIR)/$(PROJECT).bin -a 0 -s $(FLASH_ADDRESS) $(DFU_OPTIONS) + dfu-util -d 0483:df11 -D $(OBJ_DIR)/$(PROJECT).bin -a 0 -s $(FLASH_ADDRESS) $(DFU_OPTIONS) touch $@ flash: $(OBJ_DIR)/flash From bb96509ed1e92c12b0b622f105eaa813d32009b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Wed, 8 Dec 2021 06:27:16 +0300 Subject: [PATCH 24/32] FuriHal: temporary switch to hal ticks for timeouts. (#880) --- firmware/targets/f6/furi-hal/furi-hal-i2c.c | 12 ++++++------ firmware/targets/f7/furi-hal/furi-hal-i2c.c | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/firmware/targets/f6/furi-hal/furi-hal-i2c.c b/firmware/targets/f6/furi-hal/furi-hal-i2c.c index 3e64b390..826d98a5 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-i2c.c +++ b/firmware/targets/f6/furi-hal/furi-hal-i2c.c @@ -51,11 +51,11 @@ bool furi_hal_i2c_tx( furi_assert(timeout > 0); bool ret = true; - uint32_t timeout_tick = osKernelGetTickCount() + timeout; + uint32_t timeout_tick = HAL_GetTick() + timeout; do { while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { - if(osKernelGetTickCount() >= timeout_tick) { + if(HAL_GetTick() >= timeout_tick) { ret = false; break; } @@ -80,7 +80,7 @@ bool furi_hal_i2c_tx( size--; } - if(osKernelGetTickCount() >= timeout_tick) { + if(HAL_GetTick() >= timeout_tick) { ret = false; break; } @@ -103,11 +103,11 @@ bool furi_hal_i2c_rx( furi_assert(timeout > 0); bool ret = true; - uint32_t timeout_tick = osKernelGetTickCount() + timeout; + uint32_t timeout_tick = HAL_GetTick() + timeout; do { while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { - if(osKernelGetTickCount() >= timeout_tick) { + if(HAL_GetTick() >= timeout_tick) { ret = false; break; } @@ -132,7 +132,7 @@ bool furi_hal_i2c_rx( size--; } - if(osKernelGetTickCount() >= timeout_tick) { + if(HAL_GetTick() >= timeout_tick) { ret = false; break; } diff --git a/firmware/targets/f7/furi-hal/furi-hal-i2c.c b/firmware/targets/f7/furi-hal/furi-hal-i2c.c index 3e64b390..826d98a5 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-i2c.c +++ b/firmware/targets/f7/furi-hal/furi-hal-i2c.c @@ -51,11 +51,11 @@ bool furi_hal_i2c_tx( furi_assert(timeout > 0); bool ret = true; - uint32_t timeout_tick = osKernelGetTickCount() + timeout; + uint32_t timeout_tick = HAL_GetTick() + timeout; do { while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { - if(osKernelGetTickCount() >= timeout_tick) { + if(HAL_GetTick() >= timeout_tick) { ret = false; break; } @@ -80,7 +80,7 @@ bool furi_hal_i2c_tx( size--; } - if(osKernelGetTickCount() >= timeout_tick) { + if(HAL_GetTick() >= timeout_tick) { ret = false; break; } @@ -103,11 +103,11 @@ bool furi_hal_i2c_rx( furi_assert(timeout > 0); bool ret = true; - uint32_t timeout_tick = osKernelGetTickCount() + timeout; + uint32_t timeout_tick = HAL_GetTick() + timeout; do { while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { - if(osKernelGetTickCount() >= timeout_tick) { + if(HAL_GetTick() >= timeout_tick) { ret = false; break; } @@ -132,7 +132,7 @@ bool furi_hal_i2c_rx( size--; } - if(osKernelGetTickCount() >= timeout_tick) { + if(HAL_GetTick() >= timeout_tick) { ret = false; break; } From 7170864fe41f783ea84892f2e326ab120e2ee446 Mon Sep 17 00:00:00 2001 From: gornekich Date: Wed, 8 Dec 2021 14:28:01 +0300 Subject: [PATCH 25/32] [FL-1976] BLE HID (#852) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ble: prototype ble hid * ble: add HID service and characteristics * debug tools: add ble keyboard app * ble: change appearance * ble: working keyboard * bt: introduce furi-hal-bt-hid * bt: restart hid service on each keyboard app enter * bt: introduce switch profile * bt: add profile to ble glue * bt: working profile switch * bt: introduce bt serial profile, rework API * bt: rewotk HID profile * bt: rework gap with profile configuration * bt: move change profile routine to furi hal bt * bt: change switch profile API to blocking * bt: move battery update to furi hal bt * bt: cleanup * bt: add support for f6 target * bt: update documentation * bt: clean up code * bt: remove NO OUTPUT setting * bt: set numeric comparison pairing in BLE HID * bt: support f6 target * bt: set mac address in profile configuration * bt: set advertise name in profile config * bt: rework with furi thread * bt: support f6 target * bt: clear hci command buffer on core2 restart * bt: correct thread kill sequence * bt: fix freertos functions calls * bt: add some enterprise delays fo correct memory free * bt: code cleanup * bt: change terminate -> stop * bt: fix memory leakage Co-authored-by: あく --- applications/applications.c | 5 + applications/applications.mk | 8 +- applications/bt/bt_service/bt.c | 153 ++++++---- applications/bt/bt_service/bt.h | 16 ++ applications/bt/bt_service/bt_api.c | 15 + applications/bt/bt_service/bt_i.h | 7 + .../debug_tools/ble_keyboard/ble_keyboard.c | 138 +++++++++ .../targets/f6/ble-glue/battery_service.c | 4 + .../targets/f6/ble-glue/battery_service.h | 2 + firmware/targets/f6/ble-glue/ble_app.c | 81 ++++-- firmware/targets/f6/ble-glue/ble_app.h | 1 + firmware/targets/f6/ble-glue/ble_glue.c | 75 ++++- firmware/targets/f6/ble-glue/ble_glue.h | 2 + .../targets/f6/ble-glue/dev_info_service.c | 4 + .../targets/f6/ble-glue/dev_info_service.h | 2 + firmware/targets/f6/ble-glue/gap.c | 237 +++++++++------- firmware/targets/f6/ble-glue/gap.h | 26 +- firmware/targets/f6/ble-glue/hid_service.c | 268 ++++++++++++++++++ firmware/targets/f6/ble-glue/hid_service.h | 23 ++ firmware/targets/f6/ble-glue/serial_service.c | 30 +- firmware/targets/f6/ble-glue/serial_service.h | 22 +- .../targets/f6/furi-hal/furi-hal-bt-hid.c | 141 +++++++++ .../targets/f6/furi-hal/furi-hal-bt-serial.c | 51 ++++ firmware/targets/f6/furi-hal/furi-hal-bt.c | 150 ++++++++-- firmware/targets/f6/furi-hal/furi-hal-flash.c | 8 +- .../targets/f7/ble-glue/battery_service.c | 4 + .../targets/f7/ble-glue/battery_service.h | 2 + firmware/targets/f7/ble-glue/ble_app.c | 81 ++++-- firmware/targets/f7/ble-glue/ble_app.h | 1 + firmware/targets/f7/ble-glue/ble_glue.c | 75 ++++- firmware/targets/f7/ble-glue/ble_glue.h | 2 + .../targets/f7/ble-glue/dev_info_service.c | 4 + .../targets/f7/ble-glue/dev_info_service.h | 2 + firmware/targets/f7/ble-glue/gap.c | 237 +++++++++------- firmware/targets/f7/ble-glue/gap.h | 26 +- firmware/targets/f7/ble-glue/hid_service.c | 268 ++++++++++++++++++ firmware/targets/f7/ble-glue/hid_service.h | 23 ++ firmware/targets/f7/ble-glue/serial_service.c | 30 +- firmware/targets/f7/ble-glue/serial_service.h | 22 +- .../targets/f7/furi-hal/furi-hal-bt-hid.c | 141 +++++++++ .../targets/f7/furi-hal/furi-hal-bt-serial.c | 51 ++++ firmware/targets/f7/furi-hal/furi-hal-bt.c | 150 ++++++++-- firmware/targets/f7/furi-hal/furi-hal-flash.c | 8 +- .../furi-hal-include/furi-hal-bt-hid.h | 34 +++ .../furi-hal-include/furi-hal-bt-serial.h | 37 +++ .../targets/furi-hal-include/furi-hal-bt.h | 60 ++-- 46 files changed, 2288 insertions(+), 439 deletions(-) create mode 100755 applications/bt/bt_service/bt_api.c create mode 100755 applications/debug_tools/ble_keyboard/ble_keyboard.c create mode 100644 firmware/targets/f6/ble-glue/hid_service.c create mode 100644 firmware/targets/f6/ble-glue/hid_service.h create mode 100644 firmware/targets/f6/furi-hal/furi-hal-bt-hid.c create mode 100644 firmware/targets/f6/furi-hal/furi-hal-bt-serial.c create mode 100644 firmware/targets/f7/ble-glue/hid_service.c create mode 100644 firmware/targets/f7/ble-glue/hid_service.h create mode 100644 firmware/targets/f7/furi-hal/furi-hal-bt-hid.c create mode 100644 firmware/targets/f7/furi-hal/furi-hal-bt-serial.c create mode 100644 firmware/targets/furi-hal-include/furi-hal-bt-hid.h create mode 100644 firmware/targets/furi-hal-include/furi-hal-bt-serial.h diff --git a/applications/applications.c b/applications/applications.c index f8e7f422..82a0c833 100644 --- a/applications/applications.c +++ b/applications/applications.c @@ -40,6 +40,7 @@ extern int32_t subghz_app(void* p); extern int32_t usb_mouse_app(void* p); extern int32_t usb_test_app(void* p); extern int32_t vibro_test_app(void* p); +extern int32_t ble_keyboard_app(void* p); // Plugins extern int32_t music_player_app(void* p); @@ -218,6 +219,10 @@ const size_t FLIPPER_PLUGINS_COUNT = sizeof(FLIPPER_PLUGINS) / sizeof(FlipperApp // Plugin menu const FlipperApplication FLIPPER_DEBUG_APPS[] = { +#ifdef APP_BLE_KEYBOARD + {.app = ble_keyboard_app, .name = "BLE keyboard demo", .stack_size = 1024, .icon = NULL}, +#endif + #ifdef APP_BLINK {.app = blink_test_app, .name = "Blink Test", .stack_size = 1024, .icon = NULL}, #endif diff --git a/applications/applications.mk b/applications/applications.mk index 093da7bb..e067faef 100644 --- a/applications/applications.mk +++ b/applications/applications.mk @@ -47,7 +47,7 @@ APP_SD_TEST = 1 APP_VIBRO_TEST = 1 APP_USB_TEST = 1 APP_DISPLAY_TEST = 1 - +APP_BLE_KEYBOARD = 1 APP_USB_MOUSE = 1 APP_BAD_USB = 1 APP_UART_ECHO = 1 @@ -167,6 +167,12 @@ CFLAGS += -DAPP_BAD_USB SRV_GUI = 1 endif +APP_BLE_KEYBOARD ?=0 +ifeq ($(APP_BLE_KEYBOARD), 1) +CFLAGS += -DAPP_BLE_KEYBOARD +SRV_GUI = 1 +endif + APP_KEYPAD_TEST ?= 0 ifeq ($(APP_KEYPAD_TEST), 1) CFLAGS += -DAPP_KEYPAD_TEST diff --git a/applications/bt/bt_service/bt.c b/applications/bt/bt_service/bt.c index bcf37fa0..074ab980 100755 --- a/applications/bt/bt_service/bt.c +++ b/applications/bt/bt_service/bt.c @@ -39,6 +39,19 @@ static void bt_pin_code_show_event_handler(Bt* bt, uint32_t pin) { string_clear(pin_str); } +static bool bt_pin_code_verify_event_handler(Bt* bt, uint32_t pin) { + furi_assert(bt); + string_t pin_str; + dialog_message_set_icon(bt->dialog_message, &I_BLE_Pairing_128x64, 0, 0); + string_init_printf(pin_str, "Verify code\n%06d", pin); + dialog_message_set_text( + bt->dialog_message, string_get_cstr(pin_str), 64, 4, AlignCenter, AlignTop); + dialog_message_set_buttons(bt->dialog_message, "Cancel", "Ok", NULL); + DialogMessageButton button = dialog_message_show(bt->dialogs, bt->dialog_message); + string_clear(pin_str); + return button == DialogMessageButtonCenter; +} + static void bt_battery_level_changed_callback(const void* _event, void* context) { furi_assert(_event); furi_assert(context); @@ -56,7 +69,8 @@ static void bt_battery_level_changed_callback(const void* _event, void* context) Bt* bt_alloc() { Bt* bt = furi_alloc(sizeof(Bt)); // Init default maximum packet size - bt->max_packet_size = FURI_HAL_BT_PACKET_SIZE_MAX; + bt->max_packet_size = FURI_HAL_BT_SERIAL_PACKET_SIZE_MAX; + bt->profile = BtProfileSerial; // Load settings if(!bt_settings_load(&bt->bt_settings)) { bt_settings_save(&bt->bt_settings); @@ -83,27 +97,30 @@ Bt* bt_alloc() { bt->rpc = furi_record_open("rpc"); bt->rpc_event = osEventFlagsNew(NULL); + // API evnent + bt->api_event = osEventFlagsNew(NULL); + return bt; } // Called from GAP thread from Serial service -static uint16_t bt_on_data_received_callback(uint8_t* data, uint16_t size, void* context) { +static uint16_t bt_serial_event_callback(SerialServiceEvent event, void* context) { furi_assert(context); Bt* bt = context; + uint16_t ret = 0; - size_t bytes_processed = rpc_session_feed(bt->rpc_session, data, size, 1000); - if(bytes_processed != size) { - FURI_LOG_E(TAG, "Only %d of %d bytes processed by RPC", bytes_processed, size); + if(event.event == SerialServiceEventTypeDataReceived) { + size_t bytes_processed = + rpc_session_feed(bt->rpc_session, event.data.buffer, event.data.size, 1000); + if(bytes_processed != event.data.size) { + FURI_LOG_E( + TAG, "Only %d of %d bytes processed by RPC", bytes_processed, event.data.size); + } + ret = rpc_session_get_available_size(bt->rpc_session); + } else if(event.event == SerialServiceEventTypeDataSent) { + osEventFlagsSet(bt->rpc_event, BT_RPC_EVENT_BUFF_SENT); } - return rpc_session_get_available_size(bt->rpc_session); -} - -// Called from GAP thread from Serial service -static void bt_on_data_sent_callback(void* context) { - furi_assert(context); - Bt* bt = context; - - osEventFlagsSet(bt->rpc_event, BT_RPC_EVENT_BUFF_SENT); + return ret; } // Called from RPC thread @@ -115,11 +132,11 @@ static void bt_rpc_send_bytes_callback(void* context, uint8_t* bytes, size_t byt size_t bytes_sent = 0; while(bytes_sent < bytes_len) { size_t bytes_remain = bytes_len - bytes_sent; - if(bytes_remain > bt->max_packet_size) { - furi_hal_bt_tx(&bytes[bytes_sent], bt->max_packet_size); - bytes_sent += bt->max_packet_size; + if(bytes_remain > FURI_HAL_BT_SERIAL_PACKET_SIZE_MAX) { + furi_hal_bt_serial_tx(&bytes[bytes_sent], FURI_HAL_BT_SERIAL_PACKET_SIZE_MAX); + bytes_sent += FURI_HAL_BT_SERIAL_PACKET_SIZE_MAX; } else { - furi_hal_bt_tx(&bytes[bytes_sent], bytes_remain); + furi_hal_bt_serial_tx(&bytes[bytes_sent], bytes_remain); bytes_sent += bytes_remain; } uint32_t event_flag = @@ -130,58 +147,65 @@ static void bt_rpc_send_bytes_callback(void* context, uint8_t* bytes, size_t byt } } -static void bt_rpc_buffer_is_empty_callback(void* context) { - furi_assert(context); - furi_hal_bt_notify_buffer_is_empty(); -} - // Called from GAP thread -static void bt_on_gap_event_callback(BleEvent event, void* context) { +static bool bt_on_gap_event_callback(BleEvent event, void* context) { furi_assert(context); Bt* bt = context; + bool ret = false; if(event.type == BleEventTypeConnected) { // Update status bar bt->status = BtStatusConnected; BtMessage message = {.type = BtMessageTypeUpdateStatusbar}; furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); - // Open RPC session - FURI_LOG_I(TAG, "Open RPC connection"); - bt->rpc_session = rpc_session_open(bt->rpc); - rpc_session_set_send_bytes_callback(bt->rpc_session, bt_rpc_send_bytes_callback); - rpc_session_set_buffer_is_empty_callback(bt->rpc_session, bt_rpc_buffer_is_empty_callback); - rpc_session_set_context(bt->rpc_session, bt); - furi_hal_bt_set_data_event_callbacks( - RPC_BUFFER_SIZE, bt_on_data_received_callback, bt_on_data_sent_callback, bt); + if(bt->profile == BtProfileSerial) { + // Open RPC session + FURI_LOG_I(TAG, "Open RPC connection"); + bt->rpc_session = rpc_session_open(bt->rpc); + rpc_session_set_send_bytes_callback(bt->rpc_session, bt_rpc_send_bytes_callback); + rpc_session_set_buffer_is_empty_callback( + bt->rpc_session, furi_hal_bt_serial_notify_buffer_is_empty); + rpc_session_set_context(bt->rpc_session, bt); + furi_hal_bt_serial_set_event_callback(RPC_BUFFER_SIZE, bt_serial_event_callback, bt); + } // Update battery level PowerInfo info; power_get_info(bt->power, &info); message.type = BtMessageTypeUpdateBatteryLevel; message.data.battery_level = info.charge; furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); + ret = true; } else if(event.type == BleEventTypeDisconnected) { - if(bt->rpc_session) { + if(bt->profile == BtProfileSerial && bt->rpc_session) { FURI_LOG_I(TAG, "Close RPC connection"); osEventFlagsSet(bt->rpc_event, BT_RPC_EVENT_DISCONNECTED); rpc_session_close(bt->rpc_session); - furi_hal_bt_set_data_event_callbacks(0, NULL, NULL, NULL); + furi_hal_bt_serial_set_event_callback(0, NULL, NULL); bt->rpc_session = NULL; } + ret = true; } else if(event.type == BleEventTypeStartAdvertising) { bt->status = BtStatusAdvertising; BtMessage message = {.type = BtMessageTypeUpdateStatusbar}; furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); + ret = true; } else if(event.type == BleEventTypeStopAdvertising) { bt->status = BtStatusOff; BtMessage message = {.type = BtMessageTypeUpdateStatusbar}; furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); + ret = true; } else if(event.type == BleEventTypePinCodeShow) { BtMessage message = { .type = BtMessageTypePinCodeShow, .data.pin_code = event.data.pin_code}; furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); + ret = true; + } else if(event.type == BleEventTypePinCodeVerify) { + ret = bt_pin_code_verify_event_handler(bt, event.data.pin_code); } else if(event.type == BleEventTypeUpdateMTU) { bt->max_packet_size = event.data.max_packet_size; + ret = true; } + return ret; } static void bt_on_key_storage_change_callback(uint8_t* addr, uint16_t size, void* context) { @@ -204,29 +228,56 @@ static void bt_statusbar_update(Bt* bt) { } } +static void bt_change_profile(Bt* bt, BtMessage* message) { + if(bt->profile == BtProfileSerial && bt->rpc_session) { + FURI_LOG_I(TAG, "Close RPC connection"); + osEventFlagsSet(bt->rpc_event, BT_RPC_EVENT_DISCONNECTED); + rpc_session_close(bt->rpc_session); + furi_hal_bt_serial_set_event_callback(0, NULL, NULL); + bt->rpc_session = NULL; + } + + FuriHalBtProfile furi_profile; + if(message->data.profile == BtProfileHidKeyboard) { + furi_profile = FuriHalBtProfileHidKeyboard; + } else { + furi_profile = FuriHalBtProfileSerial; + } + + if(furi_hal_bt_change_app(furi_profile, bt_on_gap_event_callback, bt)) { + FURI_LOG_I(TAG, "Bt App started"); + if(bt->bt_settings.enabled) { + furi_hal_bt_start_advertising(); + } + furi_hal_bt_set_key_storage_change_callback(bt_on_key_storage_change_callback, bt); + bt->profile = message->data.profile; + *message->result = true; + } else { + FURI_LOG_E(TAG, "Failed to start Bt App"); + *message->result = false; + } + osEventFlagsSet(bt->api_event, BT_API_UNLOCK_EVENT); +} + int32_t bt_srv() { Bt* bt = bt_alloc(); furi_record_create("bt", bt); // Read keys if(!bt_load_key_storage(bt)) { - FURI_LOG_W(TAG, "Failed to load saved bonding keys"); + FURI_LOG_W(TAG, "Failed to load bonding keys"); } - // Start 2nd core - if(!furi_hal_bt_start_core2()) { - FURI_LOG_E(TAG, "Core2 startup failed"); - } else { - view_port_enabled_set(bt->statusbar_view_port, true); - if(furi_hal_bt_init_app(bt_on_gap_event_callback, bt)) { - FURI_LOG_I(TAG, "BLE stack started"); - if(bt->bt_settings.enabled) { - furi_hal_bt_start_advertising(); - } - } else { - FURI_LOG_E(TAG, "BT App start failed"); + + // Start BLE stack + if(furi_hal_bt_start_app(FuriHalBtProfileSerial, bt_on_gap_event_callback, bt)) { + FURI_LOG_I(TAG, "BLE stack started"); + if(bt->bt_settings.enabled) { + furi_hal_bt_start_advertising(); } + furi_hal_bt_set_key_storage_change_callback(bt_on_key_storage_change_callback, bt); + } else { + FURI_LOG_E(TAG, "BT App start failed"); } - furi_hal_bt_set_key_storage_change_callback(bt_on_key_storage_change_callback, bt); // Update statusbar bt_statusbar_update(bt); @@ -239,14 +290,14 @@ int32_t bt_srv() { bt_statusbar_update(bt); } else if(message.type == BtMessageTypeUpdateBatteryLevel) { // Update battery level - if(furi_hal_bt_is_active()) { - battery_svc_update_level(message.data.battery_level); - } + furi_hal_bt_update_battery_level(message.data.battery_level); } else if(message.type == BtMessageTypePinCodeShow) { // Display PIN code bt_pin_code_show_event_handler(bt, message.data.pin_code); } else if(message.type == BtMessageTypeKeysStorageUpdated) { bt_save_key_storage(bt); + } else if(message.type == BtMessageTypeSetProfile) { + bt_change_profile(bt, &message); } } return 0; diff --git a/applications/bt/bt_service/bt.h b/applications/bt/bt_service/bt.h index 0a2a924c..9f609937 100644 --- a/applications/bt/bt_service/bt.h +++ b/applications/bt/bt_service/bt.h @@ -9,6 +9,22 @@ extern "C" { typedef struct Bt Bt; +typedef enum { + BtProfileSerial, + BtProfileHidKeyboard, +} BtProfile; + +/** + * Change BLE Profile + * @note Call of this function leads to 2nd core restart + * + * @param bt Bt instance + * @param profile BtProfile + * + * @return true on success + */ +bool bt_set_profile(Bt* bt, BtProfile profile); + #ifdef __cplusplus } #endif diff --git a/applications/bt/bt_service/bt_api.c b/applications/bt/bt_service/bt_api.c new file mode 100755 index 00000000..9ff9017a --- /dev/null +++ b/applications/bt/bt_service/bt_api.c @@ -0,0 +1,15 @@ +#include "bt_i.h" + +bool bt_set_profile(Bt* bt, BtProfile profile) { + furi_assert(bt); + + // Send message + bool result = false; + BtMessage message = { + .type = BtMessageTypeSetProfile, .data.profile = profile, .result = &result}; + furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); + // Wait for unlock + osEventFlagsWait(bt->api_event, BT_API_UNLOCK_EVENT, osFlagsWaitAny, osWaitForever); + + return result; +} diff --git a/applications/bt/bt_service/bt_i.h b/applications/bt/bt_service/bt_i.h index 840d920e..4961f041 100644 --- a/applications/bt/bt_service/bt_i.h +++ b/applications/bt/bt_service/bt_i.h @@ -15,6 +15,8 @@ #include "../bt_settings.h" +#define BT_API_UNLOCK_EVENT (1UL << 0) + typedef enum { BtStatusOff, BtStatusAdvertising, @@ -26,16 +28,19 @@ typedef enum { BtMessageTypeUpdateBatteryLevel, BtMessageTypePinCodeShow, BtMessageTypeKeysStorageUpdated, + BtMessageTypeSetProfile, } BtMessageType; typedef union { uint32_t pin_code; uint8_t battery_level; + BtProfile profile; } BtMessageData; typedef struct { BtMessageType type; BtMessageData data; + bool* result; } BtMessage; struct Bt { @@ -44,6 +49,7 @@ struct Bt { uint16_t max_packet_size; BtSettings bt_settings; BtStatus status; + BtProfile profile; osMessageQueueId_t message_queue; Gui* gui; ViewPort* statusbar_view_port; @@ -53,4 +59,5 @@ struct Bt { Rpc* rpc; RpcSession* rpc_session; osEventFlagsId_t rpc_event; + osEventFlagsId_t api_event; }; diff --git a/applications/debug_tools/ble_keyboard/ble_keyboard.c b/applications/debug_tools/ble_keyboard/ble_keyboard.c new file mode 100755 index 00000000..07854382 --- /dev/null +++ b/applications/debug_tools/ble_keyboard/ble_keyboard.c @@ -0,0 +1,138 @@ +#include +#include +#include +#include +#include +#include +#include + +#define TAG "BleKeyboardApp" + +typedef enum { + EventTypeInput, +} EventType; + +typedef struct { + union { + InputEvent input; + }; + EventType type; +} BleKeyboardEvent; + +static void ble_keyboard_render_callback(Canvas* canvas, void* ctx) { + canvas_clear(canvas); + + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 0, 10, "BLE keypad demo"); + + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 0, 63, "Hold [back] to exit"); +} + +static void ble_keyboard_input_callback(InputEvent* input_event, void* ctx) { + osMessageQueueId_t event_queue = ctx; + + BleKeyboardEvent event; + event.type = EventTypeInput; + event.input = *input_event; + osMessageQueuePut(event_queue, &event, 0, osWaitForever); +} + +int32_t ble_keyboard_app(void* p) { + Bt* bt = furi_record_open("bt"); + if(!bt_set_profile(bt, BtProfileHidKeyboard)) { + FURI_LOG_E(TAG, "Failed to switch profile"); + furi_record_close("bt"); + return -1; + } + bool bt_turned_on = furi_hal_bt_is_active(); + if(!bt_turned_on) { + furi_hal_bt_start_advertising(); + } + + osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(BleKeyboardEvent), NULL); + furi_check(event_queue); + ViewPort* view_port = view_port_alloc(); + + view_port_draw_callback_set(view_port, ble_keyboard_render_callback, NULL); + view_port_input_callback_set(view_port, ble_keyboard_input_callback, event_queue); + + // Open GUI and register view_port + Gui* gui = furi_record_open("gui"); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + BleKeyboardEvent event; + while(1) { + osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, osWaitForever); + + if(event_status == osOK) { + if(event.type == EventTypeInput) { + if(event.input.type == InputTypeLong && event.input.key == InputKeyBack) { + furi_hal_bt_hid_kb_release_all(); + break; + } + + if(event.input.key == InputKeyBack) { + if(event.input.type == InputTypePress) { + furi_hal_bt_hid_kb_press(KEY_ESC); + } else if(event.input.type == InputTypeRelease) { + furi_hal_bt_hid_kb_release(KEY_ESC); + } + } + + if(event.input.key == InputKeyOk) { + if(event.input.type == InputTypePress) { + furi_hal_bt_hid_kb_press(KEY_ENTER); + } else if(event.input.type == InputTypeRelease) { + furi_hal_bt_hid_kb_release(KEY_ENTER); + } + } + + if(event.input.key == InputKeyRight) { + if(event.input.type == InputTypePress) { + furi_hal_bt_hid_kb_press(KEY_RIGHT_ARROW); + } else if(event.input.type == InputTypeRelease) { + furi_hal_bt_hid_kb_release(KEY_RIGHT_ARROW); + } + } + + if(event.input.key == InputKeyLeft) { + if(event.input.type == InputTypePress) { + furi_hal_bt_hid_kb_press(KEY_LEFT_ARROW); + } else if(event.input.type == InputTypeRelease) { + furi_hal_bt_hid_kb_release(KEY_LEFT_ARROW); + } + } + + if(event.input.key == InputKeyDown) { + if(event.input.type == InputTypePress) { + furi_hal_bt_hid_kb_press(KEY_DOWN_ARROW); + } else if(event.input.type == InputTypeRelease) { + furi_hal_bt_hid_kb_release(KEY_DOWN_ARROW); + } + } + + if(event.input.key == InputKeyUp) { + if(event.input.type == InputTypePress) { + furi_hal_bt_hid_kb_press(KEY_UP_ARROW); + } else if(event.input.type == InputTypeRelease) { + furi_hal_bt_hid_kb_release(KEY_UP_ARROW); + } + } + } + } + view_port_update(view_port); + } + + if(bt_turned_on) { + furi_hal_bt_stop_advertising(); + } + // remove & free all stuff created by app + gui_remove_view_port(gui, view_port); + view_port_free(view_port); + osMessageQueueDelete(event_queue); + furi_record_close("gui"); + bt_set_profile(bt, BtProfileSerial); + furi_record_close("bt"); + return 0; +} diff --git a/firmware/targets/f6/ble-glue/battery_service.c b/firmware/targets/f6/ble-glue/battery_service.c index 2a5dad5e..08dec734 100644 --- a/firmware/targets/f6/ble-glue/battery_service.c +++ b/firmware/targets/f6/ble-glue/battery_service.c @@ -59,6 +59,10 @@ void battery_svc_stop() { } } +bool battery_svc_is_started() { + return battery_svc != NULL; +} + bool battery_svc_update_level(uint8_t battery_charge) { // Check if service was started if(battery_svc == NULL) { diff --git a/firmware/targets/f6/ble-glue/battery_service.h b/firmware/targets/f6/ble-glue/battery_service.h index a50e607c..2d35e252 100644 --- a/firmware/targets/f6/ble-glue/battery_service.h +++ b/firmware/targets/f6/ble-glue/battery_service.h @@ -11,6 +11,8 @@ void battery_svc_start(); void battery_svc_stop(); +bool battery_svc_is_started(); + bool battery_svc_update_level(uint8_t battery_level); #ifdef __cplusplus diff --git a/firmware/targets/f6/ble-glue/ble_app.c b/firmware/targets/f6/ble-glue/ble_app.c index 40b34679..3f09d1f0 100644 --- a/firmware/targets/f6/ble-glue/ble_app.c +++ b/firmware/targets/f6/ble-glue/ble_app.c @@ -10,20 +10,24 @@ #define TAG "Bt" +#define BLE_APP_FLAG_HCI_EVENT (1UL << 0) +#define BLE_APP_FLAG_KILL_THREAD (1UL << 1) +#define BLE_APP_FLAG_ALL (BLE_APP_FLAG_HCI_EVENT | BLE_APP_FLAG_KILL_THREAD) + PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_CmdPacket_t ble_app_cmd_buffer; PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint32_t ble_app_nvm[BLE_NVM_SRAM_SIZE]; typedef struct { osMutexId_t hci_mtx; osSemaphoreId_t hci_sem; - osThreadId_t hci_thread_id; - osThreadAttr_t hci_thread_attr; + FuriThread* thread; + osEventFlagsId_t event_flags; } BleApp; -static BleApp* ble_app; +static BleApp* ble_app = NULL; -static void ble_app_hci_thread(void *arg); -static void ble_app_hci_event_handler(void * pPayload); +static int32_t ble_app_hci_thread(void* context); +static void ble_app_hci_event_handler(void* pPayload); static void ble_app_hci_status_not_handler(HCI_TL_CmdStatus_t status); bool ble_app_init() { @@ -32,10 +36,14 @@ bool ble_app_init() { // Allocate semafore and mutex for ble command buffer access ble_app->hci_mtx = osMutexNew(NULL); ble_app->hci_sem = osSemaphoreNew(1, 0, NULL); + ble_app->event_flags = osEventFlagsNew(NULL); // HCI transport layer thread to handle user asynch events - ble_app->hci_thread_attr.name = "BleHciWorker"; - ble_app->hci_thread_attr.stack_size = 1024; - ble_app->hci_thread_id = osThreadNew(ble_app_hci_thread, NULL, &ble_app->hci_thread_attr); + ble_app->thread = furi_thread_alloc(); + furi_thread_set_name(ble_app->thread, "BleHciWorker"); + furi_thread_set_stack_size(ble_app->thread, 1024); + furi_thread_set_context(ble_app->thread, ble_app); + furi_thread_set_callback(ble_app->thread, ble_app_hci_thread); + furi_thread_start(ble_app->thread); // Initialize Ble Transport Layer HCI_TL_HciInitConf_t hci_tl_config = { @@ -92,35 +100,68 @@ void ble_app_get_key_storage_buff(uint8_t** addr, uint16_t* size) { *size = sizeof(ble_app_nvm); } -static void ble_app_hci_thread(void *arg) { - while(1) { - osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever); - hci_user_evt_proc(); +void ble_app_thread_stop() { + if(ble_app) { + osEventFlagsSet(ble_app->event_flags, BLE_APP_FLAG_KILL_THREAD); + furi_thread_join(ble_app->thread); + furi_thread_free(ble_app->thread); + // Wait to make sure that EventFlags delivers pending events before memory free + osDelay(50); + // Free resources + osMutexDelete(ble_app->hci_mtx); + osSemaphoreDelete(ble_app->hci_sem); + osEventFlagsDelete(ble_app->event_flags); + free(ble_app); + ble_app = NULL; + memset(&ble_app_cmd_buffer, 0, sizeof(ble_app_cmd_buffer)); } } +static int32_t ble_app_hci_thread(void *arg) { + uint32_t flags = 0; + while(1) { + flags = osEventFlagsWait(ble_app->event_flags, BLE_APP_FLAG_ALL, osFlagsWaitAny, osWaitForever); + if(flags & BLE_APP_FLAG_KILL_THREAD) { + break; + } + if(flags & BLE_APP_FLAG_HCI_EVENT) { + hci_user_evt_proc(); + } + } + + return 0; +} + // Called by WPAN lib void hci_notify_asynch_evt(void* pdata) { - osThreadFlagsSet(ble_app->hci_thread_id, 1); + if(ble_app) { + osEventFlagsSet(ble_app->event_flags, BLE_APP_FLAG_HCI_EVENT); + } } void hci_cmd_resp_release(uint32_t flag) { - osSemaphoreRelease(ble_app->hci_sem); + if(ble_app) { + osSemaphoreRelease(ble_app->hci_sem); + } } void hci_cmd_resp_wait(uint32_t timeout) { - osSemaphoreAcquire(ble_app->hci_sem, osWaitForever); + if(ble_app) { + osSemaphoreAcquire(ble_app->hci_sem, osWaitForever); + } } static void ble_app_hci_event_handler( void * pPayload ) { SVCCTL_UserEvtFlowStatus_t svctl_return_status; tHCI_UserEvtRxParam *pParam = (tHCI_UserEvtRxParam *)pPayload; - svctl_return_status = SVCCTL_UserEvtRx((void *)&(pParam->pckt->evtserial)); - if (svctl_return_status != SVCCTL_UserEvtFlowDisable) { - pParam->status = HCI_TL_UserEventFlow_Enable; - } else { - pParam->status = HCI_TL_UserEventFlow_Disable; + if(ble_app) { + svctl_return_status = SVCCTL_UserEvtRx((void *)&(pParam->pckt->evtserial)); + if (svctl_return_status != SVCCTL_UserEvtFlowDisable) { + pParam->status = HCI_TL_UserEventFlow_Enable; + } else { + pParam->status = HCI_TL_UserEventFlow_Disable; + } } } diff --git a/firmware/targets/f6/ble-glue/ble_app.h b/firmware/targets/f6/ble-glue/ble_app.h index 64000bde..062154e9 100644 --- a/firmware/targets/f6/ble-glue/ble_app.h +++ b/firmware/targets/f6/ble-glue/ble_app.h @@ -9,6 +9,7 @@ extern "C" { bool ble_app_init(); void ble_app_get_key_storage_buff(uint8_t** addr, uint16_t* size); +void ble_app_thread_stop(); #ifdef __cplusplus } diff --git a/firmware/targets/f6/ble-glue/ble_glue.c b/firmware/targets/f6/ble-glue/ble_glue.c index 45503683..007f3645 100644 --- a/firmware/targets/f6/ble-glue/ble_glue.c +++ b/firmware/targets/f6/ble-glue/ble_glue.c @@ -12,6 +12,10 @@ #define TAG "Core2" +#define BLE_GLUE_FLAG_SHCI_EVENT (1UL << 0) +#define BLE_GLUE_FLAG_KILL_THREAD (1UL << 1) +#define BLE_GLUE_FLAG_ALL (BLE_GLUE_FLAG_SHCI_EVENT | BLE_GLUE_FLAG_KILL_THREAD) + #define POOL_SIZE (CFG_TLBLE_EVT_QUEUE_LENGTH*4U*DIVC(( sizeof(TL_PacketHeader_t) + TL_BLE_EVENT_FRAME_SIZE ), 4U)) PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t ble_glue_event_pool[POOL_SIZE]; @@ -32,8 +36,8 @@ typedef enum { typedef struct { osMutexId_t shci_mtx; osSemaphoreId_t shci_sem; - osThreadId_t shci_user_event_thread_id; - osThreadAttr_t shci_user_event_thread_attr; + osEventFlagsId_t event_flags; + FuriThread* thread; BleGlueStatus status; BleGlueKeyStorageChangedCallback callback; void* context; @@ -41,7 +45,7 @@ typedef struct { static BleGlue* ble_glue = NULL; -static void ble_glue_user_event_thread(void *argument); +static int32_t ble_glue_shci_thread(void *argument); static void ble_glue_sys_status_not_callback(SHCI_TL_CmdStatus_t status); static void ble_glue_sys_user_event_callback(void* pPayload); @@ -55,8 +59,6 @@ void ble_glue_set_key_storage_changed_callback(BleGlueKeyStorageChangedCallback void ble_glue_init() { ble_glue = furi_alloc(sizeof(BleGlue)); ble_glue->status = BleGlueStatusStartup; - ble_glue->shci_user_event_thread_attr.name = "BleShciWorker"; - ble_glue->shci_user_event_thread_attr.stack_size = 1024; // Configure the system Power Mode // Select HSI as system clock source after Wake Up from Stop mode @@ -75,9 +77,15 @@ void ble_glue_init() { ble_glue->shci_mtx = osMutexNew(NULL); ble_glue->shci_sem = osSemaphoreNew(1, 0, NULL); + ble_glue->event_flags = osEventFlagsNew(NULL); // FreeRTOS system task creation - ble_glue->shci_user_event_thread_id = osThreadNew(ble_glue_user_event_thread, NULL, &ble_glue->shci_user_event_thread_attr); + ble_glue->thread = furi_thread_alloc(); + furi_thread_set_name(ble_glue->thread, "BleShciWorker"); + furi_thread_set_stack_size(ble_glue->thread, 1024); + furi_thread_set_context(ble_glue->thread, ble_glue); + furi_thread_set_callback(ble_glue->thread, ble_glue_shci_thread); + furi_thread_start(ble_glue->thread); // System channel initialization SHci_Tl_Init_Conf.p_cmdbuffer = (uint8_t*)&ble_glue_system_cmd_buff; @@ -205,26 +213,63 @@ static void ble_glue_sys_user_event_callback( void * pPayload ) { } } -// Wrap functions -static void ble_glue_user_event_thread(void *argument) { - UNUSED(argument); - for(;;) { - osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever); - shci_user_evt_proc(); +static void ble_glue_clear_shared_memory() { + memset(ble_glue_event_pool, 0, sizeof(ble_glue_event_pool)); + memset(&ble_glue_system_cmd_buff, 0, sizeof(ble_glue_system_cmd_buff)); + memset(ble_glue_system_spare_event_buff, 0, sizeof(ble_glue_system_spare_event_buff)); + memset(ble_glue_ble_spare_event_buff, 0, sizeof(ble_glue_ble_spare_event_buff)); +} + +void ble_glue_thread_stop() { + if(ble_glue) { + osEventFlagsSet(ble_glue->event_flags, BLE_GLUE_FLAG_KILL_THREAD); + furi_thread_join(ble_glue->thread); + furi_thread_free(ble_glue->thread); + // Wait to make sure that EventFlags delivers pending events before memory free + osDelay(50); + // Free resources + osMutexDelete(ble_glue->shci_mtx); + osSemaphoreDelete(ble_glue->shci_sem); + osEventFlagsDelete(ble_glue->event_flags); + ble_glue_clear_shared_memory(); + free(ble_glue); + ble_glue = NULL; } } +// Wrap functions +static int32_t ble_glue_shci_thread(void* context) { + uint32_t flags = 0; + while(true) { + flags = osEventFlagsWait(ble_glue->event_flags, BLE_GLUE_FLAG_ALL, osFlagsWaitAny, osWaitForever); + if(flags & BLE_GLUE_FLAG_SHCI_EVENT) { + shci_user_evt_proc(); + } + if(flags & BLE_GLUE_FLAG_KILL_THREAD) { + break; + } + } + + return 0; +} + void shci_notify_asynch_evt(void* pdata) { UNUSED(pdata); - osThreadFlagsSet(ble_glue->shci_user_event_thread_id, 1); + if(ble_glue) { + osEventFlagsSet(ble_glue->event_flags, BLE_GLUE_FLAG_SHCI_EVENT); + } } void shci_cmd_resp_release(uint32_t flag) { UNUSED(flag); - osSemaphoreRelease(ble_glue->shci_sem); + if(ble_glue) { + osSemaphoreRelease(ble_glue->shci_sem); + } } void shci_cmd_resp_wait(uint32_t timeout) { UNUSED(timeout); - osSemaphoreAcquire(ble_glue->shci_sem, osWaitForever); + if(ble_glue) { + osSemaphoreAcquire(ble_glue->shci_sem, osWaitForever); + } } diff --git a/firmware/targets/f6/ble-glue/ble_glue.h b/firmware/targets/f6/ble-glue/ble_glue.h index ac668c42..a95d633c 100644 --- a/firmware/targets/f6/ble-glue/ble_glue.h +++ b/firmware/targets/f6/ble-glue/ble_glue.h @@ -38,6 +38,8 @@ bool ble_glue_is_radio_stack_ready(); */ void ble_glue_set_key_storage_changed_callback(BleGlueKeyStorageChangedCallback callback, void* context); +void ble_glue_thread_stop(); + #ifdef __cplusplus } #endif diff --git a/firmware/targets/f6/ble-glue/dev_info_service.c b/firmware/targets/f6/ble-glue/dev_info_service.c index 64ff0509..e47fdf66 100644 --- a/firmware/targets/f6/ble-glue/dev_info_service.c +++ b/firmware/targets/f6/ble-glue/dev_info_service.c @@ -154,3 +154,7 @@ void dev_info_svc_stop() { dev_info_svc = NULL; } } + +bool dev_info_svc_is_started() { + return dev_info_svc != NULL; +} diff --git a/firmware/targets/f6/ble-glue/dev_info_service.h b/firmware/targets/f6/ble-glue/dev_info_service.h index 62eccefa..f5531fc7 100644 --- a/firmware/targets/f6/ble-glue/dev_info_service.h +++ b/firmware/targets/f6/ble-glue/dev_info_service.h @@ -16,6 +16,8 @@ void dev_info_svc_start(); void dev_info_svc_stop(); +bool dev_info_svc_is_started(); + #ifdef __cplusplus } #endif diff --git a/firmware/targets/f6/ble-glue/gap.c b/firmware/targets/f6/ble-glue/gap.c index a2381653..7f574f0b 100644 --- a/firmware/targets/f6/ble-glue/gap.c +++ b/firmware/targets/f6/ble-glue/gap.c @@ -3,20 +3,14 @@ #include "ble.h" #include "cmsis_os.h" -#include "otp.h" -#include "dev_info_service.h" -#include "battery_service.h" -#include "serial_service.h" - #include +#include #define TAG "BtGap" #define FAST_ADV_TIMEOUT 30000 #define INITIAL_ADV_TIMEOUT 60000 -#define BD_ADDR_SIZE_LOCAL 6 - typedef struct { uint16_t gap_svc_handle; uint16_t dev_name_char_handle; @@ -24,18 +18,18 @@ typedef struct { uint16_t connection_handle; uint8_t adv_svc_uuid_len; uint8_t adv_svc_uuid[20]; + char* adv_name; } GapSvc; typedef struct { - GapSvc gap_svc; + GapSvc service; + GapConfig* config; GapState state; osMutexId_t state_mutex; - uint8_t mac_address[BD_ADDR_SIZE_LOCAL]; BleEventCallback on_event_cb; void* context; osTimerId advertise_timer; - osThreadAttr_t thread_attr; - osThreadId_t thread_id; + FuriThread* thread; osMessageQueueId_t command_queue; bool enable_adv; } Gap; @@ -44,47 +38,44 @@ typedef enum { GapCommandAdvFast, GapCommandAdvLowPower, GapCommandAdvStop, + GapCommandKillThread, } GapCommand; // Identity root key static const uint8_t gap_irk[16] = {0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0}; // Encryption root key static const uint8_t gap_erk[16] = {0xfe,0xdc,0xba,0x09,0x87,0x65,0x43,0x21,0xfe,0xdc,0xba,0x09,0x87,0x65,0x43,0x21}; -// Appearence characteristic UUID -static const uint8_t gap_appearence_char_uuid[] = {0x00, 0x86}; -// Default MAC address -static const uint8_t gap_default_mac_addr[] = {0x6c, 0x7a, 0xd8, 0xac, 0x57, 0x72}; static Gap* gap = NULL; static void gap_advertise_start(GapState new_state); -static void gap_app(void *arg); +static int32_t gap_app(void* context); SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) { - hci_event_pckt *event_pckt; - evt_le_meta_event *meta_evt; - evt_blue_aci *blue_evt; - hci_le_phy_update_complete_event_rp0 *evt_le_phy_update_complete; + hci_event_pckt* event_pckt; + evt_le_meta_event* meta_evt; + evt_blue_aci* blue_evt; + hci_le_phy_update_complete_event_rp0* evt_le_phy_update_complete; uint8_t tx_phy; uint8_t rx_phy; tBleStatus ret = BLE_STATUS_INVALID_PARAMS; - event_pckt = (hci_event_pckt*) ((hci_uart_pckt *) pckt)->data; + event_pckt = (hci_event_pckt*)((hci_uart_pckt*)pckt)->data; osMutexAcquire(gap->state_mutex, osWaitForever); switch (event_pckt->evt) { case EVT_DISCONN_COMPLETE: { hci_disconnection_complete_event_rp0 *disconnection_complete_event = (hci_disconnection_complete_event_rp0 *) event_pckt->data; - if (disconnection_complete_event->Connection_Handle == gap->gap_svc.connection_handle) { - gap->gap_svc.connection_handle = 0; + if (disconnection_complete_event->Connection_Handle == gap->service.connection_handle) { + gap->service.connection_handle = 0; gap->state = GapStateIdle; - FURI_LOG_I(TAG, "Disconnect from client. Reason: %d", disconnection_complete_event->Reason); + FURI_LOG_I(TAG, "Disconnect from client. Reason: %02X", disconnection_complete_event->Reason); } if(gap->enable_adv) { // Restart advertising - gap_start_advertising(); + gap_advertise_start(GapCommandAdvFast); furi_hal_power_insomnia_exit(); } BleEvent event = {.type = BleEventTypeDisconnected}; @@ -106,7 +97,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) } else { FURI_LOG_I(TAG, "Update PHY succeed"); } - ret = hci_le_read_phy(gap->gap_svc.connection_handle,&tx_phy,&rx_phy); + ret = hci_le_read_phy(gap->service.connection_handle,&tx_phy,&rx_phy); if(ret) { FURI_LOG_E(TAG, "Read PHY failed, status: %d", ret); } else { @@ -124,7 +115,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) // Update connection status and handle gap->state = GapStateConnected; - gap->gap_svc.connection_handle = connection_complete_event->Connection_Handle; + gap->service.connection_handle = connection_complete_event->Connection_Handle; // Start pairing by sending security request aci_gap_slave_security_req(connection_complete_event->Connection_Handle); @@ -148,8 +139,8 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) { // Generate random PIN code uint32_t pin = rand() % 999999; - aci_gap_pass_key_resp(gap->gap_svc.connection_handle, pin); - FURI_LOG_I(TAG, "Pass key request event. Pin: %d", pin); + aci_gap_pass_key_resp(gap->service.connection_handle, pin); + FURI_LOG_I(TAG, "Pass key request event. Pin: %06d", pin); BleEvent event = {.type = BleEventTypePinCodeShow, .data.pin_code = pin}; gap->on_event_cb(event, gap->context); } @@ -175,7 +166,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) case EVT_BLUE_GAP_BOND_LOST: FURI_LOG_I(TAG, "Bond lost event. Start rebonding"); - aci_gap_allow_rebond(gap->gap_svc.connection_handle); + aci_gap_allow_rebond(gap->service.connection_handle); break; case EVT_BLUE_GAP_DEVICE_FOUND: @@ -191,16 +182,20 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) break; case EVT_BLUE_GAP_NUMERIC_COMPARISON_VALUE: - FURI_LOG_I(TAG, "Hex_value = %lx", - ((aci_gap_numeric_comparison_value_event_rp0 *)(blue_evt->data))->Numeric_Value); - aci_gap_numeric_comparison_value_confirm_yesno(gap->gap_svc.connection_handle, 1); + { + uint32_t pin = ((aci_gap_numeric_comparison_value_event_rp0 *)(blue_evt->data))->Numeric_Value; + FURI_LOG_I(TAG, "Verify numeric comparison: %06d", pin); + BleEvent event = {.type = BleEventTypePinCodeVerify, .data.pin_code = pin}; + bool result = gap->on_event_cb(event, gap->context); + aci_gap_numeric_comparison_value_confirm_yesno(gap->service.connection_handle, result); break; + } case EVT_BLUE_GAP_PAIRING_CMPLT: pairing_complete = (aci_gap_pairing_complete_event_rp0*)blue_evt->data; if (pairing_complete->Status) { FURI_LOG_E(TAG, "Pairing failed with status: %d. Terminating connection", pairing_complete->Status); - aci_gap_terminate(gap->gap_svc.connection_handle, 5); + aci_gap_terminate(gap->service.connection_handle, 5); } else { FURI_LOG_I(TAG, "Pairing complete"); BleEvent event = {.type = BleEventTypeConnected}; @@ -220,46 +215,15 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) } static void set_advertisment_service_uid(uint8_t* uid, uint8_t uid_len) { - gap->gap_svc.adv_svc_uuid_len = 1; if(uid_len == 2) { - gap->gap_svc.adv_svc_uuid[0] = AD_TYPE_16_BIT_SERV_UUID; + gap->service.adv_svc_uuid[0] = AD_TYPE_16_BIT_SERV_UUID; } else if (uid_len == 4) { - gap->gap_svc.adv_svc_uuid[0] = AD_TYPE_32_BIT_SERV_UUID; + gap->service.adv_svc_uuid[0] = AD_TYPE_32_BIT_SERV_UUID; } else if(uid_len == 16) { - gap->gap_svc.adv_svc_uuid[0] = AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST; - } - memcpy(&gap->gap_svc.adv_svc_uuid[1], uid, uid_len); - gap->gap_svc.adv_svc_uuid_len += uid_len; -} - -GapState gap_get_state() { - return gap->state; -} - -void gap_init_mac_address(Gap* gap) { - uint8_t *otp_addr; - uint32_t udn; - uint32_t company_id; - uint32_t device_id; - - udn = LL_FLASH_GetUDN(); - if(udn != 0xFFFFFFFF) { - company_id = LL_FLASH_GetSTCompanyID(); - device_id = LL_FLASH_GetDeviceID(); - gap->mac_address[0] = (uint8_t)(udn & 0x000000FF); - gap->mac_address[1] = (uint8_t)( (udn & 0x0000FF00) >> 8 ); - gap->mac_address[2] = (uint8_t)( (udn & 0x00FF0000) >> 16 ); - gap->mac_address[3] = (uint8_t)device_id; - gap->mac_address[4] = (uint8_t)(company_id & 0x000000FF);; - gap->mac_address[5] = (uint8_t)( (company_id & 0x0000FF00) >> 8 ); - } else { - otp_addr = OTP_Read(0); - if(otp_addr) { - memcpy(gap->mac_address, ((OTP_ID0_t*)otp_addr)->bd_address, sizeof(gap->mac_address)); - } else { - memcpy(gap->mac_address, gap_default_mac_addr, sizeof(gap->mac_address)); - } + gap->service.adv_svc_uuid[0] = AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST; } + memcpy(&gap->service.adv_svc_uuid[gap->service.adv_svc_uuid_len], uid, uid_len); + gap->service.adv_svc_uuid_len += uid_len; } static void gap_init_svc(Gap* gap) { @@ -269,8 +233,7 @@ static void gap_init_svc(Gap* gap) { // HCI Reset to synchronise BLE Stack hci_reset(); // Configure mac address - gap_init_mac_address(gap); - aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET, CONFIG_DATA_PUBADDR_LEN, (uint8_t*)gap->mac_address); + aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET, CONFIG_DATA_PUBADDR_LEN, gap->config->mac_address); /* Static random Address * The two upper bits shall be set to 1 @@ -289,25 +252,42 @@ static void gap_init_svc(Gap* gap) { // Initialize GATT interface aci_gatt_init(); // Initialize GAP interface - const char *name = furi_hal_version_get_device_name_ptr(); + // Skip fist symbol AD_TYPE_COMPLETE_LOCAL_NAME + char *name = gap->service.adv_name + 1; aci_gap_init(GAP_PERIPHERAL_ROLE, 0, strlen(name), - &gap->gap_svc.gap_svc_handle, &gap->gap_svc.dev_name_char_handle, &gap->gap_svc.appearance_char_handle); + &gap->service.gap_svc_handle, &gap->service.dev_name_char_handle, &gap->service.appearance_char_handle); // Set GAP characteristics - status = aci_gatt_update_char_value(gap->gap_svc.gap_svc_handle, gap->gap_svc.dev_name_char_handle, 0, strlen(name), (uint8_t *) name); + status = aci_gatt_update_char_value(gap->service.gap_svc_handle, gap->service.dev_name_char_handle, 0, strlen(name), (uint8_t *) name); if (status) { FURI_LOG_E(TAG, "Failed updating name characteristic: %d", status); } - status = aci_gatt_update_char_value(gap->gap_svc.gap_svc_handle, gap->gap_svc.appearance_char_handle, 0, 2, gap_appearence_char_uuid); + uint8_t gap_appearence_char_uuid[2] = {gap->config->appearance_char & 0xff, gap->config->appearance_char >> 8}; + status = aci_gatt_update_char_value(gap->service.gap_svc_handle, gap->service.appearance_char_handle, 0, 2, gap_appearence_char_uuid); if(status) { FURI_LOG_E(TAG, "Failed updating appearence characteristic: %d", status); } // Set default PHY hci_le_set_default_phy(ALL_PHYS_PREFERENCE, TX_2M_PREFERRED, RX_2M_PREFERRED); // Set I/O capability - aci_gap_set_io_capability(IO_CAP_DISPLAY_ONLY); + bool keypress_supported = false; + if(gap->config->pairing_method == GapPairingPinCodeShow) { + aci_gap_set_io_capability(IO_CAP_DISPLAY_ONLY); + } else if(gap->config->pairing_method == GapPairingPinCodeVerifyYesNo){ + aci_gap_set_io_capability(IO_CAP_DISPLAY_YES_NO); + keypress_supported = true; + } // Setup authentication - aci_gap_set_authentication_requirement(1, 1, 1, 0, 8, 16, 1, 0, PUBLIC_ADDR); + aci_gap_set_authentication_requirement( + gap->config->bonding_mode, + CFG_MITM_PROTECTION, + CFG_SC_SUPPORT, + keypress_supported, + CFG_ENCRYPTION_KEY_SIZE_MIN, + CFG_ENCRYPTION_KEY_SIZE_MAX, + CFG_USED_FIXED_PIN, + 0, + PUBLIC_ADDR); // Configure whitelist aci_gap_configure_whitelist(); } @@ -336,10 +316,9 @@ static void gap_advertise_start(GapState new_state) } } // Configure advertising - const char* name = furi_hal_version_get_ble_local_device_name_ptr(); status = aci_gap_set_discoverable(ADV_IND, min_interval, max_interval, PUBLIC_ADDR, 0, - strlen(name), (uint8_t*)name, - gap->gap_svc.adv_svc_uuid_len, gap->gap_svc.adv_svc_uuid, 0, 0); + strlen(gap->service.adv_name), (uint8_t*)gap->service.adv_name, + gap->service.adv_svc_uuid_len, gap->service.adv_svc_uuid, 0, 0); if(status) { FURI_LOG_E(TAG, "Set discoverable err: %d", status); } @@ -350,11 +329,11 @@ static void gap_advertise_start(GapState new_state) } static void gap_advertise_stop() { - if(gap->state == GapStateConnected) { - // Terminate connection - aci_gap_terminate(gap->gap_svc.connection_handle, 0x13); - } if(gap->state > GapStateIdle) { + if(gap->state == GapStateConnected) { + // Terminate connection + aci_gap_terminate(gap->service.connection_handle, 0x13); + } // Stop advertising osTimerStop(gap->advertise_timer); aci_gap_set_non_discoverable(); @@ -365,17 +344,26 @@ static void gap_advertise_stop() { } void gap_start_advertising() { - FURI_LOG_I(TAG, "Start advertising"); - gap->enable_adv = true; - GapCommand command = GapCommandAdvFast; - furi_check(osMessageQueuePut(gap->command_queue, &command, 0, 0) == osOK); + osMutexAcquire(gap->state_mutex, osWaitForever); + if(gap->state == GapStateIdle) { + gap->state = GapStateStartingAdv; + FURI_LOG_I(TAG, "Start advertising"); + gap->enable_adv = true; + GapCommand command = GapCommandAdvFast; + furi_check(osMessageQueuePut(gap->command_queue, &command, 0, 0) == osOK); + } + osMutexRelease(gap->state_mutex); } void gap_stop_advertising() { - FURI_LOG_I(TAG, "Stop advertising"); - gap->enable_adv = false; - GapCommand command = GapCommandAdvStop; - furi_check(osMessageQueuePut(gap->command_queue, &command, 0, 0) == osOK); + osMutexAcquire(gap->state_mutex, osWaitForever); + if(gap->state > GapStateIdle) { + FURI_LOG_I(TAG, "Stop advertising"); + gap->enable_adv = false; + GapCommand command = GapCommandAdvStop; + furi_check(osMessageQueuePut(gap->command_queue, &command, 0, 0) == osOK); + } + osMutexRelease(gap->state_mutex); } static void gap_advetise_timer_callback(void* context) { @@ -383,44 +371,42 @@ static void gap_advetise_timer_callback(void* context) { furi_check(osMessageQueuePut(gap->command_queue, &command, 0, 0) == osOK); } -bool gap_init(BleEventCallback on_event_cb, void* context) { +bool gap_init(GapConfig* config, BleEventCallback on_event_cb, void* context) { if (!ble_glue_is_radio_stack_ready()) { return false; } gap = furi_alloc(sizeof(Gap)); + gap->config = config; srand(DWT->CYCCNT); // Create advertising timer gap->advertise_timer = osTimerNew(gap_advetise_timer_callback, osTimerOnce, NULL, NULL); // Initialization of GATT & GAP layer + gap->service.adv_name = config->adv_name; gap_init_svc(gap); // Initialization of the BLE Services SVCCTL_Init(); // Initialization of the GAP state gap->state_mutex = osMutexNew(NULL); gap->state = GapStateIdle; - gap->gap_svc.connection_handle = 0xFFFF; + gap->service.connection_handle = 0xFFFF; gap->enable_adv = true; // Thread configuration - gap->thread_attr.name = "BleGapWorker"; - gap->thread_attr.stack_size = 1024; - gap->thread_id = osThreadNew(gap_app, NULL, &gap->thread_attr); + gap->thread = furi_thread_alloc(); + furi_thread_set_name(gap->thread, "BleGapWorker"); + furi_thread_set_stack_size(gap->thread, 1024); + furi_thread_set_context(gap->thread, gap); + furi_thread_set_callback(gap->thread, gap_app); + furi_thread_start(gap->thread); // Command queue allocation gap->command_queue = osMessageQueueNew(8, sizeof(GapCommand), NULL); - // Start Device Information service - dev_info_svc_start(); - // Start Battery service - battery_svc_start(); - // Start Serial application - serial_svc_start(); - // Configure advirtise service UUID uint8_t adv_service_uid[2]; - adv_service_uid[0] = 0x80 | furi_hal_version_get_hw_color(); - adv_service_uid[1] = 0x30; - + gap->service.adv_svc_uuid_len = 1; + adv_service_uid[0] = gap->config->adv_service_uuid & 0xff; + adv_service_uid[1] = gap->config->adv_service_uuid >> 8; set_advertisment_service_uid(adv_service_uid, sizeof(adv_service_uid)); // Set callback @@ -429,11 +415,42 @@ bool gap_init(BleEventCallback on_event_cb, void* context) { return true; } -static void gap_app(void *arg) { +GapState gap_get_state() { + GapState state; + osMutexAcquire(gap->state_mutex, osWaitForever); + state = gap->state; + osMutexRelease(gap->state_mutex ); + return state; +} + +void gap_thread_stop() { + if(gap) { + osMutexAcquire(gap->state_mutex, osWaitForever); + gap->enable_adv = false; + GapCommand command = GapCommandKillThread; + osMessageQueuePut(gap->command_queue, &command, 0, osWaitForever); + osMutexRelease(gap->state_mutex); + furi_thread_join(gap->thread); + furi_thread_free(gap->thread); + // Free resources + osMutexDelete(gap->state_mutex); + osMessageQueueDelete(gap->command_queue); + osTimerStop(gap->advertise_timer); + while(xTimerIsTimerActive(gap->advertise_timer) == pdTRUE) osDelay(1); + furi_check(osTimerDelete(gap->advertise_timer) == osOK); + free(gap); + gap = NULL; + } +} + +static int32_t gap_app(void *context) { GapCommand command; while(1) { furi_check(osMessageQueueGet(gap->command_queue, &command, NULL, osWaitForever) == osOK); osMutexAcquire(gap->state_mutex, osWaitForever); + if(command == GapCommandKillThread) { + break; + } if(command == GapCommandAdvFast) { gap_advertise_start(GapStateAdvFast); } else if(command == GapCommandAdvLowPower) { @@ -443,4 +460,6 @@ static void gap_app(void *arg) { } osMutexRelease(gap->state_mutex); } + + return 0; } diff --git a/firmware/targets/f6/ble-glue/gap.h b/firmware/targets/f6/ble-glue/gap.h index dfeffd63..03d9bbfc 100644 --- a/firmware/targets/f6/ble-glue/gap.h +++ b/firmware/targets/f6/ble-glue/gap.h @@ -3,6 +3,10 @@ #include #include +#include + +#define GAP_MAC_ADDR_SIZE (6) + #ifdef __cplusplus extern "C" { #endif @@ -13,6 +17,7 @@ typedef enum { BleEventTypeStartAdvertising, BleEventTypeStopAdvertising, BleEventTypePinCodeShow, + BleEventTypePinCodeVerify, BleEventTypeUpdateMTU, } BleEventType; @@ -26,16 +31,31 @@ typedef struct { BleEventData data; } BleEvent; -typedef void(*BleEventCallback) (BleEvent event, void* context); +typedef bool(*BleEventCallback) (BleEvent event, void* context); typedef enum { GapStateIdle, + GapStateStartingAdv, GapStateAdvFast, GapStateAdvLowPower, GapStateConnected, } GapState; -bool gap_init(BleEventCallback on_event_cb, void* context); +typedef enum { + GapPairingPinCodeShow, + GapPairingPinCodeVerifyYesNo, +} GapPairing; + +typedef struct { + uint16_t adv_service_uuid; + uint16_t appearance_char; + bool bonding_mode; + GapPairing pairing_method; + uint8_t mac_address[GAP_MAC_ADDR_SIZE]; + char adv_name[FURI_HAL_VERSION_DEVICE_NAME_LENGTH]; +} GapConfig; + +bool gap_init(GapConfig* config, BleEventCallback on_event_cb, void* context); void gap_start_advertising(); @@ -43,6 +63,8 @@ void gap_stop_advertising(); GapState gap_get_state(); +void gap_thread_stop(); + #ifdef __cplusplus } #endif diff --git a/firmware/targets/f6/ble-glue/hid_service.c b/firmware/targets/f6/ble-glue/hid_service.c new file mode 100644 index 00000000..dc9a7fa5 --- /dev/null +++ b/firmware/targets/f6/ble-glue/hid_service.c @@ -0,0 +1,268 @@ +#include "hid_service.h" +#include "app_common.h" +#include "ble.h" + +#include + +#define TAG "BtHid" + +typedef struct { + uint16_t svc_handle; + uint16_t protocol_mode_char_handle; + uint16_t report_char_handle; + uint16_t report_ref_desc_handle; + uint16_t report_map_char_handle; + uint16_t keyboard_boot_char_handle; + uint16_t info_char_handle; + uint16_t ctrl_point_char_handle; +} HIDSvc; + +static HIDSvc* hid_svc = NULL; + +static SVCCTL_EvtAckStatus_t hid_svc_event_handler(void *event) { + SVCCTL_EvtAckStatus_t ret = SVCCTL_EvtNotAck; + hci_event_pckt* event_pckt = (hci_event_pckt *)(((hci_uart_pckt*)event)->data); + evt_blecore_aci* blecore_evt = (evt_blecore_aci*)event_pckt->data; + // aci_gatt_attribute_modified_event_rp0* attribute_modified; + if(event_pckt->evt == HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE) { + if(blecore_evt->ecode == ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE) { + // Process modification events + ret = SVCCTL_EvtAckFlowEnable; + } else if(blecore_evt->ecode == ACI_GATT_SERVER_CONFIRMATION_VSEVT_CODE) { + // Process notification confirmation + ret = SVCCTL_EvtAckFlowEnable; + } + } + return ret; +} + +void hid_svc_start() { + tBleStatus status; + hid_svc = furi_alloc(sizeof(HIDSvc)); + Service_UUID_t svc_uuid = {}; + Char_Desc_Uuid_t desc_uuid = {}; + Char_UUID_t char_uuid = {}; + + // Register event handler + SVCCTL_RegisterSvcHandler(hid_svc_event_handler); + // Add service + svc_uuid.Service_UUID_16 = HUMAN_INTERFACE_DEVICE_SERVICE_UUID; + status = aci_gatt_add_service(UUID_TYPE_16, + &svc_uuid, + PRIMARY_SERVICE, + 30, + &hid_svc->svc_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add HID service: %d", status); + } + // Add Protocol mode characterstics + char_uuid.Char_UUID_16 = PROTOCOL_MODE_CHAR_UUID; + status = aci_gatt_add_char(hid_svc->svc_handle, + UUID_TYPE_16, + &char_uuid, + 1, + CHAR_PROP_READ | CHAR_PROP_WRITE_WITHOUT_RESP, + ATTR_PERMISSION_NONE, + GATT_NOTIFY_ATTRIBUTE_WRITE, + 10, + CHAR_VALUE_LEN_CONSTANT, + &hid_svc->protocol_mode_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add protocol mode characteristic: %d", status); + } + // Update Protocol mode characteristic + uint8_t protocol_mode = 1; + status = aci_gatt_update_char_value(hid_svc->svc_handle, + hid_svc->protocol_mode_char_handle, + 0, + 1, + &protocol_mode); + if(status) { + FURI_LOG_E(TAG, "Failed to update protocol mode characteristic: %d", status); + } + // Add Report characterstics + char_uuid.Char_UUID_16 = REPORT_CHAR_UUID; + status = aci_gatt_add_char(hid_svc->svc_handle, + UUID_TYPE_16, + &char_uuid, + HID_SVC_REPORT_MAX_LEN, + CHAR_PROP_READ | CHAR_PROP_NOTIFY, + ATTR_PERMISSION_NONE, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_VARIABLE, + &hid_svc->report_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add report characteristic: %d", status); + } + // Add Report descriptor + uint8_t desc_val[] = {0x00, 0x01}; + desc_uuid.Char_UUID_16 = REPORT_REFERENCE_DESCRIPTOR_UUID; + status = aci_gatt_add_char_desc(hid_svc->svc_handle, + hid_svc->report_char_handle, + UUID_TYPE_16, + &desc_uuid, + HID_SVC_REPORT_REF_LEN, + HID_SVC_REPORT_REF_LEN, + desc_val, + ATTR_PERMISSION_NONE, + ATTR_ACCESS_READ_ONLY, + GATT_DONT_NOTIFY_EVENTS, + MIN_ENCRY_KEY_SIZE, + CHAR_VALUE_LEN_CONSTANT, + &hid_svc->report_ref_desc_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add report reference descriptor: %d", status); + } + // Add Report Map characteristic + char_uuid.Char_UUID_16 = REPORT_MAP_CHAR_UUID; + status = aci_gatt_add_char(hid_svc->svc_handle, + UUID_TYPE_16, + &char_uuid, + HID_SVC_REPORT_MAP_MAX_LEN, + CHAR_PROP_READ, + ATTR_PERMISSION_NONE, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_VARIABLE, + &hid_svc->report_map_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add report map characteristic: %d", status); + } + // Add Boot Keyboard characteristic + char_uuid.Char_UUID_16 = BOOT_KEYBOARD_INPUT_REPORT_CHAR_UUID; + status = aci_gatt_add_char(hid_svc->svc_handle, + UUID_TYPE_16, + &char_uuid, + HID_SVC_BOOT_KEYBOARD_INPUT_REPORT_MAX_LEN, + CHAR_PROP_READ | CHAR_PROP_NOTIFY, + ATTR_PERMISSION_NONE, + GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP, + 10, + CHAR_VALUE_LEN_VARIABLE, + &hid_svc->keyboard_boot_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add report map characteristic: %d", status); + } + // Add Information characteristic + char_uuid.Char_UUID_16 = HID_INFORMATION_CHAR_UUID; + status = aci_gatt_add_char(hid_svc->svc_handle, + UUID_TYPE_16, + &char_uuid, + HID_SVC_INFO_LEN, + CHAR_PROP_READ, + ATTR_PERMISSION_NONE, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_CONSTANT, + &hid_svc->info_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add information characteristic: %d", status); + } + // Add Control Point characteristic + char_uuid.Char_UUID_16 = HID_CONTROL_POINT_CHAR_UUID; + status = aci_gatt_add_char(hid_svc->svc_handle, + UUID_TYPE_16, + &char_uuid, + HID_SVC_CONTROL_POINT_LEN, + CHAR_PROP_WRITE_WITHOUT_RESP, + ATTR_PERMISSION_NONE, + GATT_NOTIFY_ATTRIBUTE_WRITE, + 10, + CHAR_VALUE_LEN_CONSTANT, + &hid_svc->ctrl_point_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add control point characteristic: %d", status); + } +} + +bool hid_svc_update_report_map(uint8_t* data, uint16_t len) { + furi_assert(data); + furi_assert(hid_svc); + + tBleStatus status = aci_gatt_update_char_value(hid_svc->svc_handle, + hid_svc->report_map_char_handle, + 0, + len, + data); + if(status) { + FURI_LOG_E(TAG, "Failed updating report map characteristic"); + return false; + } + return true; +} + +bool hid_svc_update_input_report(uint8_t* data, uint16_t len) { + furi_assert(data); + furi_assert(hid_svc); + + tBleStatus status = aci_gatt_update_char_value(hid_svc->svc_handle, + hid_svc->report_char_handle, + 0, + len, + data); + if(status) { + FURI_LOG_E(TAG, "Failed updating report characteristic"); + return false; + } + return true; +} + +bool hid_svc_update_info(uint8_t* data, uint16_t len) { + furi_assert(data); + furi_assert(hid_svc); + + tBleStatus status = aci_gatt_update_char_value(hid_svc->svc_handle, + hid_svc->info_char_handle, + 0, + len, + data); + if(status) { + FURI_LOG_E(TAG, "Failed updating info characteristic"); + return false; + } + return true; +} + +bool hid_svc_is_started() { + return hid_svc != NULL; +} + +void hid_svc_stop() { + tBleStatus status; + if(hid_svc) { + // Delete characteristics + status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->report_map_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete Report Map characteristic: %d", status); + } + status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->report_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete Report characteristic: %d", status); + } + status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->protocol_mode_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete Protocol Mode characteristic: %d", status); + } + status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->keyboard_boot_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete Keyboard Boot characteristic: %d", status); + } + status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->info_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete Information characteristic: %d", status); + } + status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->ctrl_point_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete Control Point characteristic: %d", status); + } + // Delete service + status = aci_gatt_del_service(hid_svc->svc_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete HID service: %d", status); + } + // Delete buffer size mutex + free(hid_svc); + hid_svc = NULL; + } +} diff --git a/firmware/targets/f6/ble-glue/hid_service.h b/firmware/targets/f6/ble-glue/hid_service.h new file mode 100644 index 00000000..ab4a2bb9 --- /dev/null +++ b/firmware/targets/f6/ble-glue/hid_service.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +#define HID_SVC_REPORT_MAP_MAX_LEN (80) +#define HID_SVC_REPORT_MAX_LEN (8) +#define HID_SVC_BOOT_KEYBOARD_INPUT_REPORT_MAX_LEN (8) +#define HID_SVC_REPORT_REF_LEN (2) +#define HID_SVC_INFO_LEN (4) +#define HID_SVC_CONTROL_POINT_LEN (1) + +void hid_svc_start(); + +void hid_svc_stop(); + +bool hid_svc_is_started(); + +bool hid_svc_update_report_map(uint8_t* data, uint16_t len); + +bool hid_svc_update_input_report(uint8_t* data, uint16_t len); + +bool hid_svc_update_info(uint8_t* data, uint16_t len); diff --git a/firmware/targets/f6/ble-glue/serial_service.c b/firmware/targets/f6/ble-glue/serial_service.c index c7ea6db2..4c70ccb0 100644 --- a/firmware/targets/f6/ble-glue/serial_service.c +++ b/firmware/targets/f6/ble-glue/serial_service.c @@ -14,8 +14,7 @@ typedef struct { osMutexId_t buff_size_mtx; uint32_t buff_size; uint16_t bytes_ready_to_receive; - SerialSvcDataReceivedCallback on_received_cb; - SerialSvcDataSentCallback on_sent_cb; + SerialServiceEventCallback callback; void* context; } SerialSvc; @@ -40,7 +39,7 @@ static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void *event) { FURI_LOG_D(TAG, "RX descriptor event"); } else if(attribute_modified->Attr_Handle == serial_svc->rx_char_handle + 1) { FURI_LOG_D(TAG, "Received %d bytes", attribute_modified->Attr_Data_Length); - if(serial_svc->on_received_cb) { + if(serial_svc->callback) { furi_check(osMutexAcquire(serial_svc->buff_size_mtx, osWaitForever) == osOK); if(attribute_modified->Attr_Data_Length > serial_svc->bytes_ready_to_receive) { FURI_LOG_W( @@ -48,8 +47,15 @@ static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void *event) { attribute_modified->Attr_Data_Length, serial_svc->bytes_ready_to_receive); } serial_svc->bytes_ready_to_receive -= MIN(serial_svc->bytes_ready_to_receive, attribute_modified->Attr_Data_Length); + SerialServiceEvent event = { + .event = SerialServiceEventTypeDataReceived, + .data = { + .buffer = attribute_modified->Attr_Data, + .size = attribute_modified->Attr_Data_Length, + } + }; uint32_t buff_free_size = - serial_svc->on_received_cb(attribute_modified->Attr_Data, attribute_modified->Attr_Data_Length, serial_svc->context); + serial_svc->callback(event, serial_svc->context); FURI_LOG_D(TAG, "Available buff size: %d", buff_free_size); furi_check(osMutexRelease(serial_svc->buff_size_mtx) == osOK); } @@ -57,8 +63,11 @@ static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void *event) { } } else if(blecore_evt->ecode == ACI_GATT_SERVER_CONFIRMATION_VSEVT_CODE) { FURI_LOG_D(TAG, "Ack received", blecore_evt->ecode); - if(serial_svc->on_sent_cb) { - serial_svc->on_sent_cb(serial_svc->context); + if(serial_svc->callback) { + SerialServiceEvent event = { + .event = SerialServiceEventTypeDataSent, + }; + serial_svc->callback(event, serial_svc->context); } ret = SVCCTL_EvtAckFlowEnable; } @@ -119,10 +128,9 @@ void serial_svc_start() { serial_svc->buff_size_mtx = osMutexNew(NULL); } -void serial_svc_set_callbacks(uint16_t buff_size, SerialSvcDataReceivedCallback on_received_cb, SerialSvcDataSentCallback on_sent_cb, void* context) { +void serial_svc_set_callbacks(uint16_t buff_size, SerialServiceEventCallback callback, void* context) { furi_assert(serial_svc); - serial_svc->on_received_cb = on_received_cb; - serial_svc->on_sent_cb = on_sent_cb; + serial_svc->callback = callback; serial_svc->context = context; serial_svc->buff_size = buff_size; serial_svc->bytes_ready_to_receive = buff_size; @@ -172,6 +180,10 @@ void serial_svc_stop() { } } +bool serial_svc_is_started() { + return serial_svc != NULL; +} + bool serial_svc_update_tx(uint8_t* data, uint8_t data_len) { if(data_len > SERIAL_SVC_DATA_LEN_MAX) { return false; diff --git a/firmware/targets/f6/ble-glue/serial_service.h b/firmware/targets/f6/ble-glue/serial_service.h index 5be13f1b..3ea548af 100644 --- a/firmware/targets/f6/ble-glue/serial_service.h +++ b/firmware/targets/f6/ble-glue/serial_service.h @@ -9,17 +9,33 @@ extern "C" { #endif -typedef uint16_t(*SerialSvcDataReceivedCallback)(uint8_t* buff, uint16_t size, void* context); -typedef void(*SerialSvcDataSentCallback)(void* context); +typedef enum { + SerialServiceEventTypeDataReceived, + SerialServiceEventTypeDataSent, +} SerialServiceEventType; + +typedef struct { + uint8_t* buffer; + uint16_t size; +} SerialServiceData; + +typedef struct { + SerialServiceEventType event; + SerialServiceData data; +} SerialServiceEvent; + +typedef uint16_t(*SerialServiceEventCallback)(SerialServiceEvent event, void* context); void serial_svc_start(); -void serial_svc_set_callbacks(uint16_t buff_size, SerialSvcDataReceivedCallback on_received_cb, SerialSvcDataSentCallback on_sent_cb, void* context); +void serial_svc_set_callbacks(uint16_t buff_size, SerialServiceEventCallback callback, void* context); void serial_svc_notify_buffer_is_empty(); void serial_svc_stop(); +bool serial_svc_is_started(); + bool serial_svc_update_tx(uint8_t* data, uint8_t data_len); #ifdef __cplusplus diff --git a/firmware/targets/f6/furi-hal/furi-hal-bt-hid.c b/firmware/targets/f6/furi-hal/furi-hal-bt-hid.c new file mode 100644 index 00000000..5d5e89ed --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-bt-hid.c @@ -0,0 +1,141 @@ +#include "furi-hal-bt-hid.h" +#include "dev_info_service.h" +#include "battery_service.h" +#include "hid_service.h" + +#include + +#define FURI_HAL_BT_INFO_BASE_USB_SPECIFICATION (0x0101) +#define FURI_HAL_BT_INFO_COUNTRY_CODE (0x00) +#define FURI_HAL_BT_HID_INFO_FLAG_REMOTE_WAKE_MSK (0x01) +#define FURI_HAL_BT_HID_INFO_FLAG_NORMALLY_CONNECTABLE_MSK (0x02) + +#define FURI_HAL_BT_HID_KB_KEYS_MAX (6) + +typedef struct { + uint8_t mods; + uint8_t reserved; + uint8_t key[FURI_HAL_BT_HID_KB_KEYS_MAX]; +} FuriHalBtHidKbReport; + +// TODO rework with HID defines +static uint8_t furi_hal_bt_hid_report_map_data[] = { + 0x05, 0x01, // Usage Page (Generic Desktop) + 0x09, 0x06, // Usage (Keyboard) + 0xA1, 0x01, // Collection (Application) + 0x05, 0x07, // Usage Page (Key Codes) + 0x19, 0xe0, // Usage Minimum (224) + 0x29, 0xe7, // Usage Maximum (231) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x75, 0x01, // Report Size (1) + 0x95, 0x08, // Report Count (8) + 0x81, 0x02, // Input (Data, Variable, Absolute) + + 0x95, 0x01, // Report Count (1) + 0x75, 0x08, // Report Size (8) + 0x81, 0x01, // Input (Constant) reserved byte(1) + + 0x95, 0x05, // Report Count (5) + 0x75, 0x01, // Report Size (1) + 0x05, 0x08, // Usage Page (Page# for LEDs) + 0x19, 0x01, // Usage Minimum (1) + 0x29, 0x05, // Usage Maximum (5) + 0x91, 0x02, // Output (Data, Variable, Absolute), Led report + 0x95, 0x01, // Report Count (1) + 0x75, 0x03, // Report Size (3) + 0x91, 0x01, // Output (Data, Variable, Absolute), Led report padding + + 0x95, 0x06, // Report Count (6) + 0x75, 0x08, // Report Size (8) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x65, // Logical Maximum (101) + 0x05, 0x07, // Usage Page (Key codes) + 0x19, 0x00, // Usage Minimum (0) + 0x29, 0x65, // Usage Maximum (101) + 0x81, 0x00, // Input (Data, Array) Key array(6 bytes) + + 0x09, 0x05, // Usage (Vendor Defined) + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xFF, 0x00, // Logical Maximum (255) + 0x75, 0x08, // Report Size (8 bit) + 0x95, 0x02, // Report Count (2) + 0xB1, 0x02, // Feature (Data, Variable, Absolute) + + 0xC0 // End Collection (Application) +}; + +FuriHalBtHidKbReport* kb_report = NULL; + +void furi_hal_bt_hid_start() { + // Start device info + if(!dev_info_svc_is_started()) { + dev_info_svc_start(); + } + // Start battery service + if(!battery_svc_is_started()) { + battery_svc_start(); + } + // Start HID service + if(!hid_svc_is_started()) { + hid_svc_start(); + } + // Configure HID Keyboard + kb_report = furi_alloc(sizeof(FuriHalBtHidKbReport)); + // Configure Report Map characteristic + hid_svc_update_report_map(furi_hal_bt_hid_report_map_data, sizeof(furi_hal_bt_hid_report_map_data)); + // Configure HID Information characteristic + uint8_t hid_info_val[4] = { + FURI_HAL_BT_INFO_BASE_USB_SPECIFICATION & 0x00ff, + (FURI_HAL_BT_INFO_BASE_USB_SPECIFICATION & 0xff00) >> 8, + FURI_HAL_BT_INFO_COUNTRY_CODE, + FURI_HAL_BT_HID_INFO_FLAG_REMOTE_WAKE_MSK | FURI_HAL_BT_HID_INFO_FLAG_NORMALLY_CONNECTABLE_MSK, + }; + hid_svc_update_info(hid_info_val, sizeof(hid_info_val)); +} + +void furi_hal_bt_hid_stop() { + furi_assert(kb_report); + // Stop all services + if(dev_info_svc_is_started()) { + dev_info_svc_stop(); + } + if(battery_svc_is_started()) { + battery_svc_stop(); + } + if(hid_svc_is_started()) { + hid_svc_stop(); + } + free(kb_report); + kb_report = NULL; +} + +bool furi_hal_bt_hid_kb_press(uint16_t button) { + furi_assert(kb_report); + for (uint8_t i = 0; i < FURI_HAL_BT_HID_KB_KEYS_MAX; i++) { + if (kb_report->key[i] == 0) { + kb_report->key[i] = button & 0xFF; + break; + } + } + kb_report->mods |= (button >> 8); + return hid_svc_update_input_report((uint8_t*)kb_report, sizeof(FuriHalBtHidKbReport)); +} + +bool furi_hal_bt_hid_kb_release(uint16_t button) { + furi_assert(kb_report); + for (uint8_t i = 0; i < FURI_HAL_BT_HID_KB_KEYS_MAX; i++) { + if (kb_report->key[i] == (button & 0xFF)) { + kb_report->key[i] = 0; + break; + } + } + kb_report->mods &= ~(button >> 8); + return hid_svc_update_input_report((uint8_t*)kb_report, sizeof(FuriHalBtHidKbReport)); +} + +bool furi_hal_bt_hid_kb_release_all() { + furi_assert(kb_report); + memset(kb_report, 0, sizeof(FuriHalBtHidKbReport)); + return hid_svc_update_input_report((uint8_t*)kb_report, sizeof(FuriHalBtHidKbReport)); +} diff --git a/firmware/targets/f6/furi-hal/furi-hal-bt-serial.c b/firmware/targets/f6/furi-hal/furi-hal-bt-serial.c new file mode 100644 index 00000000..d5ea869b --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-bt-serial.c @@ -0,0 +1,51 @@ +#include "furi-hal-bt-serial.h" +#include "dev_info_service.h" +#include "battery_service.h" +#include "serial_service.h" + +#include + +void furi_hal_bt_serial_start() { + // Start device info + if(!dev_info_svc_is_started()) { + dev_info_svc_start(); + } + // Start battery service + if(!battery_svc_is_started()) { + battery_svc_start(); + } + // Start Serial service + if(!serial_svc_is_started()) { + serial_svc_start(); + } +} + +void furi_hal_bt_serial_set_event_callback(uint16_t buff_size, FuriHalBtSerialCallback callback, void* context) { + serial_svc_set_callbacks(buff_size, callback, context); +} + +void furi_hal_bt_serial_notify_buffer_is_empty() { + serial_svc_notify_buffer_is_empty(); +} + +bool furi_hal_bt_serial_tx(uint8_t* data, uint16_t size) { + if(size > FURI_HAL_BT_SERIAL_PACKET_SIZE_MAX) { + return false; + } + return serial_svc_update_tx(data, size); +} + +void furi_hal_bt_serial_stop() { + // Stop all services + if(dev_info_svc_is_started()) { + dev_info_svc_stop(); + } + // Start battery service + if(battery_svc_is_started()) { + battery_svc_stop(); + } + // Start Serial service + if(serial_svc_is_started()) { + serial_svc_stop(); + } +} diff --git a/firmware/targets/f6/furi-hal/furi-hal-bt.c b/firmware/targets/f6/furi-hal/furi-hal-bt.c index b74a9e29..714d894f 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-bt.c +++ b/firmware/targets/f6/furi-hal/furi-hal-bt.c @@ -4,18 +4,66 @@ #include #include +#include +#include +#include +#include "battery_service.h" + #include #define TAG "FuriHalBt" +#define FURI_HAL_BT_DEFAULT_MAC_ADDR {0x6c, 0x7a, 0xd8, 0xac, 0x57, 0x72} + osMutexId_t furi_hal_bt_core2_mtx = NULL; +typedef void (*FuriHalBtProfileStart)(void); +typedef void (*FuriHalBtProfileStop)(void); + +typedef struct { + FuriHalBtProfileStart start; + FuriHalBtProfileStart stop; + GapConfig config; + uint16_t appearance_char; + uint16_t advertise_service_uuid; +} FuriHalBtProfileConfig; + +FuriHalBtProfileConfig profile_config[FuriHalBtProfileNumber] = { + [FuriHalBtProfileSerial] = { + .start = furi_hal_bt_serial_start, + .stop = furi_hal_bt_serial_stop, + .config = { + .adv_service_uuid = 0x3080, + .appearance_char = 0x8600, + .bonding_mode = true, + .pairing_method = GapPairingPinCodeShow, + .mac_address = FURI_HAL_BT_DEFAULT_MAC_ADDR, + }, + }, + [FuriHalBtProfileHidKeyboard] = { + .start = furi_hal_bt_hid_start, + .stop = furi_hal_bt_hid_stop, + .config = { + .adv_service_uuid = HUMAN_INTERFACE_DEVICE_SERVICE_UUID, + .appearance_char = GAP_APPEARANCE_KEYBOARD, + .bonding_mode = true, + .pairing_method = GapPairingPinCodeVerifyYesNo, + .mac_address = FURI_HAL_BT_DEFAULT_MAC_ADDR, + }, + } +}; +FuriHalBtProfileConfig* current_profile = NULL; + void furi_hal_bt_init() { - furi_hal_bt_core2_mtx = osMutexNew(NULL); - furi_assert(furi_hal_bt_core2_mtx); + if(!furi_hal_bt_core2_mtx) { + furi_hal_bt_core2_mtx = osMutexNew(NULL); + furi_assert(furi_hal_bt_core2_mtx); + } // Explicitly tell that we are in charge of CLK48 domain - HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID); + if(!HAL_HSEM_IsSemTaken(CFG_HW_CLK48_CONFIG_SEMID)) { + HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID); + } // Start Core2 ble_glue_init(); @@ -31,12 +79,14 @@ void furi_hal_bt_unlock_core2() { furi_check(osMutexRelease(furi_hal_bt_core2_mtx) == osOK); } -bool furi_hal_bt_start_core2() { +static bool furi_hal_bt_start_core2() { furi_assert(furi_hal_bt_core2_mtx); osMutexAcquire(furi_hal_bt_core2_mtx, osWaitForever); // Explicitly tell that we are in charge of CLK48 domain - HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID); + if(!HAL_HSEM_IsSemTaken(CFG_HW_CLK48_CONFIG_SEMID)) { + HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID); + } // Start Core2 bool ret = ble_glue_start(); osMutexRelease(furi_hal_bt_core2_mtx); @@ -44,9 +94,80 @@ bool furi_hal_bt_start_core2() { return ret; } -bool furi_hal_bt_init_app(BleEventCallback event_cb, void* context) { +bool furi_hal_bt_start_app(FuriHalBtProfile profile, BleEventCallback event_cb, void* context) { furi_assert(event_cb); - return gap_init(event_cb, context); + furi_assert(profile < FuriHalBtProfileNumber); + bool ret = true; + + do { + // Start 2nd core + ret = furi_hal_bt_start_core2(); + if(!ret) { + ble_app_thread_stop(); + FURI_LOG_E(TAG, "Failed to start 2nd core"); + break; + } + // Set mac address + memcpy( + profile_config[profile].config.mac_address, + furi_hal_version_get_ble_mac(), + sizeof(profile_config[profile].config.mac_address) + ); + // Set advertise name + strlcpy( + profile_config[profile].config.adv_name, + furi_hal_version_get_ble_local_device_name_ptr(), + FURI_HAL_VERSION_DEVICE_NAME_LENGTH + ); + // Configure GAP + GapConfig* config = &profile_config[profile].config; + if(profile == FuriHalBtProfileSerial) { + config->adv_service_uuid |= furi_hal_version_get_hw_color(); + } else if(profile == FuriHalBtProfileHidKeyboard) { + // Change MAC address for HID profile + config->mac_address[2]++; + // Change name Flipper -> Clicker + const char* clicker_str = "Clicker"; + memcpy(&config->adv_name[1], clicker_str, strlen(clicker_str) - 1); + } + ret = gap_init(config, event_cb, context); + if(!ret) { + gap_thread_stop(); + FURI_LOG_E(TAG, "Failed to init GAP"); + break; + } + // Start selected profile services + profile_config[profile].start(); + } while(false); + current_profile = &profile_config[profile]; + + return ret; +} + +bool furi_hal_bt_change_app(FuriHalBtProfile profile, BleEventCallback event_cb, void* context) { + furi_assert(event_cb); + furi_assert(profile < FuriHalBtProfileNumber); + bool ret = true; + + FURI_LOG_I(TAG, "Stop current profile services"); + current_profile->stop(); + FURI_LOG_I(TAG, "Disconnect and stop advertising"); + furi_hal_bt_stop_advertising(); + FURI_LOG_I(TAG, "Shutdow 2nd core"); + LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN); + FURI_LOG_I(TAG, "Stop BLE related RTOS threads"); + ble_app_thread_stop(); + gap_thread_stop(); + FURI_LOG_I(TAG, "Reset SHCI"); + SHCI_C2_Reinit(); + ble_glue_thread_stop(); + FURI_LOG_I(TAG, "Start BT initialization"); + furi_hal_bt_init(); + ret = furi_hal_bt_start_app(profile, event_cb, context); + if(ret) { + current_profile = &profile_config[profile]; + } + return ret; } void furi_hal_bt_start_advertising() { @@ -64,19 +185,10 @@ void furi_hal_bt_stop_advertising() { } } -void furi_hal_bt_set_data_event_callbacks(uint16_t buff_size, SerialSvcDataReceivedCallback on_received_cb, SerialSvcDataSentCallback on_sent_cb, void* context) { - serial_svc_set_callbacks(buff_size, on_received_cb, on_sent_cb, context); -} - -void furi_hal_bt_notify_buffer_is_empty() { - serial_svc_notify_buffer_is_empty(); -} - -bool furi_hal_bt_tx(uint8_t* data, uint16_t size) { - if(size > FURI_HAL_BT_PACKET_SIZE_MAX) { - return false; +void furi_hal_bt_update_battery_level(uint8_t battery_level) { + if(battery_svc_is_started()) { + battery_svc_update_level(battery_level); } - return serial_svc_update_tx(data, size); } void furi_hal_bt_get_key_storage_buff(uint8_t** key_buff_addr, uint16_t* key_buff_size) { diff --git a/firmware/targets/f6/furi-hal/furi-hal-flash.c b/firmware/targets/f6/furi-hal/furi-hal-flash.c index 156a26a9..8a1d2d06 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-flash.c +++ b/firmware/targets/f6/furi-hal/furi-hal-flash.c @@ -113,9 +113,11 @@ static void furi_hal_flash_begin_with_core2(bool erase_flag) { } // Take sempahopre and prevent core2 from anyting funky - if (HAL_HSEM_FastTake(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) != HAL_OK) { - taskEXIT_CRITICAL(); - continue; + if(!HAL_HSEM_IsSemTaken(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID)) { + if (HAL_HSEM_FastTake(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) != HAL_OK) { + taskEXIT_CRITICAL(); + continue; + } } break; diff --git a/firmware/targets/f7/ble-glue/battery_service.c b/firmware/targets/f7/ble-glue/battery_service.c index 2a5dad5e..08dec734 100644 --- a/firmware/targets/f7/ble-glue/battery_service.c +++ b/firmware/targets/f7/ble-glue/battery_service.c @@ -59,6 +59,10 @@ void battery_svc_stop() { } } +bool battery_svc_is_started() { + return battery_svc != NULL; +} + bool battery_svc_update_level(uint8_t battery_charge) { // Check if service was started if(battery_svc == NULL) { diff --git a/firmware/targets/f7/ble-glue/battery_service.h b/firmware/targets/f7/ble-glue/battery_service.h index a50e607c..2d35e252 100644 --- a/firmware/targets/f7/ble-glue/battery_service.h +++ b/firmware/targets/f7/ble-glue/battery_service.h @@ -11,6 +11,8 @@ void battery_svc_start(); void battery_svc_stop(); +bool battery_svc_is_started(); + bool battery_svc_update_level(uint8_t battery_level); #ifdef __cplusplus diff --git a/firmware/targets/f7/ble-glue/ble_app.c b/firmware/targets/f7/ble-glue/ble_app.c index 40b34679..3f09d1f0 100644 --- a/firmware/targets/f7/ble-glue/ble_app.c +++ b/firmware/targets/f7/ble-glue/ble_app.c @@ -10,20 +10,24 @@ #define TAG "Bt" +#define BLE_APP_FLAG_HCI_EVENT (1UL << 0) +#define BLE_APP_FLAG_KILL_THREAD (1UL << 1) +#define BLE_APP_FLAG_ALL (BLE_APP_FLAG_HCI_EVENT | BLE_APP_FLAG_KILL_THREAD) + PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_CmdPacket_t ble_app_cmd_buffer; PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint32_t ble_app_nvm[BLE_NVM_SRAM_SIZE]; typedef struct { osMutexId_t hci_mtx; osSemaphoreId_t hci_sem; - osThreadId_t hci_thread_id; - osThreadAttr_t hci_thread_attr; + FuriThread* thread; + osEventFlagsId_t event_flags; } BleApp; -static BleApp* ble_app; +static BleApp* ble_app = NULL; -static void ble_app_hci_thread(void *arg); -static void ble_app_hci_event_handler(void * pPayload); +static int32_t ble_app_hci_thread(void* context); +static void ble_app_hci_event_handler(void* pPayload); static void ble_app_hci_status_not_handler(HCI_TL_CmdStatus_t status); bool ble_app_init() { @@ -32,10 +36,14 @@ bool ble_app_init() { // Allocate semafore and mutex for ble command buffer access ble_app->hci_mtx = osMutexNew(NULL); ble_app->hci_sem = osSemaphoreNew(1, 0, NULL); + ble_app->event_flags = osEventFlagsNew(NULL); // HCI transport layer thread to handle user asynch events - ble_app->hci_thread_attr.name = "BleHciWorker"; - ble_app->hci_thread_attr.stack_size = 1024; - ble_app->hci_thread_id = osThreadNew(ble_app_hci_thread, NULL, &ble_app->hci_thread_attr); + ble_app->thread = furi_thread_alloc(); + furi_thread_set_name(ble_app->thread, "BleHciWorker"); + furi_thread_set_stack_size(ble_app->thread, 1024); + furi_thread_set_context(ble_app->thread, ble_app); + furi_thread_set_callback(ble_app->thread, ble_app_hci_thread); + furi_thread_start(ble_app->thread); // Initialize Ble Transport Layer HCI_TL_HciInitConf_t hci_tl_config = { @@ -92,35 +100,68 @@ void ble_app_get_key_storage_buff(uint8_t** addr, uint16_t* size) { *size = sizeof(ble_app_nvm); } -static void ble_app_hci_thread(void *arg) { - while(1) { - osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever); - hci_user_evt_proc(); +void ble_app_thread_stop() { + if(ble_app) { + osEventFlagsSet(ble_app->event_flags, BLE_APP_FLAG_KILL_THREAD); + furi_thread_join(ble_app->thread); + furi_thread_free(ble_app->thread); + // Wait to make sure that EventFlags delivers pending events before memory free + osDelay(50); + // Free resources + osMutexDelete(ble_app->hci_mtx); + osSemaphoreDelete(ble_app->hci_sem); + osEventFlagsDelete(ble_app->event_flags); + free(ble_app); + ble_app = NULL; + memset(&ble_app_cmd_buffer, 0, sizeof(ble_app_cmd_buffer)); } } +static int32_t ble_app_hci_thread(void *arg) { + uint32_t flags = 0; + while(1) { + flags = osEventFlagsWait(ble_app->event_flags, BLE_APP_FLAG_ALL, osFlagsWaitAny, osWaitForever); + if(flags & BLE_APP_FLAG_KILL_THREAD) { + break; + } + if(flags & BLE_APP_FLAG_HCI_EVENT) { + hci_user_evt_proc(); + } + } + + return 0; +} + // Called by WPAN lib void hci_notify_asynch_evt(void* pdata) { - osThreadFlagsSet(ble_app->hci_thread_id, 1); + if(ble_app) { + osEventFlagsSet(ble_app->event_flags, BLE_APP_FLAG_HCI_EVENT); + } } void hci_cmd_resp_release(uint32_t flag) { - osSemaphoreRelease(ble_app->hci_sem); + if(ble_app) { + osSemaphoreRelease(ble_app->hci_sem); + } } void hci_cmd_resp_wait(uint32_t timeout) { - osSemaphoreAcquire(ble_app->hci_sem, osWaitForever); + if(ble_app) { + osSemaphoreAcquire(ble_app->hci_sem, osWaitForever); + } } static void ble_app_hci_event_handler( void * pPayload ) { SVCCTL_UserEvtFlowStatus_t svctl_return_status; tHCI_UserEvtRxParam *pParam = (tHCI_UserEvtRxParam *)pPayload; - svctl_return_status = SVCCTL_UserEvtRx((void *)&(pParam->pckt->evtserial)); - if (svctl_return_status != SVCCTL_UserEvtFlowDisable) { - pParam->status = HCI_TL_UserEventFlow_Enable; - } else { - pParam->status = HCI_TL_UserEventFlow_Disable; + if(ble_app) { + svctl_return_status = SVCCTL_UserEvtRx((void *)&(pParam->pckt->evtserial)); + if (svctl_return_status != SVCCTL_UserEvtFlowDisable) { + pParam->status = HCI_TL_UserEventFlow_Enable; + } else { + pParam->status = HCI_TL_UserEventFlow_Disable; + } } } diff --git a/firmware/targets/f7/ble-glue/ble_app.h b/firmware/targets/f7/ble-glue/ble_app.h index 64000bde..062154e9 100644 --- a/firmware/targets/f7/ble-glue/ble_app.h +++ b/firmware/targets/f7/ble-glue/ble_app.h @@ -9,6 +9,7 @@ extern "C" { bool ble_app_init(); void ble_app_get_key_storage_buff(uint8_t** addr, uint16_t* size); +void ble_app_thread_stop(); #ifdef __cplusplus } diff --git a/firmware/targets/f7/ble-glue/ble_glue.c b/firmware/targets/f7/ble-glue/ble_glue.c index 45503683..007f3645 100644 --- a/firmware/targets/f7/ble-glue/ble_glue.c +++ b/firmware/targets/f7/ble-glue/ble_glue.c @@ -12,6 +12,10 @@ #define TAG "Core2" +#define BLE_GLUE_FLAG_SHCI_EVENT (1UL << 0) +#define BLE_GLUE_FLAG_KILL_THREAD (1UL << 1) +#define BLE_GLUE_FLAG_ALL (BLE_GLUE_FLAG_SHCI_EVENT | BLE_GLUE_FLAG_KILL_THREAD) + #define POOL_SIZE (CFG_TLBLE_EVT_QUEUE_LENGTH*4U*DIVC(( sizeof(TL_PacketHeader_t) + TL_BLE_EVENT_FRAME_SIZE ), 4U)) PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t ble_glue_event_pool[POOL_SIZE]; @@ -32,8 +36,8 @@ typedef enum { typedef struct { osMutexId_t shci_mtx; osSemaphoreId_t shci_sem; - osThreadId_t shci_user_event_thread_id; - osThreadAttr_t shci_user_event_thread_attr; + osEventFlagsId_t event_flags; + FuriThread* thread; BleGlueStatus status; BleGlueKeyStorageChangedCallback callback; void* context; @@ -41,7 +45,7 @@ typedef struct { static BleGlue* ble_glue = NULL; -static void ble_glue_user_event_thread(void *argument); +static int32_t ble_glue_shci_thread(void *argument); static void ble_glue_sys_status_not_callback(SHCI_TL_CmdStatus_t status); static void ble_glue_sys_user_event_callback(void* pPayload); @@ -55,8 +59,6 @@ void ble_glue_set_key_storage_changed_callback(BleGlueKeyStorageChangedCallback void ble_glue_init() { ble_glue = furi_alloc(sizeof(BleGlue)); ble_glue->status = BleGlueStatusStartup; - ble_glue->shci_user_event_thread_attr.name = "BleShciWorker"; - ble_glue->shci_user_event_thread_attr.stack_size = 1024; // Configure the system Power Mode // Select HSI as system clock source after Wake Up from Stop mode @@ -75,9 +77,15 @@ void ble_glue_init() { ble_glue->shci_mtx = osMutexNew(NULL); ble_glue->shci_sem = osSemaphoreNew(1, 0, NULL); + ble_glue->event_flags = osEventFlagsNew(NULL); // FreeRTOS system task creation - ble_glue->shci_user_event_thread_id = osThreadNew(ble_glue_user_event_thread, NULL, &ble_glue->shci_user_event_thread_attr); + ble_glue->thread = furi_thread_alloc(); + furi_thread_set_name(ble_glue->thread, "BleShciWorker"); + furi_thread_set_stack_size(ble_glue->thread, 1024); + furi_thread_set_context(ble_glue->thread, ble_glue); + furi_thread_set_callback(ble_glue->thread, ble_glue_shci_thread); + furi_thread_start(ble_glue->thread); // System channel initialization SHci_Tl_Init_Conf.p_cmdbuffer = (uint8_t*)&ble_glue_system_cmd_buff; @@ -205,26 +213,63 @@ static void ble_glue_sys_user_event_callback( void * pPayload ) { } } -// Wrap functions -static void ble_glue_user_event_thread(void *argument) { - UNUSED(argument); - for(;;) { - osThreadFlagsWait(1, osFlagsWaitAny, osWaitForever); - shci_user_evt_proc(); +static void ble_glue_clear_shared_memory() { + memset(ble_glue_event_pool, 0, sizeof(ble_glue_event_pool)); + memset(&ble_glue_system_cmd_buff, 0, sizeof(ble_glue_system_cmd_buff)); + memset(ble_glue_system_spare_event_buff, 0, sizeof(ble_glue_system_spare_event_buff)); + memset(ble_glue_ble_spare_event_buff, 0, sizeof(ble_glue_ble_spare_event_buff)); +} + +void ble_glue_thread_stop() { + if(ble_glue) { + osEventFlagsSet(ble_glue->event_flags, BLE_GLUE_FLAG_KILL_THREAD); + furi_thread_join(ble_glue->thread); + furi_thread_free(ble_glue->thread); + // Wait to make sure that EventFlags delivers pending events before memory free + osDelay(50); + // Free resources + osMutexDelete(ble_glue->shci_mtx); + osSemaphoreDelete(ble_glue->shci_sem); + osEventFlagsDelete(ble_glue->event_flags); + ble_glue_clear_shared_memory(); + free(ble_glue); + ble_glue = NULL; } } +// Wrap functions +static int32_t ble_glue_shci_thread(void* context) { + uint32_t flags = 0; + while(true) { + flags = osEventFlagsWait(ble_glue->event_flags, BLE_GLUE_FLAG_ALL, osFlagsWaitAny, osWaitForever); + if(flags & BLE_GLUE_FLAG_SHCI_EVENT) { + shci_user_evt_proc(); + } + if(flags & BLE_GLUE_FLAG_KILL_THREAD) { + break; + } + } + + return 0; +} + void shci_notify_asynch_evt(void* pdata) { UNUSED(pdata); - osThreadFlagsSet(ble_glue->shci_user_event_thread_id, 1); + if(ble_glue) { + osEventFlagsSet(ble_glue->event_flags, BLE_GLUE_FLAG_SHCI_EVENT); + } } void shci_cmd_resp_release(uint32_t flag) { UNUSED(flag); - osSemaphoreRelease(ble_glue->shci_sem); + if(ble_glue) { + osSemaphoreRelease(ble_glue->shci_sem); + } } void shci_cmd_resp_wait(uint32_t timeout) { UNUSED(timeout); - osSemaphoreAcquire(ble_glue->shci_sem, osWaitForever); + if(ble_glue) { + osSemaphoreAcquire(ble_glue->shci_sem, osWaitForever); + } } diff --git a/firmware/targets/f7/ble-glue/ble_glue.h b/firmware/targets/f7/ble-glue/ble_glue.h index ac668c42..a95d633c 100644 --- a/firmware/targets/f7/ble-glue/ble_glue.h +++ b/firmware/targets/f7/ble-glue/ble_glue.h @@ -38,6 +38,8 @@ bool ble_glue_is_radio_stack_ready(); */ void ble_glue_set_key_storage_changed_callback(BleGlueKeyStorageChangedCallback callback, void* context); +void ble_glue_thread_stop(); + #ifdef __cplusplus } #endif diff --git a/firmware/targets/f7/ble-glue/dev_info_service.c b/firmware/targets/f7/ble-glue/dev_info_service.c index 64ff0509..e47fdf66 100644 --- a/firmware/targets/f7/ble-glue/dev_info_service.c +++ b/firmware/targets/f7/ble-glue/dev_info_service.c @@ -154,3 +154,7 @@ void dev_info_svc_stop() { dev_info_svc = NULL; } } + +bool dev_info_svc_is_started() { + return dev_info_svc != NULL; +} diff --git a/firmware/targets/f7/ble-glue/dev_info_service.h b/firmware/targets/f7/ble-glue/dev_info_service.h index 62eccefa..f5531fc7 100644 --- a/firmware/targets/f7/ble-glue/dev_info_service.h +++ b/firmware/targets/f7/ble-glue/dev_info_service.h @@ -16,6 +16,8 @@ void dev_info_svc_start(); void dev_info_svc_stop(); +bool dev_info_svc_is_started(); + #ifdef __cplusplus } #endif diff --git a/firmware/targets/f7/ble-glue/gap.c b/firmware/targets/f7/ble-glue/gap.c index a2381653..7f574f0b 100644 --- a/firmware/targets/f7/ble-glue/gap.c +++ b/firmware/targets/f7/ble-glue/gap.c @@ -3,20 +3,14 @@ #include "ble.h" #include "cmsis_os.h" -#include "otp.h" -#include "dev_info_service.h" -#include "battery_service.h" -#include "serial_service.h" - #include +#include #define TAG "BtGap" #define FAST_ADV_TIMEOUT 30000 #define INITIAL_ADV_TIMEOUT 60000 -#define BD_ADDR_SIZE_LOCAL 6 - typedef struct { uint16_t gap_svc_handle; uint16_t dev_name_char_handle; @@ -24,18 +18,18 @@ typedef struct { uint16_t connection_handle; uint8_t adv_svc_uuid_len; uint8_t adv_svc_uuid[20]; + char* adv_name; } GapSvc; typedef struct { - GapSvc gap_svc; + GapSvc service; + GapConfig* config; GapState state; osMutexId_t state_mutex; - uint8_t mac_address[BD_ADDR_SIZE_LOCAL]; BleEventCallback on_event_cb; void* context; osTimerId advertise_timer; - osThreadAttr_t thread_attr; - osThreadId_t thread_id; + FuriThread* thread; osMessageQueueId_t command_queue; bool enable_adv; } Gap; @@ -44,47 +38,44 @@ typedef enum { GapCommandAdvFast, GapCommandAdvLowPower, GapCommandAdvStop, + GapCommandKillThread, } GapCommand; // Identity root key static const uint8_t gap_irk[16] = {0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0}; // Encryption root key static const uint8_t gap_erk[16] = {0xfe,0xdc,0xba,0x09,0x87,0x65,0x43,0x21,0xfe,0xdc,0xba,0x09,0x87,0x65,0x43,0x21}; -// Appearence characteristic UUID -static const uint8_t gap_appearence_char_uuid[] = {0x00, 0x86}; -// Default MAC address -static const uint8_t gap_default_mac_addr[] = {0x6c, 0x7a, 0xd8, 0xac, 0x57, 0x72}; static Gap* gap = NULL; static void gap_advertise_start(GapState new_state); -static void gap_app(void *arg); +static int32_t gap_app(void* context); SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) { - hci_event_pckt *event_pckt; - evt_le_meta_event *meta_evt; - evt_blue_aci *blue_evt; - hci_le_phy_update_complete_event_rp0 *evt_le_phy_update_complete; + hci_event_pckt* event_pckt; + evt_le_meta_event* meta_evt; + evt_blue_aci* blue_evt; + hci_le_phy_update_complete_event_rp0* evt_le_phy_update_complete; uint8_t tx_phy; uint8_t rx_phy; tBleStatus ret = BLE_STATUS_INVALID_PARAMS; - event_pckt = (hci_event_pckt*) ((hci_uart_pckt *) pckt)->data; + event_pckt = (hci_event_pckt*)((hci_uart_pckt*)pckt)->data; osMutexAcquire(gap->state_mutex, osWaitForever); switch (event_pckt->evt) { case EVT_DISCONN_COMPLETE: { hci_disconnection_complete_event_rp0 *disconnection_complete_event = (hci_disconnection_complete_event_rp0 *) event_pckt->data; - if (disconnection_complete_event->Connection_Handle == gap->gap_svc.connection_handle) { - gap->gap_svc.connection_handle = 0; + if (disconnection_complete_event->Connection_Handle == gap->service.connection_handle) { + gap->service.connection_handle = 0; gap->state = GapStateIdle; - FURI_LOG_I(TAG, "Disconnect from client. Reason: %d", disconnection_complete_event->Reason); + FURI_LOG_I(TAG, "Disconnect from client. Reason: %02X", disconnection_complete_event->Reason); } if(gap->enable_adv) { // Restart advertising - gap_start_advertising(); + gap_advertise_start(GapCommandAdvFast); furi_hal_power_insomnia_exit(); } BleEvent event = {.type = BleEventTypeDisconnected}; @@ -106,7 +97,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) } else { FURI_LOG_I(TAG, "Update PHY succeed"); } - ret = hci_le_read_phy(gap->gap_svc.connection_handle,&tx_phy,&rx_phy); + ret = hci_le_read_phy(gap->service.connection_handle,&tx_phy,&rx_phy); if(ret) { FURI_LOG_E(TAG, "Read PHY failed, status: %d", ret); } else { @@ -124,7 +115,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) // Update connection status and handle gap->state = GapStateConnected; - gap->gap_svc.connection_handle = connection_complete_event->Connection_Handle; + gap->service.connection_handle = connection_complete_event->Connection_Handle; // Start pairing by sending security request aci_gap_slave_security_req(connection_complete_event->Connection_Handle); @@ -148,8 +139,8 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) { // Generate random PIN code uint32_t pin = rand() % 999999; - aci_gap_pass_key_resp(gap->gap_svc.connection_handle, pin); - FURI_LOG_I(TAG, "Pass key request event. Pin: %d", pin); + aci_gap_pass_key_resp(gap->service.connection_handle, pin); + FURI_LOG_I(TAG, "Pass key request event. Pin: %06d", pin); BleEvent event = {.type = BleEventTypePinCodeShow, .data.pin_code = pin}; gap->on_event_cb(event, gap->context); } @@ -175,7 +166,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) case EVT_BLUE_GAP_BOND_LOST: FURI_LOG_I(TAG, "Bond lost event. Start rebonding"); - aci_gap_allow_rebond(gap->gap_svc.connection_handle); + aci_gap_allow_rebond(gap->service.connection_handle); break; case EVT_BLUE_GAP_DEVICE_FOUND: @@ -191,16 +182,20 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) break; case EVT_BLUE_GAP_NUMERIC_COMPARISON_VALUE: - FURI_LOG_I(TAG, "Hex_value = %lx", - ((aci_gap_numeric_comparison_value_event_rp0 *)(blue_evt->data))->Numeric_Value); - aci_gap_numeric_comparison_value_confirm_yesno(gap->gap_svc.connection_handle, 1); + { + uint32_t pin = ((aci_gap_numeric_comparison_value_event_rp0 *)(blue_evt->data))->Numeric_Value; + FURI_LOG_I(TAG, "Verify numeric comparison: %06d", pin); + BleEvent event = {.type = BleEventTypePinCodeVerify, .data.pin_code = pin}; + bool result = gap->on_event_cb(event, gap->context); + aci_gap_numeric_comparison_value_confirm_yesno(gap->service.connection_handle, result); break; + } case EVT_BLUE_GAP_PAIRING_CMPLT: pairing_complete = (aci_gap_pairing_complete_event_rp0*)blue_evt->data; if (pairing_complete->Status) { FURI_LOG_E(TAG, "Pairing failed with status: %d. Terminating connection", pairing_complete->Status); - aci_gap_terminate(gap->gap_svc.connection_handle, 5); + aci_gap_terminate(gap->service.connection_handle, 5); } else { FURI_LOG_I(TAG, "Pairing complete"); BleEvent event = {.type = BleEventTypeConnected}; @@ -220,46 +215,15 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification( void *pckt ) } static void set_advertisment_service_uid(uint8_t* uid, uint8_t uid_len) { - gap->gap_svc.adv_svc_uuid_len = 1; if(uid_len == 2) { - gap->gap_svc.adv_svc_uuid[0] = AD_TYPE_16_BIT_SERV_UUID; + gap->service.adv_svc_uuid[0] = AD_TYPE_16_BIT_SERV_UUID; } else if (uid_len == 4) { - gap->gap_svc.adv_svc_uuid[0] = AD_TYPE_32_BIT_SERV_UUID; + gap->service.adv_svc_uuid[0] = AD_TYPE_32_BIT_SERV_UUID; } else if(uid_len == 16) { - gap->gap_svc.adv_svc_uuid[0] = AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST; - } - memcpy(&gap->gap_svc.adv_svc_uuid[1], uid, uid_len); - gap->gap_svc.adv_svc_uuid_len += uid_len; -} - -GapState gap_get_state() { - return gap->state; -} - -void gap_init_mac_address(Gap* gap) { - uint8_t *otp_addr; - uint32_t udn; - uint32_t company_id; - uint32_t device_id; - - udn = LL_FLASH_GetUDN(); - if(udn != 0xFFFFFFFF) { - company_id = LL_FLASH_GetSTCompanyID(); - device_id = LL_FLASH_GetDeviceID(); - gap->mac_address[0] = (uint8_t)(udn & 0x000000FF); - gap->mac_address[1] = (uint8_t)( (udn & 0x0000FF00) >> 8 ); - gap->mac_address[2] = (uint8_t)( (udn & 0x00FF0000) >> 16 ); - gap->mac_address[3] = (uint8_t)device_id; - gap->mac_address[4] = (uint8_t)(company_id & 0x000000FF);; - gap->mac_address[5] = (uint8_t)( (company_id & 0x0000FF00) >> 8 ); - } else { - otp_addr = OTP_Read(0); - if(otp_addr) { - memcpy(gap->mac_address, ((OTP_ID0_t*)otp_addr)->bd_address, sizeof(gap->mac_address)); - } else { - memcpy(gap->mac_address, gap_default_mac_addr, sizeof(gap->mac_address)); - } + gap->service.adv_svc_uuid[0] = AD_TYPE_128_BIT_SERV_UUID_CMPLT_LIST; } + memcpy(&gap->service.adv_svc_uuid[gap->service.adv_svc_uuid_len], uid, uid_len); + gap->service.adv_svc_uuid_len += uid_len; } static void gap_init_svc(Gap* gap) { @@ -269,8 +233,7 @@ static void gap_init_svc(Gap* gap) { // HCI Reset to synchronise BLE Stack hci_reset(); // Configure mac address - gap_init_mac_address(gap); - aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET, CONFIG_DATA_PUBADDR_LEN, (uint8_t*)gap->mac_address); + aci_hal_write_config_data(CONFIG_DATA_PUBADDR_OFFSET, CONFIG_DATA_PUBADDR_LEN, gap->config->mac_address); /* Static random Address * The two upper bits shall be set to 1 @@ -289,25 +252,42 @@ static void gap_init_svc(Gap* gap) { // Initialize GATT interface aci_gatt_init(); // Initialize GAP interface - const char *name = furi_hal_version_get_device_name_ptr(); + // Skip fist symbol AD_TYPE_COMPLETE_LOCAL_NAME + char *name = gap->service.adv_name + 1; aci_gap_init(GAP_PERIPHERAL_ROLE, 0, strlen(name), - &gap->gap_svc.gap_svc_handle, &gap->gap_svc.dev_name_char_handle, &gap->gap_svc.appearance_char_handle); + &gap->service.gap_svc_handle, &gap->service.dev_name_char_handle, &gap->service.appearance_char_handle); // Set GAP characteristics - status = aci_gatt_update_char_value(gap->gap_svc.gap_svc_handle, gap->gap_svc.dev_name_char_handle, 0, strlen(name), (uint8_t *) name); + status = aci_gatt_update_char_value(gap->service.gap_svc_handle, gap->service.dev_name_char_handle, 0, strlen(name), (uint8_t *) name); if (status) { FURI_LOG_E(TAG, "Failed updating name characteristic: %d", status); } - status = aci_gatt_update_char_value(gap->gap_svc.gap_svc_handle, gap->gap_svc.appearance_char_handle, 0, 2, gap_appearence_char_uuid); + uint8_t gap_appearence_char_uuid[2] = {gap->config->appearance_char & 0xff, gap->config->appearance_char >> 8}; + status = aci_gatt_update_char_value(gap->service.gap_svc_handle, gap->service.appearance_char_handle, 0, 2, gap_appearence_char_uuid); if(status) { FURI_LOG_E(TAG, "Failed updating appearence characteristic: %d", status); } // Set default PHY hci_le_set_default_phy(ALL_PHYS_PREFERENCE, TX_2M_PREFERRED, RX_2M_PREFERRED); // Set I/O capability - aci_gap_set_io_capability(IO_CAP_DISPLAY_ONLY); + bool keypress_supported = false; + if(gap->config->pairing_method == GapPairingPinCodeShow) { + aci_gap_set_io_capability(IO_CAP_DISPLAY_ONLY); + } else if(gap->config->pairing_method == GapPairingPinCodeVerifyYesNo){ + aci_gap_set_io_capability(IO_CAP_DISPLAY_YES_NO); + keypress_supported = true; + } // Setup authentication - aci_gap_set_authentication_requirement(1, 1, 1, 0, 8, 16, 1, 0, PUBLIC_ADDR); + aci_gap_set_authentication_requirement( + gap->config->bonding_mode, + CFG_MITM_PROTECTION, + CFG_SC_SUPPORT, + keypress_supported, + CFG_ENCRYPTION_KEY_SIZE_MIN, + CFG_ENCRYPTION_KEY_SIZE_MAX, + CFG_USED_FIXED_PIN, + 0, + PUBLIC_ADDR); // Configure whitelist aci_gap_configure_whitelist(); } @@ -336,10 +316,9 @@ static void gap_advertise_start(GapState new_state) } } // Configure advertising - const char* name = furi_hal_version_get_ble_local_device_name_ptr(); status = aci_gap_set_discoverable(ADV_IND, min_interval, max_interval, PUBLIC_ADDR, 0, - strlen(name), (uint8_t*)name, - gap->gap_svc.adv_svc_uuid_len, gap->gap_svc.adv_svc_uuid, 0, 0); + strlen(gap->service.adv_name), (uint8_t*)gap->service.adv_name, + gap->service.adv_svc_uuid_len, gap->service.adv_svc_uuid, 0, 0); if(status) { FURI_LOG_E(TAG, "Set discoverable err: %d", status); } @@ -350,11 +329,11 @@ static void gap_advertise_start(GapState new_state) } static void gap_advertise_stop() { - if(gap->state == GapStateConnected) { - // Terminate connection - aci_gap_terminate(gap->gap_svc.connection_handle, 0x13); - } if(gap->state > GapStateIdle) { + if(gap->state == GapStateConnected) { + // Terminate connection + aci_gap_terminate(gap->service.connection_handle, 0x13); + } // Stop advertising osTimerStop(gap->advertise_timer); aci_gap_set_non_discoverable(); @@ -365,17 +344,26 @@ static void gap_advertise_stop() { } void gap_start_advertising() { - FURI_LOG_I(TAG, "Start advertising"); - gap->enable_adv = true; - GapCommand command = GapCommandAdvFast; - furi_check(osMessageQueuePut(gap->command_queue, &command, 0, 0) == osOK); + osMutexAcquire(gap->state_mutex, osWaitForever); + if(gap->state == GapStateIdle) { + gap->state = GapStateStartingAdv; + FURI_LOG_I(TAG, "Start advertising"); + gap->enable_adv = true; + GapCommand command = GapCommandAdvFast; + furi_check(osMessageQueuePut(gap->command_queue, &command, 0, 0) == osOK); + } + osMutexRelease(gap->state_mutex); } void gap_stop_advertising() { - FURI_LOG_I(TAG, "Stop advertising"); - gap->enable_adv = false; - GapCommand command = GapCommandAdvStop; - furi_check(osMessageQueuePut(gap->command_queue, &command, 0, 0) == osOK); + osMutexAcquire(gap->state_mutex, osWaitForever); + if(gap->state > GapStateIdle) { + FURI_LOG_I(TAG, "Stop advertising"); + gap->enable_adv = false; + GapCommand command = GapCommandAdvStop; + furi_check(osMessageQueuePut(gap->command_queue, &command, 0, 0) == osOK); + } + osMutexRelease(gap->state_mutex); } static void gap_advetise_timer_callback(void* context) { @@ -383,44 +371,42 @@ static void gap_advetise_timer_callback(void* context) { furi_check(osMessageQueuePut(gap->command_queue, &command, 0, 0) == osOK); } -bool gap_init(BleEventCallback on_event_cb, void* context) { +bool gap_init(GapConfig* config, BleEventCallback on_event_cb, void* context) { if (!ble_glue_is_radio_stack_ready()) { return false; } gap = furi_alloc(sizeof(Gap)); + gap->config = config; srand(DWT->CYCCNT); // Create advertising timer gap->advertise_timer = osTimerNew(gap_advetise_timer_callback, osTimerOnce, NULL, NULL); // Initialization of GATT & GAP layer + gap->service.adv_name = config->adv_name; gap_init_svc(gap); // Initialization of the BLE Services SVCCTL_Init(); // Initialization of the GAP state gap->state_mutex = osMutexNew(NULL); gap->state = GapStateIdle; - gap->gap_svc.connection_handle = 0xFFFF; + gap->service.connection_handle = 0xFFFF; gap->enable_adv = true; // Thread configuration - gap->thread_attr.name = "BleGapWorker"; - gap->thread_attr.stack_size = 1024; - gap->thread_id = osThreadNew(gap_app, NULL, &gap->thread_attr); + gap->thread = furi_thread_alloc(); + furi_thread_set_name(gap->thread, "BleGapWorker"); + furi_thread_set_stack_size(gap->thread, 1024); + furi_thread_set_context(gap->thread, gap); + furi_thread_set_callback(gap->thread, gap_app); + furi_thread_start(gap->thread); // Command queue allocation gap->command_queue = osMessageQueueNew(8, sizeof(GapCommand), NULL); - // Start Device Information service - dev_info_svc_start(); - // Start Battery service - battery_svc_start(); - // Start Serial application - serial_svc_start(); - // Configure advirtise service UUID uint8_t adv_service_uid[2]; - adv_service_uid[0] = 0x80 | furi_hal_version_get_hw_color(); - adv_service_uid[1] = 0x30; - + gap->service.adv_svc_uuid_len = 1; + adv_service_uid[0] = gap->config->adv_service_uuid & 0xff; + adv_service_uid[1] = gap->config->adv_service_uuid >> 8; set_advertisment_service_uid(adv_service_uid, sizeof(adv_service_uid)); // Set callback @@ -429,11 +415,42 @@ bool gap_init(BleEventCallback on_event_cb, void* context) { return true; } -static void gap_app(void *arg) { +GapState gap_get_state() { + GapState state; + osMutexAcquire(gap->state_mutex, osWaitForever); + state = gap->state; + osMutexRelease(gap->state_mutex ); + return state; +} + +void gap_thread_stop() { + if(gap) { + osMutexAcquire(gap->state_mutex, osWaitForever); + gap->enable_adv = false; + GapCommand command = GapCommandKillThread; + osMessageQueuePut(gap->command_queue, &command, 0, osWaitForever); + osMutexRelease(gap->state_mutex); + furi_thread_join(gap->thread); + furi_thread_free(gap->thread); + // Free resources + osMutexDelete(gap->state_mutex); + osMessageQueueDelete(gap->command_queue); + osTimerStop(gap->advertise_timer); + while(xTimerIsTimerActive(gap->advertise_timer) == pdTRUE) osDelay(1); + furi_check(osTimerDelete(gap->advertise_timer) == osOK); + free(gap); + gap = NULL; + } +} + +static int32_t gap_app(void *context) { GapCommand command; while(1) { furi_check(osMessageQueueGet(gap->command_queue, &command, NULL, osWaitForever) == osOK); osMutexAcquire(gap->state_mutex, osWaitForever); + if(command == GapCommandKillThread) { + break; + } if(command == GapCommandAdvFast) { gap_advertise_start(GapStateAdvFast); } else if(command == GapCommandAdvLowPower) { @@ -443,4 +460,6 @@ static void gap_app(void *arg) { } osMutexRelease(gap->state_mutex); } + + return 0; } diff --git a/firmware/targets/f7/ble-glue/gap.h b/firmware/targets/f7/ble-glue/gap.h index dfeffd63..03d9bbfc 100644 --- a/firmware/targets/f7/ble-glue/gap.h +++ b/firmware/targets/f7/ble-glue/gap.h @@ -3,6 +3,10 @@ #include #include +#include + +#define GAP_MAC_ADDR_SIZE (6) + #ifdef __cplusplus extern "C" { #endif @@ -13,6 +17,7 @@ typedef enum { BleEventTypeStartAdvertising, BleEventTypeStopAdvertising, BleEventTypePinCodeShow, + BleEventTypePinCodeVerify, BleEventTypeUpdateMTU, } BleEventType; @@ -26,16 +31,31 @@ typedef struct { BleEventData data; } BleEvent; -typedef void(*BleEventCallback) (BleEvent event, void* context); +typedef bool(*BleEventCallback) (BleEvent event, void* context); typedef enum { GapStateIdle, + GapStateStartingAdv, GapStateAdvFast, GapStateAdvLowPower, GapStateConnected, } GapState; -bool gap_init(BleEventCallback on_event_cb, void* context); +typedef enum { + GapPairingPinCodeShow, + GapPairingPinCodeVerifyYesNo, +} GapPairing; + +typedef struct { + uint16_t adv_service_uuid; + uint16_t appearance_char; + bool bonding_mode; + GapPairing pairing_method; + uint8_t mac_address[GAP_MAC_ADDR_SIZE]; + char adv_name[FURI_HAL_VERSION_DEVICE_NAME_LENGTH]; +} GapConfig; + +bool gap_init(GapConfig* config, BleEventCallback on_event_cb, void* context); void gap_start_advertising(); @@ -43,6 +63,8 @@ void gap_stop_advertising(); GapState gap_get_state(); +void gap_thread_stop(); + #ifdef __cplusplus } #endif diff --git a/firmware/targets/f7/ble-glue/hid_service.c b/firmware/targets/f7/ble-glue/hid_service.c new file mode 100644 index 00000000..dc9a7fa5 --- /dev/null +++ b/firmware/targets/f7/ble-glue/hid_service.c @@ -0,0 +1,268 @@ +#include "hid_service.h" +#include "app_common.h" +#include "ble.h" + +#include + +#define TAG "BtHid" + +typedef struct { + uint16_t svc_handle; + uint16_t protocol_mode_char_handle; + uint16_t report_char_handle; + uint16_t report_ref_desc_handle; + uint16_t report_map_char_handle; + uint16_t keyboard_boot_char_handle; + uint16_t info_char_handle; + uint16_t ctrl_point_char_handle; +} HIDSvc; + +static HIDSvc* hid_svc = NULL; + +static SVCCTL_EvtAckStatus_t hid_svc_event_handler(void *event) { + SVCCTL_EvtAckStatus_t ret = SVCCTL_EvtNotAck; + hci_event_pckt* event_pckt = (hci_event_pckt *)(((hci_uart_pckt*)event)->data); + evt_blecore_aci* blecore_evt = (evt_blecore_aci*)event_pckt->data; + // aci_gatt_attribute_modified_event_rp0* attribute_modified; + if(event_pckt->evt == HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE) { + if(blecore_evt->ecode == ACI_GATT_ATTRIBUTE_MODIFIED_VSEVT_CODE) { + // Process modification events + ret = SVCCTL_EvtAckFlowEnable; + } else if(blecore_evt->ecode == ACI_GATT_SERVER_CONFIRMATION_VSEVT_CODE) { + // Process notification confirmation + ret = SVCCTL_EvtAckFlowEnable; + } + } + return ret; +} + +void hid_svc_start() { + tBleStatus status; + hid_svc = furi_alloc(sizeof(HIDSvc)); + Service_UUID_t svc_uuid = {}; + Char_Desc_Uuid_t desc_uuid = {}; + Char_UUID_t char_uuid = {}; + + // Register event handler + SVCCTL_RegisterSvcHandler(hid_svc_event_handler); + // Add service + svc_uuid.Service_UUID_16 = HUMAN_INTERFACE_DEVICE_SERVICE_UUID; + status = aci_gatt_add_service(UUID_TYPE_16, + &svc_uuid, + PRIMARY_SERVICE, + 30, + &hid_svc->svc_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add HID service: %d", status); + } + // Add Protocol mode characterstics + char_uuid.Char_UUID_16 = PROTOCOL_MODE_CHAR_UUID; + status = aci_gatt_add_char(hid_svc->svc_handle, + UUID_TYPE_16, + &char_uuid, + 1, + CHAR_PROP_READ | CHAR_PROP_WRITE_WITHOUT_RESP, + ATTR_PERMISSION_NONE, + GATT_NOTIFY_ATTRIBUTE_WRITE, + 10, + CHAR_VALUE_LEN_CONSTANT, + &hid_svc->protocol_mode_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add protocol mode characteristic: %d", status); + } + // Update Protocol mode characteristic + uint8_t protocol_mode = 1; + status = aci_gatt_update_char_value(hid_svc->svc_handle, + hid_svc->protocol_mode_char_handle, + 0, + 1, + &protocol_mode); + if(status) { + FURI_LOG_E(TAG, "Failed to update protocol mode characteristic: %d", status); + } + // Add Report characterstics + char_uuid.Char_UUID_16 = REPORT_CHAR_UUID; + status = aci_gatt_add_char(hid_svc->svc_handle, + UUID_TYPE_16, + &char_uuid, + HID_SVC_REPORT_MAX_LEN, + CHAR_PROP_READ | CHAR_PROP_NOTIFY, + ATTR_PERMISSION_NONE, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_VARIABLE, + &hid_svc->report_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add report characteristic: %d", status); + } + // Add Report descriptor + uint8_t desc_val[] = {0x00, 0x01}; + desc_uuid.Char_UUID_16 = REPORT_REFERENCE_DESCRIPTOR_UUID; + status = aci_gatt_add_char_desc(hid_svc->svc_handle, + hid_svc->report_char_handle, + UUID_TYPE_16, + &desc_uuid, + HID_SVC_REPORT_REF_LEN, + HID_SVC_REPORT_REF_LEN, + desc_val, + ATTR_PERMISSION_NONE, + ATTR_ACCESS_READ_ONLY, + GATT_DONT_NOTIFY_EVENTS, + MIN_ENCRY_KEY_SIZE, + CHAR_VALUE_LEN_CONSTANT, + &hid_svc->report_ref_desc_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add report reference descriptor: %d", status); + } + // Add Report Map characteristic + char_uuid.Char_UUID_16 = REPORT_MAP_CHAR_UUID; + status = aci_gatt_add_char(hid_svc->svc_handle, + UUID_TYPE_16, + &char_uuid, + HID_SVC_REPORT_MAP_MAX_LEN, + CHAR_PROP_READ, + ATTR_PERMISSION_NONE, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_VARIABLE, + &hid_svc->report_map_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add report map characteristic: %d", status); + } + // Add Boot Keyboard characteristic + char_uuid.Char_UUID_16 = BOOT_KEYBOARD_INPUT_REPORT_CHAR_UUID; + status = aci_gatt_add_char(hid_svc->svc_handle, + UUID_TYPE_16, + &char_uuid, + HID_SVC_BOOT_KEYBOARD_INPUT_REPORT_MAX_LEN, + CHAR_PROP_READ | CHAR_PROP_NOTIFY, + ATTR_PERMISSION_NONE, + GATT_NOTIFY_WRITE_REQ_AND_WAIT_FOR_APPL_RESP, + 10, + CHAR_VALUE_LEN_VARIABLE, + &hid_svc->keyboard_boot_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add report map characteristic: %d", status); + } + // Add Information characteristic + char_uuid.Char_UUID_16 = HID_INFORMATION_CHAR_UUID; + status = aci_gatt_add_char(hid_svc->svc_handle, + UUID_TYPE_16, + &char_uuid, + HID_SVC_INFO_LEN, + CHAR_PROP_READ, + ATTR_PERMISSION_NONE, + GATT_DONT_NOTIFY_EVENTS, + 10, + CHAR_VALUE_LEN_CONSTANT, + &hid_svc->info_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add information characteristic: %d", status); + } + // Add Control Point characteristic + char_uuid.Char_UUID_16 = HID_CONTROL_POINT_CHAR_UUID; + status = aci_gatt_add_char(hid_svc->svc_handle, + UUID_TYPE_16, + &char_uuid, + HID_SVC_CONTROL_POINT_LEN, + CHAR_PROP_WRITE_WITHOUT_RESP, + ATTR_PERMISSION_NONE, + GATT_NOTIFY_ATTRIBUTE_WRITE, + 10, + CHAR_VALUE_LEN_CONSTANT, + &hid_svc->ctrl_point_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to add control point characteristic: %d", status); + } +} + +bool hid_svc_update_report_map(uint8_t* data, uint16_t len) { + furi_assert(data); + furi_assert(hid_svc); + + tBleStatus status = aci_gatt_update_char_value(hid_svc->svc_handle, + hid_svc->report_map_char_handle, + 0, + len, + data); + if(status) { + FURI_LOG_E(TAG, "Failed updating report map characteristic"); + return false; + } + return true; +} + +bool hid_svc_update_input_report(uint8_t* data, uint16_t len) { + furi_assert(data); + furi_assert(hid_svc); + + tBleStatus status = aci_gatt_update_char_value(hid_svc->svc_handle, + hid_svc->report_char_handle, + 0, + len, + data); + if(status) { + FURI_LOG_E(TAG, "Failed updating report characteristic"); + return false; + } + return true; +} + +bool hid_svc_update_info(uint8_t* data, uint16_t len) { + furi_assert(data); + furi_assert(hid_svc); + + tBleStatus status = aci_gatt_update_char_value(hid_svc->svc_handle, + hid_svc->info_char_handle, + 0, + len, + data); + if(status) { + FURI_LOG_E(TAG, "Failed updating info characteristic"); + return false; + } + return true; +} + +bool hid_svc_is_started() { + return hid_svc != NULL; +} + +void hid_svc_stop() { + tBleStatus status; + if(hid_svc) { + // Delete characteristics + status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->report_map_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete Report Map characteristic: %d", status); + } + status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->report_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete Report characteristic: %d", status); + } + status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->protocol_mode_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete Protocol Mode characteristic: %d", status); + } + status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->keyboard_boot_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete Keyboard Boot characteristic: %d", status); + } + status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->info_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete Information characteristic: %d", status); + } + status = aci_gatt_del_char(hid_svc->svc_handle, hid_svc->ctrl_point_char_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete Control Point characteristic: %d", status); + } + // Delete service + status = aci_gatt_del_service(hid_svc->svc_handle); + if(status) { + FURI_LOG_E(TAG, "Failed to delete HID service: %d", status); + } + // Delete buffer size mutex + free(hid_svc); + hid_svc = NULL; + } +} diff --git a/firmware/targets/f7/ble-glue/hid_service.h b/firmware/targets/f7/ble-glue/hid_service.h new file mode 100644 index 00000000..ab4a2bb9 --- /dev/null +++ b/firmware/targets/f7/ble-glue/hid_service.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +#define HID_SVC_REPORT_MAP_MAX_LEN (80) +#define HID_SVC_REPORT_MAX_LEN (8) +#define HID_SVC_BOOT_KEYBOARD_INPUT_REPORT_MAX_LEN (8) +#define HID_SVC_REPORT_REF_LEN (2) +#define HID_SVC_INFO_LEN (4) +#define HID_SVC_CONTROL_POINT_LEN (1) + +void hid_svc_start(); + +void hid_svc_stop(); + +bool hid_svc_is_started(); + +bool hid_svc_update_report_map(uint8_t* data, uint16_t len); + +bool hid_svc_update_input_report(uint8_t* data, uint16_t len); + +bool hid_svc_update_info(uint8_t* data, uint16_t len); diff --git a/firmware/targets/f7/ble-glue/serial_service.c b/firmware/targets/f7/ble-glue/serial_service.c index c7ea6db2..4c70ccb0 100644 --- a/firmware/targets/f7/ble-glue/serial_service.c +++ b/firmware/targets/f7/ble-glue/serial_service.c @@ -14,8 +14,7 @@ typedef struct { osMutexId_t buff_size_mtx; uint32_t buff_size; uint16_t bytes_ready_to_receive; - SerialSvcDataReceivedCallback on_received_cb; - SerialSvcDataSentCallback on_sent_cb; + SerialServiceEventCallback callback; void* context; } SerialSvc; @@ -40,7 +39,7 @@ static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void *event) { FURI_LOG_D(TAG, "RX descriptor event"); } else if(attribute_modified->Attr_Handle == serial_svc->rx_char_handle + 1) { FURI_LOG_D(TAG, "Received %d bytes", attribute_modified->Attr_Data_Length); - if(serial_svc->on_received_cb) { + if(serial_svc->callback) { furi_check(osMutexAcquire(serial_svc->buff_size_mtx, osWaitForever) == osOK); if(attribute_modified->Attr_Data_Length > serial_svc->bytes_ready_to_receive) { FURI_LOG_W( @@ -48,8 +47,15 @@ static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void *event) { attribute_modified->Attr_Data_Length, serial_svc->bytes_ready_to_receive); } serial_svc->bytes_ready_to_receive -= MIN(serial_svc->bytes_ready_to_receive, attribute_modified->Attr_Data_Length); + SerialServiceEvent event = { + .event = SerialServiceEventTypeDataReceived, + .data = { + .buffer = attribute_modified->Attr_Data, + .size = attribute_modified->Attr_Data_Length, + } + }; uint32_t buff_free_size = - serial_svc->on_received_cb(attribute_modified->Attr_Data, attribute_modified->Attr_Data_Length, serial_svc->context); + serial_svc->callback(event, serial_svc->context); FURI_LOG_D(TAG, "Available buff size: %d", buff_free_size); furi_check(osMutexRelease(serial_svc->buff_size_mtx) == osOK); } @@ -57,8 +63,11 @@ static SVCCTL_EvtAckStatus_t serial_svc_event_handler(void *event) { } } else if(blecore_evt->ecode == ACI_GATT_SERVER_CONFIRMATION_VSEVT_CODE) { FURI_LOG_D(TAG, "Ack received", blecore_evt->ecode); - if(serial_svc->on_sent_cb) { - serial_svc->on_sent_cb(serial_svc->context); + if(serial_svc->callback) { + SerialServiceEvent event = { + .event = SerialServiceEventTypeDataSent, + }; + serial_svc->callback(event, serial_svc->context); } ret = SVCCTL_EvtAckFlowEnable; } @@ -119,10 +128,9 @@ void serial_svc_start() { serial_svc->buff_size_mtx = osMutexNew(NULL); } -void serial_svc_set_callbacks(uint16_t buff_size, SerialSvcDataReceivedCallback on_received_cb, SerialSvcDataSentCallback on_sent_cb, void* context) { +void serial_svc_set_callbacks(uint16_t buff_size, SerialServiceEventCallback callback, void* context) { furi_assert(serial_svc); - serial_svc->on_received_cb = on_received_cb; - serial_svc->on_sent_cb = on_sent_cb; + serial_svc->callback = callback; serial_svc->context = context; serial_svc->buff_size = buff_size; serial_svc->bytes_ready_to_receive = buff_size; @@ -172,6 +180,10 @@ void serial_svc_stop() { } } +bool serial_svc_is_started() { + return serial_svc != NULL; +} + bool serial_svc_update_tx(uint8_t* data, uint8_t data_len) { if(data_len > SERIAL_SVC_DATA_LEN_MAX) { return false; diff --git a/firmware/targets/f7/ble-glue/serial_service.h b/firmware/targets/f7/ble-glue/serial_service.h index 5be13f1b..3ea548af 100644 --- a/firmware/targets/f7/ble-glue/serial_service.h +++ b/firmware/targets/f7/ble-glue/serial_service.h @@ -9,17 +9,33 @@ extern "C" { #endif -typedef uint16_t(*SerialSvcDataReceivedCallback)(uint8_t* buff, uint16_t size, void* context); -typedef void(*SerialSvcDataSentCallback)(void* context); +typedef enum { + SerialServiceEventTypeDataReceived, + SerialServiceEventTypeDataSent, +} SerialServiceEventType; + +typedef struct { + uint8_t* buffer; + uint16_t size; +} SerialServiceData; + +typedef struct { + SerialServiceEventType event; + SerialServiceData data; +} SerialServiceEvent; + +typedef uint16_t(*SerialServiceEventCallback)(SerialServiceEvent event, void* context); void serial_svc_start(); -void serial_svc_set_callbacks(uint16_t buff_size, SerialSvcDataReceivedCallback on_received_cb, SerialSvcDataSentCallback on_sent_cb, void* context); +void serial_svc_set_callbacks(uint16_t buff_size, SerialServiceEventCallback callback, void* context); void serial_svc_notify_buffer_is_empty(); void serial_svc_stop(); +bool serial_svc_is_started(); + bool serial_svc_update_tx(uint8_t* data, uint8_t data_len); #ifdef __cplusplus diff --git a/firmware/targets/f7/furi-hal/furi-hal-bt-hid.c b/firmware/targets/f7/furi-hal/furi-hal-bt-hid.c new file mode 100644 index 00000000..5d5e89ed --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-bt-hid.c @@ -0,0 +1,141 @@ +#include "furi-hal-bt-hid.h" +#include "dev_info_service.h" +#include "battery_service.h" +#include "hid_service.h" + +#include + +#define FURI_HAL_BT_INFO_BASE_USB_SPECIFICATION (0x0101) +#define FURI_HAL_BT_INFO_COUNTRY_CODE (0x00) +#define FURI_HAL_BT_HID_INFO_FLAG_REMOTE_WAKE_MSK (0x01) +#define FURI_HAL_BT_HID_INFO_FLAG_NORMALLY_CONNECTABLE_MSK (0x02) + +#define FURI_HAL_BT_HID_KB_KEYS_MAX (6) + +typedef struct { + uint8_t mods; + uint8_t reserved; + uint8_t key[FURI_HAL_BT_HID_KB_KEYS_MAX]; +} FuriHalBtHidKbReport; + +// TODO rework with HID defines +static uint8_t furi_hal_bt_hid_report_map_data[] = { + 0x05, 0x01, // Usage Page (Generic Desktop) + 0x09, 0x06, // Usage (Keyboard) + 0xA1, 0x01, // Collection (Application) + 0x05, 0x07, // Usage Page (Key Codes) + 0x19, 0xe0, // Usage Minimum (224) + 0x29, 0xe7, // Usage Maximum (231) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x75, 0x01, // Report Size (1) + 0x95, 0x08, // Report Count (8) + 0x81, 0x02, // Input (Data, Variable, Absolute) + + 0x95, 0x01, // Report Count (1) + 0x75, 0x08, // Report Size (8) + 0x81, 0x01, // Input (Constant) reserved byte(1) + + 0x95, 0x05, // Report Count (5) + 0x75, 0x01, // Report Size (1) + 0x05, 0x08, // Usage Page (Page# for LEDs) + 0x19, 0x01, // Usage Minimum (1) + 0x29, 0x05, // Usage Maximum (5) + 0x91, 0x02, // Output (Data, Variable, Absolute), Led report + 0x95, 0x01, // Report Count (1) + 0x75, 0x03, // Report Size (3) + 0x91, 0x01, // Output (Data, Variable, Absolute), Led report padding + + 0x95, 0x06, // Report Count (6) + 0x75, 0x08, // Report Size (8) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x65, // Logical Maximum (101) + 0x05, 0x07, // Usage Page (Key codes) + 0x19, 0x00, // Usage Minimum (0) + 0x29, 0x65, // Usage Maximum (101) + 0x81, 0x00, // Input (Data, Array) Key array(6 bytes) + + 0x09, 0x05, // Usage (Vendor Defined) + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xFF, 0x00, // Logical Maximum (255) + 0x75, 0x08, // Report Size (8 bit) + 0x95, 0x02, // Report Count (2) + 0xB1, 0x02, // Feature (Data, Variable, Absolute) + + 0xC0 // End Collection (Application) +}; + +FuriHalBtHidKbReport* kb_report = NULL; + +void furi_hal_bt_hid_start() { + // Start device info + if(!dev_info_svc_is_started()) { + dev_info_svc_start(); + } + // Start battery service + if(!battery_svc_is_started()) { + battery_svc_start(); + } + // Start HID service + if(!hid_svc_is_started()) { + hid_svc_start(); + } + // Configure HID Keyboard + kb_report = furi_alloc(sizeof(FuriHalBtHidKbReport)); + // Configure Report Map characteristic + hid_svc_update_report_map(furi_hal_bt_hid_report_map_data, sizeof(furi_hal_bt_hid_report_map_data)); + // Configure HID Information characteristic + uint8_t hid_info_val[4] = { + FURI_HAL_BT_INFO_BASE_USB_SPECIFICATION & 0x00ff, + (FURI_HAL_BT_INFO_BASE_USB_SPECIFICATION & 0xff00) >> 8, + FURI_HAL_BT_INFO_COUNTRY_CODE, + FURI_HAL_BT_HID_INFO_FLAG_REMOTE_WAKE_MSK | FURI_HAL_BT_HID_INFO_FLAG_NORMALLY_CONNECTABLE_MSK, + }; + hid_svc_update_info(hid_info_val, sizeof(hid_info_val)); +} + +void furi_hal_bt_hid_stop() { + furi_assert(kb_report); + // Stop all services + if(dev_info_svc_is_started()) { + dev_info_svc_stop(); + } + if(battery_svc_is_started()) { + battery_svc_stop(); + } + if(hid_svc_is_started()) { + hid_svc_stop(); + } + free(kb_report); + kb_report = NULL; +} + +bool furi_hal_bt_hid_kb_press(uint16_t button) { + furi_assert(kb_report); + for (uint8_t i = 0; i < FURI_HAL_BT_HID_KB_KEYS_MAX; i++) { + if (kb_report->key[i] == 0) { + kb_report->key[i] = button & 0xFF; + break; + } + } + kb_report->mods |= (button >> 8); + return hid_svc_update_input_report((uint8_t*)kb_report, sizeof(FuriHalBtHidKbReport)); +} + +bool furi_hal_bt_hid_kb_release(uint16_t button) { + furi_assert(kb_report); + for (uint8_t i = 0; i < FURI_HAL_BT_HID_KB_KEYS_MAX; i++) { + if (kb_report->key[i] == (button & 0xFF)) { + kb_report->key[i] = 0; + break; + } + } + kb_report->mods &= ~(button >> 8); + return hid_svc_update_input_report((uint8_t*)kb_report, sizeof(FuriHalBtHidKbReport)); +} + +bool furi_hal_bt_hid_kb_release_all() { + furi_assert(kb_report); + memset(kb_report, 0, sizeof(FuriHalBtHidKbReport)); + return hid_svc_update_input_report((uint8_t*)kb_report, sizeof(FuriHalBtHidKbReport)); +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-bt-serial.c b/firmware/targets/f7/furi-hal/furi-hal-bt-serial.c new file mode 100644 index 00000000..d5ea869b --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-bt-serial.c @@ -0,0 +1,51 @@ +#include "furi-hal-bt-serial.h" +#include "dev_info_service.h" +#include "battery_service.h" +#include "serial_service.h" + +#include + +void furi_hal_bt_serial_start() { + // Start device info + if(!dev_info_svc_is_started()) { + dev_info_svc_start(); + } + // Start battery service + if(!battery_svc_is_started()) { + battery_svc_start(); + } + // Start Serial service + if(!serial_svc_is_started()) { + serial_svc_start(); + } +} + +void furi_hal_bt_serial_set_event_callback(uint16_t buff_size, FuriHalBtSerialCallback callback, void* context) { + serial_svc_set_callbacks(buff_size, callback, context); +} + +void furi_hal_bt_serial_notify_buffer_is_empty() { + serial_svc_notify_buffer_is_empty(); +} + +bool furi_hal_bt_serial_tx(uint8_t* data, uint16_t size) { + if(size > FURI_HAL_BT_SERIAL_PACKET_SIZE_MAX) { + return false; + } + return serial_svc_update_tx(data, size); +} + +void furi_hal_bt_serial_stop() { + // Stop all services + if(dev_info_svc_is_started()) { + dev_info_svc_stop(); + } + // Start battery service + if(battery_svc_is_started()) { + battery_svc_stop(); + } + // Start Serial service + if(serial_svc_is_started()) { + serial_svc_stop(); + } +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-bt.c b/firmware/targets/f7/furi-hal/furi-hal-bt.c index b74a9e29..714d894f 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-bt.c +++ b/firmware/targets/f7/furi-hal/furi-hal-bt.c @@ -4,18 +4,66 @@ #include #include +#include +#include +#include +#include "battery_service.h" + #include #define TAG "FuriHalBt" +#define FURI_HAL_BT_DEFAULT_MAC_ADDR {0x6c, 0x7a, 0xd8, 0xac, 0x57, 0x72} + osMutexId_t furi_hal_bt_core2_mtx = NULL; +typedef void (*FuriHalBtProfileStart)(void); +typedef void (*FuriHalBtProfileStop)(void); + +typedef struct { + FuriHalBtProfileStart start; + FuriHalBtProfileStart stop; + GapConfig config; + uint16_t appearance_char; + uint16_t advertise_service_uuid; +} FuriHalBtProfileConfig; + +FuriHalBtProfileConfig profile_config[FuriHalBtProfileNumber] = { + [FuriHalBtProfileSerial] = { + .start = furi_hal_bt_serial_start, + .stop = furi_hal_bt_serial_stop, + .config = { + .adv_service_uuid = 0x3080, + .appearance_char = 0x8600, + .bonding_mode = true, + .pairing_method = GapPairingPinCodeShow, + .mac_address = FURI_HAL_BT_DEFAULT_MAC_ADDR, + }, + }, + [FuriHalBtProfileHidKeyboard] = { + .start = furi_hal_bt_hid_start, + .stop = furi_hal_bt_hid_stop, + .config = { + .adv_service_uuid = HUMAN_INTERFACE_DEVICE_SERVICE_UUID, + .appearance_char = GAP_APPEARANCE_KEYBOARD, + .bonding_mode = true, + .pairing_method = GapPairingPinCodeVerifyYesNo, + .mac_address = FURI_HAL_BT_DEFAULT_MAC_ADDR, + }, + } +}; +FuriHalBtProfileConfig* current_profile = NULL; + void furi_hal_bt_init() { - furi_hal_bt_core2_mtx = osMutexNew(NULL); - furi_assert(furi_hal_bt_core2_mtx); + if(!furi_hal_bt_core2_mtx) { + furi_hal_bt_core2_mtx = osMutexNew(NULL); + furi_assert(furi_hal_bt_core2_mtx); + } // Explicitly tell that we are in charge of CLK48 domain - HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID); + if(!HAL_HSEM_IsSemTaken(CFG_HW_CLK48_CONFIG_SEMID)) { + HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID); + } // Start Core2 ble_glue_init(); @@ -31,12 +79,14 @@ void furi_hal_bt_unlock_core2() { furi_check(osMutexRelease(furi_hal_bt_core2_mtx) == osOK); } -bool furi_hal_bt_start_core2() { +static bool furi_hal_bt_start_core2() { furi_assert(furi_hal_bt_core2_mtx); osMutexAcquire(furi_hal_bt_core2_mtx, osWaitForever); // Explicitly tell that we are in charge of CLK48 domain - HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID); + if(!HAL_HSEM_IsSemTaken(CFG_HW_CLK48_CONFIG_SEMID)) { + HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID); + } // Start Core2 bool ret = ble_glue_start(); osMutexRelease(furi_hal_bt_core2_mtx); @@ -44,9 +94,80 @@ bool furi_hal_bt_start_core2() { return ret; } -bool furi_hal_bt_init_app(BleEventCallback event_cb, void* context) { +bool furi_hal_bt_start_app(FuriHalBtProfile profile, BleEventCallback event_cb, void* context) { furi_assert(event_cb); - return gap_init(event_cb, context); + furi_assert(profile < FuriHalBtProfileNumber); + bool ret = true; + + do { + // Start 2nd core + ret = furi_hal_bt_start_core2(); + if(!ret) { + ble_app_thread_stop(); + FURI_LOG_E(TAG, "Failed to start 2nd core"); + break; + } + // Set mac address + memcpy( + profile_config[profile].config.mac_address, + furi_hal_version_get_ble_mac(), + sizeof(profile_config[profile].config.mac_address) + ); + // Set advertise name + strlcpy( + profile_config[profile].config.adv_name, + furi_hal_version_get_ble_local_device_name_ptr(), + FURI_HAL_VERSION_DEVICE_NAME_LENGTH + ); + // Configure GAP + GapConfig* config = &profile_config[profile].config; + if(profile == FuriHalBtProfileSerial) { + config->adv_service_uuid |= furi_hal_version_get_hw_color(); + } else if(profile == FuriHalBtProfileHidKeyboard) { + // Change MAC address for HID profile + config->mac_address[2]++; + // Change name Flipper -> Clicker + const char* clicker_str = "Clicker"; + memcpy(&config->adv_name[1], clicker_str, strlen(clicker_str) - 1); + } + ret = gap_init(config, event_cb, context); + if(!ret) { + gap_thread_stop(); + FURI_LOG_E(TAG, "Failed to init GAP"); + break; + } + // Start selected profile services + profile_config[profile].start(); + } while(false); + current_profile = &profile_config[profile]; + + return ret; +} + +bool furi_hal_bt_change_app(FuriHalBtProfile profile, BleEventCallback event_cb, void* context) { + furi_assert(event_cb); + furi_assert(profile < FuriHalBtProfileNumber); + bool ret = true; + + FURI_LOG_I(TAG, "Stop current profile services"); + current_profile->stop(); + FURI_LOG_I(TAG, "Disconnect and stop advertising"); + furi_hal_bt_stop_advertising(); + FURI_LOG_I(TAG, "Shutdow 2nd core"); + LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN); + FURI_LOG_I(TAG, "Stop BLE related RTOS threads"); + ble_app_thread_stop(); + gap_thread_stop(); + FURI_LOG_I(TAG, "Reset SHCI"); + SHCI_C2_Reinit(); + ble_glue_thread_stop(); + FURI_LOG_I(TAG, "Start BT initialization"); + furi_hal_bt_init(); + ret = furi_hal_bt_start_app(profile, event_cb, context); + if(ret) { + current_profile = &profile_config[profile]; + } + return ret; } void furi_hal_bt_start_advertising() { @@ -64,19 +185,10 @@ void furi_hal_bt_stop_advertising() { } } -void furi_hal_bt_set_data_event_callbacks(uint16_t buff_size, SerialSvcDataReceivedCallback on_received_cb, SerialSvcDataSentCallback on_sent_cb, void* context) { - serial_svc_set_callbacks(buff_size, on_received_cb, on_sent_cb, context); -} - -void furi_hal_bt_notify_buffer_is_empty() { - serial_svc_notify_buffer_is_empty(); -} - -bool furi_hal_bt_tx(uint8_t* data, uint16_t size) { - if(size > FURI_HAL_BT_PACKET_SIZE_MAX) { - return false; +void furi_hal_bt_update_battery_level(uint8_t battery_level) { + if(battery_svc_is_started()) { + battery_svc_update_level(battery_level); } - return serial_svc_update_tx(data, size); } void furi_hal_bt_get_key_storage_buff(uint8_t** key_buff_addr, uint16_t* key_buff_size) { diff --git a/firmware/targets/f7/furi-hal/furi-hal-flash.c b/firmware/targets/f7/furi-hal/furi-hal-flash.c index 156a26a9..8a1d2d06 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-flash.c +++ b/firmware/targets/f7/furi-hal/furi-hal-flash.c @@ -113,9 +113,11 @@ static void furi_hal_flash_begin_with_core2(bool erase_flag) { } // Take sempahopre and prevent core2 from anyting funky - if (HAL_HSEM_FastTake(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) != HAL_OK) { - taskEXIT_CRITICAL(); - continue; + if(!HAL_HSEM_IsSemTaken(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID)) { + if (HAL_HSEM_FastTake(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) != HAL_OK) { + taskEXIT_CRITICAL(); + continue; + } } break; diff --git a/firmware/targets/furi-hal-include/furi-hal-bt-hid.h b/firmware/targets/furi-hal-include/furi-hal-bt-hid.h new file mode 100644 index 00000000..03b2c7f7 --- /dev/null +++ b/firmware/targets/furi-hal-include/furi-hal-bt-hid.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +/** Start Hid Keyboard Profile + */ +void furi_hal_bt_hid_start(); + +/** Stop Hid Keyboard Profile + */ +void furi_hal_bt_hid_stop(); + +/** Press key button + * + * @param button button code from HID specification + * + * @return true on success + */ +bool furi_hal_bt_hid_kb_press(uint16_t button); + +/** Release key button + * + * @param button button code from HID specification + * + * @return true on success + */ +bool furi_hal_bt_hid_kb_release(uint16_t button); + +/** Release all key buttons + * + * @return true on success + */ +bool furi_hal_bt_hid_kb_release_all(); diff --git a/firmware/targets/furi-hal-include/furi-hal-bt-serial.h b/firmware/targets/furi-hal-include/furi-hal-bt-serial.h new file mode 100644 index 00000000..a1c71041 --- /dev/null +++ b/firmware/targets/furi-hal-include/furi-hal-bt-serial.h @@ -0,0 +1,37 @@ +#pragma once + +#include "serial_service.h" + +#define FURI_HAL_BT_SERIAL_PACKET_SIZE_MAX SERIAL_SVC_DATA_LEN_MAX + +/** Serial service callback type */ +typedef SerialServiceEventCallback FuriHalBtSerialCallback; + +/** Start Serial Profile + */ +void furi_hal_bt_serial_start(); + +/** Stop Serial Profile + */ +void furi_hal_bt_serial_stop(); + +/** Set Serial service events callback + * + * @param buffer_size Applicaition buffer size + * @param calback FuriHalBtSerialCallback instance + * @param context pointer to context + */ +void furi_hal_bt_serial_set_event_callback(uint16_t buff_size, FuriHalBtSerialCallback callback, void* context); + +/** Notify that application buffer is empty + */ +void furi_hal_bt_serial_notify_buffer_is_empty(); + +/** Send data through BLE + * + * @param data data buffer + * @param size data buffer size + * + * @return true on success + */ +bool furi_hal_bt_serial_tx(uint8_t* data, uint16_t size); diff --git a/firmware/targets/furi-hal-include/furi-hal-bt.h b/firmware/targets/furi-hal-include/furi-hal-bt.h index c7d86165..8de7296f 100644 --- a/firmware/targets/furi-hal-include/furi-hal-bt.h +++ b/firmware/targets/furi-hal-include/furi-hal-bt.h @@ -12,13 +12,20 @@ #include #include - -#define FURI_HAL_BT_PACKET_SIZE_MAX SERIAL_SVC_DATA_LEN_MAX +#include "furi-hal-bt-serial.h" #ifdef __cplusplus extern "C" { #endif +typedef enum { + FuriHalBtProfileSerial, + FuriHalBtProfileHidKeyboard, + + // Keep last for Profiles number calculation + FuriHalBtProfileNumber, +} FuriHalBtProfile; + /** Initialize */ void furi_hal_bt_init(); @@ -29,17 +36,32 @@ void furi_hal_bt_lock_core2(); /** Lock core2 state transition */ void furi_hal_bt_unlock_core2(); -/** Start 2nd core and BLE stack - * - * @return true on success - */ -bool furi_hal_bt_start_core2(); - /** Start BLE app - * @param event_cb - BleEventCallback instance - * @param context - pointer to context + * + * @param profile FuriHalBtProfile instance + * @param event_cb BleEventCallback instance + * @param context pointer to context + * + * @return true on success */ -bool furi_hal_bt_init_app(BleEventCallback event_cb, void* context); +bool furi_hal_bt_start_app(FuriHalBtProfile profile, BleEventCallback event_cb, void* context); + +/** Change BLE app + * Restarts 2nd core + * + * @param profile FuriHalBtProfile instance + * @param event_cb BleEventCallback instance + * @param context pointer to context + * + * @return true on success +*/ +bool furi_hal_bt_change_app(FuriHalBtProfile profile, BleEventCallback event_cb, void* context); + +/** Update battery level + * + * @param battery_level battery level + */ +void furi_hal_bt_update_battery_level(uint8_t battery_level); /** Start advertising */ @@ -91,22 +113,6 @@ void furi_hal_bt_nvm_sram_sem_release(); */ void furi_hal_bt_set_key_storage_change_callback(BleGlueKeyStorageChangedCallback callback, void* context); -/** Set data event callbacks - * @param on_received_cb - SerialSvcDataReceivedCallback instance - * @param on_sent_cb - SerialSvcDataSentCallback instance - * @param context - pointer to context - */ -void furi_hal_bt_set_data_event_callbacks(uint16_t buff_size, SerialSvcDataReceivedCallback on_received_cb, SerialSvcDataSentCallback on_sent_cb, void* context); - -/** Notify that buffer is empty */ -void furi_hal_bt_notify_buffer_is_empty(); - -/** Send data through BLE - * @param data - data buffer - * @param size - data buffer size - */ -bool furi_hal_bt_tx(uint8_t* data, uint16_t size); - /** Start ble tone tx at given channel and power * * @param[in] channel The channel From f0aed7e58331557fe41b7617b8dff49b63645f40 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Wed, 8 Dec 2021 17:42:01 +0400 Subject: [PATCH 26/32] SubGhz: add GFSK modulation, refactoring subghz_chat (#866) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SubGhz: add GFSK modulation, refactoring subghz_chat * SubGhz: off echo subghz_chat * SubGhz: subghz_chat add sending and receiving formatted text, translation of the chat to events * SubGhz: add UTF support in subghz_chat_worker_alloc Co-authored-by: あく --- applications/cli/cli.h | 1 + applications/subghz/helpers/subghz_chat.c | 141 ++++++++++++++++ applications/subghz/helpers/subghz_chat.h | 29 ++++ applications/subghz/subghz_cli.c | 157 ++++++++++++------ .../targets/f6/furi-hal/furi-hal-subghz.c | 77 ++++++++- .../targets/f7/furi-hal/furi-hal-subghz.c | 67 +++++++- .../furi-hal-include/furi-hal-subghz.h | 11 ++ lib/subghz/subghz_tx_rx_worker.c | 72 ++++---- 8 files changed, 459 insertions(+), 96 deletions(-) create mode 100644 applications/subghz/helpers/subghz_chat.c create mode 100644 applications/subghz/helpers/subghz_chat.h diff --git a/applications/cli/cli.h b/applications/cli/cli.h index 9a166dc5..1f1b61a2 100644 --- a/applications/cli/cli.h +++ b/applications/cli/cli.h @@ -18,6 +18,7 @@ typedef enum { CliSymbolAsciiBell = 0x07, CliSymbolAsciiBackspace = 0x08, CliSymbolAsciiTab = 0x09, + CliSymbolAsciiLF = 0x0A, CliSymbolAsciiCR = 0x0D, CliSymbolAsciiEsc = 0x1B, CliSymbolAsciiUS = 0x1F, diff --git a/applications/subghz/helpers/subghz_chat.c b/applications/subghz/helpers/subghz_chat.c new file mode 100644 index 00000000..15e08dde --- /dev/null +++ b/applications/subghz/helpers/subghz_chat.c @@ -0,0 +1,141 @@ +#include "subghz_chat.h" +#include + +#define TAG "SubGhzChat" +#define SUBGHZ_CHAT_WORKER_TIMEOUT_BETWEEN_MESSAGES 500 + +struct SubGhzChatWorker { + FuriThread* thread; + SubGhzTxRxWorker* subghz_txrx; + + volatile bool worker_running; + volatile bool worker_stoping; + osMessageQueueId_t event_queue; + uint32_t last_time_rx_data; +}; + +/** Worker thread + * + * @param context + * @return exit code + */ +static int32_t subghz_chat_worker_thread(void* context) { + SubGhzChatWorker* instance = context; + FURI_LOG_I(TAG, "Worker start"); + char c; + SubghzChatEvent event; + event.event = SubghzChatEventUserEntrance; + osMessageQueuePut(instance->event_queue, &event, 0, 0); + while(instance->worker_running) { + if(furi_hal_vcp_rx_with_timeout((uint8_t*)&c, 1, osWaitForever) == 1) { + event.event = SubghzChatEventInputData; + event.c = c; + osMessageQueuePut(instance->event_queue, &event, 0, osWaitForever); + } + } + + FURI_LOG_I(TAG, "Worker stop"); + return 0; +} + +static void subghz_chat_worker_update_rx_event_chat(void* context) { + furi_assert(context); + SubGhzChatWorker* instance = context; + SubghzChatEvent event; + if((millis() - instance->last_time_rx_data) > SUBGHZ_CHAT_WORKER_TIMEOUT_BETWEEN_MESSAGES) { + event.event = SubghzChatEventNewMessage; + osMessageQueuePut(instance->event_queue, &event, 0, osWaitForever); + } + instance->last_time_rx_data = millis(); + event.event = SubghzChatEventRXData; + osMessageQueuePut(instance->event_queue, &event, 0, osWaitForever); +} + +SubGhzChatWorker* subghz_chat_worker_alloc() { + SubGhzChatWorker* instance = furi_alloc(sizeof(SubGhzChatWorker)); + + instance->thread = furi_thread_alloc(); + furi_thread_set_name(instance->thread, "SubghzChat"); + furi_thread_set_stack_size(instance->thread, 2048); + furi_thread_set_context(instance->thread, instance); + furi_thread_set_callback(instance->thread, subghz_chat_worker_thread); + instance->subghz_txrx = subghz_tx_rx_worker_alloc(); + instance->event_queue = osMessageQueueNew(80, sizeof(SubghzChatEvent), NULL); + return instance; +} + +void subghz_chat_worker_free(SubGhzChatWorker* instance) { + furi_assert(instance); + furi_assert(!instance->worker_running); + osMessageQueueDelete(instance->event_queue); + subghz_tx_rx_worker_free(instance->subghz_txrx); + furi_thread_free(instance->thread); + + free(instance); +} + +bool subghz_chat_worker_start(SubGhzChatWorker* instance, uint32_t frequency) { + furi_assert(instance); + furi_assert(!instance->worker_running); + bool res = false; + + if(subghz_tx_rx_worker_start(instance->subghz_txrx, frequency)) { + osMessageQueueReset(instance->event_queue); + subghz_tx_rx_worker_set_callback_have_read( + instance->subghz_txrx, subghz_chat_worker_update_rx_event_chat, instance); + + instance->worker_running = true; + instance->last_time_rx_data = 0; + + res = furi_thread_start(instance->thread); + } + return res; +} + +void subghz_chat_worker_stop(SubGhzChatWorker* instance) { + furi_assert(instance); + furi_assert(instance->worker_running); + if(subghz_tx_rx_worker_is_running(instance->subghz_txrx)) { + subghz_tx_rx_worker_stop(instance->subghz_txrx); + } + + instance->worker_running = false; + + furi_thread_join(instance->thread); +} + +bool subghz_chat_worker_is_running(SubGhzChatWorker* instance) { + furi_assert(instance); + return instance->worker_running; +} + +SubghzChatEvent subghz_chat_worker_get_event_chat(SubGhzChatWorker* instance) { + furi_assert(instance); + SubghzChatEvent event; + if(osMessageQueueGet(instance->event_queue, &event, NULL, osWaitForever) == osOK) { + return event; + } else { + event.event = SubghzChatEventNoEvent; + return event; + } +} + +void subghz_chat_worker_put_event_chat(SubGhzChatWorker* instance, SubghzChatEvent* event) { + furi_assert(instance); + osMessageQueuePut(instance->event_queue, event, 0, osWaitForever); +} + +size_t subghz_chat_worker_available(SubGhzChatWorker* instance) { + furi_assert(instance); + return subghz_tx_rx_worker_available(instance->subghz_txrx); +} + +size_t subghz_chat_worker_read(SubGhzChatWorker* instance, uint8_t* data, size_t size) { + furi_assert(instance); + return subghz_tx_rx_worker_read(instance->subghz_txrx, data, size); +} + +bool subghz_chat_worker_write(SubGhzChatWorker* instance, uint8_t* data, size_t size) { + furi_assert(instance); + return subghz_tx_rx_worker_write(instance->subghz_txrx, data, size); +} \ No newline at end of file diff --git a/applications/subghz/helpers/subghz_chat.h b/applications/subghz/helpers/subghz_chat.h new file mode 100644 index 00000000..89f82ef3 --- /dev/null +++ b/applications/subghz/helpers/subghz_chat.h @@ -0,0 +1,29 @@ +#pragma once +#include "../subghz_i.h" + +typedef struct SubGhzChatWorker SubGhzChatWorker; + +typedef enum { + SubghzChatEventNoEvent, + SubghzChatEventUserEntrance, + SubghzChatEventUserExit, + SubghzChatEventInputData, + SubghzChatEventRXData, + SubghzChatEventNewMessage, +} SubghzChatEventType; + +typedef struct { + SubghzChatEventType event; + char c; +} SubghzChatEvent; + +SubGhzChatWorker* subghz_chat_worker_alloc(); +void subghz_chat_worker_free(SubGhzChatWorker* instance); +bool subghz_chat_worker_start(SubGhzChatWorker* instance, uint32_t frequency); +void subghz_chat_worker_stop(SubGhzChatWorker* instance); +bool subghz_chat_worker_is_running(SubGhzChatWorker* instance); +SubghzChatEvent subghz_chat_worker_get_event_chat(SubGhzChatWorker* instance); +void subghz_chat_worker_put_event_chat(SubGhzChatWorker* instance, SubghzChatEvent* event); +size_t subghz_chat_worker_available(SubGhzChatWorker* instance); +size_t subghz_chat_worker_read(SubGhzChatWorker* instance, uint8_t* data, size_t size); +bool subghz_chat_worker_write(SubGhzChatWorker* instance, uint8_t* data, size_t size); diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index 2578fb26..2f9d698e 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -9,7 +9,8 @@ #include #include #include -#include + +#include "helpers/subghz_chat.h" #include @@ -377,23 +378,34 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { return; } - SubGhzTxRxWorker* subghz_txrx = subghz_tx_rx_worker_alloc(); - subghz_tx_rx_worker_start(subghz_txrx, frequency); + SubGhzChatWorker* subghz_chat = subghz_chat_worker_alloc(); + if(!subghz_chat_worker_start(subghz_chat, frequency)) { + printf("Startup error SubGhzChatWorker\r\n"); + + if(subghz_chat_worker_is_running(subghz_chat)) { + subghz_chat_worker_stop(subghz_chat); + subghz_chat_worker_free(subghz_chat); + } + return; + } printf("Receiving at frequency %lu Hz\r\n", frequency); printf("Press CTRL+C to stop\r\n"); furi_hal_power_suppress_charge_enter(); + size_t message_max_len = 64; uint8_t message[64] = {0}; string_t input; string_init(input); string_t name; string_init(name); + string_t output; + string_init(output); string_t sysmsg; string_init(sysmsg); - char c; bool exit = false; + SubghzChatEvent chat_event; NotificationApp* notification = furi_record_open("notification"); @@ -402,71 +414,120 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { printf("%s", string_get_cstr(input)); fflush(stdout); - string_printf(sysmsg, "\033[0;34m%s joined chat.\033[0m", furi_hal_version_get_name_ptr()); - subghz_tx_rx_worker_write( - subghz_txrx, (uint8_t*)string_get_cstr(sysmsg), strlen(string_get_cstr(sysmsg))); - while(!exit) { - if(furi_hal_vcp_rx_with_timeout((uint8_t*)&c, 1, 0) == 1) { - if(c == CliSymbolAsciiETX) { + chat_event = subghz_chat_worker_get_event_chat(subghz_chat); + switch(chat_event.event) { + case SubghzChatEventInputData: + if(chat_event.c == CliSymbolAsciiETX) { printf("\r\n"); - exit = true; + chat_event.event = SubghzChatEventUserExit; + subghz_chat_worker_put_event_chat(subghz_chat, &chat_event); break; - } else if((c >= 0x20 && c < 0x7F) || (c >= 0x80 && c < 0xF0)) { - putc(c, stdout); - fflush(stdout); - string_push_back(input, c); - } else if((c == CliSymbolAsciiBackspace) || (c == CliSymbolAsciiDel)) { - size_t len = string_size(input); - if(len > string_size(name)) { + } else if( + (chat_event.c == CliSymbolAsciiBackspace) || (chat_event.c == CliSymbolAsciiDel)) { + size_t len = string_length_u(input); + if(len > string_length_u(name)) { printf("%s", "\e[D\e[1P"); fflush(stdout); - string_set_strn(input, string_get_cstr(input), len - 1); + //delete 1 char UTF + const char* str = string_get_cstr(input); + size_t size = 0; + m_str1ng_utf8_state_e s = M_STRING_UTF8_STARTING; + string_unicode_t u = 0; + string_reset(sysmsg); + while(*str) { + m_str1ng_utf8_decode(*str, &s, &u); + if((s == M_STRING_UTF8_ERROR) || s == M_STRING_UTF8_STARTING) { + string_push_u(sysmsg, u); + if(++size >= len - 1) break; + s = M_STRING_UTF8_STARTING; + } + str++; + } + string_set(input, sysmsg); } - } else if(c == CliSymbolAsciiCR) { + } else if(chat_event.c == CliSymbolAsciiCR) { printf("\r\n"); - subghz_tx_rx_worker_write( - subghz_txrx, (uint8_t*)string_get_cstr(input), strlen(string_get_cstr(input))); + string_push_back(input, '\r'); + string_push_back(input, '\n'); + while(!subghz_chat_worker_write( + subghz_chat, + (uint8_t*)string_get_cstr(input), + strlen(string_get_cstr(input)))) { + delay(10); + } + string_printf(input, "%s", string_get_cstr(name)); printf("%s", string_get_cstr(input)); fflush(stdout); + } else if(chat_event.c == CliSymbolAsciiLF) { + //cut out the symbol \n + } else { + putc(chat_event.c, stdout); + fflush(stdout); + string_push_back(input, chat_event.c); + break; + case SubghzChatEventRXData: + do { + memset(message, 0x00, message_max_len); + size_t len = subghz_chat_worker_read(subghz_chat, message, message_max_len); + for(size_t i = 0; i < len; i++) { + string_push_back(output, message[i]); + if(message[i] == '\n') { + printf("\r"); + for(uint8_t i = 0; i < 80; i++) { + printf(" "); + } + printf("\r %s", string_get_cstr(output)); + printf("%s", string_get_cstr(input)); + fflush(stdout); + string_reset(output); + } + } + } while(subghz_chat_worker_available(subghz_chat)); + break; + case SubghzChatEventNewMessage: + notification_message(notification, &sequence_single_vibro); + break; + case SubghzChatEventUserEntrance: + string_printf( + sysmsg, + "\033[0;34m%s joined chat.\033[0m\r\n", + furi_hal_version_get_name_ptr()); + subghz_chat_worker_write( + subghz_chat, + (uint8_t*)string_get_cstr(sysmsg), + strlen(string_get_cstr(sysmsg))); + break; + case SubghzChatEventUserExit: + string_printf( + sysmsg, "\033[0;31m%s left chat.\033[0m\r\n", furi_hal_version_get_name_ptr()); + subghz_chat_worker_write( + subghz_chat, + (uint8_t*)string_get_cstr(sysmsg), + strlen(string_get_cstr(sysmsg))); + delay(10); + exit = true; + break; + default: + FURI_LOG_W("SubGhzChat", "Error event"); + break; } } - - if(subghz_tx_rx_worker_available(subghz_txrx)) { - memset(message, 0x00, message_max_len); - subghz_tx_rx_worker_read(subghz_txrx, message, message_max_len); - printf("\r"); - for(uint8_t i = 0; i < 80; i++) { - printf(" "); - } - - printf("\r %s\r\n", message); - - printf("%s", string_get_cstr(input)); - fflush(stdout); - - notification_message(notification, &sequence_single_vibro); - } - osDelay(1); } - string_printf(sysmsg, "\033[0;31m%s left chat.\033[0m", furi_hal_version_get_name_ptr()); - subghz_tx_rx_worker_write( - subghz_txrx, (uint8_t*)string_get_cstr(sysmsg), strlen(string_get_cstr(sysmsg))); - osDelay(10); - - printf("\r\nExit chat\r\n"); string_clear(input); string_clear(name); + string_clear(output); string_clear(sysmsg); furi_hal_power_suppress_charge_exit(); furi_record_close("notification"); - if(subghz_tx_rx_worker_is_running(subghz_txrx)) { - subghz_tx_rx_worker_stop(subghz_txrx); - subghz_tx_rx_worker_free(subghz_txrx); + if(subghz_chat_worker_is_running(subghz_chat)) { + subghz_chat_worker_stop(subghz_chat); + subghz_chat_worker_free(subghz_chat); } + printf("\r\nExit chat\r\n"); } static void subghz_cli_command(Cli* cli, string_t args, void* context) { diff --git a/firmware/targets/f6/furi-hal/furi-hal-subghz.c b/firmware/targets/f6/furi-hal/furi-hal-subghz.c index 20e9c1f9..85fe401e 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-subghz.c +++ b/firmware/targets/f6/furi-hal/furi-hal-subghz.c @@ -291,6 +291,45 @@ static const uint8_t furi_hal_subghz_preset_msk_99_97kb_async_regs[][2] = { /* End */ {0, 0}, }; +static const uint8_t furi_hal_subghz_preset_gfsk_9_99kb_async_regs[][2] = { + + {CC1101_IOCFG0, 0x06}, //GDO0 Output Pin Configuration + {CC1101_FIFOTHR, 0x47}, //RX FIFO and TX FIFO Thresholds + + //1 : CRC calculation in TX and CRC check in RX enabled, + //1 : Variable packet length mode. Packet length configured by the first byte after sync word + {CC1101_PKTCTRL0, 0x05}, + + {CC1101_FSCTRL1, 0x06}, //Frequency Synthesizer Control + + {CC1101_SYNC1, 0x46}, + {CC1101_SYNC0, 0x4C}, + {CC1101_ADDR, 0x00}, + {CC1101_PKTLEN, 0x00}, + + {CC1101_MDMCFG4, 0xC8}, //Modem Configuration 9.99 + {CC1101_MDMCFG3, 0x93}, //Modem Configuration + {CC1101_MDMCFG2, 0x12}, // 2: 16/16 sync word bits detected + + {CC1101_DEVIATN, 0x34}, //Deviation = 19.042969 + {CC1101_MCSM0, 0x18}, //Main Radio Control State Machine Configuration + {CC1101_FOCCFG, 0x16}, //Frequency Offset Compensation Configuration + + {CC1101_AGCCTRL2, 0x43}, //AGC Control + {CC1101_AGCCTRL1, 0x40}, + {CC1101_AGCCTRL0, 0x91}, + + {CC1101_WORCTRL, 0xFB}, //Wake On Radio Control + {CC1101_FSCAL3, 0xE9}, //Frequency Synthesizer Calibration + {CC1101_FSCAL2, 0x2A}, //Frequency Synthesizer Calibration + {CC1101_FSCAL1, 0x00}, //Frequency Synthesizer Calibration + {CC1101_FSCAL0, 0x1F}, //Frequency Synthesizer Calibration + {CC1101_TEST2, 0x81}, //Various Test Settings + {CC1101_TEST1, 0x35}, //Various Test Settings + {CC1101_TEST0, 0x09}, //Various Test Settings + /* End */ + {0, 0}, +}; static const uint8_t furi_hal_subghz_preset_ook_async_patable[8] = { 0x00, @@ -319,6 +358,15 @@ static const uint8_t furi_hal_subghz_preset_msk_async_patable[8] = { 0x00, 0x00, 0x00}; +static const uint8_t furi_hal_subghz_preset_gfsk_async_patable[8] = { + 0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12 + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00}; void furi_hal_subghz_init() { furi_assert(furi_hal_subghz_state == SubGhzStateInit); @@ -344,7 +392,8 @@ void furi_hal_subghz_init() { ; // GD0 high - cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); + cc1101_write_reg( + &furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); while(hal_gpio_read(&gpio_cc1101_g0) != true) ; @@ -402,6 +451,9 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { } else if(preset == FuriHalSubGhzPresetMSK99_97KbAsync) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_msk_99_97kb_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_msk_async_patable); + } else if(preset == FuriHalSubGhzPresetGFSK9_99KbAsync) { + furi_hal_subghz_load_registers(furi_hal_subghz_preset_gfsk_9_99kb_async_regs); + furi_hal_subghz_load_patable(furi_hal_subghz_preset_gfsk_async_patable); } else { furi_crash(NULL); } @@ -438,10 +490,17 @@ void furi_hal_subghz_flush_rx() { furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } +void furi_hal_subghz_flush_tx() { + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_flush_tx(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); +} + bool furi_hal_subghz_rx_pipe_not_empty() { CC1101RxBytes status[1]; furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); - cc1101_read_reg(&furi_hal_spi_bus_handle_subghz, (CC1101_STATUS_RXBYTES) | CC1101_BURST, (uint8_t*)status); + cc1101_read_reg( + &furi_hal_spi_bus_handle_subghz, (CC1101_STATUS_RXBYTES) | CC1101_BURST, (uint8_t*)status); furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); // TODO: you can add a buffer overflow flag if needed if(status->NUM_RXBYTES > 0) { @@ -520,6 +579,14 @@ float furi_hal_subghz_get_rssi() { return rssi; } +uint8_t furi_hal_subghz_get_lqi() { + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + uint8_t data[1]; + cc1101_read_reg(&furi_hal_spi_bus_handle_subghz, CC1101_STATUS_LQI | CC1101_BURST, data); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); + return data[0] & 0x7F; +} + bool furi_hal_subghz_is_frequency_valid(uint32_t value) { if(!(value >= 299999755 && value <= 348000335) && !(value >= 386999938 && value <= 464000000) && @@ -607,13 +674,15 @@ void furi_hal_subghz_set_path(FuriHalSubGhzPath path) { furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); if(path == FuriHalSubGhzPath433) { hal_gpio_write(&gpio_rf_sw_0, 0); - cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); + cc1101_write_reg( + &furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); } else if(path == FuriHalSubGhzPath315) { hal_gpio_write(&gpio_rf_sw_0, 1); cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW); } else if(path == FuriHalSubGhzPath868) { hal_gpio_write(&gpio_rf_sw_0, 1); - cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); + cc1101_write_reg( + &furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); } else if(path == FuriHalSubGhzPathIsolate) { hal_gpio_write(&gpio_rf_sw_0, 0); cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW); diff --git a/firmware/targets/f7/furi-hal/furi-hal-subghz.c b/firmware/targets/f7/furi-hal/furi-hal-subghz.c index 20e9c1f9..3e810880 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-subghz.c +++ b/firmware/targets/f7/furi-hal/furi-hal-subghz.c @@ -291,6 +291,45 @@ static const uint8_t furi_hal_subghz_preset_msk_99_97kb_async_regs[][2] = { /* End */ {0, 0}, }; +static const uint8_t furi_hal_subghz_preset_gfsk_9_99kb_async_regs[][2] = { + + {CC1101_IOCFG0, 0x06}, //GDO0 Output Pin Configuration + {CC1101_FIFOTHR, 0x47}, //RX FIFO and TX FIFO Thresholds + + //1 : CRC calculation in TX and CRC check in RX enabled, + //1 : Variable packet length mode. Packet length configured by the first byte after sync word + {CC1101_PKTCTRL0,0x05}, + + {CC1101_FSCTRL1, 0x06}, //Frequency Synthesizer Control + + {CC1101_SYNC1, 0x46}, + {CC1101_SYNC0, 0x4C}, + {CC1101_ADDR, 0x00}, + {CC1101_PKTLEN, 0x00}, + + {CC1101_MDMCFG4, 0xC8}, //Modem Configuration 9.99 + {CC1101_MDMCFG3, 0x93}, //Modem Configuration + {CC1101_MDMCFG2, 0x12}, // 2: 16/16 sync word bits detected + + {CC1101_DEVIATN, 0x34}, //Deviation = 19.042969 + {CC1101_MCSM0, 0x18}, //Main Radio Control State Machine Configuration + {CC1101_FOCCFG, 0x16}, //Frequency Offset Compensation Configuration + + {CC1101_AGCCTRL2, 0x43 }, //AGC Control + {CC1101_AGCCTRL1, 0x40}, + {CC1101_AGCCTRL0, 0x91}, + + {CC1101_WORCTRL, 0xFB}, //Wake On Radio Control + {CC1101_FSCAL3, 0xE9}, //Frequency Synthesizer Calibration + {CC1101_FSCAL2, 0x2A}, //Frequency Synthesizer Calibration + {CC1101_FSCAL1, 0x00}, //Frequency Synthesizer Calibration + {CC1101_FSCAL0, 0x1F}, //Frequency Synthesizer Calibration + {CC1101_TEST2, 0x81}, //Various Test Settings + {CC1101_TEST1, 0x35}, //Various Test Settings + {CC1101_TEST0, 0x09}, //Various Test Settings + /* End */ + {0, 0}, +}; static const uint8_t furi_hal_subghz_preset_ook_async_patable[8] = { 0x00, @@ -319,6 +358,15 @@ static const uint8_t furi_hal_subghz_preset_msk_async_patable[8] = { 0x00, 0x00, 0x00}; +static const uint8_t furi_hal_subghz_preset_gfsk_async_patable[8] = { + 0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12 + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00}; void furi_hal_subghz_init() { furi_assert(furi_hal_subghz_state == SubGhzStateInit); @@ -402,7 +450,10 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { } else if(preset == FuriHalSubGhzPresetMSK99_97KbAsync) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_msk_99_97kb_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_msk_async_patable); - } else { + } else if(preset == FuriHalSubGhzPresetGFSK9_99KbAsync) { + furi_hal_subghz_load_registers(furi_hal_subghz_preset_gfsk_9_99kb_async_regs); + furi_hal_subghz_load_patable(furi_hal_subghz_preset_gfsk_async_patable); + } else{ furi_crash(NULL); } } @@ -438,6 +489,12 @@ void furi_hal_subghz_flush_rx() { furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); } +void furi_hal_subghz_flush_tx() { + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + cc1101_flush_tx(&furi_hal_spi_bus_handle_subghz); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); +} + bool furi_hal_subghz_rx_pipe_not_empty() { CC1101RxBytes status[1]; furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); @@ -520,6 +577,14 @@ float furi_hal_subghz_get_rssi() { return rssi; } +uint8_t furi_hal_subghz_get_lqi() { + furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); + uint8_t data[1]; + cc1101_read_reg(&furi_hal_spi_bus_handle_subghz, CC1101_STATUS_LQI | CC1101_BURST, data); + furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); + return data[0] & 0x7F; +} + bool furi_hal_subghz_is_frequency_valid(uint32_t value) { if(!(value >= 299999755 && value <= 348000335) && !(value >= 386999938 && value <= 464000000) && diff --git a/firmware/targets/furi-hal-include/furi-hal-subghz.h b/firmware/targets/furi-hal-include/furi-hal-subghz.h index cde71705..bc69e68c 100644 --- a/firmware/targets/furi-hal-include/furi-hal-subghz.h +++ b/firmware/targets/furi-hal-include/furi-hal-subghz.h @@ -21,6 +21,7 @@ typedef enum { FuriHalSubGhzPreset2FSKDev238Async, /**< FM, deviation 2.380371 kHz, asynchronous */ FuriHalSubGhzPreset2FSKDev476Async, /**< FM, deviation 4.760742 kHz, asynchronous */ FuriHalSubGhzPresetMSK99_97KbAsync, /**< MSK, deviation 47.60742 kHz, 99.97Kb/s, asynchronous */ + FuriHalSubGhzPresetGFSK9_99KbAsync /**< GFSK, deviation 19.042969 kHz, 9.996Kb/s, asynchronous */ } FuriHalSubGhzPreset; /** Switchable Radio Paths */ @@ -114,6 +115,10 @@ void furi_hal_subghz_read_packet(uint8_t* data, uint8_t* size); */ void furi_hal_subghz_flush_rx(); +/** Flush tx FIFO buffer + */ +void furi_hal_subghz_flush_tx(); + /** Shutdown Issue spwd command * @warning registers content will be lost */ @@ -144,6 +149,12 @@ bool furi_hal_subghz_tx(); */ float furi_hal_subghz_get_rssi(); +/** Get LQI + * + * @return LQI value + */ +uint8_t furi_hal_subghz_get_lqi(); + /** Check if frequency is in valid range * * @param value frequency in Hz diff --git a/lib/subghz/subghz_tx_rx_worker.c b/lib/subghz/subghz_tx_rx_worker.c index d151babe..09b77219 100644 --- a/lib/subghz/subghz_tx_rx_worker.c +++ b/lib/subghz/subghz_tx_rx_worker.c @@ -5,11 +5,11 @@ #define TAG "SubGhzTxRxWorker" -#define GUBGHZ_TXRX_WORKER_BUF_SIZE 2048 +#define SUBGHZ_TXRX_WORKER_BUF_SIZE 2048 //you can not set more than 62 because it will not fit into the FIFO CC1101 -#define GUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE 60 +#define SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE 60 -#define GUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF 40 +#define SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF 40 struct SubGhzTxRxWorker { FuriThread* thread; @@ -19,7 +19,7 @@ struct SubGhzTxRxWorker { volatile bool worker_running; volatile bool worker_stoping; - SubGhzTxRxWorkerStatus satus; + SubGhzTxRxWorkerStatus status; uint32_t frequency; @@ -33,7 +33,7 @@ bool subghz_tx_rx_worker_write(SubGhzTxRxWorker* instance, uint8_t* data, size_t size_t stream_tx_free_byte = xStreamBufferSpacesAvailable(instance->stream_tx); if(size && (stream_tx_free_byte >= size)) { if(xStreamBufferSend( - instance->stream_tx, data, size, GUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF) == + instance->stream_tx, data, size, SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF) == size) { ret = true; } @@ -48,22 +48,7 @@ size_t subghz_tx_rx_worker_available(SubGhzTxRxWorker* instance) { size_t subghz_tx_rx_worker_read(SubGhzTxRxWorker* instance, uint8_t* data, size_t size) { furi_assert(instance); - size_t len = 0; - size_t stream_rx_byte = xStreamBufferBytesAvailable(instance->stream_rx); - - if(stream_rx_byte > 0) { - if(stream_rx_byte <= size) { - len = xStreamBufferReceive( - instance->stream_rx, - data, - stream_rx_byte, - GUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); - } else { - len = xStreamBufferReceive( - instance->stream_rx, data, size, GUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); - } - } - return len; + return xStreamBufferReceive(instance->stream_rx, data, size, 0); } void subghz_tx_rx_worker_set_callback_have_read( @@ -78,11 +63,11 @@ void subghz_tx_rx_worker_set_callback_have_read( } bool subghz_tx_rx_worker_rx(SubGhzTxRxWorker* instance, uint8_t* data, uint8_t* size) { - uint8_t timeout = 20; + uint8_t timeout = 100; bool ret = false; - if(instance->satus != SubGhzTxRxWorkerStatusRx) { + if(instance->status != SubGhzTxRxWorkerStatusRx) { furi_hal_subghz_rx(); - instance->satus = SubGhzTxRxWorkerStatusRx; + instance->status = SubGhzTxRxWorkerStatusRx; osDelay(1); } //waiting for reception to complete @@ -97,6 +82,8 @@ bool subghz_tx_rx_worker_rx(SubGhzTxRxWorker* instance, uint8_t* data, uint8_t* } if(furi_hal_subghz_rx_pipe_not_empty()) { + FURI_LOG_I( + TAG, "RSSI: %03.1fdbm LQI: %d", furi_hal_subghz_get_rssi(), furi_hal_subghz_get_lqi()); if(furi_hal_subghz_is_rx_data_crc_valid()) { furi_hal_subghz_read_packet(data, size); ret = true; @@ -108,15 +95,13 @@ bool subghz_tx_rx_worker_rx(SubGhzTxRxWorker* instance, uint8_t* data, uint8_t* } void subghz_tx_rx_worker_tx(SubGhzTxRxWorker* instance, uint8_t* data, size_t size) { - uint8_t timeout = 40; - if(instance->satus != SubGhzTxRxWorkerStatusIDLE) { + uint8_t timeout = 200; + if(instance->status != SubGhzTxRxWorkerStatusIDLE) { furi_hal_subghz_idle(); } furi_hal_subghz_write_packet(data, size); - instance->satus = SubGhzTxRxWorkerStatusTx; - furi_hal_subghz_tx(); //start send - + instance->status = SubGhzTxRxWorkerStatusTx; while(!hal_gpio_read(&gpio_cc1101_g0)) { // Wait for GDO0 to be set -> sync transmitted osDelay(1); if(!--timeout) { @@ -132,7 +117,7 @@ void subghz_tx_rx_worker_tx(SubGhzTxRxWorker* instance, uint8_t* data, size_t si } } furi_hal_subghz_idle(); - instance->satus = SubGhzTxRxWorkerStatusIDLE; + instance->status = SubGhzTxRxWorkerStatusIDLE; } /** Worker thread * @@ -145,13 +130,14 @@ static int32_t subghz_tx_rx_worker_thread(void* context) { furi_hal_subghz_reset(); furi_hal_subghz_idle(); - furi_hal_subghz_load_preset(FuriHalSubGhzPresetMSK99_97KbAsync); + furi_hal_subghz_load_preset(FuriHalSubGhzPresetGFSK9_99KbAsync); + //furi_hal_subghz_load_preset(FuriHalSubGhzPresetMSK99_97KbAsync); hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); furi_hal_subghz_set_frequency_and_path(instance->frequency); furi_hal_subghz_flush_rx(); - uint8_t data[GUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE] = {0}; + uint8_t data[SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE + 1] = {0}; size_t size_tx = 0; uint8_t size_rx[1] = {0}; uint8_t timeout_tx = 0; @@ -161,18 +147,18 @@ static int32_t subghz_tx_rx_worker_thread(void* context) { //transmit size_tx = xStreamBufferBytesAvailable(instance->stream_tx); if(size_tx > 0 && !timeout_tx) { - timeout_tx = 20; //20ms - if(size_tx > GUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE) { + timeout_tx = 10; //20ms + if(size_tx > SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE) { xStreamBufferReceive( instance->stream_tx, &data, - GUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE, - GUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); - subghz_tx_rx_worker_tx(instance, data, GUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE); + SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE, + SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); + subghz_tx_rx_worker_tx(instance, data, SUBGHZ_TXRX_WORKER_MAX_TXRX_SIZE); } else { //todo checking that he managed to write all the data to the TX buffer xStreamBufferReceive( - instance->stream_tx, &data, size_tx, GUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); + instance->stream_tx, &data, size_tx, SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); subghz_tx_rx_worker_tx(instance, data, size_tx); } } else { @@ -188,7 +174,7 @@ static int32_t subghz_tx_rx_worker_thread(void* context) { instance->stream_rx, &data, size_rx[0], - GUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); + SUBGHZ_TXRX_WORKER_TIMEOUT_READ_WRITE_BUF); if(callback_rx) { instance->callback_have_read(instance->context_have_read); callback_rx = false; @@ -219,11 +205,11 @@ SubGhzTxRxWorker* subghz_tx_rx_worker_alloc() { furi_thread_set_context(instance->thread, instance); furi_thread_set_callback(instance->thread, subghz_tx_rx_worker_thread); instance->stream_tx = - xStreamBufferCreate(sizeof(uint8_t) * GUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t)); + xStreamBufferCreate(sizeof(uint8_t) * SUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t)); instance->stream_rx = - xStreamBufferCreate(sizeof(uint8_t) * GUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t)); + xStreamBufferCreate(sizeof(uint8_t) * SUBGHZ_TXRX_WORKER_BUF_SIZE, sizeof(uint8_t)); - instance->satus = SubGhzTxRxWorkerStatusIDLE; + instance->status = SubGhzTxRxWorkerStatusIDLE; instance->worker_stoping = true; return instance; @@ -231,7 +217,7 @@ SubGhzTxRxWorker* subghz_tx_rx_worker_alloc() { void subghz_tx_rx_worker_free(SubGhzTxRxWorker* instance) { furi_assert(instance); - + furi_assert(!instance->worker_running); vStreamBufferDelete(instance->stream_tx); vStreamBufferDelete(instance->stream_rx); furi_thread_free(instance->thread); From c6cb6ae810d8ec540f330c37447f53a1fbd58dac Mon Sep 17 00:00:00 2001 From: tonyfreeman <24860049+tonyfreeman@users.noreply.github.com> Date: Wed, 8 Dec 2021 16:59:40 +0300 Subject: [PATCH 27/32] BLE: Increase mtu (#837) * Incease mtu & buffer size * bt: process mtu size in RPC callbacks Co-authored-by: Tony Freeman Co-authored-by: gornekich --- applications/bt/bt_service/bt.c | 6 ++-- firmware/targets/f6/ble-glue/app_conf.h | 2 +- firmware/targets/f6/ble-glue/serial_service.c | 28 ++++++++++++++----- firmware/targets/f6/ble-glue/serial_service.h | 4 +-- firmware/targets/f7/ble-glue/app_conf.h | 2 +- firmware/targets/f7/ble-glue/serial_service.c | 28 ++++++++++++++----- firmware/targets/f7/ble-glue/serial_service.h | 5 ++-- 7 files changed, 52 insertions(+), 23 deletions(-) diff --git a/applications/bt/bt_service/bt.c b/applications/bt/bt_service/bt.c index 074ab980..97cc156b 100755 --- a/applications/bt/bt_service/bt.c +++ b/applications/bt/bt_service/bt.c @@ -132,9 +132,9 @@ static void bt_rpc_send_bytes_callback(void* context, uint8_t* bytes, size_t byt size_t bytes_sent = 0; while(bytes_sent < bytes_len) { size_t bytes_remain = bytes_len - bytes_sent; - if(bytes_remain > FURI_HAL_BT_SERIAL_PACKET_SIZE_MAX) { - furi_hal_bt_serial_tx(&bytes[bytes_sent], FURI_HAL_BT_SERIAL_PACKET_SIZE_MAX); - bytes_sent += FURI_HAL_BT_SERIAL_PACKET_SIZE_MAX; + if(bytes_remain > bt->max_packet_size) { + furi_hal_bt_serial_tx(&bytes[bytes_sent], bt->max_packet_size); + bytes_sent += bt->max_packet_size; } else { furi_hal_bt_serial_tx(&bytes[bytes_sent], bytes_remain); bytes_sent += bytes_remain; diff --git a/firmware/targets/f6/ble-glue/app_conf.h b/firmware/targets/f6/ble-glue/app_conf.h index eebdbbdb..059e8e4f 100644 --- a/firmware/targets/f6/ble-glue/app_conf.h +++ b/firmware/targets/f6/ble-glue/app_conf.h @@ -139,7 +139,7 @@ /** * Maximum supported ATT_MTU size */ -#define CFG_BLE_MAX_ATT_MTU (251) +#define CFG_BLE_MAX_ATT_MTU (489) /** * Size of the storage area for Attribute values diff --git a/firmware/targets/f6/ble-glue/serial_service.c b/firmware/targets/f6/ble-glue/serial_service.c index 4c70ccb0..ab201546 100644 --- a/firmware/targets/f6/ble-glue/serial_service.c +++ b/firmware/targets/f6/ble-glue/serial_service.c @@ -184,17 +184,31 @@ bool serial_svc_is_started() { return serial_svc != NULL; } -bool serial_svc_update_tx(uint8_t* data, uint8_t data_len) { +bool serial_svc_update_tx(uint8_t* data, uint16_t data_len) { if(data_len > SERIAL_SVC_DATA_LEN_MAX) { return false; } - tBleStatus result = aci_gatt_update_char_value(serial_svc->svc_handle, - serial_svc->tx_char_handle, + + for(uint16_t remained = data_len; remained > 0;) { + uint8_t value_len = MIN(SERIAL_SVC_CHAR_VALUE_LEN_MAX, remained); + uint16_t value_offset = data_len - remained; + remained -= value_len; + + tBleStatus result = aci_gatt_update_char_value_ext( 0, + serial_svc->svc_handle, + serial_svc->tx_char_handle, + remained ? 0x00 : 0x02, data_len, - data); - if(result) { - FURI_LOG_E(TAG, "Failed updating TX characteristic: %d", result); + value_offset, + value_len, + data + value_offset); + + if(result) { + FURI_LOG_E(TAG, "Failed updating TX characteristic: %d", result); + return false; + } } - return result != BLE_STATUS_SUCCESS; + + return true; } diff --git a/firmware/targets/f6/ble-glue/serial_service.h b/firmware/targets/f6/ble-glue/serial_service.h index 3ea548af..1c365c0e 100644 --- a/firmware/targets/f6/ble-glue/serial_service.h +++ b/firmware/targets/f6/ble-glue/serial_service.h @@ -3,7 +3,7 @@ #include #include -#define SERIAL_SVC_DATA_LEN_MAX (248) +#define SERIAL_SVC_DATA_LEN_MAX (486) #ifdef __cplusplus extern "C" { @@ -36,7 +36,7 @@ void serial_svc_stop(); bool serial_svc_is_started(); -bool serial_svc_update_tx(uint8_t* data, uint8_t data_len); +bool serial_svc_update_tx(uint8_t* data, uint16_t data_len); #ifdef __cplusplus } diff --git a/firmware/targets/f7/ble-glue/app_conf.h b/firmware/targets/f7/ble-glue/app_conf.h index eebdbbdb..059e8e4f 100644 --- a/firmware/targets/f7/ble-glue/app_conf.h +++ b/firmware/targets/f7/ble-glue/app_conf.h @@ -139,7 +139,7 @@ /** * Maximum supported ATT_MTU size */ -#define CFG_BLE_MAX_ATT_MTU (251) +#define CFG_BLE_MAX_ATT_MTU (489) /** * Size of the storage area for Attribute values diff --git a/firmware/targets/f7/ble-glue/serial_service.c b/firmware/targets/f7/ble-glue/serial_service.c index 4c70ccb0..ab201546 100644 --- a/firmware/targets/f7/ble-glue/serial_service.c +++ b/firmware/targets/f7/ble-glue/serial_service.c @@ -184,17 +184,31 @@ bool serial_svc_is_started() { return serial_svc != NULL; } -bool serial_svc_update_tx(uint8_t* data, uint8_t data_len) { +bool serial_svc_update_tx(uint8_t* data, uint16_t data_len) { if(data_len > SERIAL_SVC_DATA_LEN_MAX) { return false; } - tBleStatus result = aci_gatt_update_char_value(serial_svc->svc_handle, - serial_svc->tx_char_handle, + + for(uint16_t remained = data_len; remained > 0;) { + uint8_t value_len = MIN(SERIAL_SVC_CHAR_VALUE_LEN_MAX, remained); + uint16_t value_offset = data_len - remained; + remained -= value_len; + + tBleStatus result = aci_gatt_update_char_value_ext( 0, + serial_svc->svc_handle, + serial_svc->tx_char_handle, + remained ? 0x00 : 0x02, data_len, - data); - if(result) { - FURI_LOG_E(TAG, "Failed updating TX characteristic: %d", result); + value_offset, + value_len, + data + value_offset); + + if(result) { + FURI_LOG_E(TAG, "Failed updating TX characteristic: %d", result); + return false; + } } - return result != BLE_STATUS_SUCCESS; + + return true; } diff --git a/firmware/targets/f7/ble-glue/serial_service.h b/firmware/targets/f7/ble-glue/serial_service.h index 3ea548af..6e19f86d 100644 --- a/firmware/targets/f7/ble-glue/serial_service.h +++ b/firmware/targets/f7/ble-glue/serial_service.h @@ -3,7 +3,8 @@ #include #include -#define SERIAL_SVC_DATA_LEN_MAX (248) +#define SERIAL_SVC_DATA_LEN_MAX (486) +#define SERIAL_SVC_CHAR_VALUE_LEN_MAX (243) #ifdef __cplusplus extern "C" { @@ -36,7 +37,7 @@ void serial_svc_stop(); bool serial_svc_is_started(); -bool serial_svc_update_tx(uint8_t* data, uint8_t data_len); +bool serial_svc_update_tx(uint8_t* data, uint16_t data_len); #ifdef __cplusplus } From 9f28338d9e56836b319ca6b019b86497e5756c8c Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Wed, 8 Dec 2021 19:00:54 +0400 Subject: [PATCH 28/32] [FL-2100] SubGhz: GUI download and transfer RAW file (#881) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SubGhz: fix exit subghz_chat * SubGhz: refactoring GUI RAW Co-authored-by: あく --- applications/subghz/helpers/subghz_chat.c | 2 +- .../subghz/scenes/subghz_scene_read_raw.c | 8 +++++-- .../subghz/scenes/subghz_scene_saved.c | 7 +++++- applications/subghz/subghz_i.h | 1 + applications/subghz/views/subghz_read_raw.c | 22 ++++++++++++++++++- applications/subghz/views/subghz_read_raw.h | 5 ++++- 6 files changed, 39 insertions(+), 6 deletions(-) diff --git a/applications/subghz/helpers/subghz_chat.c b/applications/subghz/helpers/subghz_chat.c index 15e08dde..4bc79b89 100644 --- a/applications/subghz/helpers/subghz_chat.c +++ b/applications/subghz/helpers/subghz_chat.c @@ -27,7 +27,7 @@ static int32_t subghz_chat_worker_thread(void* context) { event.event = SubghzChatEventUserEntrance; osMessageQueuePut(instance->event_queue, &event, 0, 0); while(instance->worker_running) { - if(furi_hal_vcp_rx_with_timeout((uint8_t*)&c, 1, osWaitForever) == 1) { + if(furi_hal_vcp_rx_with_timeout((uint8_t*)&c, 1, 1000) == 1) { event.event = SubghzChatEventInputData; event.c = c; osMessageQueuePut(instance->event_queue, &event, 0, osWaitForever); diff --git a/applications/subghz/scenes/subghz_scene_read_raw.c b/applications/subghz/scenes/subghz_scene_read_raw.c index c9d59d8d..615df4cb 100644 --- a/applications/subghz/scenes/subghz_scene_read_raw.c +++ b/applications/subghz/scenes/subghz_scene_read_raw.c @@ -41,9 +41,13 @@ void subghz_scene_read_raw_on_enter(void* context) { SubGhz* subghz = context; if(subghz->txrx->rx_key_state == SubGhzRxKeyStateBack) { - subghz_read_raw_set_status(subghz->subghz_read_raw, SubghzReadRAWStatusIDLE); + subghz_read_raw_set_status(subghz->subghz_read_raw, SubghzReadRAWStatusIDLE, ""); + } else if(subghz->txrx->rx_key_state == SubGhzRxKeyStateRAWLoad) { + subghz_read_raw_set_status( + subghz->subghz_read_raw, SubghzReadRAWStatusTX, subghz->file_name); + subghz->txrx->rx_key_state = SubGhzRxKeyStateAddKey; } else { - subghz_read_raw_set_status(subghz->subghz_read_raw, SubghzReadRAWStatusStart); + subghz_read_raw_set_status(subghz->subghz_read_raw, SubghzReadRAWStatusStart, ""); subghz->txrx->rx_key_state = SubGhzRxKeyStateIDLE; } diff --git a/applications/subghz/scenes/subghz_scene_saved.c b/applications/subghz/scenes/subghz_scene_saved.c index 68231ba6..4dcb103a 100644 --- a/applications/subghz/scenes/subghz_scene_saved.c +++ b/applications/subghz/scenes/subghz_scene_saved.c @@ -4,7 +4,12 @@ void subghz_scene_saved_on_enter(void* context) { SubGhz* subghz = context; if(subghz_load_protocol_from_file(subghz)) { - scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSavedMenu); + if((!strcmp(subghz->txrx->protocol_result->name, "RAW"))) { + subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWLoad; + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW); + } else { + scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSavedMenu); + } } else { scene_manager_search_and_switch_to_previous_scene(subghz->scene_manager, SubGhzSceneStart); } diff --git a/applications/subghz/subghz_i.h b/applications/subghz/subghz_i.h index e459642d..c206f87b 100644 --- a/applications/subghz/subghz_i.h +++ b/applications/subghz/subghz_i.h @@ -73,6 +73,7 @@ typedef enum { SubGhzRxKeyStateBack, SubGhzRxKeyStateAddKey, SubGhzRxKeyStateExit, + SubGhzRxKeyStateRAWLoad, } SubGhzRxKeyState; struct SubGhzTxRx { diff --git a/applications/subghz/views/subghz_read_raw.c b/applications/subghz/views/subghz_read_raw.c index 11b711d7..993ca914 100644 --- a/applications/subghz/views/subghz_read_raw.c +++ b/applications/subghz/views/subghz_read_raw.c @@ -21,6 +21,7 @@ typedef struct { string_t frequency_str; string_t preset_str; string_t sample_write; + string_t file_name; uint8_t* rssi_history; bool rssi_history_end; uint8_t ind_write; @@ -224,6 +225,8 @@ void subghz_read_raw_draw(Canvas* canvas, SubghzReadRAWModel* model) { elements_button_left(canvas, "Erase"); elements_button_center(canvas, "Send"); elements_button_right(canvas, "Save"); + canvas_draw_str_aligned( + canvas, 58, 28, AlignCenter, AlignTop, string_get_cstr(model->file_name)); } else if(model->satus == SubghzReadRAWStatusStart) { elements_button_left(canvas, "Config"); elements_button_center(canvas, "REC"); @@ -297,6 +300,7 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { model->rssi_history_end = false; model->ind_write = 0; string_set(model->sample_write, "0 spl."); + string_reset(model->file_name); instance->callback(SubghzCustomEventViewReadRAWErase, instance->context); } return true; @@ -332,7 +336,10 @@ bool subghz_read_raw_input(InputEvent* event, void* context) { return true; } -void subghz_read_raw_set_status(SubghzReadRAW* instance, SubghzReadRAWStatus satus) { +void subghz_read_raw_set_status( + SubghzReadRAW* instance, + SubghzReadRAWStatus satus, + const char* file_name) { furi_assert(instance); if(satus == SubghzReadRAWStatusStart) { with_view_model( @@ -340,6 +347,7 @@ void subghz_read_raw_set_status(SubghzReadRAW* instance, SubghzReadRAWStatus sat model->satus = SubghzReadRAWStatusStart; model->rssi_history_end = false; model->ind_write = 0; + string_reset(model->file_name); string_set(model->sample_write, "0 spl."); return true; }); @@ -349,6 +357,16 @@ void subghz_read_raw_set_status(SubghzReadRAW* instance, SubghzReadRAWStatus sat model->satus = SubghzReadRAWStatusIDLE; return true; }); + } else if(satus == SubghzReadRAWStatusTX) { + with_view_model( + instance->view, (SubghzReadRAWModel * model) { + model->satus = SubghzReadRAWStatusIDLE; + model->rssi_history_end = false; + model->ind_write = 0; + string_set(model->file_name, file_name); + string_set(model->sample_write, "RAW"); + return true; + }); } } @@ -389,6 +407,7 @@ SubghzReadRAW* subghz_read_raw_alloc() { string_init(model->frequency_str); string_init(model->preset_str); string_init(model->sample_write); + string_init(model->file_name); model->rssi_history = furi_alloc(SUBGHZ_READ_RAW_RSSI_HISTORY_SIZE * sizeof(uint8_t)); return true; }); @@ -404,6 +423,7 @@ void subghz_read_raw_free(SubghzReadRAW* instance) { string_clear(model->frequency_str); string_clear(model->preset_str); string_clear(model->sample_write); + string_clear(model->file_name); free(model->rssi_history); return true; }); diff --git a/applications/subghz/views/subghz_read_raw.h b/applications/subghz/views/subghz_read_raw.h index 6e1f79da..86b69253 100644 --- a/applications/subghz/views/subghz_read_raw.h +++ b/applications/subghz/views/subghz_read_raw.h @@ -37,6 +37,9 @@ void subghz_read_raw_update_sin(SubghzReadRAW* instance); void subghz_read_raw_add_data_rssi(SubghzReadRAW* instance, float rssi); -void subghz_read_raw_set_status(SubghzReadRAW* instance, SubghzReadRAWStatus satus); +void subghz_read_raw_set_status( + SubghzReadRAW* instance, + SubghzReadRAWStatus satus, + const char* file_name); View* subghz_read_raw_get_view(SubghzReadRAW* subghz_static); From f5b2ed67d543ece28c225bd2da80f74874db2555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=81=8F?= Date: Thu, 9 Dec 2021 07:58:07 +0300 Subject: [PATCH 29/32] Github: fix non zero return behavior in docker actions. Firmware: fix F6 build. (#886) * Github: treat non 0 exit code as fatal * GitHub: inject missing -e flag to bash in docker * Firmware: sync targets --- .github/workflows/build.yml | 2 ++ firmware/targets/f6/ble-glue/serial_service.h | 1 + .../targets/f6/furi-hal/furi-hal-subghz.c | 22 ++++++++----------- firmware/targets/f6/furi-hal/furi-hal-uart.h | 2 +- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c1cafd42..e7c8546f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -82,6 +82,7 @@ jobs: uses: ./.github/actions/docker with: run: | + set -e for TARGET in ${TARGETS} do make TARGET=${TARGET} @@ -92,6 +93,7 @@ jobs: uses: ./.github/actions/docker with: run: | + set -e for TARGET in ${TARGETS} do mv dist/${TARGET}/* artifacts/ diff --git a/firmware/targets/f6/ble-glue/serial_service.h b/firmware/targets/f6/ble-glue/serial_service.h index 1c365c0e..6e19f86d 100644 --- a/firmware/targets/f6/ble-glue/serial_service.h +++ b/firmware/targets/f6/ble-glue/serial_service.h @@ -4,6 +4,7 @@ #include #define SERIAL_SVC_DATA_LEN_MAX (486) +#define SERIAL_SVC_CHAR_VALUE_LEN_MAX (243) #ifdef __cplusplus extern "C" { diff --git a/firmware/targets/f6/furi-hal/furi-hal-subghz.c b/firmware/targets/f6/furi-hal/furi-hal-subghz.c index 85fe401e..3e810880 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-subghz.c +++ b/firmware/targets/f6/furi-hal/furi-hal-subghz.c @@ -296,9 +296,9 @@ static const uint8_t furi_hal_subghz_preset_gfsk_9_99kb_async_regs[][2] = { {CC1101_IOCFG0, 0x06}, //GDO0 Output Pin Configuration {CC1101_FIFOTHR, 0x47}, //RX FIFO and TX FIFO Thresholds - //1 : CRC calculation in TX and CRC check in RX enabled, + //1 : CRC calculation in TX and CRC check in RX enabled, //1 : Variable packet length mode. Packet length configured by the first byte after sync word - {CC1101_PKTCTRL0, 0x05}, + {CC1101_PKTCTRL0,0x05}, {CC1101_FSCTRL1, 0x06}, //Frequency Synthesizer Control @@ -314,8 +314,8 @@ static const uint8_t furi_hal_subghz_preset_gfsk_9_99kb_async_regs[][2] = { {CC1101_DEVIATN, 0x34}, //Deviation = 19.042969 {CC1101_MCSM0, 0x18}, //Main Radio Control State Machine Configuration {CC1101_FOCCFG, 0x16}, //Frequency Offset Compensation Configuration - - {CC1101_AGCCTRL2, 0x43}, //AGC Control + + {CC1101_AGCCTRL2, 0x43 }, //AGC Control {CC1101_AGCCTRL1, 0x40}, {CC1101_AGCCTRL0, 0x91}, @@ -392,8 +392,7 @@ void furi_hal_subghz_init() { ; // GD0 high - cc1101_write_reg( - &furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); while(hal_gpio_read(&gpio_cc1101_g0) != true) ; @@ -454,7 +453,7 @@ void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset) { } else if(preset == FuriHalSubGhzPresetGFSK9_99KbAsync) { furi_hal_subghz_load_registers(furi_hal_subghz_preset_gfsk_9_99kb_async_regs); furi_hal_subghz_load_patable(furi_hal_subghz_preset_gfsk_async_patable); - } else { + } else{ furi_crash(NULL); } } @@ -499,8 +498,7 @@ void furi_hal_subghz_flush_tx() { bool furi_hal_subghz_rx_pipe_not_empty() { CC1101RxBytes status[1]; furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); - cc1101_read_reg( - &furi_hal_spi_bus_handle_subghz, (CC1101_STATUS_RXBYTES) | CC1101_BURST, (uint8_t*)status); + cc1101_read_reg(&furi_hal_spi_bus_handle_subghz, (CC1101_STATUS_RXBYTES) | CC1101_BURST, (uint8_t*)status); furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz); // TODO: you can add a buffer overflow flag if needed if(status->NUM_RXBYTES > 0) { @@ -674,15 +672,13 @@ void furi_hal_subghz_set_path(FuriHalSubGhzPath path) { furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); if(path == FuriHalSubGhzPath433) { hal_gpio_write(&gpio_rf_sw_0, 0); - cc1101_write_reg( - &furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); } else if(path == FuriHalSubGhzPath315) { hal_gpio_write(&gpio_rf_sw_0, 1); cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW); } else if(path == FuriHalSubGhzPath868) { hal_gpio_write(&gpio_rf_sw_0, 1); - cc1101_write_reg( - &furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); + cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); } else if(path == FuriHalSubGhzPathIsolate) { hal_gpio_write(&gpio_rf_sw_0, 0); cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW); diff --git a/firmware/targets/f6/furi-hal/furi-hal-uart.h b/firmware/targets/f6/furi-hal/furi-hal-uart.h index f245c484..53a45f1e 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-uart.h +++ b/firmware/targets/f6/furi-hal/furi-hal-uart.h @@ -74,4 +74,4 @@ void furi_hal_uart_set_irq_cb( #ifdef __cplusplus } -#endif +#endif \ No newline at end of file From d6f080f7d0a1bc9793bedcd73402ad6bffff57ee Mon Sep 17 00:00:00 2001 From: SG Date: Fri, 10 Dec 2021 02:53:29 +1000 Subject: [PATCH 30/32] [FL-2125] Cli: input_dump (#887) * Cli: input_dump * Tied together input_dump and input service * input_dump and input service are now very tightly tied * Input: remove record open in input_dump. Co-authored-by: Aleksandr Kutuzov --- applications/input/input.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/applications/input/input.c b/applications/input/input.c index 1d160e55..fb393f97 100644 --- a/applications/input/input.c +++ b/applications/input/input.c @@ -92,6 +92,37 @@ void input_cli_send(Cli* cli, string_t args, void* context) { furi_pubsub_publish(input->event_pubsub, &event); } +static void input_cli_dump_events_callback(const void* value, void* ctx) { + furi_assert(value); + furi_assert(ctx); + osMessageQueueId_t input_queue = ctx; + osMessageQueuePut(input_queue, value, 0, osWaitForever); +} + +static void input_cli_dump(Cli* cli, string_t args, void* context) { + osMessageQueueId_t input_queue = osMessageQueueNew(8, sizeof(InputEvent), NULL); + FuriPubSubSubscription* input_subscription = + furi_pubsub_subscribe(input->event_pubsub, input_cli_dump_events_callback, input_queue); + + bool stop = false; + InputEvent input_event; + while(!stop) { + if(osMessageQueueGet(input_queue, &input_event, NULL, 100) == osOK) { + printf( + "key: %s type: %s\r\n", + input_get_key_name(input_event.key), + input_get_type_name(input_event.type)); + } + + if(cli_cmd_interrupt_received(cli)) { + stop = true; + } + } + + furi_pubsub_unsubscribe(input->event_pubsub, input_subscription); + osMessageQueueDelete(input_queue); +} + const char* input_get_key_name(InputKey key) { for(size_t i = 0; i < input_pins_count; i++) { if(input_pins[i].key == key) { @@ -126,7 +157,9 @@ int32_t input_srv() { input->cli = furi_record_open("cli"); if(input->cli) { cli_add_command( - input->cli, "input_send", CliCommandFlagParallelSafe, input_cli_send, input); + input->cli, "input_send", CliCommandFlagParallelSafe, input_cli_send, NULL); + cli_add_command( + input->cli, "input_dump", CliCommandFlagParallelSafe, input_cli_dump, NULL); } input->pin_states = furi_alloc(input_pins_count * sizeof(InputPinState)); From 195f422bb9c2a1154b511536448d3104202e0e51 Mon Sep 17 00:00:00 2001 From: Anna Prosvetova Date: Fri, 10 Dec 2021 14:51:36 +0300 Subject: [PATCH 31/32] Rpc: implement SystemFactoryReset (#890) * Rpc: update protobuf sources * Rpc: implement SystemFactoryReset --- applications/rpc/rpc_system.c | 13 +++++++++++++ assets/compiled/flipper.pb.h | 6 +++++- assets/compiled/system.pb.c | 3 +++ assets/compiled/system.pb.h | 14 ++++++++++++++ assets/protobuf | 2 +- 5 files changed, 36 insertions(+), 2 deletions(-) diff --git a/applications/rpc/rpc_system.c b/applications/rpc/rpc_system.c index 92a770ad..2ce23129 100644 --- a/applications/rpc/rpc_system.c +++ b/applications/rpc/rpc_system.c @@ -3,6 +3,7 @@ #include "status.pb.h" #include +#include #include void rpc_system_system_ping_process(const PB_Main* msg_request, void* context) { @@ -98,6 +99,15 @@ void rpc_system_system_device_info_process(const PB_Main* request, void* context free(response); } +void rpc_system_system_factory_reset_process(const PB_Main* request, void* context) { + furi_assert(request); + furi_assert(request->which_content == PB_Main_system_factory_reset_request_tag); + furi_assert(context); + + furi_hal_bootloader_set_flags(FuriHalBootloaderFlagFactoryReset); + power_reboot(PowerBootModeNormal); +} + void* rpc_system_system_alloc(Rpc* rpc) { RpcHandler rpc_handler = { .message_handler = NULL, @@ -114,5 +124,8 @@ void* rpc_system_system_alloc(Rpc* rpc) { rpc_handler.message_handler = rpc_system_system_device_info_process; rpc_add_handler(rpc, PB_Main_system_device_info_request_tag, &rpc_handler); + rpc_handler.message_handler = rpc_system_system_factory_reset_process; + rpc_add_handler(rpc, PB_Main_system_factory_reset_request_tag, &rpc_handler); + return NULL; } diff --git a/assets/compiled/flipper.pb.h b/assets/compiled/flipper.pb.h index 7599e3c5..5ce575fd 100644 --- a/assets/compiled/flipper.pb.h +++ b/assets/compiled/flipper.pb.h @@ -91,6 +91,7 @@ typedef struct _PB_Main { PB_System_RebootRequest system_reboot_request; PB_System_DeviceInfoRequest system_device_info_request; PB_System_DeviceInfoResponse system_device_info_response; + PB_System_FactoryResetRequest system_factory_reset_request; } content; } PB_Main; @@ -147,6 +148,7 @@ extern "C" { #define PB_Main_system_reboot_request_tag 31 #define PB_Main_system_device_info_request_tag 32 #define PB_Main_system_device_info_response_tag 33 +#define PB_Main_system_factory_reset_request_tag 34 /* Struct field encoding specification for nanopb */ #define PB_Empty_FIELDLIST(X, a) \ @@ -192,7 +194,8 @@ X(a, STATIC, ONEOF, MSG_W_CB, (content,storage_info_response,content.storag X(a, STATIC, ONEOF, MSG_W_CB, (content,storage_rename_request,content.storage_rename_request), 30) \ X(a, STATIC, ONEOF, MSG_W_CB, (content,system_reboot_request,content.system_reboot_request), 31) \ X(a, STATIC, ONEOF, MSG_W_CB, (content,system_device_info_request,content.system_device_info_request), 32) \ -X(a, STATIC, ONEOF, MSG_W_CB, (content,system_device_info_response,content.system_device_info_response), 33) +X(a, STATIC, ONEOF, MSG_W_CB, (content,system_device_info_response,content.system_device_info_response), 33) \ +X(a, STATIC, ONEOF, MSG_W_CB, (content,system_factory_reset_request,content.system_factory_reset_request), 34) #define PB_Main_CALLBACK NULL #define PB_Main_DEFAULT NULL #define PB_Main_content_empty_MSGTYPE PB_Empty @@ -225,6 +228,7 @@ X(a, STATIC, ONEOF, MSG_W_CB, (content,system_device_info_response,content. #define PB_Main_content_system_reboot_request_MSGTYPE PB_System_RebootRequest #define PB_Main_content_system_device_info_request_MSGTYPE PB_System_DeviceInfoRequest #define PB_Main_content_system_device_info_response_MSGTYPE PB_System_DeviceInfoResponse +#define PB_Main_content_system_factory_reset_request_MSGTYPE PB_System_FactoryResetRequest extern const pb_msgdesc_t PB_Empty_msg; extern const pb_msgdesc_t PB_StopSession_msg; diff --git a/assets/compiled/system.pb.c b/assets/compiled/system.pb.c index 128e1c08..dd1bc623 100644 --- a/assets/compiled/system.pb.c +++ b/assets/compiled/system.pb.c @@ -21,5 +21,8 @@ PB_BIND(PB_System_DeviceInfoRequest, PB_System_DeviceInfoRequest, AUTO) PB_BIND(PB_System_DeviceInfoResponse, PB_System_DeviceInfoResponse, AUTO) +PB_BIND(PB_System_FactoryResetRequest, PB_System_FactoryResetRequest, AUTO) + + diff --git a/assets/compiled/system.pb.h b/assets/compiled/system.pb.h index 84120fc9..dbb23ff7 100644 --- a/assets/compiled/system.pb.h +++ b/assets/compiled/system.pb.h @@ -25,6 +25,10 @@ typedef struct _PB_System_DeviceInfoResponse { char *value; } PB_System_DeviceInfoResponse; +typedef struct _PB_System_FactoryResetRequest { + char dummy_field; +} PB_System_FactoryResetRequest; + typedef struct _PB_System_PingRequest { pb_bytes_array_t *data; } PB_System_PingRequest; @@ -54,11 +58,13 @@ extern "C" { #define PB_System_RebootRequest_init_default {_PB_System_RebootRequest_RebootMode_MIN} #define PB_System_DeviceInfoRequest_init_default {0} #define PB_System_DeviceInfoResponse_init_default {NULL, NULL} +#define PB_System_FactoryResetRequest_init_default {0} #define PB_System_PingRequest_init_zero {NULL} #define PB_System_PingResponse_init_zero {NULL} #define PB_System_RebootRequest_init_zero {_PB_System_RebootRequest_RebootMode_MIN} #define PB_System_DeviceInfoRequest_init_zero {0} #define PB_System_DeviceInfoResponse_init_zero {NULL, NULL} +#define PB_System_FactoryResetRequest_init_zero {0} /* Field tags (for use in manual encoding/decoding) */ #define PB_System_DeviceInfoResponse_key_tag 1 @@ -94,11 +100,17 @@ X(a, POINTER, SINGULAR, STRING, value, 2) #define PB_System_DeviceInfoResponse_CALLBACK NULL #define PB_System_DeviceInfoResponse_DEFAULT NULL +#define PB_System_FactoryResetRequest_FIELDLIST(X, a) \ + +#define PB_System_FactoryResetRequest_CALLBACK NULL +#define PB_System_FactoryResetRequest_DEFAULT NULL + extern const pb_msgdesc_t PB_System_PingRequest_msg; extern const pb_msgdesc_t PB_System_PingResponse_msg; extern const pb_msgdesc_t PB_System_RebootRequest_msg; extern const pb_msgdesc_t PB_System_DeviceInfoRequest_msg; extern const pb_msgdesc_t PB_System_DeviceInfoResponse_msg; +extern const pb_msgdesc_t PB_System_FactoryResetRequest_msg; /* Defines for backwards compatibility with code written before nanopb-0.4.0 */ #define PB_System_PingRequest_fields &PB_System_PingRequest_msg @@ -106,12 +118,14 @@ extern const pb_msgdesc_t PB_System_DeviceInfoResponse_msg; #define PB_System_RebootRequest_fields &PB_System_RebootRequest_msg #define PB_System_DeviceInfoRequest_fields &PB_System_DeviceInfoRequest_msg #define PB_System_DeviceInfoResponse_fields &PB_System_DeviceInfoResponse_msg +#define PB_System_FactoryResetRequest_fields &PB_System_FactoryResetRequest_msg /* Maximum encoded size of messages (where known) */ /* PB_System_PingRequest_size depends on runtime parameters */ /* PB_System_PingResponse_size depends on runtime parameters */ /* PB_System_DeviceInfoResponse_size depends on runtime parameters */ #define PB_System_DeviceInfoRequest_size 0 +#define PB_System_FactoryResetRequest_size 0 #define PB_System_RebootRequest_size 2 #ifdef __cplusplus diff --git a/assets/protobuf b/assets/protobuf index 5761a237..f6fdc10e 160000 --- a/assets/protobuf +++ b/assets/protobuf @@ -1 +1 @@ -Subproject commit 5761a23786b4729303bfa49142effea51870e549 +Subproject commit f6fdc10e6d111b289188e88ac1d432698bb739cf From 58ce937321cb259714fbdf38335df174d4c221ad Mon Sep 17 00:00:00 2001 From: SG Date: Sun, 12 Dec 2021 21:03:39 +1000 Subject: [PATCH 32/32] [FL-1891] Release 0.42 bugfixes (#891) * Fixed the "ibutton can only emulate after reading" bug * Fixed previous fix. FIXES FOR THE FIX GOD! BUGS FOR THE BUG THRONE! * Fixed "Repeat code" position on code input screen * Changed CAME protocol icon * Brewfile: add imagemagick missing assets compiler dependency * Correct fix for "Repeat code" position on code input screen Co-authored-by: Aleksandr Kutuzov --- Brewfile | 3 ++- applications/gui/modules/code_input.c | 2 +- applications/ibutton/helpers/key-emulator.cpp | 4 ++++ applications/ibutton/helpers/key-reader.cpp | 13 ++++++++----- applications/ibutton/helpers/pulse-sequencer.cpp | 2 +- applications/lfrfid/helpers/rfid-writer.cpp | 4 +++- firmware/targets/f6/furi-hal/furi-hal-rfid.c | 8 ++++++++ firmware/targets/f7/furi-hal/furi-hal-rfid.c | 8 ++++++++ firmware/targets/furi-hal-include/furi-hal-rfid.h | 8 ++++++++ lib/subghz/protocols/subghz_protocol_came_atomo.c | 2 +- 10 files changed, 44 insertions(+), 10 deletions(-) diff --git a/Brewfile b/Brewfile index aa88d642..64f9d9bc 100644 --- a/Brewfile +++ b/Brewfile @@ -3,4 +3,5 @@ brew "protobuf" brew "heatshrink" brew "open-ocd" brew "clang-format" -brew "dfu-util" \ No newline at end of file +brew "dfu-util" +brew "imagemagick" \ No newline at end of file diff --git a/applications/gui/modules/code_input.c b/applications/gui/modules/code_input.c index 9e220d54..988742f9 100644 --- a/applications/gui/modules/code_input.c +++ b/applications/gui/modules/code_input.c @@ -312,7 +312,7 @@ static void code_input_view_draw_callback(Canvas* canvas, void* _model) { 44 + y_offset, model->current); - if(model->current) canvas_draw_str(canvas, 2, 39 - y_offset, "Repeat code"); + if(model->current) canvas_draw_str(canvas, 2, 39 + y_offset, "Repeat code"); break; default: diff --git a/applications/ibutton/helpers/key-emulator.cpp b/applications/ibutton/helpers/key-emulator.cpp index 7c8c5c97..a09d83e8 100644 --- a/applications/ibutton/helpers/key-emulator.cpp +++ b/applications/ibutton/helpers/key-emulator.cpp @@ -17,6 +17,9 @@ void KeyEmulator::start(iButtonKey* key) { anything_emulated = false; stop(); + // pulldown pull pin, to prevent low-pass filtering by the RFID part of the schematic + furi_hal_rfid_pin_pull_pulldown(); + switch(key->get_key_type()) { case iButtonKeyType::KeyDallas: start_dallas_emulate(key); @@ -44,6 +47,7 @@ bool KeyEmulator::emulated() { void KeyEmulator::stop() { onewire_slave->stop(); pulser.stop(); + furi_hal_rfid_pins_reset(); } void KeyEmulator::start_cyfral_emulate(iButtonKey* key) { diff --git a/applications/ibutton/helpers/key-reader.cpp b/applications/ibutton/helpers/key-reader.cpp index fcb2a480..7abe5df7 100644 --- a/applications/ibutton/helpers/key-reader.cpp +++ b/applications/ibutton/helpers/key-reader.cpp @@ -115,12 +115,10 @@ bool KeyReader::verify_key(iButtonKeyType key_type, const uint8_t* const data, u } void KeyReader::start_comaparator(void) { - // pulldown lf-rfid pins to prevent interference - hal_gpio_init(&gpio_rfid_pull, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); - hal_gpio_write(&gpio_rfid_pull, false); + furi_hal_rfid_pins_reset(); - hal_gpio_init(&gpio_rfid_carrier_out, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); - hal_gpio_write(&gpio_rfid_carrier_out, false); + // pulldown pull pin, we sense the signal through the analog part of the RFID schematic + furi_hal_rfid_pin_pull_pulldown(); comparator_callback_pointer = cbc::obtain_connector(this, &KeyReader::comparator_trigger_callback); @@ -130,6 +128,11 @@ void KeyReader::start_comaparator(void) { } void KeyReader::stop_comaparator(void) { + furi_hal_rfid_pins_reset(); + + // rfid_pins_reset will disable ibutton pin + furi_hal_ibutton_start(); + HAL_COMP_Stop(&hcomp1); api_interrupt_remove(comparator_callback_pointer, InterruptTypeComparatorTrigger); } diff --git a/applications/ibutton/helpers/pulse-sequencer.cpp b/applications/ibutton/helpers/pulse-sequencer.cpp index 328df7ac..9a8b0d98 100644 --- a/applications/ibutton/helpers/pulse-sequencer.cpp +++ b/applications/ibutton/helpers/pulse-sequencer.cpp @@ -56,7 +56,7 @@ void PulseSequencer::init_timer(uint32_t period) { HAL_NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn); - hal_gpio_init(&ibutton_gpio, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); + hal_gpio_init(&ibutton_gpio, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedVeryHigh); } void PulseSequencer::deinit_timer() { diff --git a/applications/lfrfid/helpers/rfid-writer.cpp b/applications/lfrfid/helpers/rfid-writer.cpp index f983ce35..0f4b8c96 100644 --- a/applications/lfrfid/helpers/rfid-writer.cpp +++ b/applications/lfrfid/helpers/rfid-writer.cpp @@ -37,7 +37,9 @@ void RfidWriter::start() { furi_hal_rfid_tim_read(125000, 0.5); furi_hal_rfid_pins_read(); furi_hal_rfid_tim_read_start(); - hal_gpio_write(&gpio_rfid_pull, true); + + // do not ground the antenna + furi_hal_rfid_pin_pull_release(); } void RfidWriter::stop() { diff --git a/firmware/targets/f6/furi-hal/furi-hal-rfid.c b/firmware/targets/f6/furi-hal/furi-hal-rfid.c index d7092f88..c14d48fd 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-rfid.c +++ b/firmware/targets/f6/furi-hal/furi-hal-rfid.c @@ -61,6 +61,14 @@ void furi_hal_rfid_pins_read() { hal_gpio_init(&gpio_rfid_data_in, GpioModeAnalog, GpioPullNo, GpioSpeedLow); } +void furi_hal_rfid_pin_pull_release() { + hal_gpio_write(&gpio_rfid_pull, true); +} + +void furi_hal_rfid_pin_pull_pulldown() { + hal_gpio_write(&gpio_rfid_pull, false); +} + void furi_hal_rfid_tim_read(float freq, float duty_cycle) { // TODO LL init uint32_t period = (uint32_t)((SystemCoreClock) / freq) - 1; diff --git a/firmware/targets/f7/furi-hal/furi-hal-rfid.c b/firmware/targets/f7/furi-hal/furi-hal-rfid.c index 02a82bd1..b4b5af50 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-rfid.c +++ b/firmware/targets/f7/furi-hal/furi-hal-rfid.c @@ -66,6 +66,14 @@ void furi_hal_rfid_pins_read() { hal_gpio_init(&gpio_rfid_data_in, GpioModeAnalog, GpioPullNo, GpioSpeedLow); } +void furi_hal_rfid_pin_pull_release() { + hal_gpio_write(&gpio_rfid_pull, true); +} + +void furi_hal_rfid_pin_pull_pulldown() { + hal_gpio_write(&gpio_rfid_pull, false); +} + void furi_hal_rfid_tim_read(float freq, float duty_cycle) { // TODO LL init uint32_t period = (uint32_t)((SystemCoreClock) / freq) - 1; diff --git a/firmware/targets/furi-hal-include/furi-hal-rfid.h b/firmware/targets/furi-hal-include/furi-hal-rfid.h index 5e11c6d6..68ac18c1 100644 --- a/firmware/targets/furi-hal-include/furi-hal-rfid.h +++ b/firmware/targets/furi-hal-include/furi-hal-rfid.h @@ -29,6 +29,14 @@ void furi_hal_rfid_pins_emulate(); */ void furi_hal_rfid_pins_read(); +/** Release rfid pull pin + */ +void furi_hal_rfid_pin_pull_release(); + +/** Pulldown rfid pull pin + */ +void furi_hal_rfid_pin_pull_pulldown(); + /** Config rfid timer to read state * * @param freq timer frequency diff --git a/lib/subghz/protocols/subghz_protocol_came_atomo.c b/lib/subghz/protocols/subghz_protocol_came_atomo.c index fbf9ca38..ff4dff67 100644 --- a/lib/subghz/protocols/subghz_protocol_came_atomo.c +++ b/lib/subghz/protocols/subghz_protocol_came_atomo.c @@ -26,7 +26,7 @@ SubGhzProtocolCameAtomo* subghz_protocol_came_atomo_alloc() { instance->common.te_short = 600; instance->common.te_long = 1200; instance->common.te_delta = 250; - instance->common.type_protocol = SubGhzProtocolCommonTypeStatic; + instance->common.type_protocol = SubGhzProtocolCommonTypeDynamic; instance->common.to_string = (SubGhzProtocolCommonToStr)subghz_protocol_came_atomo_to_str; instance->common.to_load_protocol = (SubGhzProtocolCommonLoadFromRAW)subghz_decoder_came_atomo_to_load_protocol;