Add support for 39F040 to flash programmer

This commit is contained in:
sanni 2024-09-13 15:26:28 +02:00
parent 405b73577a
commit d82ee0432f

View File

@ -36,7 +36,8 @@ static const char* const menuOptionsFLASH8[] PROGMEM = { flashMenuItemBlankcheck
// Flash mode menu // Flash mode menu
static const char modeMenuItem1[] PROGMEM = "CFI Mode"; static const char modeMenuItem1[] PROGMEM = "CFI Mode";
static const char modeMenuItem2[] PROGMEM = "Standard Mode"; static const char modeMenuItem2[] PROGMEM = "Standard Mode";
static const char* const menuOptionsMode[] PROGMEM = { modeMenuItem1, modeMenuItem2, FSTRING_RESET }; static const char modeMenuItem3[] PROGMEM = "PLCC32 to SNES";
static const char* const menuOptionsMode[] PROGMEM = { modeMenuItem1, modeMenuItem2, modeMenuItem3, FSTRING_RESET };
#endif #endif
// Misc flash strings // Misc flash strings
@ -46,9 +47,10 @@ const char PROGMEM ATTENTION_3_3V[] = "ATTENTION 3.3V";
// Flash start menu // Flash start menu
static const char flashMenuItem1[] PROGMEM = "CFI"; static const char flashMenuItem1[] PROGMEM = "CFI";
static const char flashMenuItem2[] PROGMEM = "8bit Flash"; static const char flashMenuItem2[] PROGMEM = "8bit Flash";
static const char flashMenuItem3[] PROGMEM = "Eprom"; static const char flashMenuItem3[] PROGMEM = "PLCC32 to SNES";
static const char flashMenuItem4[] PROGMEM = "16bit Flash"; static const char flashMenuItem4[] PROGMEM = "Eprom";
static const char* const menuOptionsFlash[] PROGMEM = { flashMenuItem1, flashMenuItem2, flashMenuItem3, flashMenuItem4, FSTRING_RESET }; static const char flashMenuItem5[] PROGMEM = "16bit Flash";
static const char* const menuOptionsFlash[] PROGMEM = { flashMenuItem1, flashMenuItem2, flashMenuItem3, flashMenuItem4, flashMenuItem5, FSTRING_RESET };
// 16bit Flash menu items // 16bit Flash menu items
static const char* const menuOptionsFLASH16[] PROGMEM = { flashMenuItemBlankcheck, flashMenuItemErase, flashMenuItemRead, flashMenuItemWrite, flashMenuItemID, flashMenuItemPrint, FSTRING_RESET }; static const char* const menuOptionsFLASH16[] PROGMEM = { flashMenuItemBlankcheck, flashMenuItemErase, flashMenuItemRead, flashMenuItemWrite, flashMenuItemID, flashMenuItemPrint, FSTRING_RESET };
@ -62,11 +64,11 @@ void flashMenu() {
display_Update(); display_Update();
mapping = 0; mapping = 0;
// create menu with title and 5 options to choose from // create menu with title and 6 options to choose from
unsigned char flashSlot; unsigned char flashSlot;
// Copy menuOptions out of progmem // Copy menuOptions out of progmem
convertPgm(menuOptionsFlash, 5); convertPgm(menuOptionsFlash, 6);
flashSlot = question_box(F("Select Mode"), menuOptions, 5, 0); flashSlot = question_box(F("Select Mode"), menuOptions, 6, 0);
// wait for user choice to come back from the question box menu // wait for user choice to come back from the question box menu
switch (flashSlot) { switch (flashSlot) {
@ -89,18 +91,26 @@ void flashMenu() {
break; break;
case 2: case 2:
mapping = 3;
setup_Flash8();
id_Flash8();
wait();
mode = CORE_FLASH8;
break;
case 3:
setup_Eprom(); setup_Eprom();
mode = CORE_EPROM; mode = CORE_EPROM;
break; break;
case 3: case 4:
setup_Flash16(); setup_Flash16();
id_Flash16(); id_Flash16();
wait(); wait();
mode = CORE_FLASH16; mode = CORE_FLASH16;
break; break;
case 4: case 5:
resetArduino(); resetArduino();
break; break;
@ -114,11 +124,11 @@ void flashMenu() {
display_Update(); display_Update();
mapping = 0; mapping = 0;
// create menu with title and 3 options to choose from // create menu with title and 4 options to choose from
unsigned char flashMode; unsigned char flashMode;
// Copy menuOptions out of progmem // Copy menuOptions out of progmem
convertPgm(menuOptionsMode, 3); convertPgm(menuOptionsMode, 4);
flashMode = question_box(F("Select Flash Mode"), menuOptions, 3, 0); flashMode = question_box(F("Select Flash Mode"), menuOptions, 4, 0);
// wait for user choice to come back from the question box menu // wait for user choice to come back from the question box menu
switch (flashMode) { switch (flashMode) {
@ -139,6 +149,21 @@ void flashMenu() {
wait(); wait();
mode = CORE_FLASH8; mode = CORE_FLASH8;
break; break;
case 2:
mapping = 3;
setup_Flash8();
id_Flash8();
wait();
mode = CORE_FLASH8;
break;
case 3:
resetArduino();
break;
default:
print_MissingModule(); // does not return
} }
} }
#endif #endif
@ -647,7 +672,6 @@ idtheflash:
} else if ((flashid == 0x8916) || (flashid == 0x8917) || (flashid == 0x8918)) { } else if ((flashid == 0x8916) || (flashid == 0x8917) || (flashid == 0x8918)) {
// E28FXXXJ3A // E28FXXXJ3A
print_Msg(F("E28F")); print_Msg(F("E28F"));
switch (flashid & 0x00f0) { switch (flashid & 0x00f0) {
case 0x60: case 0x60:
flashSize = 131072 * 32; flashSize = 131072 * 32;
@ -662,11 +686,14 @@ idtheflash:
print_Msg(F("128")); print_Msg(F("128"));
break; break;
} }
println_Msg(F("J3A detected")); println_Msg(F("J3A detected"));
sectorSize = 131072; sectorSize = 131072;
bufferSize = 32; bufferSize = 32;
flashromType = 3; flashromType = 3;
} else if (flashid == 0xBFB7) {
println_Msg(F("39F040 detected"));
flashSize = 524288;
flashromType = 1;
} else if (secondID == 1) { } else if (secondID == 1) {
// Read ID a second time using a different command (type 1 flashrom) // Read ID a second time using a different command (type 1 flashrom)
resetFlash8(); resetFlash8();
@ -676,7 +703,6 @@ idtheflash:
} else if (secondID == 2) { } else if (secondID == 2) {
// Backup first ID read-out // Backup first ID read-out
strncpy(vendorID, flashid_str, 5); strncpy(vendorID, flashid_str, 5);
// Read ID a third time using a different command (type 2 flashrom) // Read ID a third time using a different command (type 2 flashrom)
resetFlash8(); resetFlash8();
idFlash29F1610(); idFlash29F1610();
@ -944,6 +970,37 @@ void writeByte_Flash(unsigned long myAddress, byte myData) {
// A16-A23 // A16-A23
PORTL = (myAddress >> 16) & 0xFF; PORTL = (myAddress >> 16) & 0xFF;
} }
/* SNES maskrom flash adapter combined with PLCC32 adapter
SNES A19 -> 32PLCC A17
SNES A18 -> 32PLCC A16
SNES A17 -> 32PLCC A18
SNES A16 -> 32PLCC OE
SNES CS/Flash OE -> 32PLCC WE
*/
else if (mapping == 3) {
// A8-A15
PORTK = (myAddress >> 8) & 0xFF;
// A16
if (!(((myAddress >> 16) & 0xFF) & 0x1)) {
PORTL &= ~(1 << 2);
} else if (((myAddress >> 16) & 0xFF) & 0x1) {
PORTL |= (1 << 2);
}
// A17
if (!(((myAddress >> 16) & 0xFF) & 0x2)) {
PORTL &= ~(1 << 3);
} else if (((myAddress >> 16) & 0xFF) & 0x2) {
PORTL |= (1 << 3);
}
// A18
if (!(((myAddress >> 16) & 0xFF) & 0x4)) {
PORTL &= ~(1 << 1);
} else if (((myAddress >> 16) & 0xFF) & 0x4) {
PORTL |= (1 << 1);
}
// Switch PLCC32 OE to HIGH to disable output
PORTL |= (1 << 0);
}
// SNES LoRom // SNES LoRom
else if (mapping == 1) { else if (mapping == 1) {
// A8-A14 // A8-A14
@ -1065,6 +1122,10 @@ void writeByte_Flash(unsigned long myAddress, byte myData) {
"nop\n\t" "nop\n\t"
"nop\n\t"); "nop\n\t");
if (mapping == 3)
// Switch PLCC32 WE to LOW
PORTH &= ~(1 << 3);
else
// Switch WE(PH4) WE_SNS(PH5) to LOW // Switch WE(PH4) WE_SNS(PH5) to LOW
PORTH &= ~((1 << 4) | (1 << 5)); PORTH &= ~((1 << 4) | (1 << 5));
@ -1076,6 +1137,10 @@ void writeByte_Flash(unsigned long myAddress, byte myData) {
"nop\n\t" "nop\n\t"
"nop\n\t"); "nop\n\t");
if (mapping == 3)
// Switch PLCC32 WE to HIGH
PORTH |= (1 << 3);
else
// Switch WE(PH4) WE_SNS(PH5) to HIGH // Switch WE(PH4) WE_SNS(PH5) to HIGH
PORTH |= (1 << 4) | (1 << 5); PORTH |= (1 << 4) | (1 << 5);
@ -1099,6 +1164,37 @@ byte readByte_Flash(unsigned long myAddress) {
// A16-A23 // A16-A23
PORTL = (myAddress >> 16) & 0xFF; PORTL = (myAddress >> 16) & 0xFF;
} }
/* SNES maskrom flash adapter combined with PLCC32 adapter
SNES A19 -> 32PLCC A17
SNES A18 -> 32PLCC A16
SNES A17 -> 32PLCC A18
SNES A16 -> 32PLCC OE
SNES CS/Flash OE -> 32PLCC WE
*/
else if (mapping == 3) {
// A8-A15
PORTK = (myAddress >> 8) & 0xFF;
// A16
if (!(((myAddress >> 16) & 0xFF) & 0x1)) {
PORTL &= ~(1 << 2);
} else if (((myAddress >> 16) & 0xFF) & 0x1) {
PORTL |= (1 << 2);
}
// A17
if (!(((myAddress >> 16) & 0xFF) & 0x2)) {
PORTL &= ~(1 << 3);
} else if (((myAddress >> 16) & 0xFF) & 0x2) {
PORTL |= (1 << 3);
}
// A18
if (!(((myAddress >> 16) & 0xFF) & 0x4)) {
PORTL &= ~(1 << 1);
} else if (((myAddress >> 16) & 0xFF) & 0x4) {
PORTL |= (1 << 1);
}
// Switch PLCC32 WE to HIGH to disable writing
PORTH |= (1 << 3);
}
// SNES LoRom // SNES LoRom
else if (mapping == 1) { else if (mapping == 1) {
// A8-A14 // A8-A14
@ -1219,6 +1315,9 @@ byte readByte_Flash(unsigned long myAddress) {
if (byteCtrl) { if (byteCtrl) {
// Setting OE(PH1) LOW // Setting OE(PH1) LOW
PORTH &= ~(1 << 1); PORTH &= ~(1 << 1);
} else if (mapping == 3) {
// Switch PLCC32 OE to LOW
PORTL &= ~(1 << 0);
} else { } else {
// Setting OE(PH1) OE_SNS(PH3) LOW // Setting OE(PH1) OE_SNS(PH3) LOW
PORTH &= ~((1 << 1) | (1 << 3)); PORTH &= ~((1 << 1) | (1 << 3));
@ -1237,6 +1336,9 @@ byte readByte_Flash(unsigned long myAddress) {
if (byteCtrl) { if (byteCtrl) {
// Setting OE(PH1) HIGH // Setting OE(PH1) HIGH
PORTH |= (1 << 1); PORTH |= (1 << 1);
} else if (mapping == 3) {
// Switch PLCC32 OE to HIGH
PORTL |= (1 << 0);
} else { } else {
// Setting OE(PH1) OE_SNS(PH3) HIGH // Setting OE(PH1) OE_SNS(PH3) HIGH
PORTH |= (1 << 1) | (1 << 3); PORTH |= (1 << 1) | (1 << 3);
@ -1374,10 +1476,17 @@ bool openVerifyFlashFile() {
Command functions Command functions
*****************************************/ *****************************************/
void writeByteCommand_Flash(byte command) { void writeByteCommand_Flash(byte command) {
if (mapping == 3) {
//39F040
writeByte_Flash(0x5555, 0xaa);
writeByte_Flash(0x2aaa, 0x55);
writeByte_Flash(0x5555, command);
} else {
writeByte_Flash(0x555, 0xaa); writeByte_Flash(0x555, 0xaa);
writeByte_Flash(0x2aa, 0x55); writeByte_Flash(0x2aa, 0x55);
writeByte_Flash(0x555, command); writeByte_Flash(0x555, command);
} }
}
void writeByteCommandShift_Flash(byte command) { void writeByteCommandShift_Flash(byte command) {
writeByte_Flash(0x5555 << 1, 0xaa); writeByte_Flash(0x5555 << 1, 0xaa);