1 const int CE = A5, OE = 2, WE = 3, 2 CS1 = 4, CS2 = 5, 3 DQ0 = 6, DQ1 = 7, DQ2 = 8, DQ3 = 9, 4 DQ4 = 10, DQ5 = 11, DQ6 = 12, DQ7 = 13; 5 6 const int BUFSIZE = 8; 7 char inbuffer[BUFSIZE]; 8 9 const char ERASE[][8] = { 10 "W5555AA", "W2AAA55", "W555580", "W5555AA", "W2AAA55" 11 }; 12 const char PROGRAM[][8] = { 13 "W5555AA", "W2AAA55", "W5555A0" 14 }; 15 16 int fromHex(char c) 17 { 18 if ((c >= 48) && (c <= 57)) 19 return c - 48; 20 if ((c >= 65) && (c <= 70)) 21 return c - 65 + 10; 22 if ((c >= 97) && (c <= 102)) 23 return c - 97 + 10; 24 return 0; 25 } 26 27 void setDataOut() 28 { 29 pinMode(DQ0, OUTPUT); 30 pinMode(DQ1, OUTPUT); 31 pinMode(DQ2, OUTPUT); 32 pinMode(DQ3, OUTPUT); 33 pinMode(DQ4, OUTPUT); 34 pinMode(DQ5, OUTPUT); 35 pinMode(DQ6, OUTPUT); 36 pinMode(DQ7, OUTPUT); 37 } 38 39 void setDataIn() 40 { 41 pinMode(DQ0, INPUT); 42 pinMode(DQ1, INPUT); 43 pinMode(DQ2, INPUT); 44 pinMode(DQ3, INPUT); 45 pinMode(DQ4, INPUT); 46 pinMode(DQ5, INPUT); 47 pinMode(DQ6, INPUT); 48 pinMode(DQ7, INPUT); 49 } 50 51 int sampleData() 52 { 53 int i = DQ7; 54 int data = 0; 55 56 while (1) 57 { 58 data += digitalRead(i); 59 if (i == DQ0) 60 break; 61 i--; 62 data <<= 1; 63 } 64 65 return data; 66 } 67 68 int readData() 69 { 70 int data = 0; 71 72 setDataIn(); 73 delay(1); 74 data = sampleData(); 75 setDataOut(); 76 return data; 77 } 78 79 void writeData(int data) 80 { 81 int i = DQ0; 82 83 while (1) 84 { 85 digitalWrite(i, data % 2); 86 if (i == DQ7) 87 break; 88 i++; 89 data >>= 1; 90 } 91 } 92 93 void setAddress(int high, int low) 94 { 95 writeData(high); 96 delayMicroseconds(1); 97 digitalWrite(CS2, HIGH); 98 delayMicroseconds(1); 99 digitalWrite(CS2, LOW); 100 writeData(low); 101 delayMicroseconds(1); 102 digitalWrite(CS1, HIGH); 103 delayMicroseconds(1); 104 digitalWrite(CS1, LOW); 105 } 106 107 int readOp(int high, int low) 108 { 109 int data; 110 111 digitalWrite(CE, LOW); 112 setAddress(high, low); 113 delay(1); 114 digitalWrite(OE, LOW); 115 data = readData(); 116 delay(1); 117 digitalWrite(OE, HIGH); 118 digitalWrite(CE, HIGH); 119 120 return data; 121 } 122 123 void writeOp(int high, int low, int data) 124 { 125 digitalWrite(CE, LOW); 126 setAddress(high, low); 127 delay(1); 128 digitalWrite(WE, LOW); 129 writeData(data); 130 delay(1); 131 digitalWrite(WE, HIGH); 132 digitalWrite(CE, HIGH); 133 } 134 135 int readCommand(int nread, const char buffer[]) 136 { 137 int high, low; 138 139 if (nread < 5) 140 return 0; 141 142 high = (fromHex(buffer[1]) << 4) + (fromHex(buffer[2])); 143 low = (fromHex(buffer[3]) << 4) + (fromHex(buffer[4])); 144 145 return readOp(high, low); 146 } 147 148 bool writeCommand(int nread, const char buffer[]) 149 { 150 int high, low, data; 151 152 if (nread < 7) 153 return false; 154 155 high = (fromHex(buffer[1]) << 4) + (fromHex(buffer[2])); 156 low = (fromHex(buffer[3]) << 4) + (fromHex(buffer[4])); 157 data = (fromHex(buffer[5]) << 4) + (fromHex(buffer[6])); 158 159 writeOp(high, low, data); 160 161 return true; 162 } 163 164 bool waitForCompletion(int high, int low, int written) 165 { 166 int data, then = millis(); 167 168 do 169 { 170 delay(10); 171 data = readOp(high, low); 172 } while ( 173 ((data & 0x80) != (written & 0x80)) && 174 ((data & 0x20) == 0) && 175 (millis() - then < 2000) 176 ); 177 178 return readOp(high, low) == written; 179 } 180 181 bool chipErase() 182 { 183 for (int i = 0; i < 5; i++) 184 { 185 writeCommand(7, ERASE[i]); 186 } 187 writeOp(0x55, 0x55, 0x30); 188 return waitForCompletion(0, 0, 0xff); 189 } 190 191 bool sectorErase(int nread, const char buffer[]) 192 { 193 int high; 194 195 if (nread < 2) 196 return false; 197 198 // 3-bit number shifted to A16...A14 with A16 discarded. 199 // Thus, only sectors from 0 to 3 are supported. 200 201 high = (fromHex(buffer[1]) << 6) & 0xff; 202 203 for (int i = 0; i < 5; i++) 204 { 205 writeCommand(7, ERASE[i]); 206 } 207 writeOp(high, 0, 0x30); 208 209 // Result of erase if 0xff written to all locations. 210 211 return waitForCompletion(high, 0, 0xff); 212 } 213 214 bool program(int nread, const char buffer[]) 215 { 216 int high, low, data; 217 218 if (nread < 7) 219 return false; 220 221 high = (fromHex(buffer[1]) << 4) + (fromHex(buffer[2])); 222 low = (fromHex(buffer[3]) << 4) + (fromHex(buffer[4])); 223 data = (fromHex(buffer[5]) << 4) + (fromHex(buffer[6])); 224 225 for (int i = 0; i < 3; i++) 226 { 227 writeCommand(7, PROGRAM[i]); 228 } 229 writeOp(high, low, data); 230 231 return waitForCompletion(high, low, data); 232 } 233 234 void setup() 235 { 236 Serial.begin(115200); 237 pinMode(CE, OUTPUT); 238 pinMode(OE, OUTPUT); 239 pinMode(WE, OUTPUT); 240 pinMode(CS1, OUTPUT); 241 pinMode(CS2, OUTPUT); 242 setDataOut(); 243 244 // Initial state for the flash device. 245 246 digitalWrite(CE, HIGH); 247 digitalWrite(OE, HIGH); 248 digitalWrite(WE, HIGH); 249 250 // Initial state for the latches. 251 252 digitalWrite(CS1, LOW); 253 digitalWrite(CS2, LOW); 254 255 // Interface loop. 256 257 Serial.println("?"); 258 Serial.setTimeout(3600000); // 1 hour 259 } 260 261 void loop() 262 { 263 int nread = 0; 264 265 if (nread = Serial.readBytesUntil('\n', inbuffer, BUFSIZE)) 266 { 267 switch (inbuffer[0]) 268 { 269 case 'R': 270 Serial.println(readCommand(nread, inbuffer), HEX); 271 break; 272 273 case 'W': 274 if (writeCommand(nread, inbuffer)) 275 Serial.println("W"); 276 else 277 Serial.println("C"); 278 break; 279 280 case 'E': 281 if (chipErase()) 282 Serial.println("E"); 283 else 284 Serial.println("C"); 285 break; 286 287 case 'S': 288 if (sectorErase(nread, inbuffer)) 289 Serial.println("S"); 290 else 291 Serial.println("C"); 292 break; 293 294 case 'P': 295 if (program(nread, inbuffer)) 296 Serial.println("P"); 297 else 298 Serial.println("C"); 299 break; 300 301 default: 302 Serial.println("?"); 303 break; 304 } 305 } 306 } 307 308 extern "C" void __cxa_pure_virtual(void) { 309 while(1); 310 } 311 312 // tabstop=4 expandtab shiftwidth=4