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