| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157 |
- #include "avr_isp_worker_rw.h"
- #include <furi_hal_pwm.h>
- #include "avr_isp_types.h"
- #include "avr_isp.h"
- #include "../lib/driver/avr_isp_prog_cmd.h"
- #include "../lib/driver/avr_isp_chip_arr.h"
- #include "flipper_i32hex_file.h"
- #include <flipper_format/flipper_format.h>
- #include <furi.h>
- #define TAG "AvrIspWorkerRW"
- #define NAME_PATERN_FLASH_FILE "flash.hex"
- #define NAME_PATERN_EEPROM_FILE "eeprom.hex"
- struct AvrIspWorkerRW {
- AvrIsp* avr_isp;
- FuriThread* thread;
- volatile bool worker_running;
- uint32_t chip_arr_ind;
- bool chip_detect;
- uint8_t lfuse;
- uint8_t hfuse;
- uint8_t efuse;
- uint8_t lock;
- float progress_flash;
- float progress_eeprom;
- const char* file_path;
- const char* file_name;
- AvrIspSignature signature;
- AvrIspWorkerRWCallback callback;
- void* context;
- AvrIspWorkerRWStatusCallback callback_status;
- void* context_status;
- };
- typedef enum {
- AvrIspWorkerRWEvtStop = (1 << 0),
- AvrIspWorkerRWEvtReading = (1 << 1),
- AvrIspWorkerRWEvtVerification = (1 << 2),
- AvrIspWorkerRWEvtWriting = (1 << 3),
- AvrIspWorkerRWEvtWritingFuse = (1 << 4),
- } AvrIspWorkerRWEvt;
- #define AVR_ISP_WORKER_ALL_EVENTS \
- (AvrIspWorkerRWEvtWritingFuse | AvrIspWorkerRWEvtWriting | AvrIspWorkerRWEvtVerification | \
- AvrIspWorkerRWEvtReading | AvrIspWorkerRWEvtStop)
- /** Worker thread
- *
- * @param context
- * @return exit code
- */
- static int32_t avr_isp_worker_rw_thread(void* context) {
- AvrIspWorkerRW* instance = context;
- /* start PWM on &gpio_ext_pa4 */
- if(!furi_hal_pwm_is_running(FuriHalPwmOutputIdLptim2PA4)) {
- furi_hal_pwm_start(FuriHalPwmOutputIdLptim2PA4, 4000000, 50);
- }
- FURI_LOG_D(TAG, "Start");
- while(1) {
- uint32_t events =
- furi_thread_flags_wait(AVR_ISP_WORKER_ALL_EVENTS, FuriFlagWaitAny, FuriWaitForever);
- if(events & AvrIspWorkerRWEvtStop) {
- break;
- }
- if(events & AvrIspWorkerRWEvtWritingFuse) {
- if(avr_isp_worker_rw_write_fuse(instance, instance->file_path, instance->file_name)) {
- if(instance->callback_status)
- instance->callback_status(
- instance->context_status, AvrIspWorkerRWStatusEndWritingFuse);
- } else {
- if(instance->callback_status)
- instance->callback_status(
- instance->context_status, AvrIspWorkerRWStatusErrorWritingFuse);
- }
- }
- if(events & AvrIspWorkerRWEvtWriting) {
- if(avr_isp_worker_rw_write_dump(instance, instance->file_path, instance->file_name)) {
- if(instance->callback_status)
- instance->callback_status(
- instance->context_status, AvrIspWorkerRWStatusEndWriting);
- } else {
- if(instance->callback_status)
- instance->callback_status(
- instance->context_status, AvrIspWorkerRWStatusErrorWriting);
- }
- }
- if(events & AvrIspWorkerRWEvtVerification) {
- if(avr_isp_worker_rw_verification(instance, instance->file_path, instance->file_name)) {
- if(instance->callback_status)
- instance->callback_status(
- instance->context_status, AvrIspWorkerRWStatusEndVerification);
- } else {
- if(instance->callback_status)
- instance->callback_status(
- instance->context_status, AvrIspWorkerRWStatusErrorVerification);
- }
- }
- if(events & AvrIspWorkerRWEvtReading) {
- if(avr_isp_worker_rw_read_dump(instance, instance->file_path, instance->file_name)) {
- if(instance->callback_status)
- instance->callback_status(
- instance->context_status, AvrIspWorkerRWStatusEndReading);
- } else {
- if(instance->callback_status)
- instance->callback_status(
- instance->context_status, AvrIspWorkerRWStatusErrorReading);
- }
- }
- }
- FURI_LOG_D(TAG, "Stop");
- if(furi_hal_pwm_is_running(FuriHalPwmOutputIdLptim2PA4)) {
- furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4);
- }
- return 0;
- }
- bool avr_isp_worker_rw_detect_chip(AvrIspWorkerRW* instance) {
- furi_assert(instance);
- FURI_LOG_D(TAG, "Detecting AVR chip");
- instance->chip_detect = false;
- instance->chip_arr_ind = avr_isp_chip_arr_size + 1;
- /* start PWM on &gpio_ext_pa4 */
- bool was_pwm_enabled = false;
- if(!furi_hal_pwm_is_running(FuriHalPwmOutputIdLptim2PA4)) {
- furi_hal_pwm_start(FuriHalPwmOutputIdLptim2PA4, 4000000, 50);
- } else {
- was_pwm_enabled = true;
- }
- do {
- if(!avr_isp_auto_set_spi_speed_start_pmode(instance->avr_isp)) {
- FURI_LOG_E(TAG, "Well, I managed to enter the mod program");
- break;
- }
- instance->signature = avr_isp_read_signature(instance->avr_isp);
- if(instance->signature.vendor != 0x1E) {
- //No detect chip
- } else {
- for(uint32_t ind = 0; ind < avr_isp_chip_arr_size; ind++) {
- if(avr_isp_chip_arr[ind].avrarch != F_AVR8) continue;
- if(avr_isp_chip_arr[ind].sigs[1] == instance->signature.part_family) {
- if(avr_isp_chip_arr[ind].sigs[2] == instance->signature.part_number) {
- FURI_LOG_D(TAG, "Detect AVR chip = \"%s\"", avr_isp_chip_arr[ind].name);
- FURI_LOG_D(
- TAG,
- "Signature = 0x%02X 0x%02X 0x%02X",
- instance->signature.vendor,
- instance->signature.part_family,
- instance->signature.part_number);
- switch(avr_isp_chip_arr[ind].nfuses) {
- case 1:
- instance->lfuse = avr_isp_read_fuse_low(instance->avr_isp);
- FURI_LOG_D(TAG, "Lfuse = %02X", instance->lfuse);
- break;
- case 2:
- instance->lfuse = avr_isp_read_fuse_low(instance->avr_isp);
- instance->hfuse = avr_isp_read_fuse_high(instance->avr_isp);
- FURI_LOG_D(
- TAG, "Lfuse = %02X Hfuse = %02X", instance->lfuse, instance->hfuse);
- break;
- case 3:
- instance->lfuse = avr_isp_read_fuse_low(instance->avr_isp);
- instance->hfuse = avr_isp_read_fuse_high(instance->avr_isp);
- instance->efuse = avr_isp_read_fuse_extended(instance->avr_isp);
- FURI_LOG_D(
- TAG,
- "Lfuse = %02X Hfuse = %02X Efuse = %02X",
- instance->lfuse,
- instance->hfuse,
- instance->efuse);
- break;
- default:
- break;
- }
- if(avr_isp_chip_arr[ind].nlocks == 1) {
- instance->lock = avr_isp_read_lock_byte(instance->avr_isp);
- FURI_LOG_D(TAG, "Lock = %02X", instance->lock);
- }
- instance->chip_detect = true;
- instance->chip_arr_ind = ind;
- break;
- }
- }
- }
- }
- avr_isp_end_pmode(instance->avr_isp);
- } while(0);
- if(furi_hal_pwm_is_running(FuriHalPwmOutputIdLptim2PA4) && !was_pwm_enabled) {
- furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4);
- }
- if(instance->callback) {
- if(instance->chip_arr_ind > avr_isp_chip_arr_size) {
- instance->callback(instance->context, "No detect", instance->chip_detect, 0);
- } else if(instance->chip_arr_ind < avr_isp_chip_arr_size) {
- instance->callback(
- instance->context,
- avr_isp_chip_arr[instance->chip_arr_ind].name,
- instance->chip_detect,
- avr_isp_chip_arr[instance->chip_arr_ind].flashsize);
- } else {
- instance->callback(instance->context, "Unknown", instance->chip_detect, 0);
- }
- }
- return instance->chip_detect;
- }
- AvrIspWorkerRW* avr_isp_worker_rw_alloc(void* context) {
- furi_assert(context);
- UNUSED(context);
- AvrIspWorkerRW* instance = malloc(sizeof(AvrIspWorkerRW));
- instance->avr_isp = avr_isp_alloc();
- instance->thread =
- furi_thread_alloc_ex("AvrIspWorkerRW", 4096, avr_isp_worker_rw_thread, instance);
- instance->chip_detect = false;
- instance->lfuse = 0;
- instance->hfuse = 0;
- instance->efuse = 0;
- instance->lock = 0;
- instance->progress_flash = 0.0f;
- instance->progress_eeprom = 0.0f;
- return instance;
- }
- void avr_isp_worker_rw_free(AvrIspWorkerRW* instance) {
- furi_assert(instance);
- avr_isp_free(instance->avr_isp);
- furi_check(!instance->worker_running);
- furi_thread_free(instance->thread);
- free(instance);
- }
- void avr_isp_worker_rw_start(AvrIspWorkerRW* instance) {
- furi_assert(instance);
- furi_assert(!instance->worker_running);
- instance->worker_running = true;
- furi_thread_start(instance->thread);
- }
- void avr_isp_worker_rw_stop(AvrIspWorkerRW* instance) {
- furi_assert(instance);
- furi_assert(instance->worker_running);
- instance->worker_running = false;
- furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerRWEvtStop);
- furi_thread_join(instance->thread);
- }
- bool avr_isp_worker_rw_is_running(AvrIspWorkerRW* instance) {
- furi_assert(instance);
- return instance->worker_running;
- }
- void avr_isp_worker_rw_set_callback(
- AvrIspWorkerRW* instance,
- AvrIspWorkerRWCallback callback,
- void* context) {
- furi_assert(instance);
- instance->callback = callback;
- instance->context = context;
- }
- void avr_isp_worker_rw_set_callback_status(
- AvrIspWorkerRW* instance,
- AvrIspWorkerRWStatusCallback callback_status,
- void* context_status) {
- furi_assert(instance);
- instance->callback_status = callback_status;
- instance->context_status = context_status;
- }
- float avr_isp_worker_rw_get_progress_flash(AvrIspWorkerRW* instance) {
- furi_assert(instance);
- return instance->progress_flash;
- }
- float avr_isp_worker_rw_get_progress_eeprom(AvrIspWorkerRW* instance) {
- furi_assert(instance);
- return instance->progress_eeprom;
- }
- static void avr_isp_worker_rw_get_dump_flash(AvrIspWorkerRW* instance, const char* file_path) {
- furi_assert(instance);
- furi_check(instance->avr_isp);
- FURI_LOG_D(TAG, "Dump FLASH %s", file_path);
- FlipperI32HexFile* flipper_hex_flash = flipper_i32hex_file_open_write(
- file_path, avr_isp_chip_arr[instance->chip_arr_ind].flashoffset);
- uint8_t data[272] = {0};
- bool send_extended_addr = ((avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2) > 0x10000);
- uint8_t extended_addr = 0;
- for(int32_t i = avr_isp_chip_arr[instance->chip_arr_ind].flashoffset;
- i < avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2;
- i += avr_isp_chip_arr[instance->chip_arr_ind].pagesize / 2) {
- if(send_extended_addr) {
- if(extended_addr <= ((i >> 16) & 0xFF)) {
- avr_isp_write_extended_addr(instance->avr_isp, extended_addr);
- extended_addr = ((i >> 16) & 0xFF) + 1;
- }
- }
- avr_isp_read_page(
- instance->avr_isp,
- STK_SET_FLASH_TYPE,
- (uint16_t)i,
- avr_isp_chip_arr[instance->chip_arr_ind].pagesize,
- data,
- sizeof(data));
- flipper_i32hex_file_bin_to_i32hex_set_data(
- flipper_hex_flash, data, avr_isp_chip_arr[instance->chip_arr_ind].pagesize);
- FURI_LOG_D(TAG, "%s", flipper_i32hex_file_get_string(flipper_hex_flash));
- instance->progress_flash =
- (float)(i) / ((float)avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2.0f);
- }
- flipper_i32hex_file_bin_to_i32hex_set_end_line(flipper_hex_flash);
- FURI_LOG_D(TAG, "%s", flipper_i32hex_file_get_string(flipper_hex_flash));
- flipper_i32hex_file_close(flipper_hex_flash);
- instance->progress_flash = 1.0f;
- }
- static void avr_isp_worker_rw_get_dump_eeprom(AvrIspWorkerRW* instance, const char* file_path) {
- furi_assert(instance);
- furi_check(instance->avr_isp);
- FURI_LOG_D(TAG, "Dump EEPROM %s", file_path);
- FlipperI32HexFile* flipper_hex_eeprom = flipper_i32hex_file_open_write(
- file_path, avr_isp_chip_arr[instance->chip_arr_ind].eepromoffset);
- int32_t size_data = 32;
- uint8_t data[256] = {0};
- if(size_data > avr_isp_chip_arr[instance->chip_arr_ind].eepromsize)
- size_data = avr_isp_chip_arr[instance->chip_arr_ind].eepromsize;
- for(int32_t i = avr_isp_chip_arr[instance->chip_arr_ind].eepromoffset;
- i < avr_isp_chip_arr[instance->chip_arr_ind].eepromsize;
- i += size_data) {
- avr_isp_read_page(
- instance->avr_isp, STK_SET_EEPROM_TYPE, (uint16_t)i, size_data, data, sizeof(data));
- flipper_i32hex_file_bin_to_i32hex_set_data(flipper_hex_eeprom, data, size_data);
- FURI_LOG_D(TAG, "%s", flipper_i32hex_file_get_string(flipper_hex_eeprom));
- instance->progress_eeprom =
- (float)(i) / ((float)avr_isp_chip_arr[instance->chip_arr_ind].eepromsize);
- }
- flipper_i32hex_file_bin_to_i32hex_set_end_line(flipper_hex_eeprom);
- FURI_LOG_D(TAG, "%s", flipper_i32hex_file_get_string(flipper_hex_eeprom));
- flipper_i32hex_file_close(flipper_hex_eeprom);
- instance->progress_eeprom = 1.0f;
- }
- bool avr_isp_worker_rw_read_dump(
- AvrIspWorkerRW* instance,
- const char* file_path,
- const char* file_name) {
- furi_assert(instance);
- furi_assert(file_path);
- furi_assert(file_name);
- FURI_LOG_D(TAG, "Read dump chip");
- instance->progress_flash = 0.0f;
- instance->progress_eeprom = 0.0f;
- bool ret = false;
- Storage* storage = furi_record_open(RECORD_STORAGE);
- FlipperFormat* flipper_format = flipper_format_file_alloc(storage);
- FuriString* file_path_name = furi_string_alloc();
- if(!avr_isp_worker_rw_detect_chip(instance)) {
- FURI_LOG_E(TAG, "No detect AVR chip");
- } else {
- do {
- furi_string_printf(
- file_path_name, "%s/%s%s", file_path, file_name, AVR_ISP_APP_EXTENSION);
- if(!flipper_format_file_open_always(
- flipper_format, furi_string_get_cstr(file_path_name))) {
- FURI_LOG_E(TAG, "flipper_format_file_open_always");
- break;
- }
- if(!flipper_format_write_header_cstr(
- flipper_format, AVR_ISP_APP_FILE_TYPE, AVR_ISP_APP_FILE_VERSION)) {
- FURI_LOG_E(TAG, "flipper_format_write_header_cstr");
- break;
- }
- if(!flipper_format_write_string_cstr(
- flipper_format, "Chip name", avr_isp_chip_arr[instance->chip_arr_ind].name)) {
- FURI_LOG_E(TAG, "Chip name");
- break;
- }
- if(!flipper_format_write_hex(
- flipper_format,
- "Signature",
- (uint8_t*)&instance->signature,
- sizeof(AvrIspSignature))) {
- FURI_LOG_E(TAG, "Unable to add Signature");
- break;
- }
- if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 0) {
- if(!flipper_format_write_hex(flipper_format, "Lfuse", &instance->lfuse, 1)) {
- FURI_LOG_E(TAG, "Unable to add Lfuse");
- break;
- }
- }
- if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 1) {
- if(!flipper_format_write_hex(flipper_format, "Hfuse", &instance->hfuse, 1)) {
- FURI_LOG_E(TAG, "Unable to add Hfuse");
- break;
- }
- }
- if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 2) {
- if(!flipper_format_write_hex(flipper_format, "Efuse", &instance->efuse, 1)) {
- FURI_LOG_E(TAG, "Unable to add Efuse");
- break;
- }
- }
- if(avr_isp_chip_arr[instance->chip_arr_ind].nlocks == 1) {
- if(!flipper_format_write_hex(flipper_format, "Lock", &instance->lock, 1)) {
- FURI_LOG_E(TAG, "Unable to add Lock");
- break;
- }
- }
- furi_string_printf(file_path_name, "%s_%s", file_name, NAME_PATERN_FLASH_FILE);
- if(!flipper_format_write_string_cstr(
- flipper_format, "Dump_flash", furi_string_get_cstr(file_path_name))) {
- FURI_LOG_E(TAG, "Unable to add Dump_flash");
- break;
- }
- if(avr_isp_chip_arr[instance->chip_arr_ind].eepromsize > 0) {
- furi_string_printf(file_path_name, "%s_%s", file_name, NAME_PATERN_EEPROM_FILE);
- if(avr_isp_chip_arr[instance->chip_arr_ind].eepromsize > 0) {
- if(!flipper_format_write_string_cstr(
- flipper_format, "Dump_eeprom", furi_string_get_cstr(file_path_name))) {
- FURI_LOG_E(TAG, "Unable to add Dump_eeprom");
- break;
- }
- }
- }
- ret = true;
- } while(false);
- }
- flipper_format_free(flipper_format);
- furi_record_close(RECORD_STORAGE);
- if(ret) {
- if(avr_isp_auto_set_spi_speed_start_pmode(instance->avr_isp)) {
- //Dump flash
- furi_string_printf(
- file_path_name, "%s/%s_%s", file_path, file_name, NAME_PATERN_FLASH_FILE);
- avr_isp_worker_rw_get_dump_flash(instance, furi_string_get_cstr(file_path_name));
- //Dump eeprom
- if(avr_isp_chip_arr[instance->chip_arr_ind].eepromsize > 0) {
- furi_string_printf(
- file_path_name, "%s/%s_%s", file_path, file_name, NAME_PATERN_EEPROM_FILE);
- avr_isp_worker_rw_get_dump_eeprom(instance, furi_string_get_cstr(file_path_name));
- }
- avr_isp_end_pmode(instance->avr_isp);
- }
- }
- furi_string_free(file_path_name);
- return true;
- }
- void avr_isp_worker_rw_read_dump_start(
- AvrIspWorkerRW* instance,
- const char* file_path,
- const char* file_name) {
- furi_assert(instance);
- instance->file_path = file_path;
- instance->file_name = file_name;
- furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerRWEvtReading);
- }
- static bool avr_isp_worker_rw_verification_flash(AvrIspWorkerRW* instance, const char* file_path) {
- furi_assert(instance);
- furi_assert(file_path);
- FURI_LOG_D(TAG, "Verification flash %s", file_path);
- instance->progress_flash = 0.0;
- bool ret = true;
- FlipperI32HexFile* flipper_hex_flash = flipper_i32hex_file_open_read(file_path);
- uint8_t data_read_flash[272] = {0};
- uint8_t data_read_hex[272] = {0};
- uint32_t addr = avr_isp_chip_arr[instance->chip_arr_ind].flashoffset;
- bool send_extended_addr = ((avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2) > 0x10000);
- uint8_t extended_addr = 0;
- FlipperI32HexFileRet flipper_hex_ret = flipper_i32hex_file_i32hex_to_bin_get_data(
- flipper_hex_flash, data_read_hex, sizeof(data_read_hex));
- while(((flipper_hex_ret.status == FlipperI32HexFileStatusData) ||
- (flipper_hex_ret.status == FlipperI32HexFileStatusUdateAddr)) &&
- ret) {
- switch(flipper_hex_ret.status) {
- case FlipperI32HexFileStatusData:
- if(send_extended_addr) {
- if(extended_addr <= ((addr >> 16) & 0xFF)) {
- avr_isp_write_extended_addr(instance->avr_isp, extended_addr);
- extended_addr = ((addr >> 16) & 0xFF) + 1;
- }
- }
- avr_isp_read_page(
- instance->avr_isp,
- STK_SET_FLASH_TYPE,
- (uint16_t)addr,
- flipper_hex_ret.data_size,
- data_read_flash,
- sizeof(data_read_flash));
- if(memcmp(data_read_hex, data_read_flash, flipper_hex_ret.data_size) != 0) {
- ret = false;
- FURI_LOG_E(TAG, "Verification flash error");
- FURI_LOG_E(TAG, "Addr: 0x%04lX", addr);
- for(uint32_t i = 0; i < flipper_hex_ret.data_size; i++) {
- FURI_LOG_RAW_E("%02X ", data_read_hex[i]);
- }
- FURI_LOG_RAW_E("\r\n");
- for(uint32_t i = 0; i < flipper_hex_ret.data_size; i++) {
- FURI_LOG_RAW_E("%02X ", data_read_flash[i]);
- }
- FURI_LOG_RAW_E("\r\n");
- }
- addr += flipper_hex_ret.data_size / 2;
- instance->progress_flash =
- (float)(addr) / ((float)avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2.0f);
- break;
- case FlipperI32HexFileStatusUdateAddr:
- addr = (data_read_hex[0] << 24 | data_read_hex[1] << 16) / 2;
- break;
- default:
- furi_crash(TAG " Incorrect status.");
- break;
- }
- flipper_hex_ret = flipper_i32hex_file_i32hex_to_bin_get_data(
- flipper_hex_flash, data_read_hex, sizeof(data_read_hex));
- }
- flipper_i32hex_file_close(flipper_hex_flash);
- instance->progress_flash = 1.0f;
- return ret;
- }
- static bool
- avr_isp_worker_rw_verification_eeprom(AvrIspWorkerRW* instance, const char* file_path) {
- furi_assert(instance);
- furi_assert(file_path);
- FURI_LOG_D(TAG, "Verification eeprom %s", file_path);
- instance->progress_eeprom = 0.0;
- bool ret = true;
- FlipperI32HexFile* flipper_hex_eeprom = flipper_i32hex_file_open_read(file_path);
- uint8_t data_read_eeprom[272] = {0};
- uint8_t data_read_hex[272] = {0};
- uint32_t addr = avr_isp_chip_arr[instance->chip_arr_ind].eepromoffset;
- FlipperI32HexFileRet flipper_hex_ret = flipper_i32hex_file_i32hex_to_bin_get_data(
- flipper_hex_eeprom, data_read_hex, sizeof(data_read_hex));
- while(((flipper_hex_ret.status == FlipperI32HexFileStatusData) ||
- (flipper_hex_ret.status == FlipperI32HexFileStatusUdateAddr)) &&
- ret) {
- switch(flipper_hex_ret.status) {
- case FlipperI32HexFileStatusData:
- avr_isp_read_page(
- instance->avr_isp,
- STK_SET_EEPROM_TYPE,
- (uint16_t)addr,
- flipper_hex_ret.data_size,
- data_read_eeprom,
- sizeof(data_read_eeprom));
- if(memcmp(data_read_hex, data_read_eeprom, flipper_hex_ret.data_size) != 0) {
- ret = false;
- FURI_LOG_E(TAG, "Verification eeprom error");
- FURI_LOG_E(TAG, "Addr: 0x%04lX", addr);
- for(uint32_t i = 0; i < flipper_hex_ret.data_size; i++) {
- FURI_LOG_RAW_E("%02X ", data_read_hex[i]);
- }
- FURI_LOG_RAW_E("\r\n");
- for(uint32_t i = 0; i < flipper_hex_ret.data_size; i++) {
- FURI_LOG_RAW_E("%02X ", data_read_eeprom[i]);
- }
- FURI_LOG_RAW_E("\r\n");
- }
- addr += flipper_hex_ret.data_size;
- instance->progress_eeprom =
- (float)(addr) / ((float)avr_isp_chip_arr[instance->chip_arr_ind].eepromsize);
- break;
- case FlipperI32HexFileStatusUdateAddr:
- addr = (data_read_hex[0] << 24 | data_read_hex[1] << 16);
- break;
- default:
- furi_crash(TAG " Incorrect status.");
- break;
- }
- flipper_hex_ret = flipper_i32hex_file_i32hex_to_bin_get_data(
- flipper_hex_eeprom, data_read_hex, sizeof(data_read_hex));
- }
- flipper_i32hex_file_close(flipper_hex_eeprom);
- instance->progress_eeprom = 1.0f;
- return ret;
- }
- bool avr_isp_worker_rw_verification(
- AvrIspWorkerRW* instance,
- const char* file_path,
- const char* file_name) {
- furi_assert(instance);
- furi_assert(file_path);
- furi_assert(file_name);
- FURI_LOG_D(TAG, "Verification chip");
- instance->progress_flash = 0.0f;
- instance->progress_eeprom = 0.0f;
- FuriString* file_path_name = furi_string_alloc();
- bool ret = false;
- if(avr_isp_auto_set_spi_speed_start_pmode(instance->avr_isp)) {
- do {
- furi_string_printf(
- file_path_name, "%s/%s_%s", file_path, file_name, NAME_PATERN_FLASH_FILE);
- if(!avr_isp_worker_rw_verification_flash(
- instance, furi_string_get_cstr(file_path_name)))
- break;
- if(avr_isp_chip_arr[instance->chip_arr_ind].eepromsize > 0) {
- furi_string_printf(
- file_path_name, "%s/%s_%s", file_path, file_name, NAME_PATERN_EEPROM_FILE);
- if(!avr_isp_worker_rw_verification_eeprom(
- instance, furi_string_get_cstr(file_path_name)))
- break;
- }
- ret = true;
- } while(false);
- avr_isp_end_pmode(instance->avr_isp);
- furi_string_free(file_path_name);
- }
- return ret;
- }
- void avr_isp_worker_rw_verification_start(
- AvrIspWorkerRW* instance,
- const char* file_path,
- const char* file_name) {
- furi_assert(instance);
- instance->file_path = file_path;
- instance->file_name = file_name;
- furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerRWEvtVerification);
- }
- static void avr_isp_worker_rw_write_flash(AvrIspWorkerRW* instance, const char* file_path) {
- furi_assert(instance);
- furi_check(instance->avr_isp);
- instance->progress_flash = 0.0;
- FURI_LOG_D(TAG, "Write Flash %s", file_path);
- uint8_t data[288] = {0};
- FlipperI32HexFile* flipper_hex_flash = flipper_i32hex_file_open_read(file_path);
- uint32_t addr = avr_isp_chip_arr[instance->chip_arr_ind].flashoffset;
- bool send_extended_addr = ((avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2) > 0x10000);
- uint8_t extended_addr = 0;
- FlipperI32HexFileRet flipper_hex_ret =
- flipper_i32hex_file_i32hex_to_bin_get_data(flipper_hex_flash, data, sizeof(data));
- while((flipper_hex_ret.status == FlipperI32HexFileStatusData) ||
- (flipper_hex_ret.status == FlipperI32HexFileStatusUdateAddr)) {
- switch(flipper_hex_ret.status) {
- case FlipperI32HexFileStatusData:
- if(send_extended_addr) {
- if(extended_addr <= ((addr >> 16) & 0xFF)) {
- avr_isp_write_extended_addr(instance->avr_isp, extended_addr);
- extended_addr = ((addr >> 16) & 0xFF) + 1;
- }
- }
- if(!avr_isp_write_page(
- instance->avr_isp,
- STK_SET_FLASH_TYPE,
- avr_isp_chip_arr[instance->chip_arr_ind].flashsize,
- (uint16_t)addr,
- avr_isp_chip_arr[instance->chip_arr_ind].pagesize,
- data,
- flipper_hex_ret.data_size)) {
- break;
- }
- addr += flipper_hex_ret.data_size / 2;
- instance->progress_flash =
- (float)(addr) / ((float)avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2.0f);
- break;
- case FlipperI32HexFileStatusUdateAddr:
- addr = (data[0] << 24 | data[1] << 16) / 2;
- break;
- default:
- furi_crash(TAG " Incorrect status.");
- break;
- }
- flipper_hex_ret =
- flipper_i32hex_file_i32hex_to_bin_get_data(flipper_hex_flash, data, sizeof(data));
- }
- flipper_i32hex_file_close(flipper_hex_flash);
- instance->progress_flash = 1.0f;
- }
- static void avr_isp_worker_rw_write_eeprom(AvrIspWorkerRW* instance, const char* file_path) {
- furi_assert(instance);
- furi_check(instance->avr_isp);
- instance->progress_eeprom = 0.0;
- uint8_t data[288] = {0};
- FURI_LOG_D(TAG, "Write EEPROM %s", file_path);
- FlipperI32HexFile* flipper_hex_eeprom_read = flipper_i32hex_file_open_read(file_path);
- uint32_t addr = avr_isp_chip_arr[instance->chip_arr_ind].eepromoffset;
- FlipperI32HexFileRet flipper_hex_ret =
- flipper_i32hex_file_i32hex_to_bin_get_data(flipper_hex_eeprom_read, data, sizeof(data));
- while((flipper_hex_ret.status == FlipperI32HexFileStatusData) ||
- (flipper_hex_ret.status == FlipperI32HexFileStatusUdateAddr)) {
- switch(flipper_hex_ret.status) {
- case FlipperI32HexFileStatusData:
- if(!avr_isp_write_page(
- instance->avr_isp,
- STK_SET_EEPROM_TYPE,
- avr_isp_chip_arr[instance->chip_arr_ind].eepromsize,
- (uint16_t)addr,
- avr_isp_chip_arr[instance->chip_arr_ind].eeprompagesize,
- data,
- flipper_hex_ret.data_size)) {
- break;
- }
- addr += flipper_hex_ret.data_size;
- instance->progress_eeprom =
- (float)(addr) / ((float)avr_isp_chip_arr[instance->chip_arr_ind].eepromsize);
- break;
- case FlipperI32HexFileStatusUdateAddr:
- addr = data[0] << 24 | data[1] << 16;
- break;
- default:
- furi_crash(TAG " Incorrect status.");
- break;
- }
- flipper_hex_ret = flipper_i32hex_file_i32hex_to_bin_get_data(
- flipper_hex_eeprom_read, data, sizeof(data));
- }
- flipper_i32hex_file_close(flipper_hex_eeprom_read);
- instance->progress_eeprom = 1.0f;
- }
- bool avr_isp_worker_rw_write_dump(
- AvrIspWorkerRW* instance,
- const char* file_path,
- const char* file_name) {
- furi_assert(instance);
- furi_assert(file_path);
- furi_assert(file_name);
- FURI_LOG_D(TAG, "Write dump chip");
- instance->progress_flash = 0.0f;
- instance->progress_eeprom = 0.0f;
- bool ret = false;
- Storage* storage = furi_record_open(RECORD_STORAGE);
- FlipperFormat* flipper_format = flipper_format_file_alloc(storage);
- FuriString* file_path_name = furi_string_alloc();
- FuriString* temp_str_1 = furi_string_alloc();
- FuriString* temp_str_2 = furi_string_alloc();
- uint32_t temp_data32;
- if(!avr_isp_worker_rw_detect_chip(instance)) {
- FURI_LOG_E(TAG, "No detect AVR chip");
- } else {
- //upload file with description
- do {
- furi_string_printf(
- file_path_name, "%s/%s%s", file_path, file_name, AVR_ISP_APP_EXTENSION);
- if(!flipper_format_file_open_existing(
- flipper_format, furi_string_get_cstr(file_path_name))) {
- FURI_LOG_E(TAG, "Error open file %s", furi_string_get_cstr(file_path_name));
- break;
- }
- if(!flipper_format_read_header(flipper_format, temp_str_1, &temp_data32)) {
- FURI_LOG_E(TAG, "Missing or incorrect header");
- break;
- }
- if((!strcmp(furi_string_get_cstr(temp_str_1), AVR_ISP_APP_FILE_TYPE)) &&
- temp_data32 == AVR_ISP_APP_FILE_VERSION) {
- } else {
- FURI_LOG_E(TAG, "Type or version mismatch");
- break;
- }
- AvrIspSignature sig_read = {0};
- if(!flipper_format_read_hex(
- flipper_format, "Signature", (uint8_t*)&sig_read, sizeof(AvrIspSignature))) {
- FURI_LOG_E(TAG, "Missing Signature");
- break;
- }
- if(memcmp(
- (uint8_t*)&instance->signature, (uint8_t*)&sig_read, sizeof(AvrIspSignature)) !=
- 0) {
- FURI_LOG_E(
- TAG,
- "Wrong chip. Connected (%02X %02X %02X), read from file (%02X %02X %02X)",
- instance->signature.vendor,
- instance->signature.part_family,
- instance->signature.part_number,
- sig_read.vendor,
- sig_read.part_family,
- sig_read.part_number);
- break;
- }
- if(!flipper_format_read_string(flipper_format, "Dump_flash", temp_str_1)) {
- FURI_LOG_E(TAG, "Missing Dump_flash");
- break;
- }
- //may not be
- flipper_format_read_string(flipper_format, "Dump_eeprom", temp_str_2);
- ret = true;
- } while(false);
- }
- flipper_format_free(flipper_format);
- furi_record_close(RECORD_STORAGE);
- if(ret) {
- do {
- //checking .hex files for errors
- furi_string_printf(
- file_path_name, "%s/%s", file_path, furi_string_get_cstr(temp_str_1));
- FURI_LOG_D(TAG, "Check flash file");
- FlipperI32HexFile* flipper_hex_flash_read =
- flipper_i32hex_file_open_read(furi_string_get_cstr(file_path_name));
- if(flipper_i32hex_file_check(flipper_hex_flash_read)) {
- FURI_LOG_D(TAG, "Check flash file: OK");
- } else {
- FURI_LOG_E(TAG, "Check flash file: Error");
- ret = false;
- }
- flipper_i32hex_file_close(flipper_hex_flash_read);
- if(furi_string_size(temp_str_2) > 4) {
- furi_string_printf(
- file_path_name, "%s/%s", file_path, furi_string_get_cstr(temp_str_2));
- FURI_LOG_D(TAG, "Check eeprom file");
- FlipperI32HexFile* flipper_hex_eeprom_read =
- flipper_i32hex_file_open_read(furi_string_get_cstr(file_path_name));
- if(flipper_i32hex_file_check(flipper_hex_eeprom_read)) {
- FURI_LOG_D(TAG, "Check eeprom file: OK");
- } else {
- FURI_LOG_E(TAG, "Check eeprom file: Error");
- ret = false;
- }
- flipper_i32hex_file_close(flipper_hex_eeprom_read);
- }
- if(!ret) break;
- ret = false;
- //erase chip
- FURI_LOG_D(TAG, "Erase chip");
- if(!avr_isp_erase_chip(instance->avr_isp)) {
- FURI_LOG_E(TAG, "Erase chip: Error");
- break;
- }
- if(!avr_isp_auto_set_spi_speed_start_pmode(instance->avr_isp)) {
- FURI_LOG_E(TAG, "Well, I managed to enter the mod program");
- break;
- }
- //write flash
- furi_string_printf(
- file_path_name, "%s/%s", file_path, furi_string_get_cstr(temp_str_1));
- avr_isp_worker_rw_write_flash(instance, furi_string_get_cstr(file_path_name));
- //write eeprom
- if(furi_string_size(temp_str_2) > 4) {
- furi_string_printf(
- file_path_name, "%s/%s", file_path, furi_string_get_cstr(temp_str_2));
- avr_isp_worker_rw_write_eeprom(instance, furi_string_get_cstr(file_path_name));
- }
- ret = true;
- avr_isp_end_pmode(instance->avr_isp);
- } while(false);
- }
- furi_string_free(file_path_name);
- furi_string_free(temp_str_1);
- furi_string_free(temp_str_2);
- return ret;
- }
- void avr_isp_worker_rw_write_dump_start(
- AvrIspWorkerRW* instance,
- const char* file_path,
- const char* file_name) {
- furi_assert(instance);
- instance->file_path = file_path;
- instance->file_name = file_name;
- furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerRWEvtWriting);
- }
- bool avr_isp_worker_rw_write_fuse(
- AvrIspWorkerRW* instance,
- const char* file_path,
- const char* file_name) {
- furi_assert(instance);
- furi_assert(file_path);
- furi_assert(file_name);
- FURI_LOG_D(TAG, "Write fuse chip");
- bool ret = false;
- uint8_t lfuse;
- uint8_t hfuse;
- uint8_t efuse;
- uint8_t lock;
- Storage* storage = furi_record_open(RECORD_STORAGE);
- FlipperFormat* flipper_format = flipper_format_file_alloc(storage);
- FuriString* temp_str = furi_string_alloc();
- uint32_t temp_data32;
- if(!avr_isp_worker_rw_detect_chip(instance)) {
- FURI_LOG_E(TAG, "No detect AVR chip");
- } else {
- //upload file with description
- do {
- furi_string_printf(temp_str, "%s/%s%s", file_path, file_name, AVR_ISP_APP_EXTENSION);
- if(!flipper_format_file_open_existing(flipper_format, furi_string_get_cstr(temp_str))) {
- FURI_LOG_E(TAG, "Error open file %s", furi_string_get_cstr(temp_str));
- break;
- }
- if(!flipper_format_read_header(flipper_format, temp_str, &temp_data32)) {
- FURI_LOG_E(TAG, "Missing or incorrect header");
- break;
- }
- if((!strcmp(furi_string_get_cstr(temp_str), AVR_ISP_APP_FILE_TYPE)) &&
- temp_data32 == AVR_ISP_APP_FILE_VERSION) {
- } else {
- FURI_LOG_E(TAG, "Type or version mismatch");
- break;
- }
- AvrIspSignature sig_read = {0};
- if(!flipper_format_read_hex(
- flipper_format, "Signature", (uint8_t*)&sig_read, sizeof(AvrIspSignature))) {
- FURI_LOG_E(TAG, "Missing Signature");
- break;
- }
- if(memcmp(
- (uint8_t*)&instance->signature, (uint8_t*)&sig_read, sizeof(AvrIspSignature)) !=
- 0) {
- FURI_LOG_E(
- TAG,
- "Wrong chip. Connected (%02X %02X %02X), read from file (%02X %02X %02X)",
- instance->signature.vendor,
- instance->signature.part_family,
- instance->signature.part_number,
- sig_read.vendor,
- sig_read.part_family,
- sig_read.part_number);
- break;
- }
- if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 0) {
- if(!flipper_format_read_hex(flipper_format, "Lfuse", &lfuse, 1)) {
- FURI_LOG_E(TAG, "Missing Lfuse");
- break;
- }
- }
- if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 1) {
- if(!flipper_format_read_hex(flipper_format, "Hfuse", &hfuse, 1)) {
- FURI_LOG_E(TAG, "Missing Hfuse");
- break;
- }
- }
- if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 2) {
- if(!flipper_format_read_hex(flipper_format, "Efuse", &efuse, 1)) {
- FURI_LOG_E(TAG, "Missing Efuse");
- break;
- }
- }
- if(avr_isp_chip_arr[instance->chip_arr_ind].nlocks == 1) {
- if(!flipper_format_read_hex(flipper_format, "Lock", &lock, 1)) {
- FURI_LOG_E(TAG, "Missing Lock");
- break;
- }
- }
- if(!avr_isp_auto_set_spi_speed_start_pmode(instance->avr_isp)) {
- FURI_LOG_E(TAG, "Well, I managed to enter the mod program");
- break;
- }
- ret = true;
- if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 0) {
- if(instance->lfuse != lfuse) {
- if(!avr_isp_write_fuse_low(instance->avr_isp, lfuse)) {
- FURI_LOG_E(TAG, "Write Lfuse: error");
- ret = false;
- }
- }
- }
- if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 1) {
- if(instance->hfuse != hfuse) {
- if(!avr_isp_write_fuse_high(instance->avr_isp, hfuse)) {
- FURI_LOG_E(TAG, "Write Hfuse: error");
- ret = false;
- }
- }
- }
- if(avr_isp_chip_arr[instance->chip_arr_ind].nfuses > 2) {
- if(instance->efuse != efuse) {
- if(!avr_isp_write_fuse_extended(instance->avr_isp, efuse)) {
- FURI_LOG_E(TAG, "Write Efuse: error");
- ret = false;
- }
- }
- }
- if(avr_isp_chip_arr[instance->chip_arr_ind].nlocks == 1) {
- FURI_LOG_D(TAG, "Write lock byte");
- if(instance->lock != lock) {
- if(!avr_isp_write_lock_byte(instance->avr_isp, lock)) {
- FURI_LOG_E(TAG, "Write Lock byte: error");
- ret = false;
- }
- }
- }
- avr_isp_end_pmode(instance->avr_isp);
- } while(false);
- }
- flipper_format_free(flipper_format);
- furi_record_close(RECORD_STORAGE);
- furi_string_free(temp_str);
- return ret;
- }
- void avr_isp_worker_rw_write_fuse_start(
- AvrIspWorkerRW* instance,
- const char* file_path,
- const char* file_name) {
- furi_assert(instance);
- instance->file_path = file_path;
- instance->file_name = file_name;
- furi_thread_flags_set(furi_thread_get_id(instance->thread), AvrIspWorkerRWEvtWritingFuse);
- }
|