ArduinoAm29F010

ArduinoAm29F010.cpp

27:dcd08661531d
2015-08-09 Paul Boddie Changed the programmer wiring for better routing in a PCB design.
     1 /*     2 Interfacing the Arduino Duemilanove to Am29F010 devices.     3      4 Copyright (C) 2015 Paul Boddie <paul@boddie.org.uk>     5      6 This program is free software; you can redistribute it and/or modify it under     7 the terms of the GNU General Public License as published by the Free Software     8 Foundation; either version 3 of the License, or (at your option) any later     9 version.    10     11 This program is distributed in the hope that it will be useful, but WITHOUT ANY    12 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A    13 PARTICULAR PURPOSE.  See the GNU General Public License for more details.    14     15 You should have received a copy of the GNU General Public License along    16 with this program.  If not, see <http://www.gnu.org/licenses/>.    17 */    18     19 const int CE = A5, OE = A4, WE = A3,    20           CS1 = 2, CS2 = 3,    21           DQ0 = 7, DQ1 = 6, DQ2 = 5, DQ3 = 4,    22           DQ4 = 8, DQ5 = 9, DQ6 = 10, DQ7 = 11;    23     24 const int BUFSIZE = 8;    25 char inbuffer[BUFSIZE];    26 int nread = 0;    27     28 const char ERASE[][8] = {    29     "W5555AA", "W2AAA55", "W555580", "W5555AA", "W2AAA55"    30     };    31 const char PROGRAM[][8] = {    32     "W5555AA", "W2AAA55", "W5555A0"    33     };    34     35 int fromHex(char c)    36 {    37     if ((c >= 48) && (c <= 57))    38         return c - 48;    39     if ((c >= 65) && (c <= 70))    40         return c - 65 + 10;    41     if ((c >= 97) && (c <= 102))    42         return c - 97 + 10;    43     return 0;    44 }    45     46 void setDataOut()    47 {    48     pinMode(DQ0, OUTPUT);    49     pinMode(DQ1, OUTPUT);    50     pinMode(DQ2, OUTPUT);    51     pinMode(DQ3, OUTPUT);    52     pinMode(DQ4, OUTPUT);    53     pinMode(DQ5, OUTPUT);    54     pinMode(DQ6, OUTPUT);    55     pinMode(DQ7, OUTPUT);    56 }    57     58 void setDataIn()    59 {    60     pinMode(DQ0, INPUT);    61     pinMode(DQ1, INPUT);    62     pinMode(DQ2, INPUT);    63     pinMode(DQ3, INPUT);    64     pinMode(DQ4, INPUT);    65     pinMode(DQ5, INPUT);    66     pinMode(DQ6, INPUT);    67     pinMode(DQ7, INPUT);    68 }    69     70 int sampleData()    71 {    72     int i = DQ7;    73     int data = 0;    74     75     while (1)    76     {    77         data += digitalRead(i);    78         if (i == DQ0)    79             break;    80         i--;    81         data <<= 1;    82     }    83     84     return data;    85 }    86     87 int readData()    88 {    89     int data = 0;    90     91     setDataIn();    92     delay(1);    93     data = sampleData();    94     setDataOut();    95     return data;    96 }    97     98 void writeData(int data)    99 {   100     int i = DQ0;   101    102     while (1)   103     {   104         digitalWrite(i, data % 2);   105         if (i == DQ7)   106             break;   107         i++;   108         data >>= 1;   109     }   110 }   111    112 void setAddress(int high, int low)   113 {   114     writeData(high);   115     delayMicroseconds(1);   116     digitalWrite(CS2, HIGH);   117     delayMicroseconds(1);   118     digitalWrite(CS2, LOW);   119     writeData(low);   120     delayMicroseconds(1);   121     digitalWrite(CS1, HIGH);   122     delayMicroseconds(1);   123     digitalWrite(CS1, LOW);   124 }   125    126 int readOp(int high, int low)   127 {   128     int data;   129    130     digitalWrite(CE, LOW);   131     setAddress(high, low);   132     delay(1);   133     digitalWrite(OE, LOW);   134     data = readData();   135     delay(1);   136     digitalWrite(OE, HIGH);   137     digitalWrite(CE, HIGH);   138    139     return data;   140 }   141    142 void writeOp(int high, int low, int data)   143 {   144     digitalWrite(CE, LOW);   145     setAddress(high, low);   146     delay(1);   147     digitalWrite(WE, LOW);   148     writeData(data);   149     delay(1);   150     digitalWrite(WE, HIGH);   151     digitalWrite(CE, HIGH);   152 }   153    154 int readCommand(const char buffer[])   155 {   156     int high, low;   157    158     high = (fromHex(buffer[1]) << 4) + (fromHex(buffer[2]));   159     low = (fromHex(buffer[3]) << 4) + (fromHex(buffer[4]));   160    161     return readOp(high, low);   162 }   163    164 bool writeCommand(const char buffer[])   165 {   166     int high, low, data;   167    168     high = (fromHex(buffer[1]) << 4) + (fromHex(buffer[2]));   169     low = (fromHex(buffer[3]) << 4) + (fromHex(buffer[4]));   170     data = (fromHex(buffer[5]) << 4) + (fromHex(buffer[6]));   171    172     writeOp(high, low, data);   173    174     return true;   175 }   176    177 bool waitForCompletion(int high, int low, int written)   178 {   179     int data, then = millis();   180    181     setDataIn();   182     digitalWrite(CE, LOW);   183     digitalWrite(OE, LOW);   184    185     do   186     {   187         delay(10);   188         data = sampleData();   189     } while (   190         ((data & 0x80) != (written & 0x80)) &&   191         ((data & 0x20) == 0) &&   192         (millis() - then < 2000)   193         );   194    195     digitalWrite(OE, HIGH);   196     digitalWrite(CE, HIGH);   197     setDataOut();   198     delay(10);   199     return readOp(high, low) == written;   200 }   201    202 bool chipErase()   203 {   204     for (int i = 0; i < 5; i++)   205     {   206         writeCommand(ERASE[i]);   207     }   208     writeOp(0x55, 0x55, 0x30);   209     return waitForCompletion(0, 0, 0xff);   210 }   211    212 bool sectorErase(const char buffer[])   213 {   214     int high;   215    216     // 3-bit number shifted to A16...A14 with A16 discarded.   217     // Thus, only sectors from 0 to 3 are supported.   218    219     high = (fromHex(buffer[1]) << 6) & 0xff;   220    221     for (int i = 0; i < 5; i++)   222     {   223         writeCommand(ERASE[i]);   224     }   225     writeOp(high, 0, 0x30);   226    227     // Result of erase if 0xff written to all locations.   228    229     return waitForCompletion(high, 0, 0xff);   230 }   231    232 bool program(const char buffer[])   233 {   234     int high, low, data;   235    236     high = (fromHex(buffer[1]) << 4) + (fromHex(buffer[2]));   237     low = (fromHex(buffer[3]) << 4) + (fromHex(buffer[4]));   238     data = (fromHex(buffer[5]) << 4) + (fromHex(buffer[6]));   239    240     for (int i = 0; i < 3; i++)   241     {   242         writeCommand(PROGRAM[i]);   243     }   244     writeOp(high, low, data);   245    246     return waitForCompletion(high, low, data);   247 }   248    249 void setup()   250 {   251     Serial.begin(115200);   252     pinMode(CE, OUTPUT);   253     pinMode(OE, OUTPUT);   254     pinMode(WE, OUTPUT);   255     pinMode(CS1, OUTPUT);   256     pinMode(CS2, OUTPUT);   257     setDataOut();   258    259     // Initial state for the flash device.   260    261     digitalWrite(CE, HIGH);   262     digitalWrite(OE, HIGH);   263     digitalWrite(WE, HIGH);   264    265     // Initial state for the latches.   266    267     digitalWrite(CS1, LOW);   268     digitalWrite(CS2, LOW);   269    270     // Interface loop.   271    272     Serial.println("?");   273 }   274    275 void loop()   276 {   277     if (nread += Serial.readBytesUntil('\n', inbuffer + nread, BUFSIZE - nread))   278     {   279         switch (inbuffer[0])   280         {   281             case 'R':   282             if (nread >= 5)   283             {   284                 Serial.println(readCommand(inbuffer), HEX);   285                 nread = 0;   286             }   287             break;   288    289             case 'W':   290             if (nread >= 7)   291             {   292                 if (writeCommand(inbuffer))   293                     Serial.println("W");   294                 else   295                     Serial.println("C");   296                 nread = 0;   297             }   298             break;   299    300             case 'E':   301             if (chipErase())   302                 Serial.println("E");   303             else   304                 Serial.println("C");   305             nread = 0;   306             break;   307    308             case 'S':   309             if (nread >= 2)   310             {   311                 if (sectorErase(inbuffer))   312                     Serial.println("S");   313                 else   314                     Serial.println("C");   315                 nread = 0;   316             }   317             break;   318    319             case 'P':   320             if (nread >= 7)   321             {   322                 if (program(inbuffer))   323                     Serial.println("P");   324                 else   325                     Serial.println("C");   326                 nread = 0;   327             }   328             break;   329    330             default:   331             Serial.println(inbuffer[0]);   332             nread = 0;   333             break;   334         }   335    336         Serial.flush();   337     }   338 }   339    340 extern "C" void __cxa_pure_virtual(void) {   341     while(1);   342 }   343    344 // tabstop=4 expandtab shiftwidth=4