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