From a746699f5f27d2c5e3a3e0dafe217acf4b4a4ab3 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 19 Apr 2018 00:27:44 +0200 Subject: [PATCH] chg: reading / writing flashmem works better now. --- armsrc/appmain.c | 45 +++++++++++++++++++++--- armsrc/flashmem.c | 86 +++++++++++++++++++++++++-------------------- armsrc/flashmem.h | 11 ++++-- client/cmdanalyse.c | 76 ++++++++++++++++++++++++++++++++++----- 4 files changed, 164 insertions(+), 54 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index d321b43c1..86291e841 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1081,7 +1081,7 @@ void UsbPacketReceived(uint8_t *packet, int len) { // arg2 = RFU //Dbprintf("transfer to client parameters: %" PRIu32 " | %" PRIu32 " | %" PRIu32, startidx, numofbytes, c->arg[2]); - for(size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) { + for (size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) { len = MIN((numofbytes - i), USB_CMD_DATA_SIZE); isok = cmd_send(CMD_DOWNLOADED_EML_BIGBUF, i, len, 0, mem + startidx + i, len); if (!isok) @@ -1096,11 +1096,48 @@ void UsbPacketReceived(uint8_t *packet, int len) { ReadMem(c->arg[0]); break; #ifdef WITH_FLASH - case CMD_READ_FLASH_MEM: - case CMD_WRITE_FLASH_MEM: + case CMD_READ_FLASH_MEM: { + + LED_B_ON(); + uint16_t isok = 0; + size_t len = 0; + uint32_t startidx = c->arg[0]; + uint16_t numofbytes = c->arg[1]; + + Dbprintf("FlashMem read | %d - %d", startidx, numofbytes); + + uint8_t *mem = BigBuf_malloc(USB_CMD_DATA_SIZE); + + for(size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) { + len = MIN((numofbytes - i), USB_CMD_DATA_SIZE); + + Dbprintf("FlashMem reading | %d | %d | %d", startidx + i, i, len); + + isok = Flash_ReadData(startidx + i, mem, len); + if ( isok == len ) { + print_result("Chunk: ", mem, len); + } else { + Dbprintf("FlashMem reading failed | %d | %d", len, isok); + break; + } + } + // Trigger a finish downloading signal with an ACK frame + cmd_send(CMD_ACK, 1, 0, 0, 0, 0); + LED_B_OFF(); + break; + } + case CMD_WRITE_FLASH_MEM: { + LED_B_ON(); + uint32_t startidx = c->arg[0]; + uint16_t len = c->arg[1]; + uint16_t res = Flash_WriteData(startidx, c->d.asBytes, len); + uint8_t isok = (res == len) ? 1 : 0; + cmd_send(CMD_ACK, isok, 0, 0, 0, 0); + LED_B_OFF(); + break; + } case CMD_UPLOAD_FLASH_MEM: case CMD_DOWNLOAND_FLASH_MEM: - EXFLASH_TEST(); break; #endif case CMD_SET_LF_DIVISOR: diff --git a/armsrc/flashmem.c b/armsrc/flashmem.c index 83bc3d43e..c03eb91a3 100644 --- a/armsrc/flashmem.c +++ b/armsrc/flashmem.c @@ -207,7 +207,12 @@ void Flash_UniqueID(uint8_t *uid) { uid[0] = FlashSendLastByte(0xFF); } -uint8_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) { +uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) { + + if (!FlashInit()) return 0; + + Flash_ReadStat1(); + // length should never be zero if (!len || Flash_CheckBusy(1000)) return 0; @@ -221,17 +226,50 @@ uint8_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) { out[i] = FlashSendByte(0xFF); out[i] = FlashSendLastByte(0xFF); + + FlashStop(); return len; } // Write data -uint8_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) { +uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) { + // length should never be zero - if (!len || Flash_CheckBusy(1000)) return 0; + if (!len) { + Dbprintf("Flash_WriteData len is zero error"); + return 0; + } + + if (!FlashInit()) { + Dbprintf("Flash_WriteData init fail"); + return 0; + } + + Flash_ReadStat1(); + + Flash_WriteEnable(); + + if ( len < 0x1000 ) + Flash_Erase4k(0x00); + else if ( len >= 0x1000 && len < 0x7FFF ) + Flash_Erase32k(0x00); + else + Flash_Erase64k(0x00); + // busy after erasing + if (Flash_CheckBusy(1000)) { + Dbprintf("Flash_WriteData check busy"); + return 0; + } + // 不能跨越 256 字节边界 - if (((address & 255) + len) > 256) return 0; + if (((address & 255) + len) > 256) { + Dbprintf("Flash_WriteData 256 fail"); + return 0; + } + Flash_WriteEnable(); + FlashSendByte(PAGEPROG); FlashSendByte((address >> 16) & 0xFF); FlashSendByte((address >> 8) & 0xFF); @@ -242,6 +280,8 @@ uint8_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) { FlashSendByte(in[i]); FlashSendLastByte(in[i]); + + FlashStop(); return len; } @@ -268,7 +308,7 @@ bool Flash_Erase4k(uint32_t address) { // erase 32K at one time bool Flash_Erase32k(uint32_t address) { if (address & (32*1024 - 1)) { - if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase4k : Address is not align at 4096"); + if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase32k : Address is not align at 4096"); return false; } FlashSendByte(BLOCK32ERASE); @@ -280,9 +320,8 @@ bool Flash_Erase32k(uint32_t address) { // erase 64k at one time bool Flash_Erase64k(uint32_t address) { - if (address & (64*1024 - 1)) { - if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase4k : Address is not align at 4096"); + if ( MF_DBGLEVEL > 1 ) Dbprintf("Flash_Erase64k : Address is not align at 4096"); return false; } FlashSendByte(BLOCK64ERASE); @@ -312,37 +351,6 @@ bool FlashInit(void) { return true; } -void EXFLASH_TEST(void) { - uint8_t data[256] = { 0x00, 0x01, 0x02 }; - uint8_t data2[256] = { 0x00}; - - if (!FlashInit()) return; - - Flash_ReadStat1(); - - Dbprintf("Flash test write: 012 to 0x00 0x01 0x02"); - Flash_WriteEnable(); - Flash_Erase4k(0x00); - if (Flash_CheckBusy(1000)) { - Dbprintf("Flash_Erase4k CheckBusy Error."); - return; - } - - Flash_ReadData(0, data2, 256); - Flash_WriteEnable(); - Flash_WriteData(0x12, data, sizeof(data)); // this will never run, cuz out of 256byte boundary - Flash_WriteData(0x12, data, 3); - - if (Flash_CheckBusy(1000)) { - Dbprintf("Flash_WriteDate CheckBusy Error."); - return; - } - - Flash_ReadData(0, data2, 256); - FlashStop(); -} - - void Flashmem_print_status(void) { DbpString("Flash memory"); @@ -375,5 +383,5 @@ void Flashmem_print_status(void) { uid[3], uid[2], uid[1], uid[0] ); - FlashStop(); + FlashStop(); } \ No newline at end of file diff --git a/armsrc/flashmem.h b/armsrc/flashmem.h index 8c534eda0..7122aea42 100644 --- a/armsrc/flashmem.h +++ b/armsrc/flashmem.h @@ -117,13 +117,18 @@ bool Flash_WaitIdle(void); uint8_t Flash_ReadStat1(void); uint8_t Flash_ReadStat2(void); uint16_t FlashSendByte(uint32_t data); + +void Flash_WriteEnable(); +bool Flash_Erase4k(uint32_t address); +bool Flash_Erase32k(uint32_t address); +bool Flash_Erase64k(uint32_t address); + bool FlashInit(); -void EXFLASH_TEST(void); void Flash_UniqueID(uint8_t *uid); uint8_t Flash_ReadID(void); -uint8_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len); -uint8_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len); +uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len); +uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len); void Flashmem_print_status(void); #endif \ No newline at end of file diff --git a/client/cmdanalyse.c b/client/cmdanalyse.c index 267f3ce48..5f6c4e146 100644 --- a/client/cmdanalyse.c +++ b/client/cmdanalyse.c @@ -461,15 +461,75 @@ char* pb(uint32_t b) { int CmdAnalyseA(const char *Cmd){ - UsbCommand c = {CMD_READ_FLASH_MEM, {0,0,0}}; - clearCommandBuffer(); - SendCommand(&c); - UsbCommand resp; + int hexlen = 0; + uint8_t cmdp = 0; + bool errors = false; + uint32_t startindex = 0, len = 0, cmd = 0; + uint8_t data[USB_CMD_DATA_SIZE] = {0x00}; + + while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { + switch (tolower(param_getchar(Cmd, cmdp))) { + case 'l': + len = param_get32ex(Cmd, cmdp+1, 0, 10); + cmdp += 2; + break; + case 'i': + startindex = param_get32ex(Cmd, cmdp+1, 0, 10); + cmdp += 2; + break; + case 'c': + cmd = param_get8ex(Cmd, cmdp+1, 0, 10); + cmdp += 2; + break; + case 'd': + param_gethex_ex(Cmd, cmdp+1, data, &hexlen); + if ( hexlen != sizeof(data) ) { + PrintAndLogEx(WARNING, "Read %d bytes of %u", hexlen, sizeof(data) ); + } + cmdp += 2; + break; + case 'h': + return usage_analyse_checksum(); + default: + PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); + errors = true; + break; + } + } + //Validations + if (errors || cmdp == 0 ) return usage_analyse_checksum(); + + UsbCommand c, resp; + + switch ( cmd ) { + case 0: + c = (UsbCommand) {CMD_READ_FLASH_MEM, {startindex, len, 0}}; + clearCommandBuffer(); + SendCommand(&c); + if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) { + PrintAndLogEx(NORMAL, "timeout while waiting for reply."); + return 1; + } + break; + case 1: + c = (UsbCommand) {CMD_WRITE_FLASH_MEM, {startindex, len, 0}}; + memcpy(c.d.asBytes, data, len); + clearCommandBuffer(); + SendCommand(&c); + + if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) { + PrintAndLogEx(NORMAL, "timeout while waiting for reply."); + return 1; + } + uint8_t isok = resp.arg[0] & 0xFF; + if (isok) + PrintAndLogEx(SUCCESS, "Flash write ok"); + else + PrintAndLogEx(FAILED, "Flash write ok"); + + break; + } - if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2000) ) { - PrintAndLogEx(NORMAL, "timeout while waiting for reply."); - return 1; - } return 0; PrintAndLogEx(NORMAL, "-- " _BLUE_(its my message) "\n");