V26: Flashrom Programmer Bugfixes

- It seems like flashroms in the 16bit slot like the 29L3211 were accidentally programmed byte swapped up until now and only the 8bit slot worked correctly.
- You can now program files smaller than the flashrom's size without getting a verification error 
- Added the special 29F1601 flashrom taken out of the Nintendo Power SF Memory carts
This commit is contained in:
sanni 2017-06-25 03:03:15 +02:00 committed by GitHub
parent b412ca0615
commit e6d49feb92
3 changed files with 203 additions and 40 deletions

View File

@ -2,8 +2,8 @@
Cartridge Reader for Arduino Mega2560 Cartridge Reader for Arduino Mega2560
Author: sanni Author: sanni
Date: 2017-06-10 Date: 2017-06-25
Version: V25D Version: V26
SD lib: https://github.com/greiman/SdFat SD lib: https://github.com/greiman/SdFat
LCD lib: https://github.com/adafruit/Adafruit_SSD1306 LCD lib: https://github.com/adafruit/Adafruit_SSD1306
@ -34,7 +34,7 @@
YamaArashi - GBA flashrom bank switch command YamaArashi - GBA flashrom bank switch command
**********************************************************************************/ **********************************************************************************/
char ver[5] = "V25D"; char ver[5] = "V26";
/****************************************** /******************************************
Define Output Define Output
@ -190,6 +190,7 @@ byte romVersion = 0;
char cartID[5]; char cartID[5];
unsigned long cartSize; unsigned long cartSize;
char flashid[5]; char flashid[5];
unsigned long fileSize;
// Variable to count errors // Variable to count errors
unsigned long writeErrors; unsigned long writeErrors;

View File

@ -68,8 +68,6 @@ void flashromMenu8() {
} }
else { else {
eraseFlash29F1610(); eraseFlash29F1610();
delay(1000);
busyCheck29F1610();
} }
println_Msg(F("Flashrom erased")); println_Msg(F("Flashrom erased"));
display_Update(); display_Update();
@ -96,21 +94,22 @@ void flashromMenu8() {
time = millis(); time = millis();
if (flashromType == 1) if (flashromType == 1)
writeFlash29F032(); writeFlash29F032();
else if (flashromType == 2) else if (flashromType == 2) {
if (strcmp(flashid, "C2F3") == 0)
writeFlash29F1601();
else
writeFlash29F1610(); writeFlash29F1610();
}
delay(100);
// Reset twice just to be sure // Reset twice just to be sure
delay(1000);
if (flashromType == 1) if (flashromType == 1)
resetFlash29F032(); resetFlash29F032();
else else
resetFlash29F1610(); resetFlash29F1610();
delay(1000);
if (flashromType == 1) if (flashromType == 1)
resetFlash29F032(); resetFlash29F032();
else else
resetFlash29F1610(); resetFlash29F1610();
delay(1000);
verifyFlash(); verifyFlash();
break; break;
@ -150,7 +149,6 @@ void flashromMenu8() {
resetFlash29F032(); resetFlash29F032();
else else
resetFlash29F1610(); resetFlash29F1610();
delay(500);
asm volatile (" jmp 0"); asm volatile (" jmp 0");
break; break;
} }
@ -189,12 +187,10 @@ void flashromMenu16() {
println_Msg(F("Erase Flashrom")); println_Msg(F("Erase Flashrom"));
display_Update(); display_Update();
time = millis(); time = millis();
resetFlash16();
eraseFlash16(); eraseFlash16();
delay(1000);
busyCheck16();
println_Msg(F("Flashrom erased.")); println_Msg(F("Flashrom erased."));
display_Update(); display_Update();
resetFlash16();
break; break;
case 2: case 2:
@ -210,7 +206,12 @@ void flashromMenu16() {
fileBrowser("Select file"); fileBrowser("Select file");
display_Clear(); display_Clear();
time = millis(); time = millis();
if (strcmp(flashid, "C2F3") == 0) {
writeFlash16_29F1601();
}
else {
writeFlash16(); writeFlash16();
}
delay(100); delay(100);
resetFlash16(); resetFlash16();
delay(100); delay(100);
@ -241,7 +242,6 @@ void flashromMenu16() {
display_Clear(); display_Clear();
display_Update(); display_Update();
resetFlash16(); resetFlash16();
delay(500);
asm volatile (" jmp 0"); asm volatile (" jmp 0");
break; break;
} }
@ -296,6 +296,11 @@ idtheflash:
flashSize = 2097152; flashSize = 2097152;
flashromType = 2; flashromType = 2;
} }
else if (strcmp(flashid, "C2F3") == 0) {
println_Msg(F("MX29F1601 detected"));
flashSize = 2097152;
flashromType = 2;
}
else if (strcmp(flashid, "C2F9") == 0) { else if (strcmp(flashid, "C2F9") == 0) {
println_Msg(F("MX29L3211 detected")); println_Msg(F("MX29L3211 detected"));
println_Msg(F("ATTENTION 3.3V")); println_Msg(F("ATTENTION 3.3V"));
@ -359,7 +364,7 @@ void setup_Flash16() {
// Setting CE(PH6) LOW // Setting CE(PH6) LOW
PORTH &= ~(1 << 6); PORTH &= ~(1 << 6);
delay(10); delay(100);
// ID flash // ID flash
idFlash16(); idFlash16();
@ -375,6 +380,11 @@ void setup_Flash16() {
flashSize = 2097152; flashSize = 2097152;
flashromType = 2; flashromType = 2;
} }
else if (strcmp(flashid, "C2F3") == 0) {
println_Msg(F("MX29F1601 detected"));
flashSize = 2097152;
flashromType = 2;
}
else if (strcmp(flashid, "C2F9") == 0) { else if (strcmp(flashid, "C2F9") == 0) {
println_Msg(F("MX29L3211 detected")); println_Msg(F("MX29L3211 detected"));
println_Msg(F("ATTENTION 3.3V")); println_Msg(F("ATTENTION 3.3V"));
@ -522,6 +532,8 @@ void resetFlash29F032() {
// Set data pins to input again // Set data pins to input again
dataIn8(); dataIn8();
delay(500);
} }
void idFlash29F032() { void idFlash29F032() {
@ -578,12 +590,16 @@ void writeFlash29F032() {
// Open file on sd card // Open file on sd card
if (myFile.open(filePath, O_READ)) { if (myFile.open(filePath, O_READ)) {
// Get rom size from file
fileSize = myFile.fileSize();
if (fileSize > flashSize)
print_Error(F("File size exceeds flash size."), true);
// Set data pins to output // Set data pins to output
dataOut(); dataOut();
// Fill sdBuffer // Fill sdBuffer
for (unsigned long currByte = 0; currByte < flashSize; currByte += 512) { for (unsigned long currByte = 0; currByte < fileSize; currByte += 512) {
myFile.read(sdBuffer, 512); myFile.read(sdBuffer, 512);
// Blink led // Blink led
if (currByte % 2048 == 0) if (currByte % 2048 == 0)
@ -644,6 +660,8 @@ void resetFlash29F1610() {
// Set data pins to input again // Set data pins to input again
dataIn8(); dataIn8();
delay(500);
} }
void writeFlash29F1610() { void writeFlash29F1610() {
@ -655,10 +673,15 @@ void writeFlash29F1610() {
// Open file on sd card // Open file on sd card
if (myFile.open(filePath, O_READ)) { if (myFile.open(filePath, O_READ)) {
// Get rom size from file
fileSize = myFile.fileSize();
if (fileSize > flashSize)
print_Error(F("File size exceeds flash size."), true);
// Set data pins to output // Set data pins to output
dataOut(); dataOut();
for (unsigned long currByte = 0; currByte < flashSize; currByte += 128) { for (unsigned long currByte = 0; currByte < fileSize; currByte += 128) {
// Fill sdBuffer with 1 page at a time then write it repeat until all bytes are written // Fill sdBuffer with 1 page at a time then write it repeat until all bytes are written
myFile.read(sdBuffer, 128); myFile.read(sdBuffer, 128);
@ -681,6 +704,69 @@ void writeFlash29F1610() {
} }
} }
// Check if write is complete
busyCheck29F1610();
// Set data pins to input again
dataIn8();
// Close the file:
myFile.close();
}
else {
println_Msg(F("Can't open file on SD"));
display_Update();
}
}
void writeFlash29F1601() {
// Create filepath
sprintf(filePath, "%s/%s", filePath, fileName);
println_Msg(F("Flashing file "));
println_Msg(filePath);
display_Update();
// Open file on sd card
if (myFile.open(filePath, O_READ)) {
// Get rom size from file
fileSize = myFile.fileSize();
if (fileSize > flashSize)
print_Error(F("File size exceeds flash size."), true);
// Set data pins to output
dataOut();
for (unsigned long currByte = 0; currByte < fileSize; currByte += 128) {
// Fill sdBuffer with 1 page at a time then write it repeat until all bytes are written
myFile.read(sdBuffer, 128);
// Blink led
if (currByte % 3072 == 0)
PORTB ^= (1 << 4);
// Check if write is complete
delayMicroseconds(100);
busyCheck29F1610();
// Write command sequence
writeByte_Flash(0x5555 << 1, 0xaa);
writeByte_Flash(0x2aaa << 1, 0x55);
writeByte_Flash(0x5555 << 1, 0xa0);
// Write one full page at a time
for (byte c = 0; c < 128; c++) {
writeByte_Flash(currByte + c, sdBuffer[c]);
if (c == 127) {
// Write the last byte twice or else it won't write at all
writeByte_Flash(currByte + c, sdBuffer[c]);
}
}
}
// Check if write is complete
busyCheck29F1610();
// Set data pins to input again // Set data pins to input again
dataIn8(); dataIn8();
@ -740,6 +826,8 @@ void eraseFlash29F1610() {
// Set data pins to input again // Set data pins to input again
dataIn8(); dataIn8();
busyCheck29F1610();
} }
// Delay between write operations based on status register // Delay between write operations based on status register
@ -783,15 +871,18 @@ void blankcheck_Flash() {
} }
void verifyFlash() { void verifyFlash() {
println_Msg(F("Verifying against")); println_Msg(F("Verifying..."));
println_Msg(filePath);
display_Update(); display_Update();
// Open file on sd card // Open file on sd card
if (myFile.open(filePath, O_READ)) { if (myFile.open(filePath, O_READ)) {
// Get rom size from file
fileSize = myFile.fileSize();
if (fileSize > flashSize)
print_Error(F("File size exceeds flash size."), true);
blank = 0; blank = 0;
for (unsigned long currByte = 0; currByte < flashSize; currByte += 512) { for (unsigned long currByte = 0; currByte < fileSize; currByte += 512) {
//fill sdBuffer //fill sdBuffer
myFile.read(sdBuffer, 512); myFile.read(sdBuffer, 512);
for (int c = 0; c < 512; c++) { for (int c = 0; c < 512; c++) {
@ -887,6 +978,8 @@ void resetFlash16() {
// Set data pins to input again // Set data pins to input again
dataIn16(); dataIn16();
delay(500);
} }
void writeFlash16() { void writeFlash16() {
@ -898,12 +991,17 @@ void writeFlash16() {
// Open file on sd card // Open file on sd card
if (myFile.open(filePath, O_READ)) { if (myFile.open(filePath, O_READ)) {
// Get rom size from file
fileSize = myFile.fileSize();
if (fileSize > flashSize)
print_Error(F("File size exceeds flash size."), true);
// Set data pins to output // Set data pins to output
dataOut16(); dataOut16();
// Fill sdBuffer with 1 page at a time then write it repeat until all bytes are written // Fill sdBuffer with 1 page at a time then write it repeat until all bytes are written
int d = 0; int d = 0;
for (unsigned long currByte = 0; currByte < flashSize / 2; currByte += 64) { for (unsigned long currByte = 0; currByte < fileSize / 2; currByte += 64) {
myFile.read(sdBuffer, 128); myFile.read(sdBuffer, 128);
// Blink led // Blink led
@ -921,13 +1019,80 @@ void writeFlash16() {
// Write one full page at a time // Write one full page at a time
for (byte c = 0; c < 64; c++) { for (byte c = 0; c < 64; c++) {
word currWord = ((sdBuffer[d + 1] << 8) | sdBuffer[d]); word currWord = ( ( sdBuffer[d] & 0xFF ) << 8 ) | ( sdBuffer[d + 1] & 0xFF );
writeWord_Flash(currByte + c, currWord); writeWord_Flash(currByte + c, currWord);
d += 2; d += 2;
} }
d = 0; d = 0;
} }
// Check if write is complete
busyCheck16();
// Set data pins to input again
dataIn16();
// Close the file:
myFile.close();
}
else {
println_Msg(F("Can't open file on SD."));
display_Update();
}
}
void writeFlash16_29F1601() {
// Create filepath
sprintf(filePath, "%s/%s", filePath, fileName);
println_Msg(F("Flashing file "));
println_Msg(filePath);
display_Update();
// Open file on sd card
if (myFile.open(filePath, O_READ)) {
// Get rom size from file
fileSize = myFile.fileSize();
if (fileSize > flashSize)
print_Error(F("File size exceeds flash size."), true);
// Set data pins to output
dataOut16();
// Fill sdBuffer with 1 page at a time then write it repeat until all bytes are written
int d = 0;
for (unsigned long currByte = 0; currByte < fileSize / 2; currByte += 64) {
myFile.read(sdBuffer, 128);
// Blink led
if (currByte % 2048 == 0)
PORTB ^= (1 << 4);
// Check if write is complete
delayMicroseconds(100);
busyCheck16();
// Write command sequence
writeWord_Flash(0x5555, 0xaa);
writeWord_Flash(0x2aaa, 0x55);
writeWord_Flash(0x5555, 0xa0);
// Write one full page at a time
for (byte c = 0; c < 64; c++) {
word currWord = ( ( sdBuffer[d] & 0xFF ) << 8 ) | ( sdBuffer[d + 1] & 0xFF );
writeWord_Flash(currByte + c, currWord);
if (c == 63) {
// Write the last byte twice or else it won't write at all
writeWord_Flash(currByte + c, sdBuffer[d + 1]);
}
d += 2;
}
d = 0;
}
// Check if write is complete
busyCheck16();
// Set data pins to input again // Set data pins to input again
dataIn16(); dataIn16();
@ -987,6 +1152,8 @@ void eraseFlash16() {
// Set data pins to input again // Set data pins to input again
dataIn16(); dataIn16();
busyCheck16();
} }
void blankcheck16() { void blankcheck16() {
@ -1006,29 +1173,30 @@ void blankcheck16() {
display_Update(); display_Update();
} }
else { else {
println_Msg(F("Error: Not blank!")); print_Error(F("Error: Not blank"), false);
display_Update();
} }
} }
void verifyFlash16() { void verifyFlash16() {
println_Msg(F("Verifying..."));
println_Msg(F("Verifying against"));
println_Msg(filePath);
display_Update(); display_Update();
// Open file on sd card // Open file on sd card
if (myFile.open(filePath, O_READ)) { if (myFile.open(filePath, O_READ)) {
// Get rom size from file
fileSize = myFile.fileSize();
if (fileSize > flashSize) {
print_Error(F("File size exceeds flash size."), true);
}
blank = 0; blank = 0;
word d = 0; word d = 0;
for (unsigned long currByte = 0; currByte < flashSize / 2; currByte += 256) { for (unsigned long currByte = 0; currByte < fileSize / 2; currByte += 256) {
//fill sdBuffer //fill sdBuffer
myFile.read(sdBuffer, 512); myFile.read(sdBuffer, 512);
for (int c = 0; c < 256; c++) { for (int c = 0; c < 256; c++) {
word currWord = ((sdBuffer[d] << 8) | sdBuffer[d + 1]); word currWord = ((sdBuffer[d] << 8) | sdBuffer[d + 1]);
// Swap bytes in word
currWord = ((currWord >> 8) & 0x00FF00FF) | ((currWord & 0x00FF00FF) << 8);
if (readWord_Flash(currByte + c) != currWord) { if (readWord_Flash(currByte + c) != currWord) {
blank++; blank++;
} }
@ -1085,8 +1253,6 @@ void readFlash16() {
for (unsigned long currByte = 0; currByte < flashSize / 2; currByte += 256) { for (unsigned long currByte = 0; currByte < flashSize / 2; currByte += 256) {
for (word c = 0; c < 256; c++) { for (word c = 0; c < 256; c++) {
word currWord = readWord_Flash(currByte + c); word currWord = readWord_Flash(currByte + c);
// Swap bytes in word
currWord = ((currWord >> 8) & 0x00FF00FF) | ((currWord & 0x00FF00FF) << 8);
// Split word into two bytes // Split word into two bytes
// Left // Left
sdBuffer[d] = (( currWord >> 8 ) & 0xFF); sdBuffer[d] = (( currWord >> 8 ) & 0xFF);
@ -1118,9 +1284,6 @@ void printFlash16(int numBytes) {
word currWord = readWord_Flash(currByte + c); word currWord = readWord_Flash(currByte + c);
// Swap bytes in word
currWord = ((currWord >> 8) & 0x00FF00FF) | ((currWord & 0x00FF00FF) << 8);
// Split word into two bytes // Split word into two bytes
byte right_byte = currWord & 0xFF; byte right_byte = currWord & 0xFF;
byte left_byte = ( currWord >> 8 ) & 0xFF; byte left_byte = ( currWord >> 8 ) & 0xFF;

View File

@ -38,7 +38,6 @@ String lastbutton = "N/A";
// Rom base address // Rom base address
unsigned long romBase = 0x10000000; unsigned long romBase = 0x10000000;
unsigned long sramBase = 0x08000000; unsigned long sramBase = 0x08000000;
unsigned long fileSize;
// Flashram type // Flashram type
byte flashramType = 1; byte flashramType = 1;