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 setDataIn(); 169 digitalWrite(CE, LOW); 170 digitalWrite(OE, LOW); 171 172 do 173 { 174 delay(10); 175 data = sampleData(); 176 } while ( 177 ((data & 0x80) != (written & 0x80)) && 178 ((data & 0x20) == 0) && 179 (millis() - then < 2000) 180 ); 181 182 digitalWrite(OE, HIGH); 183 digitalWrite(CE, HIGH); 184 setDataOut(); 185 delay(10); 186 return readOp(high, low) == written; 187 } 188 189 bool chipErase() 190 { 191 for (int i = 0; i < 5; i++) 192 { 193 writeCommand(7, ERASE[i]); 194 } 195 writeOp(0x55, 0x55, 0x30); 196 return waitForCompletion(0, 0, 0xff); 197 } 198 199 bool sectorErase(int nread, const char buffer[]) 200 { 201 int high; 202 203 if (nread < 2) 204 return false; 205 206 // 3-bit number shifted to A16...A14 with A16 discarded. 207 // Thus, only sectors from 0 to 3 are supported. 208 209 high = (fromHex(buffer[1]) << 6) & 0xff; 210 211 for (int i = 0; i < 5; i++) 212 { 213 writeCommand(7, ERASE[i]); 214 } 215 writeOp(high, 0, 0x30); 216 217 // Result of erase if 0xff written to all locations. 218 219 return waitForCompletion(high, 0, 0xff); 220 } 221 222 bool program(int nread, const char buffer[]) 223 { 224 int high, low, data; 225 226 if (nread < 7) 227 return false; 228 229 high = (fromHex(buffer[1]) << 4) + (fromHex(buffer[2])); 230 low = (fromHex(buffer[3]) << 4) + (fromHex(buffer[4])); 231 data = (fromHex(buffer[5]) << 4) + (fromHex(buffer[6])); 232 233 for (int i = 0; i < 3; i++) 234 { 235 writeCommand(7, PROGRAM[i]); 236 } 237 writeOp(high, low, data); 238 239 return waitForCompletion(high, low, data); 240 } 241 242 void setup() 243 { 244 Serial.begin(115200); 245 pinMode(CE, OUTPUT); 246 pinMode(OE, OUTPUT); 247 pinMode(WE, OUTPUT); 248 pinMode(CS1, OUTPUT); 249 pinMode(CS2, OUTPUT); 250 setDataOut(); 251 252 // Initial state for the flash device. 253 254 digitalWrite(CE, HIGH); 255 digitalWrite(OE, HIGH); 256 digitalWrite(WE, HIGH); 257 258 // Initial state for the latches. 259 260 digitalWrite(CS1, LOW); 261 digitalWrite(CS2, LOW); 262 263 // Interface loop. 264 265 Serial.println("?"); 266 Serial.setTimeout(3600000); // 1 hour 267 } 268 269 void loop() 270 { 271 int nread = 0; 272 273 if (nread = Serial.readBytesUntil('\n', inbuffer, BUFSIZE)) 274 { 275 switch (inbuffer[0]) 276 { 277 case 'R': 278 Serial.println(readCommand(nread, inbuffer), HEX); 279 break; 280 281 case 'W': 282 if (writeCommand(nread, inbuffer)) 283 Serial.println("W"); 284 else 285 Serial.println("C"); 286 break; 287 288 case 'E': 289 if (chipErase()) 290 Serial.println("E"); 291 else 292 Serial.println("C"); 293 break; 294 295 case 'S': 296 if (sectorErase(nread, inbuffer)) 297 Serial.println("S"); 298 else 299 Serial.println("C"); 300 break; 301 302 case 'P': 303 if (program(nread, inbuffer)) 304 Serial.println("P"); 305 else 306 Serial.println("C"); 307 break; 308 309 default: 310 Serial.println(inbuffer[0]); 311 break; 312 } 313 314 Serial.flush(); 315 } 316 } 317 318 extern "C" void __cxa_pure_virtual(void) { 319 while(1); 320 } 321 322 // tabstop=4 expandtab shiftwidth=4