ArduinoAm29F010

Changeset

32:c44b58a7fc69
2015-08-24 Paul Boddie raw files shortlog changelog graph Introduced a requirement for 5-digit addresses. Removed the timeout on operations, testing instead the write status, and implementing the algorithm described in the datasheet. Added support for the reset command. Reduced various delays substantially. Added some failure handling to the upload script.
ArduinoAm29F010.cpp (file) README.txt (file) upload.py (file)
     1.1 --- a/ArduinoAm29F010.cpp	Sun Aug 23 20:02:09 2015 +0200
     1.2 +++ b/ArduinoAm29F010.cpp	Mon Aug 24 13:00:39 2015 +0200
     1.3 @@ -26,11 +26,14 @@
     1.4  char inbuffer[BUFSIZE];
     1.5  int nread = 0;
     1.6  
     1.7 -const char ERASE[][8] = {
     1.8 -    "W5555AA", "W2AAA55", "W555580", "W5555AA", "W2AAA55"
     1.9 +const char RESET[][9] = {
    1.10 +    "W05555AA", "W02AAA55", "W05555F0"
    1.11      };
    1.12 -const char PROGRAM[][8] = {
    1.13 -    "W5555AA", "W2AAA55", "W5555A0"
    1.14 +const char ERASE[][9] = {
    1.15 +    "W05555AA", "W02AAA55", "W0555580", "W05555AA", "W02AAA55"
    1.16 +    };
    1.17 +const char PROGRAM[][9] = {
    1.18 +    "W05555AA", "W02AAA55", "W05555A0"
    1.19      };
    1.20  
    1.21  int fromHex(char c)
    1.22 @@ -88,7 +91,7 @@
    1.23      int data = 0;
    1.24  
    1.25      setDataIn();
    1.26 -    delay(1);
    1.27 +    delayMicroseconds(1);
    1.28      data = sampleData();
    1.29      setDataOut();
    1.30      return data;
    1.31 @@ -100,7 +103,7 @@
    1.32  
    1.33      while (i > 0)
    1.34      {
    1.35 -	i--;
    1.36 +        i--;
    1.37          digitalWrite(datapins[i], data % 2);
    1.38          data >>= 1;
    1.39      }
    1.40 @@ -135,10 +138,10 @@
    1.41  
    1.42      digitalWrite(CE, LOW);
    1.43      setAddress(high, low);
    1.44 -    delay(1);
    1.45 +    delayMicroseconds(1);
    1.46      digitalWrite(OE, LOW);
    1.47      data = readData();
    1.48 -    delay(1);
    1.49 +    delayMicroseconds(1);
    1.50      digitalWrite(OE, HIGH);
    1.51      digitalWrite(CE, HIGH);
    1.52  
    1.53 @@ -149,62 +152,51 @@
    1.54  {
    1.55      digitalWrite(CE, LOW);
    1.56      setAddress(high, low);
    1.57 -    delay(1);
    1.58 +    delayMicroseconds(1);
    1.59      digitalWrite(WE, LOW);
    1.60      writeData(data);
    1.61 -    delay(1);
    1.62 +    delayMicroseconds(1);
    1.63      digitalWrite(WE, HIGH);
    1.64      digitalWrite(CE, HIGH);
    1.65  }
    1.66  
    1.67  int readCommand(const char buffer[], int nread)
    1.68  {
    1.69 -    int high, low, i;
    1.70 +    int high, low;
    1.71  
    1.72 -    if (nread > 5)
    1.73 -    {
    1.74 -        high = fromHex(buffer[1]) << 8;
    1.75 -        i = 2;
    1.76 -    }
    1.77 -    else
    1.78 -    {
    1.79 -        high = 0;
    1.80 -        i = 1;
    1.81 -    }
    1.82 -
    1.83 -    high |= (fromHex(buffer[i]) << 4) + (fromHex(buffer[i+1]));
    1.84 -    low = (fromHex(buffer[i+2]) << 4) + (fromHex(buffer[i+3]));
    1.85 +    high = (fromHex(buffer[1]) << 8) + (fromHex(buffer[2]) << 4) + (fromHex(buffer[3]));
    1.86 +    low = (fromHex(buffer[4]) << 4) + (fromHex(buffer[5]));
    1.87  
    1.88      return readOp(high, low);
    1.89  }
    1.90  
    1.91  bool writeCommand(const char buffer[], int nread)
    1.92  {
    1.93 -    int high, low, data, i;
    1.94 +    int high, low, data;
    1.95  
    1.96 -    if (nread > 7)
    1.97 -    {
    1.98 -        high = fromHex(buffer[1]) << 8;
    1.99 -        i = 2;
   1.100 -    }
   1.101 -    else
   1.102 -    {
   1.103 -        high = 0;
   1.104 -        i = 1;
   1.105 -    }
   1.106 -
   1.107 -    high |= (fromHex(buffer[i]) << 4) + (fromHex(buffer[i+1]));
   1.108 -    low = (fromHex(buffer[i+2]) << 4) + (fromHex(buffer[i+3]));
   1.109 -    data = (fromHex(buffer[i+4]) << 4) + (fromHex(buffer[i+5]));
   1.110 +    high = (fromHex(buffer[1]) << 8) + (fromHex(buffer[2]) << 4) + (fromHex(buffer[3]));
   1.111 +    low = (fromHex(buffer[4]) << 4) + (fromHex(buffer[5]));
   1.112 +    data = (fromHex(buffer[6]) << 4) + (fromHex(buffer[7]));
   1.113  
   1.114      writeOp(high, low, data);
   1.115  
   1.116      return true;
   1.117  }
   1.118  
   1.119 +bool haveCompletion(int data, int written)
   1.120 +{
   1.121 +    return ((data & 0x80) == (written & 0x80));
   1.122 +}
   1.123 +
   1.124 +bool haveFault(int data)
   1.125 +{
   1.126 +    return ((data & 0x20) != 0);
   1.127 +}
   1.128 +
   1.129  bool waitForCompletion(int high, int low, int written)
   1.130  {
   1.131 -    int data, then = millis();
   1.132 +    int data;
   1.133 +    bool match;
   1.134  
   1.135      setDataIn();
   1.136      digitalWrite(CE, LOW);
   1.137 @@ -212,19 +204,28 @@
   1.138  
   1.139      do
   1.140      {
   1.141 -        delay(10);
   1.142 -        data = sampleData();
   1.143 -    } while (
   1.144 -        ((data & 0x80) != (written & 0x80)) &&
   1.145 -        ((data & 0x20) == 0) &&
   1.146 -        (millis() - then < 2000)
   1.147 -        );
   1.148 +        data = readOp(high, low);
   1.149 +        match = haveCompletion(data, written);
   1.150 +    } while (!match && !haveFault(data));
   1.151  
   1.152 +    if (!match)
   1.153 +    {
   1.154 +        data = readOp(high, low);
   1.155 +        match = haveCompletion(data, written);
   1.156 +    }
   1.157 +
   1.158 +    setDataOut();
   1.159      digitalWrite(OE, HIGH);
   1.160      digitalWrite(CE, HIGH);
   1.161 -    setDataOut();
   1.162 -    delay(10);
   1.163 -    return readOp(high, low) == written;
   1.164 +    return match;
   1.165 +}
   1.166 +
   1.167 +bool reset()
   1.168 +{
   1.169 +    for (int i = 0; i < 3; i++)
   1.170 +    {
   1.171 +        writeCommand(RESET[i], 7);
   1.172 +    }
   1.173  }
   1.174  
   1.175  bool chipErase()
   1.176 @@ -259,22 +260,11 @@
   1.177  
   1.178  bool program(const char buffer[], int nread)
   1.179  {
   1.180 -    int high, low, data, i;
   1.181 +    int high, low, data;
   1.182  
   1.183 -    if (nread > 7)
   1.184 -    {
   1.185 -        high = fromHex(buffer[1]) << 8;
   1.186 -        i = 2;
   1.187 -    }
   1.188 -    else
   1.189 -    {
   1.190 -        high = 0;
   1.191 -        i = 1;
   1.192 -    }
   1.193 -
   1.194 -    high |= (fromHex(buffer[i]) << 4) + (fromHex(buffer[i+1]));
   1.195 -    low = (fromHex(buffer[i+2]) << 4) + (fromHex(buffer[i+3]));
   1.196 -    data = (fromHex(buffer[i+4]) << 4) + (fromHex(buffer[i+5]));
   1.197 +    high = (fromHex(buffer[1]) << 8) + (fromHex(buffer[2]) << 4) + (fromHex(buffer[3]));
   1.198 +    low = (fromHex(buffer[4]) << 4) + (fromHex(buffer[5]));
   1.199 +    data = (fromHex(buffer[6]) << 4) + (fromHex(buffer[7]));
   1.200  
   1.201      for (int i = 0; i < 3; i++)
   1.202      {
   1.203 @@ -315,12 +305,22 @@
   1.204  
   1.205  void loop()
   1.206  {
   1.207 +    /* Read bytes, obtaining the number read excluding any newline terminator. */
   1.208 +
   1.209      if (nread += Serial.readBytesUntil('\n', inbuffer + nread, BUFSIZE - nread))
   1.210      {
   1.211 +        /* Handle each command, waiting for the newline. */
   1.212 +
   1.213          switch (inbuffer[0])
   1.214          {
   1.215 +            case 'r':
   1.216 +            reset();
   1.217 +            Serial.println("r");
   1.218 +            nread = 0;
   1.219 +            break;
   1.220 +
   1.221              case 'R':
   1.222 -            if (nread >= 5)
   1.223 +            if (nread >= 6)
   1.224              {
   1.225                  Serial.println(readCommand(inbuffer, nread), HEX);
   1.226                  nread = 0;
   1.227 @@ -328,7 +328,7 @@
   1.228              break;
   1.229  
   1.230              case 'W':
   1.231 -            if (nread >= 7)
   1.232 +            if (nread >= 8)
   1.233              {
   1.234                  if (writeCommand(inbuffer, nread))
   1.235                      Serial.println("W");
   1.236 @@ -358,7 +358,7 @@
   1.237              break;
   1.238  
   1.239              case 'P':
   1.240 -            if (nread >= 7)
   1.241 +            if (nread >= 8)
   1.242              {
   1.243                  if (program(inbuffer, nread))
   1.244                      Serial.println("P");
     2.1 --- a/README.txt	Sun Aug 23 20:02:09 2015 +0200
     2.2 +++ b/README.txt	Mon Aug 24 13:00:39 2015 +0200
     2.3 @@ -43,10 +43,8 @@
     2.4  Issuing read commands permits the testing of addresses in the device:
     2.5  
     2.6          location    sector
     2.7 -R0000   0x0000      0       (the first location in the device)
     2.8 -R00000  0x0000      0       (all 17 address bits indicated)
     2.9 -R7fff   0x7fff      1       (the final location in sector 1)
    2.10 -R07fff  0x7fff      1       (all 17 address bits indicated)
    2.11 +R00000  0x0000      0       (the first location in the device)
    2.12 +R07fff  0x7fff      1       (the final location in sector 1)
    2.13  R10000  0x10000     4       (the first location in sector 4)
    2.14  R1ffff  0x1ffff     7       (the final location in the device)
    2.15  
     3.1 --- a/upload.py	Sun Aug 23 20:02:09 2015 +0200
     3.2 +++ b/upload.py	Mon Aug 24 13:00:39 2015 +0200
     3.3 @@ -86,15 +86,23 @@
     3.4          if not verify_only:
     3.5              writeToPort("P%05x%02x\n" % (addr, value))
     3.6              resp = readFromPort()
     3.7 -            if resp != "P":
     3.8 -                print >>sys.stderr, "Program of location %04x failed: %s" % (addr, resp)
     3.9 -                return False
    3.10 -        else:
    3.11 +            if resp == "P":
    3.12 +                i += 1
    3.13 +                continue
    3.14 +            else:
    3.15 +                closePort()
    3.16 +                openPort()
    3.17 +
    3.18 +        for attempt in "first", "second":
    3.19              writeToPort("R%05x\n" % addr)
    3.20              resp = readFromPort()
    3.21 -            if resp != "%02X" % value and resp != "%X" % value:
    3.22 -                print >>sys.stderr, "Verify of location %04x failed: %s" % (addr, resp)
    3.23 -                return False
    3.24 +            if resp == "%02X" % value or resp == "%X" % value:
    3.25 +                break
    3.26 +            closePort()
    3.27 +            openPort()
    3.28 +        else:
    3.29 +            print >>sys.stderr, "%s of location %05x failed: %s" % (verify_only and "Verify" or "Program", addr, resp)
    3.30 +            return False
    3.31  
    3.32          i += 1
    3.33