mirror of
https://github.com/sanni/cartreader.git
synced 2024-11-14 08:55:06 +01:00
V32: Add writing ST M27C322 Eproms (beta)
Needs custom flash adapter with 12V step-up converter modul for VPP. 5V VCC seems to work even though datasheet specifies 6.25V VCC while programming.
This commit is contained in:
parent
8f4e33e20b
commit
45f67ed300
@ -2,8 +2,8 @@
|
||||
Cartridge Reader for Arduino Mega2560
|
||||
|
||||
Author: sanni
|
||||
Date: 2018-04-03
|
||||
Version: V31A
|
||||
Date: 2018-04-04
|
||||
Version: V32
|
||||
|
||||
SD lib: https://github.com/greiman/SdFat
|
||||
LCD lib: https://github.com/adafruit/Adafruit_SSD1306
|
||||
@ -35,7 +35,7 @@
|
||||
infinest - help with GB Memory cart
|
||||
|
||||
**********************************************************************************/
|
||||
char ver[5] = "V31A";
|
||||
char ver[5] = "V32";
|
||||
|
||||
/******************************************
|
||||
Define Starting Point
|
||||
@ -134,6 +134,7 @@ SdFile myFile;
|
||||
#define mode_GBA 9
|
||||
#define mode_GBM 10
|
||||
#define mode_MD 11
|
||||
#define mode_EPROM 12
|
||||
|
||||
/******************************************
|
||||
Variables
|
||||
@ -1286,6 +1287,9 @@ void loop() {
|
||||
else if (mode == mode_FLASH16) {
|
||||
flashromMenu16();
|
||||
}
|
||||
else if (mode == mode_EPROM) {
|
||||
epromMenu();
|
||||
}
|
||||
else if (mode == mode_SFM) {
|
||||
sfmMenu();
|
||||
}
|
||||
|
@ -18,7 +18,8 @@ unsigned long blank;
|
||||
// Flash start menu
|
||||
static const char flashMenuItem1[] PROGMEM = "8bit adapter";
|
||||
static const char flashMenuItem2[] PROGMEM = "16bit adapter";
|
||||
static const char* const menuOptionsFlash[] PROGMEM = {flashMenuItem1, flashMenuItem2};
|
||||
static const char flashMenuItem3[] PROGMEM = "Eprom adapter";
|
||||
static const char* const menuOptionsFlash[] PROGMEM = {flashMenuItem1, flashMenuItem2, flashMenuItem3};
|
||||
|
||||
// 8bit Flash menu items
|
||||
static const char flash8MenuItem1[] PROGMEM = "Blankcheck";
|
||||
@ -40,12 +41,19 @@ static const char flash16MenuItem6[] PROGMEM = "Print";
|
||||
static const char flash16MenuItem7[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsFLASH16[] PROGMEM = {flash16MenuItem1, flash16MenuItem2, flash16MenuItem3, flash16MenuItem4, flash16MenuItem5, flash16MenuItem6, flash16MenuItem7};
|
||||
|
||||
// Eprom menu items
|
||||
static const char epromMenuItem1[] PROGMEM = "Blankcheck";
|
||||
static const char epromMenuItem2[] PROGMEM = "Read 27C322";
|
||||
static const char epromMenuItem3[] PROGMEM = "Write 27C322";
|
||||
static const char epromMenuItem4[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsEprom[] PROGMEM = {epromMenuItem1, epromMenuItem2, epromMenuItem3, epromMenuItem4};
|
||||
|
||||
void flashMenu() {
|
||||
// create menu with title and 2 options to choose from
|
||||
// create menu with title and 3 options to choose from
|
||||
unsigned char flashSlot;
|
||||
// Copy menuOptions out of progmem
|
||||
convertPgm(menuOptionsFlash, 2);
|
||||
flashSlot = question_box("Select flashrom slot", menuOptions, 2, 0);
|
||||
convertPgm(menuOptionsFlash, 3);
|
||||
flashSlot = question_box("Select flashrom slot", menuOptions, 3, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (flashSlot)
|
||||
@ -63,6 +71,13 @@ void flashMenu() {
|
||||
setup_Flash16();
|
||||
mode = mode_FLASH16;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
display_Clear();
|
||||
display_Update();
|
||||
setup_Eprom();
|
||||
mode = mode_EPROM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -290,6 +305,55 @@ void flashromMenu16() {
|
||||
wait();
|
||||
}
|
||||
|
||||
void epromMenu() {
|
||||
// create menu with title "Eprom Writer" and 4 options to choose from
|
||||
unsigned char mainMenu;
|
||||
// Copy menuOptions out of progmem
|
||||
convertPgm(menuOptionsEprom, 4);
|
||||
mainMenu = question_box("Eprom Writer", menuOptions, 4, 0);
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (mainMenu)
|
||||
{
|
||||
case 0:
|
||||
display_Clear();
|
||||
println_Msg(F("Blankcheck"));
|
||||
display_Update();
|
||||
time = millis();
|
||||
blankcheck_Eprom();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
display_Clear();
|
||||
time = millis();
|
||||
read_Eprom();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
filePath[0] = '\0';
|
||||
sd.chdir("/");
|
||||
fileBrowser("Select file");
|
||||
display_Clear();
|
||||
time = millis();
|
||||
write_Eprom();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
time = 0;
|
||||
display_Clear();
|
||||
display_Update();
|
||||
asm volatile (" jmp 0");
|
||||
break;
|
||||
}
|
||||
if (time != 0) {
|
||||
print_Msg(F("Operation took: "));
|
||||
print_Msg((millis() - time) / 1000, DEC);
|
||||
println_Msg("s");
|
||||
display_Update();
|
||||
}
|
||||
wait();
|
||||
}
|
||||
|
||||
/******************************************
|
||||
Setup
|
||||
*****************************************/
|
||||
@ -478,6 +542,34 @@ void setup_Flash16() {
|
||||
wait();
|
||||
}
|
||||
|
||||
void setup_Eprom() {
|
||||
// Set Address Pins to Output
|
||||
//A0-A7
|
||||
DDRF = 0xFF;
|
||||
//A8-A15
|
||||
DDRK = 0xFF;
|
||||
//A16-A23
|
||||
DDRL = 0xFF;
|
||||
|
||||
// Set Data Pins (D0-D15) to Input
|
||||
DDRC = 0x00;
|
||||
DDRA = 0x00;
|
||||
// Disable Internal Pullups
|
||||
PORTC = 0x00;
|
||||
PORTA = 0x00;
|
||||
|
||||
// Set Control Pins to Output VPP/OE(PH5) CE(PH6)
|
||||
DDRH |= (1 << 5) | (1 << 6);
|
||||
|
||||
// Setting CE(PH6) HIGH
|
||||
PORTH |= (1 << 6);
|
||||
// Setting VPP/OE(PH5) LOW
|
||||
PORTH &= ~(1 << 5);
|
||||
|
||||
// 27C322 is a 4MB eprom
|
||||
flashSize = 4194304;
|
||||
}
|
||||
|
||||
/******************************************
|
||||
I/O Functions
|
||||
*****************************************/
|
||||
@ -1534,6 +1626,202 @@ void writeFlash16_29LV640() {
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************
|
||||
Eprom functions
|
||||
*****************************************/
|
||||
void writeWord_Eprom(unsigned long myAddress, word myData) {
|
||||
// Data out
|
||||
DDRC = 0xFF;
|
||||
DDRA = 0xFF;
|
||||
// Set address
|
||||
PORTF = myAddress & 0xFF;
|
||||
PORTK = (myAddress >> 8) & 0xFF;
|
||||
PORTL = (myAddress >> 16) & 0xFF;
|
||||
// Set data
|
||||
PORTC = myData;
|
||||
PORTA = (myData >> 8) & 0xFF;
|
||||
|
||||
// Arduino running at 16Mhz -> one nop = 62.5ns
|
||||
// Wait till output is stable
|
||||
__asm__("nop\n\t");
|
||||
|
||||
// Switch VPP/OE(PH5) to HIGH
|
||||
PORTH |= (1 << 5);
|
||||
// Setting CE(PH6) LOW
|
||||
PORTH &= ~(1 << 6);
|
||||
|
||||
// Leave VPP HIGH for a 50us programming pulse
|
||||
delayMicroseconds(50);
|
||||
|
||||
// Setting CE(PH6) HIGH
|
||||
PORTH |= (1 << 6);
|
||||
// Switch VPP/OE(PH5) to LOW
|
||||
PORTH &= ~(1 << 5);
|
||||
|
||||
// Leave VPP LOW for a little bit
|
||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
||||
}
|
||||
|
||||
word readWord_Eprom(unsigned long myAddress) {
|
||||
// Data in
|
||||
DDRC = 0x00;
|
||||
DDRA = 0x00;
|
||||
// Set address
|
||||
PORTF = myAddress & 0xFF;
|
||||
PORTK = (myAddress >> 8) & 0xFF;
|
||||
PORTL = (myAddress >> 16) & 0xFF;
|
||||
|
||||
// Arduino running at 16Mhz -> one nop = 62.5ns
|
||||
__asm__("nop\n\t");
|
||||
|
||||
// Setting CE(PH6) LOW
|
||||
PORTH &= ~(1 << 6);
|
||||
|
||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
||||
|
||||
// Read
|
||||
word tempWord = ( ( PINA & 0xFF ) << 8 ) | ( PINC & 0xFF );
|
||||
|
||||
__asm__("nop\n\t");
|
||||
|
||||
// Setting CE(PH6) HIGH
|
||||
PORTH |= (1 << 6);
|
||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
||||
|
||||
return tempWord;
|
||||
}
|
||||
|
||||
void blankcheck_Eprom() {
|
||||
|
||||
println_Msg(F("Please wait..."));
|
||||
display_Update();
|
||||
|
||||
blank = 1;
|
||||
for (unsigned long currWord = 0; currWord < flashSize / 2; currWord++) {
|
||||
if (readWord_Eprom(currWord) != 0xFFFF) {
|
||||
currWord = flashSize / 2;
|
||||
blank = 0;
|
||||
}
|
||||
}
|
||||
if (blank) {
|
||||
println_Msg(F("Flashrom is empty."));
|
||||
display_Update();
|
||||
}
|
||||
else {
|
||||
print_Error(F("Error: Not blank"), false);
|
||||
}
|
||||
}
|
||||
|
||||
void read_Eprom() {
|
||||
// Reset to root directory
|
||||
sd.chdir("/");
|
||||
|
||||
// Get name, add extension and convert to char array for sd lib
|
||||
EEPROM_readAnything(10, foldern);
|
||||
sd.mkdir("FLASH", true);
|
||||
sd.chdir("FLASH");
|
||||
sprintf(fileName, "FL%d", foldern);
|
||||
strcat(fileName, ".bin");
|
||||
// write new folder number back to eeprom
|
||||
foldern = foldern + 1;
|
||||
EEPROM_writeAnything(10, foldern);
|
||||
|
||||
display_Clear();
|
||||
print_Msg(F("Saving as "));
|
||||
print_Msg(fileName);
|
||||
println_Msg(F("..."));
|
||||
display_Update();
|
||||
|
||||
// Open file on sd card
|
||||
if (!myFile.open(fileName, O_RDWR | O_CREAT)) {
|
||||
println_Msg(F("Can't create file on SD."));
|
||||
display_Update();
|
||||
while (1);
|
||||
}
|
||||
word d = 0;
|
||||
for (unsigned long currWord = 0; currWord < flashSize / 2; currWord += 256) {
|
||||
for (word c = 0; c < 256; c++) {
|
||||
word myWord = readWord_Eprom(currWord + c);
|
||||
// Split word into two bytes
|
||||
// Right
|
||||
sdBuffer[d + 1] = ((myWord >> 8 ) & 0xFF);
|
||||
// Left
|
||||
sdBuffer[d] = (myWord & 0xFF);
|
||||
d += 2;
|
||||
}
|
||||
myFile.write(sdBuffer, 512);
|
||||
d = 0;
|
||||
}
|
||||
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
println_Msg(F("Finished reading."));
|
||||
display_Update();
|
||||
}
|
||||
|
||||
void write_Eprom() {
|
||||
// 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);
|
||||
|
||||
int d = 0;
|
||||
for (unsigned long currWord = 0; currWord < fileSize / 2; currWord += 256) {
|
||||
// Fill SD buffer
|
||||
myFile.read(sdBuffer, 512);
|
||||
|
||||
// Blink led
|
||||
if (currWord % 2048 == 0)
|
||||
PORTB ^= (1 << 4);
|
||||
|
||||
// Work through SD buffer
|
||||
for (int c = 0; c < 256; c++) {
|
||||
word myWord = ( ( sdBuffer[d + 1] & 0xFF ) << 8 ) | ( sdBuffer[d] & 0xFF );
|
||||
|
||||
// No need to write word if it's 0xFFFF
|
||||
if (myWord != 0xFFFF) {
|
||||
// Error counter
|
||||
byte n = 0;
|
||||
|
||||
// Presto III allows up to 25 rewrites per word
|
||||
do {
|
||||
// Write word
|
||||
writeWord_Eprom(currWord + c, myWord);
|
||||
// Check for fail
|
||||
if (n == 25) {
|
||||
print_Msg("Program Error 0x");
|
||||
println_Msg(currWord + c, HEX);
|
||||
print_Msg("0x");
|
||||
print_Msg(readWord_Eprom(currWord + c), HEX);
|
||||
print_Msg(" != 0x");
|
||||
println_Msg(myWord, HEX);
|
||||
print_Error(F("Press button to reset"), true);
|
||||
}
|
||||
n++;
|
||||
}
|
||||
while (readWord_Eprom(currWord + c) != myWord);
|
||||
}
|
||||
d += 2;
|
||||
}
|
||||
d = 0;
|
||||
}
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
}
|
||||
else {
|
||||
println_Msg(F("Can't open file on SD."));
|
||||
display_Update();
|
||||
}
|
||||
}
|
||||
|
||||
//******************************************
|
||||
// End of File
|
||||
//******************************************
|
||||
|
Loading…
Reference in New Issue
Block a user