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 // 3-bit number shifted to A16...A14 with A16 discarded. 221 // Thus, only sectors from 0 to 3 are supported. 222 223 high = (fromHex(buffer[1]) << 6) & 0xff; 224 low = (fromHex(buffer[3]) << 4) + (fromHex(buffer[4])); 225 data = (fromHex(buffer[5]) << 4) + (fromHex(buffer[6])); 226 227 for (int i = 0; i < 3; i++) 228 { 229 writeCommand(7, PROGRAM[i]); 230 } 231 writeOp(high, low, data); 232 233 return waitForCompletion(high, low, data); 234 } 235 236 void setup() 237 { 238 Serial.begin(115200); 239 pinMode(CE, OUTPUT); 240 pinMode(OE, OUTPUT); 241 pinMode(WE, OUTPUT); 242 pinMode(CS1, OUTPUT); 243 pinMode(CS2, OUTPUT); 244 setDataOut(); 245 246 // Initial state for the flash device. 247 248 digitalWrite(CE, HIGH); 249 digitalWrite(OE, HIGH); 250 digitalWrite(WE, HIGH); 251 252 // Initial state for the latches. 253 254 digitalWrite(CS1, LOW); 255 digitalWrite(CS2, LOW); 256 257 // Interface loop. 258 259 Serial.println("?"); 260 Serial.setTimeout(3600000); // 1 hour 261 } 262 263 void loop() 264 { 265 int nread = 0; 266 267 if (nread = Serial.readBytesUntil('\n', inbuffer, BUFSIZE)) 268 { 269 switch (inbuffer[0]) 270 { 271 case 'R': 272 Serial.println(readCommand(nread, inbuffer), HEX); 273 break; 274 275 case 'W': 276 if (writeCommand(nread, inbuffer)) 277 Serial.println("W"); 278 else 279 Serial.println("C"); 280 break; 281 282 case 'E': 283 if (chipErase()) 284 Serial.println("E"); 285 else 286 Serial.println("C"); 287 break; 288 289 case 'S': 290 if (sectorErase(nread, inbuffer)) 291 Serial.println("S"); 292 else 293 Serial.println("C"); 294 break; 295 296 case 'P': 297 if (program(nread, inbuffer)) 298 Serial.println("P"); 299 else 300 Serial.println("C"); 301 break; 302 303 default: 304 Serial.println("?"); 305 break; 306 } 307 } 308 } 309 310 extern "C" void __cxa_pure_virtual(void) { 311 while(1); 312 } 313 314 // tabstop=4 expandtab shiftwidth=4