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 CHIP_ERASE[] = "W5555AA\nW2AAA55\nW555580\nW5555AA\nW2AAA55\nW555510\n"; 10 const char SECTOR_ERASE[] = "W5555AA\nW2AAA55\nW555580\nW5555AA\nW2AAA55\n"; 11 const char PROGRAM[] = "W5555AA\nW2AAA55\nW5555A0\n"; 12 13 int fromHex(char c) 14 { 15 if ((c >= 48) && (c <= 57)) 16 return c - 48; 17 if ((c >= 65) && (c <= 70)) 18 return c - 65 + 10; 19 if ((c >= 97) && (c <= 102)) 20 return c - 97 + 10; 21 return 0; 22 } 23 24 void setDataOut() 25 { 26 pinMode(DQ0, OUTPUT); 27 pinMode(DQ1, OUTPUT); 28 pinMode(DQ2, OUTPUT); 29 pinMode(DQ3, OUTPUT); 30 pinMode(DQ4, OUTPUT); 31 pinMode(DQ5, OUTPUT); 32 pinMode(DQ6, OUTPUT); 33 pinMode(DQ7, OUTPUT); 34 } 35 36 void setDataIn() 37 { 38 pinMode(DQ0, INPUT); 39 pinMode(DQ1, INPUT); 40 pinMode(DQ2, INPUT); 41 pinMode(DQ3, INPUT); 42 pinMode(DQ4, INPUT); 43 pinMode(DQ5, INPUT); 44 pinMode(DQ6, INPUT); 45 pinMode(DQ7, INPUT); 46 } 47 48 int sampleData() 49 { 50 int i = DQ7; 51 int data = 0; 52 53 while (1) 54 { 55 data += digitalRead(i); 56 if (i == DQ0) 57 break; 58 i--; 59 data <<= 1; 60 } 61 62 return data; 63 } 64 65 int readData() 66 { 67 int data = 0; 68 69 setDataIn(); 70 delay(10); 71 data = sampleData(); 72 setDataOut(); 73 return data; 74 } 75 76 void writeData(int data) 77 { 78 int i = DQ0; 79 80 while (1) 81 { 82 digitalWrite(i, data % 2); 83 if (i == DQ7) 84 break; 85 i++; 86 data >>= 1; 87 } 88 } 89 90 void setAddress(int high, int low) 91 { 92 writeData(high); 93 delayMicroseconds(1); 94 digitalWrite(CS2, HIGH); 95 delayMicroseconds(1); 96 digitalWrite(CS2, LOW); 97 writeData(low); 98 delayMicroseconds(1); 99 digitalWrite(CS1, HIGH); 100 delayMicroseconds(1); 101 digitalWrite(CS1, LOW); 102 } 103 104 int readOp(int high, int low) 105 { 106 int data; 107 108 digitalWrite(CE, LOW); 109 setAddress(high, low); 110 delay(10); 111 digitalWrite(OE, LOW); 112 data = readData(); 113 delay(10); 114 digitalWrite(OE, HIGH); 115 digitalWrite(CE, HIGH); 116 117 return data; 118 } 119 120 void writeOp(int high, int low, int data) 121 { 122 digitalWrite(CE, LOW); 123 setAddress(high, low); 124 delay(10); 125 digitalWrite(WE, LOW); 126 writeData(data); 127 delay(10); 128 digitalWrite(WE, HIGH); 129 digitalWrite(CE, HIGH); 130 } 131 132 int readCommand(int nread, const char buffer[]) 133 { 134 int high, low; 135 136 if (nread < 5) 137 return 0; 138 139 high = (fromHex(buffer[1]) << 4) + (fromHex(buffer[2])); 140 low = (fromHex(buffer[3]) << 4) + (fromHex(buffer[4])); 141 142 return readOp(high, low); 143 } 144 145 bool writeCommand(int nread, const char buffer[]) 146 { 147 int high, low, data; 148 149 if (nread < 7) 150 return false; 151 152 high = (fromHex(buffer[1]) << 4) + (fromHex(buffer[2])); 153 low = (fromHex(buffer[3]) << 4) + (fromHex(buffer[4])); 154 data = (fromHex(buffer[5]) << 4) + (fromHex(buffer[6])); 155 156 writeOp(high, low, data); 157 158 return true; 159 } 160 161 bool waitForCompletion(int high, int low, int written) 162 { 163 int data; 164 165 setDataIn(); 166 digitalWrite(CE, LOW); 167 168 do 169 { 170 delay(10); 171 digitalWrite(OE, LOW); 172 delay(10); 173 data = sampleData(); 174 delay(10); 175 digitalWrite(OE, HIGH); 176 Serial.println(data, BIN); 177 } while ( 178 ((data & 0x80) != (written & 0x80)) && 179 ((data & 0x20) == 0) 180 ); 181 182 digitalWrite(CE, HIGH); 183 setDataOut(); 184 185 return ((data & 0x20) == 0); 186 } 187 188 bool chipErase() 189 { 190 writeCommand(sizeof(CHIP_ERASE), CHIP_ERASE); 191 return waitForCompletion(0, 0, 0xff); 192 } 193 194 bool sectorErase(int nread, const char buffer[]) 195 { 196 int high; 197 198 if (nread < 2) 199 return false; 200 201 // 3-bit number shifted to A16...A14 with A16 discarded. 202 // Thus, only sectors from 0 to 3 are supported. 203 204 high = (fromHex(buffer[1]) << 6) & 0xff; 205 206 writeCommand(sizeof(SECTOR_ERASE), SECTOR_ERASE); 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 // 3-bit number shifted to A16...A14 with A16 discarded. 222 // Thus, only sectors from 0 to 3 are supported. 223 224 high = (fromHex(buffer[1]) << 6) & 0xff; 225 low = (fromHex(buffer[3]) << 4) + (fromHex(buffer[4])); 226 data = (fromHex(buffer[5]) << 4) + (fromHex(buffer[6])); 227 228 writeCommand(sizeof(PROGRAM), PROGRAM); 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