diff --git a/board_detect.c b/board_detect.c index 811479f..c25beed 100644 --- a/board_detect.c +++ b/board_detect.c @@ -103,7 +103,7 @@ int led_pin() return PIN_LED_ITSY; default: return PIN_LED_WS; - }; + }; } int pwr_pin() @@ -115,7 +115,7 @@ int pwr_pin() return PIN_LED_PWR_ITSY; default: return 31; - }; + }; } int scl_pin() @@ -131,7 +131,7 @@ int scl_pin() return PIN_SCL_SQC; default: return PIN_SCL_WS; - }; + }; } int sda_pin() @@ -147,7 +147,7 @@ int sda_pin() return PIN_SDA_SQC; default: return PIN_SDA_WS; - }; + }; } int gli_pin() @@ -161,7 +161,7 @@ int gli_pin() return PIN_GLI_PICO; default: return PIN_GLI_WS; - }; + }; } bool is_pico() diff --git a/boot_detect.c b/boot_detect.c index 8d28763..8242f4f 100644 --- a/boot_detect.c +++ b/boot_detect.c @@ -53,7 +53,7 @@ bool wait_for_boot(int timeout_ms) { else if (last_word == 0x51000000 && word == 0x0055) //read block 0 { // OLED models sometimes need more time between block 0 and block 1 - // original was 100ms, increased to 250ms for (hopefully) better OLED compatibility + // original was 100ms, increased to 250ms for better OLED compatibility tio_full = make_timeout_time_ms(250); was_read_zero = true; } else if (was_read_zero && last_word == 0x4D000200 && word == 0x00B1) // read status - erista only @@ -67,12 +67,11 @@ bool wait_for_boot(int timeout_ms) { last_word = word; } } - - // properly clean up all state machines before retrying - // original deinit only disabled SM 0 and 1, but SM 2 (G_DAT0_SM) was left running - pio_set_sm_mask_enabled(pio1, 0x7, false); // disable SM 0, 1, AND 2 (0x7 = 0b111) - + // properly clean up all state machines before retrying + // SM 2 (G_DAT0_SM) must also be disabled (0x7 = 0b111 covers SM 0, 1, and 2) + pio_set_sm_mask_enabled(pio1, 0x7, false); + // clean up GPIO pins for (int i = PIN_CLK; i <= PIN_DAT; i++) { @@ -81,7 +80,7 @@ bool wait_for_boot(int timeout_ms) { gpio_disable_input_output(i); } gpio_deinit(gli_pin()); - + // only halt with error if all retries are exhausted if (retry == BOOT_DETECT_MAX_RETRIES - 1) { if (was_read_zero) { @@ -93,10 +92,10 @@ bool wait_for_boot(int timeout_ms) { halt_with_error(3, 3); } } - + // small delay before retrying to let hardware settle sleep_ms(50); } - + return false; } diff --git a/config.h b/config.h index 261f101..19789ff 100644 --- a/config.h +++ b/config.h @@ -1,7 +1,7 @@ #include "hardware/flash.h" #define OFFSET_DIV 8 #define OFFSET_MIN 6200 -#define OFFSET_MAX 6950 +#define OFFSET_MAX 6900 #define VER_HI 2 #define VER_LO 81 diff --git a/glitch.c b/glitch.c index 2f2ba95..811b250 100644 --- a/glitch.c +++ b/glitch.c @@ -65,8 +65,7 @@ void init_glitch_pio() { } void deinit_glitch_pio() { - // original code only disabled SM 0 and 1 (mask 0x3 = 0b011) - // SM 2 (G_DAT0_SM) is also used, so all 3 (mask 0x7 = 0b111) need to be disabled + // SM 2 (G_DAT0_SM) is also used, so all 3 state machines need to be disabled (0x7 = 0b111) pio_set_sm_mask_enabled(pio1, 0x7, false); for (int i = PIN_CLK; i <= PIN_DAT; i++) { @@ -136,14 +135,14 @@ int do_glitch(int delay, int width, int total_ms, int after_ms) { int tries = 0; -// Green pulsing implementation. +// Blue pulsing implementation. void inc_tries() { tries += 1; if(tries & 1) - put_pixel(PIX_g); + put_pixel(PIX_b); else - put_pixel(PIX_gre); + put_pixel(PIX_blu); } // random() for glitch offset array generation diff --git a/main.c b/main.c index c38718c..5c657f8 100644 --- a/main.c +++ b/main.c @@ -21,23 +21,24 @@ bool write_payload(); -// optimized: increased voltage for better stability at higher clock +// overclock to 200 MHz void init_system() { vreg_set_voltage(VREG_VOLTAGE_1_30); - set_sys_clock_khz(200000, true); + set_sys_clock_khz(200000, true); } +// filled within "fast check" on eMMC init extern uint8_t cid_buf[17]; void rewrite_payload() { put_pixel(PIX_whi); write_payload(); - put_pixel(PIX_gre); + put_pixel(PIX_blu); + // used to automatically rewrite payload when eMMC/console changes init_config(cid_buf + 1); } -// optimized: reduced timeout and combined checks bool safe_test_voltage(int pin, float target, float range) { gpio_enable_input_output(pin); @@ -49,28 +50,34 @@ bool safe_test_voltage(int pin, float target, float range) return voltage >= (target - range) && voltage <= (target + range); } -// optimized: reduced timeout from 2500ms to 1500ms, faster convergence +// test all ADC pins void self_test() { - absolute_time_t tio_time = make_timeout_time_ms(1500); + absolute_time_t tio_time = make_timeout_time_ms(2500); adc_init(); - uint8_t check_mask = 0; // bit flags: 0=rst, 1=cmd, 2=d0 - - while (!time_reached(tio_time) && check_mask != 0x07) { - if (!(check_mask & 0x01)) - check_mask |= safe_test_voltage(PIN_RST, 1.8f, 0.2f) ? 0x01 : 0; - if (!(check_mask & 0x02)) - check_mask |= safe_test_voltage(PIN_CMD, 1.8f, 0.2f) ? 0x02 : 0; - if (!(check_mask & 0x04)) - check_mask |= safe_test_voltage(PIN_DAT, 1.8f, 0.2f) ? 0x04 : 0; + bool rst_ok = false, cmd_ok = false, d0_ok = false, clk_ok = false; + while (!time_reached(tio_time)) { + if (!rst_ok) + rst_ok |= safe_test_voltage(PIN_RST, 1.8f, 0.2f); + if (!cmd_ok) + cmd_ok |= safe_test_voltage(PIN_CMD, 1.8f, 0.2f); + if (!d0_ok) + d0_ok |= safe_test_voltage(PIN_DAT, 1.8f, 0.2f); + if (rst_ok && cmd_ok && d0_ok) + break; } - - if(!(check_mask & 0x01)) + if(!rst_ok) + { halt_with_error(0, 2); - if(!(check_mask & 0x02)) + } + if(!cmd_ok) + { halt_with_error(1, 2); - if(!(check_mask & 0x04)) + } + if(!d0_ok) + { halt_with_error(2, 2); + } } extern bool was_self_reset; @@ -79,125 +86,89 @@ int main() { // stop watchdog *(uint32_t*)(0x40058000 + 0x3000) = (1 << 30); - - // init board detection + // init reset, mosfet and LED detect_board(); - // clocks & voltage - init_system(); - + init_system(); // fuses counter init_fuses(); - // LED & glitch & emmc PIO upload_pio(); - if (is_tiny()) { gpio_put(led_pin(), 0); - sleep_us(50); // optimized: reduced from 100us + sleep_us(100); put_pixel(0); - sleep_us(50); // optimized: reduced from 100us + sleep_us(100); } - // check if this is the very first start if (watchdog_caused_reboot() && boot_try == 0) - halt_with_error(1, 1); - + { + halt_with_error(1, 1); + } // is chip reset required bool force_button = detect_by_pull(1, 0, 1); - // start LED - put_pixel(PIX_gre); - + put_pixel(PIX_blu); // test pins self_test(); - // wait till the CPU has proper power & started reading the eMMC - wait_for_boot(2490); - + wait_for_boot(2500); // ensure the BCT has not been overwritten by system update bool force_check = fast_check(); was_self_reset = force_button || !is_configured(cid_buf + 1); - // perform payload rewrite if required if (!force_check || was_self_reset) { rewrite_payload(); } - // setup the glitch trigger for Mariko if (mariko) { pio1->instr_mem[gtrig_pio_offset + 4] = pio_encode_nop(); pio1->instr_mem[gtrig_pio_offset + 5] = pio_encode_nop(); } - - // optimized: start with slightly lower width for faster convergence - int width = 140; + // start from some default width + int width = 150; bool glitched = false; int offset = 0; - - // optimized: removed outer loop since it just repeats rewrite_payload - // try saved records first - for (int y = 0; (y < 2) && !glitched; y++) { - int max_weight = -1; - while (1) { - offset = find_best_record(&max_weight); - if (offset == -1) - break; - // optimized: reduced attempts from 3 to 2 for faster iteration - glitched = glitch_try_offset(offset, &width, 2); - if (glitched) - break; - } - } - - // try random offsets if saved records failed - if (!glitched) { - for(int z = 0; (z < 2) && !glitched; z++) { - prepare_random_array(); - for(int y = 0; y < OFFSET_CNT; y++) - { - offset = offsets_array[y]; - // optimized: reduced attempts from 4 to 3 + for (int full_try = 0; full_try < 2; full_try++) { + // try saved records + for (int y = 0; (y < 2) && !glitched; y++) { + int max_weight = -1; + while (1) { + offset = find_best_record(&max_weight); + if (offset == -1) + break; + // try glitch glitched = glitch_try_offset(offset, &width, 3); if (glitched) break; } } - } - - // if still not glitched, try one more time with payload rewrite - if (!glitched) { - rewrite_payload(); - - // one more attempt with saved records - int max_weight = -1; - for (int y = 0; (y < 3) && !glitched; y++) { - offset = find_best_record(&max_weight); - if (offset == -1) - break; - glitched = glitch_try_offset(offset, &width, 2); + if (!glitched) { + for(int z = 0; (z < 2) && !glitched; z++) { + prepare_random_array(); + for(int y = 0; y < OFFSET_CNT; y++) + { + offset = offsets_array[y]; + glitched = glitch_try_offset(offset, &width, 4); + if (glitched) + break; + } + } + } + if (glitched) { + if ((count_fuses() & 1) != boot_slot) + { + // finish update / rollback + burn_fuse(); + } + add_boot_record(offset); + halt_with_error(0, 1); + } + if (full_try == 0) { + rewrite_payload(); } } - - if (glitched) { - // ensure all glitching operations are complete - sleep_us(100); - // force success LED display - put_pixel(0); // clear any previous LED state - sleep_ms(50); - put_pixel(PIX_whi); // show white success - sleep_ms(200); // longer delay to ensure visibility - - if ((count_fuses() & 1) != boot_slot) - { - // finish update / rollback - burn_fuse(); - } - add_boot_record(offset); - halt_with_error(0, 1); - } - // attempts limit halt_with_error(7, 3); -} \ No newline at end of file +} diff --git a/misc.c b/misc.c index ae95e3b..8e26ba5 100644 --- a/misc.c +++ b/misc.c @@ -10,14 +10,13 @@ extern int ws_pio_offset; -// optimized: reduced timing constants for faster error signaling -#define BLINK_TIME 500 +#define BLINK_TIME 700 #define SHORT_TIME ( BLINK_TIME * 2 / 10 ) #define SHORT_PAUSE_TIME ((BLINK_TIME - SHORT_TIME) / 2) #define LONG_TIME ( BLINK_TIME * 8 / 10 ) #define LONG_PAUSE_TIME ((BLINK_TIME - LONG_TIME) / 2) -#define PAUSE_BETWEEN 1500 -#define PAUSE_BEFORE 500 +#define PAUSE_BETWEEN 2000 +#define PAUSE_BEFORE 750 #define CODE_REPEATS 3 #define GPIO_OD PADS_BANK0_GPIO0_OD_BITS @@ -26,7 +25,6 @@ extern int ws_pio_offset; typedef void nopar(); -// optimized: streamlined power down sequence void __not_in_flash_func(zzz)() { *(uint32_t*)(0x4000803C + 0x3000) = 1; // go to 12 MHz uint32_t * vreg = (uint32_t*)0x40064000; @@ -34,27 +32,30 @@ void __not_in_flash_func(zzz)() { *(uint32_t*)0x40060000 = 0x00d1e000; // disable rosc vreg[0] = 1; // lowest possible power *(uint32_t*)0x40024000 = 0x00d1e000; // disable xosc - while(1) __asm volatile("wfi"); // optimized: use WFI to save more power + while(1); } -// optimized: combined loop for faster execution void finish_pins_except_leds() { - for(int pin = 0; pin <= 29; pin++) { + for(int pin = 0; pin <= 29; pin += 1) { if (pin == led_pin() || pin == pwr_pin()) continue; - if (pin == PIN_GLI_PICO || pin == PIN_GLI_XIAO || pin == PIN_GLI_WS || pin == PIN_GLI_ITSY) + { gpio_pull_down(pin); + } else + { gpio_disable_pulls(pin); - + } gpio_disable_input_output(pin); } } void finish_pins_leds() { if (!is_tiny()) + { gpio_disable_input_output(led_pin()); + } gpio_disable_input_output(pwr_pin()); } @@ -65,62 +66,50 @@ void halt_with_error(uint32_t err, uint32_t bits) pio_set_sm_mask_enabled(pio1, 0xF, false); set_sys_clock_khz(48000, true); vreg_set_voltage(VREG_VOLTAGE_0_95); - if (bits != 1) { put_pixel(0); sleep_ms(PAUSE_BEFORE); } - for(int j = 0; j < CODE_REPEATS; j++) { for(int i = 0; i < bits; i++) { bool is_long = err & (1 << (bits - i - 1)); sleep_ms(is_long ? LONG_PAUSE_TIME : SHORT_PAUSE_TIME); - bool success = bits == 1 && is_long == 0; - put_pixel(success ? PIX_whi : PIX_red); + if (success) + put_pixel(PIX_whi); + else + put_pixel(PIX_red); sleep_ms(is_long ? LONG_TIME : success ? SHORT_TIME * 2 : SHORT_TIME); put_pixel(0); - if (i != bits - 1 || j != CODE_REPEATS - 1) sleep_ms(is_long ? LONG_PAUSE_TIME : SHORT_PAUSE_TIME); if (i == bits - 1 && j != CODE_REPEATS - 1) sleep_ms(PAUSE_BETWEEN); } - // first write case, do not repeat this kind of error code if (bits == 1) break; } - finish_pins_leds(); zzz(); } -// optimized: reduced LED delays for faster startup -void put_pixel(uint32_t pixel_rgb) +void put_pixel(uint32_t pixel_grb) { static bool led_enabled = false; - if (is_pico()) { gpio_init(led_pin()); - if (pixel_rgb) { + if (pixel_grb) { gpio_set_dir(led_pin(), true); gpio_put(led_pin(), 1); } return; } - - uint8_t red = (pixel_rgb >> 16) & 0xFF; - uint8_t green = (pixel_rgb >> 8) & 0xFF; - uint8_t blue = pixel_rgb & 0xFF; - uint32_t pixel_grb = (green << 16) | (red << 8) | blue; - ws2812_program_init(pio0, 3, ws_pio_offset, led_pin(), 800000, true); - if (!led_enabled && pwr_pin() != 31) { led_enabled = true; @@ -128,41 +117,39 @@ void put_pixel(uint32_t pixel_rgb) gpio_set_drive_strength(pwr_pin(), GPIO_DRIVE_STRENGTH_12MA); gpio_set_dir(pwr_pin(), true); gpio_put(pwr_pin(), 1); - sleep_us(100); // optimized: reduced from 200us + sleep_us(200); } - pio_sm_put_blocking(pio0, 3, pixel_grb << 8u); - sleep_us(30); // optimized: reduced from 50us + sleep_us(50); pio_sm_set_enabled(pio0, 3, false); - if (!is_tiny()) + { gpio_init(led_pin()); + } } -// optimized: direct register access void gpio_disable_input_output(int pin) { - uint32_t pad_reg = 0x4001c000 + 4 + (pin << 2); // optimized: Use shift instead of multiply + uint32_t pad_reg = 0x4001c000 + 4 + pin*4; *(uint32_t*)(pad_reg + 0x2000) = GPIO_OD; *(uint32_t*)(pad_reg + 0x3000) = GPIO_IE; } void gpio_enable_input_output(int pin) { - uint32_t pad_reg = 0x4001c000 + 4 + (pin << 2); // optimized: Use shift instead of multiply + uint32_t pad_reg = 0x4001c000 + 4 + pin*4; *(uint32_t*)(pad_reg + 0x3000) = GPIO_OD; *(uint32_t*)(pad_reg + 0x2000) = GPIO_IE; } -// optimized: reduced delays for faster reset cycles void reset_cpu() { gpio_enable_input_output(PIN_RST); gpio_pull_up(PIN_RST); - sleep_us(800); // optimized: reduced from 1000us + sleep_us(1000); gpio_init(PIN_RST); gpio_set_dir(PIN_RST, true); - sleep_us(1800); // decreased slightly for button detection stability + sleep_us(2000); gpio_deinit(PIN_RST); gpio_disable_pulls(PIN_RST); gpio_disable_input_output(PIN_RST); -} \ No newline at end of file +} diff --git a/misc.h b/misc.h index db4e299..04cd216 100644 --- a/misc.h +++ b/misc.h @@ -1,8 +1,9 @@ -#define PIX_gre 0x16537e -#define PIX_red 0xc90000 -#define PIX_whi 0xff9200 +#define RGB(r, g, b) (((g) << 16) | ((r) << 8) | (b)) -#define PIX_g 0x6fa8dc +#define PIX_blu RGB(0x16, 0x53, 0x7e) // blue (glitching) +#define PIX_b RGB(0x6f, 0xa8, 0xdc) // light blue dim (glitch pulse) +#define PIX_whi RGB(0xff, 0x92, 0x00) // amber/yellow (success + comparison) +#define PIX_red RGB(0xc9, 0x00, 0x00) // red (error codes) void put_pixel(uint32_t pixel_grb); @@ -14,4 +15,4 @@ void gpio_enable_input_output(int pin); void finish_pins_except_leds(); -void reset_cpu(); +void reset_cpu(); \ No newline at end of file diff --git a/payload.c b/payload.c index c0cc0ba..8e32c39 100644 --- a/payload.c +++ b/payload.c @@ -81,7 +81,7 @@ extern bool mariko; static inline uint16_t crc_itu_t_byte(uint16_t crc, const uint8_t data) { - return (crc << 8) ^ crc_itu_t_table[((crc >> 8) ^ data) & 0xff]; + return (crc << 8) ^ crc_itu_t_table[((crc >> 8) ^ data) & 0xff]; } uint16_t crc_itu_t(uint16_t crc, const uint8_t *buffer, size_t len) @@ -91,9 +91,9 @@ uint16_t crc_itu_t(uint16_t crc, const uint8_t *buffer, size_t len) { crc_prepare_table(); } - while (len--) - crc = crc_itu_t_byte(crc, *buffer++); - return crc; + while (len--) + crc = crc_itu_t_byte(crc, *buffer++); + return crc; } extern void zzz(); @@ -108,18 +108,18 @@ uint16_t payload_crc() int crc7(uint8_t *buffer, int size) { - uint8_t crc = 0; - for (int i = 0; i < size; i++) { - uint8_t c = buffer[i]; - for (int j = 0; j < 8; j++) { - crc <<= 1; - if ((crc ^ c) & 0x80) - crc ^= 9; - c <<= 1; - } - crc &= 0x7Fu; - } - return crc; + uint8_t crc = 0; + for (int i = 0; i < size; i++) { + uint8_t c = buffer[i]; + for (int j = 0; j < 8; j++) { + crc <<= 1; + if ((crc ^ c) & 0x80) + crc ^= 9; + c <<= 1; + } + crc &= 0x7Fu; + } + return crc; } void __time_critical_func(cmd_write)(uint8_t cmd, uint32_t argument) @@ -130,9 +130,9 @@ void __time_critical_func(cmd_write)(uint8_t cmd, uint32_t argument) pio_sm_set_out_pins(pio0, SM_OUT, PIN_CMD, 1); pio_sm_set_enabled(pio0, SM_OUT, true); - data[0] = cmd | 0x40; - *(uint32_t *) &data[1] = __builtin_bswap32(argument); - data[5] = (crc7(data, 5) << 1) | 1; + data[0] = cmd | 0x40; + *(uint32_t *) &data[1] = __builtin_bswap32(argument); + data[5] = (crc7(data, 5) << 1) | 1; uint32_t fifo[3]; fifo[0] = 0xFFCF0000 | (data[0] << 8) | data[1]; fifo[1] = __builtin_bswap32(*(uint32_t*)(data + 2)); @@ -151,7 +151,7 @@ bool __time_critical_func(dat_write)() pio_sm_set_out_pins(pio0, SM_OUT, PIN_DAT, 1); pio_sm_set_enabled(pio0, SM_OUT, true); uint8_t * buffer = data_buf; - uint16_t crc = crc_itu_t(0, buffer, 512); + uint16_t crc = crc_itu_t(0, buffer, 512); uint32_t words[130]; int size_bits = 514 * 8 + 2; words[0] = ((size_bits ^ 0xFFFF) << 16) | (buffer[0] << 7) | (buffer[1] >> 1); @@ -413,13 +413,13 @@ uint32_t mmc_init_table[] = { }; bool mmc_initialize() { - if (!init_op_cond()) { + if (!init_op_cond()) { return false; } if (!cmd_exec_cid()) { return false; } - for (int i = 0; i < sizeof(mmc_init_table)/sizeof(mmc_init_table[0]); i += 4) + for (int i = 0; i < sizeof(mmc_init_table)/sizeof(mmc_init_table[0]); i += 4) { uint32_t res= 0; if (!simple_cmd_exec_with_ret(mmc_init_table[i], mmc_init_table[i+1], &res)) { @@ -495,9 +495,9 @@ extern int boot_slot; uint8_t temp_buf[512]; struct fw_header { - uint32_t size; - uint32_t crc; - uint8_t data[]; + uint32_t size; + uint32_t crc; + uint8_t data[]; }; #define fw_slot_0 ((struct fw_header *) (XIP_BASE + 0x10000)) @@ -713,7 +713,7 @@ void prepare_mariko_bct() * drops writes to BctNormalMain (offset 0x0000) and BctSafeMain (offset 0x4000) * when it detects the modchip's custom public key fill pattern (0x59, 0x69...) in those * slots. this is by design for AutoRCM preservation, but it means that after a firmware - * update via syscfw, UpdateBootImages successfully writes the new BCT to BctNormalSub (0x8000) and BctSafeSub (0xC000), + * update via syscfw, UpdateBootImages successfully writes the new BCT to BctNormalSub (0x8000) and BctSafeSub (0xC000), * but the writes to BctNormalMain and BctSafeMain are discarded. the result is that Main slots still hold the modchip * synthetic/fake BCT while Sub slots have the new firmware's real BCT. * @@ -799,4 +799,4 @@ void write_payload() { stop_mmc(); if (!is_space_bl && !is_command && !was_self_reset) halt_with_error(0, 0); -} \ No newline at end of file +}