#define A0 0 // ADDRESS PIN A0
#define A1 1 // ADDRESS PIN A1
#define A2 2 // ADDRESS PIN A2
#define A3 3 // ADDRESS PIN A3
#define A4 4 // ADDRESS PIN A4
#define A5 5 // ADDRESS PIN A5
#define A6 6 // ADDRESS PIN A6
#define A7 7 // ADDRESS PIN A7
#define A8 8 // ADDRESS PIN A8
#define A9 9 // ADDRESS PIN A9
#define A10 10 // ADDRESS PIN A10
#define A11 11 // ADDRESS PIN A11
#define A12 12 // ADDRESS PIN A12
#define A13 13 // ADDRESS PIN A13
#define A14 14 // ADDRESS PIN A14
#define A15 15 // ADDRESS PIN A15
#define A16 16 // ADDRESS PIN A16
#define A17 17 // ADDRESS PIN A17
#define A18 18 // ADDRESS PIN A18
#define A19 19 // ADDRESS PIN A19
#define D0 20 // DATA PIN DQ0
#define D1 21 // DATA PIN DQ1
#define D2 22 // DATA PIN DQ2
#define D3 23 // DATA PIN DQ3
#define D4 24 // DATA PIN DQ4
#define D5 25 // DATA PIN DQ5
#define D6 26 // DATA PIN DQ6
#define D7 27 // DATA PIN DQ7
#define CE 28 // CHIP ENABLE# PIN
#define OE 29 // OUTPUT ENABLE# PIN
#define WE 30 // WRITE ENABLE# PIN
#define RESET 31 // RESET# PIN
#define RY_BY 32 // READY/BUSY# PIN
#define seconds() (millis()/1000)
unsigned int mfgID = 0;
unsigned int flashID = 0;
//unsigned int *flashrom = (unsigned int *) malloc(1048576);
unsigned char flashrom[262144];
void setup() {
// put your setup code here, to run once:
for (unsigned long i=0; i < 262144; i++)
{
flashrom[i] = 0;
}
//resetChipState();
Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
pinMode(A0, OUTPUT); pinMode(A1, OUTPUT); pinMode(A2, OUTPUT);pinMode(A3, OUTPUT);pinMode(A4, OUTPUT);
pinMode(A5, OUTPUT);pinMode(A6, OUTPUT);pinMode(A7, OUTPUT);pinMode(A8, OUTPUT);pinMode(A9, OUTPUT);
pinMode(A10, OUTPUT);pinMode(A11, OUTPUT);pinMode(A12, OUTPUT);pinMode(A13, OUTPUT);pinMode(A14, OUTPUT);
pinMode(A15, OUTPUT);pinMode(A16, OUTPUT);pinMode(A17, OUTPUT);pinMode(A18, OUTPUT);pinMode(A19, OUTPUT); // SET ALL ADDRESS PINS TO OUTPUT
digitalWrite(0, LOW);digitalWrite(1, LOW);digitalWrite(2, LOW);digitalWrite(3, LOW);
digitalWrite(4, LOW);digitalWrite(5, LOW);digitalWrite(6, LOW);digitalWrite(7, LOW);
digitalWrite(8, LOW);digitalWrite(9, LOW);digitalWrite(10, LOW);digitalWrite(11, LOW);
digitalWrite(12, LOW);digitalWrite(13, LOW);digitalWrite(14, LOW);digitalWrite(15, LOW);
digitalWrite(16, LOW);digitalWrite(17, LOW);digitalWrite(18, LOW);digitalWrite(19, LOW);
pinMode(D0, INPUT);
pinMode(D1, INPUT);
pinMode(D2, INPUT);
pinMode(D3, INPUT);
pinMode(D4, INPUT);
pinMode(D5, INPUT);
pinMode(D6, INPUT);
pinMode(D7, INPUT); // SET ALL DATA PINS AS INPUT INITIALLY, WILL NEED TO CHANGE FOR SENDING COMMAND DATA
pinMode (CE, OUTPUT);
pinMode (OE, OUTPUT);
pinMode (WE, OUTPUT);
pinMode (RESET, OUTPUT);
pinMode (RY_BY, INPUT); // SET CONTROL LINES AS OUTPUTS
digitalWrite(CE, HIGH);
digitalWrite(OE, HIGH);
digitalWrite(WE, HIGH);
digitalWrite(RESET, HIGH);
clearDataLines();
}
int incomingByte = 0;
int runonce = 0;
void loop() {
// put your main code here, to run repeatedly:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
if (runonce == 0){
readID();
Serial.println(mfgID);
Serial.println(flashID);
Serial.println("INCOMINGx262144");
for(unsigned long i = 0; i < 262144; i=i+16) {
for(int k = 0; k < 16; k++)
{
if (flashrom[i] < 16){
Serial.print("0");
}
Serial.print(flashrom[i+k], HEX);
Serial.print(" ");
}
Serial.println("");
}
Serial.println("COMPLETE");
runonce = 1;
}
}
}
void setDataBusToInput(){
pinMode(D0, INPUT);
pinMode(D1, INPUT);
pinMode(D2, INPUT);
pinMode(D3, INPUT);
pinMode(D4, INPUT);
pinMode(D5, INPUT);
pinMode(D6, INPUT);
pinMode(D7, INPUT);
}
void setDataBusToOutput(){
pinMode(D0, OUTPUT);
pinMode(D1, OUTPUT);
pinMode(D2, OUTPUT);
pinMode(D3, OUTPUT);
pinMode(D4, OUTPUT);
pinMode(D5, OUTPUT);
pinMode(D6, OUTPUT);
pinMode(D7, OUTPUT);
}
#define SUCCESS 1;
#define FAIL 0;
void clearAddrLines() {
for(int i = 0; i < 20; i++){
digitalWrite(i, LOW);
}
}
void clearDataLines() {
for(int i = 20; i < 28; i++){
digitalWrite(i, LOW);
}
}
void resetChipState() {
commandWrite(0,0xF0);
}
void readFlashViaSerial() {
Serial.println("INCOMINGx262144");
for(int i = 0; i < 262144; i++) {
Serial.println(readDataByte(i));
}
Serial.println("COMPLETE");
}
void readFlash() {
Serial.println("/debug readFlash");
for(int i = 0; i < 262144; i++) {
flashrom[i] = readDataByte(i);
}
}
void readID() {
commandWrite(0x555, 0xAA);
commandWrite(0x2AA, 0x55);
commandWrite(0x555, 0x90);
mfgID = readDataByte(0);
flashID = readDataByte(1);
//resetChipState();
}
void commandWrite(unsigned int address, unsigned int dataByte) {
setAddrLines(address);
setDataBusToOutput();
setDataLines(dataByte);
digitalWrite(OE, HIGH);
//delayCycle(30); // delay as required between OE and WE
delay(1);
digitalWrite(CE, LOW);
delay(1);
digitalWrite(WE, LOW);
//delayCycle(30); // delay cycle before setting WE back to high
delay(1);
digitalWrite(WE, HIGH);
digitalWrite(CE, HIGH);
//delayCycle(15); // delay to allow flash to program command
delay(1);
}
unsigned int writeDataByte(unsigned int address, unsigned int dataByte) {
commandWrite(0x555, 0xAA);
commandWrite(0x2AA, 0x55);
commandWrite(0x555, 0xA0);
commandWrite(address, dataByte);
return checkWriteSuccess(dataByte);
}
unsigned int readDataByte(unsigned long address){
Serial.println("/debug readDataByte");
unsigned int flashByte = 0;
setAddrLines(address);
setDataBusToInput();
digitalWrite(WE, HIGH);
digitalWrite(CE, LOW);
digitalWrite(OE, LOW);
//delayCycle(60); // delay to allow data lines to be ready with data. Approx 90-100ns (60 cycles)
delay(1);
for(int i = 0; i < 8; i++) {
if ((digitalRead(20+i)) == HIGH) {
flashByte = flashByte | 1U << i; // loop through each data line input and set each bit of flashByte accordingly
}
else{
flashByte = flashByte &~ (1U << i);
}
}
Serial.println("END");
return flashByte;
}
void setDataLines(char data) {
for(int i = 20; i < 28; i++) { // loop through each data byte and set each data output line individually
if ((data >> (i-20)) & 1UL == 1) {
digitalWrite(i, HIGH); // ***** digitalWrite(i+20...) i+20 is an offset into data output lines as data lines mapped to GPIO pins 20-27 *****
}
else{
digitalWrite(i, LOW);
}
}
}
void setAddrLines(unsigned long address) {
for(int i = 0; i < 20; i++) { // loop through each address byte and set each address output line individually
if ((address >> i) & 1UL == 1) {
digitalWrite(i, HIGH); // ***** digitalWrite(i...) only works as address lines are physically mapped 1:1 to equivalent numbered inputs *****
}
else{
digitalWrite(i, LOW);
}
}
}