chg: reading / writing flashmem works better now.

This commit is contained in:
iceman1001 2018-04-19 00:27:44 +02:00
commit a746699f5f
4 changed files with 164 additions and 54 deletions

View file

@ -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:

View file

@ -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");

View file

@ -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

View file

@ -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");