mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 05:13:46 -07:00
chg: reading / writing flashmem works better now.
This commit is contained in:
parent
fd52946ef8
commit
a746699f5f
4 changed files with 164 additions and 54 deletions
|
@ -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:
|
||||
|
|
|
@ -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,16 +226,49 @@ 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);
|
||||
|
@ -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");
|
||||
|
||||
|
|
|
@ -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
|
|
@ -461,15 +461,75 @@ char* pb(uint32_t b) {
|
|||
|
||||
int CmdAnalyseA(const char *Cmd){
|
||||
|
||||
UsbCommand c = {CMD_READ_FLASH_MEM, {0,0,0}};
|
||||
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);
|
||||
UsbCommand resp;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
PrintAndLogEx(NORMAL, "-- " _BLUE_(its my message) "\n");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue