diff --git a/firmware/targets/f7/Inc/alt_boot.h b/firmware/targets/f7/Inc/alt_boot.h index 91bf9bdf..d8be3aa4 100644 --- a/firmware/targets/f7/Inc/alt_boot.h +++ b/firmware/targets/f7/Inc/alt_boot.h @@ -8,6 +8,8 @@ void flipper_boot_update_exec(); void flipper_boot_dfu_exec(); +void flipper_boot_recovery_exec(); + #ifdef __cplusplus } #endif diff --git a/firmware/targets/f7/Src/main.c b/firmware/targets/f7/Src/main.c index d9a2221a..1f2b5d6e 100644 --- a/firmware/targets/f7/Src/main.c +++ b/firmware/targets/f7/Src/main.c @@ -49,6 +49,10 @@ int main() { // But if we do, abandon to avoid bootloops furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal); furi_hal_power_reset(); + } else if(!furi_hal_gpio_read(&gpio_button_up)) { + furi_hal_light_sequence("rgb WR"); + flipper_boot_recovery_exec(); + furi_hal_power_reset(); } else { furi_hal_light_sequence("rgb G"); furi_thread_start(main_thread); diff --git a/firmware/targets/f7/Src/recovery.c b/firmware/targets/f7/Src/recovery.c new file mode 100644 index 00000000..fa57482c --- /dev/null +++ b/firmware/targets/f7/Src/recovery.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include + +#define COUNTER_VALUE (100U) + +static void flipper_boot_recovery_draw_splash(u8g2_t* fb, size_t progress) { + u8g2_ClearBuffer(fb); + u8g2_SetDrawColor(fb, 0x01); + + u8g2_SetFont(fb, u8g2_font_helvB08_tr); + u8g2_DrawStr(fb, 2, 8, "PIN and Factory Reset"); + u8g2_SetFont(fb, u8g2_font_haxrcorp4089_tr); + u8g2_DrawStr(fb, 2, 21, "Hold Right to confirm"); + u8g2_DrawStr(fb, 2, 31, "Press Down to cancel"); + + if(progress < COUNTER_VALUE) { + size_t width = progress / (COUNTER_VALUE / 100); + u8g2_DrawBox(fb, 14 + (50 - width / 2), 54, width, 3); + } + + u8g2_SetPowerSave(fb, 0); + u8g2_SendBuffer(fb); +} + +void flipper_boot_recovery_exec() { + u8g2_t* fb = malloc(sizeof(u8g2_t)); + u8g2_Setup_st756x_flipper(fb, U8G2_R0, u8x8_hw_spi_stm32, u8g2_gpio_and_delay_stm32); + u8g2_InitDisplay(fb); + + size_t counter = COUNTER_VALUE; + while(counter) { + if(!furi_hal_gpio_read(&gpio_button_down)) { + break; + } + + if(!furi_hal_gpio_read(&gpio_button_right)) { + counter--; + } else { + counter = COUNTER_VALUE; + } + + flipper_boot_recovery_draw_splash(fb, counter); + } + + if(!counter) { + furi_hal_rtc_set_flag(FuriHalRtcFlagFactoryReset); + furi_hal_rtc_set_pin_fails(0); + furi_hal_rtc_reset_flag(FuriHalRtcFlagLock); + } +} \ 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 98ebedf5..4a32d708 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.c @@ -73,8 +73,18 @@ const InputPin input_pins[] = { const size_t input_pins_count = sizeof(input_pins) / sizeof(InputPin); +static void furi_hal_resources_init_input_pins(GpioMode mode) { + for(size_t i = 0; i < input_pins_count; i++) { + furi_hal_gpio_init( + input_pins[i].gpio, + mode, + (input_pins[i].inverted) ? GpioPullUp : GpioPullDown, + GpioSpeedLow); + } +} + void furi_hal_resources_init_early() { - furi_hal_gpio_init(&gpio_button_left, GpioModeInput, GpioPullUp, GpioSpeedLow); + furi_hal_resources_init_input_pins(GpioModeInput); // SD Card stepdown control furi_hal_gpio_write(&periph_power, 1); @@ -117,14 +127,12 @@ void furi_hal_resources_init_early() { } void furi_hal_resources_deinit_early() { + furi_hal_resources_init_input_pins(GpioModeAnalog); } void furi_hal_resources_init() { // Button pins - for(size_t i = 0; i < input_pins_count; i++) { - furi_hal_gpio_init( - input_pins[i].gpio, GpioModeInterruptRiseFall, GpioPullUp, GpioSpeedLow); - } + furi_hal_resources_init_input_pins(GpioModeInterruptRiseFall); // Display pins furi_hal_gpio_init(&gpio_display_rst_n, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); diff --git a/lib/nfc/protocols/mifare_classic.c b/lib/nfc/protocols/mifare_classic.c index 28667f09..e4d5e027 100644 --- a/lib/nfc/protocols/mifare_classic.c +++ b/lib/nfc/protocols/mifare_classic.c @@ -438,9 +438,9 @@ bool mf_classic_block_to_value(const uint8_t* block, int32_t* value, uint8_t* ad void mf_classic_value_to_block(int32_t value, uint8_t addr, uint8_t* block) { uint32_t v_inv = ~((uint32_t)value); - memcpy(block, &value, 4); - memcpy(block + 4, &v_inv, 4); - memcpy(block + 8, &value, 4); + memcpy(block, &value, 4); //-V1086 + memcpy(block + 4, &v_inv, 4); //-V1086 + memcpy(block + 8, &value, 4); //-V1086 block[12] = addr; block[13] = ~addr & 0xFF;