The verify after write only reads the amount of data needed now -- so if

you flash a 512 KB file to a 2 MB SIMM, it will only read back 512 KB.

I haven't tested this other change yet, but after a verify, it should now
tell you which chips are returning bad data.

I also fixed a newly-introduced bug which caused the "erasing SIMM" message
to never appear because the code path that caused it to appear wasn't being
reached after my 8 MB SIMM support change.
This commit is contained in:
Doug Brown 2012-09-15 15:16:43 -07:00
parent 8121a6ae38
commit 97f31bfec4
3 changed files with 100 additions and 21 deletions

View File

@ -236,7 +236,26 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
// Start reading from SIMM to temporary RAM buffer
resetAndShowStatusPage();
p->readSIMM(verifyBuffer);
// Only read back the size of the file if we can. This will save
// some time and prevent us from needing to read the ENTIRE SIMM
// if the file is only a quarter of the size of the SIMM.
uint32_t readLen = 0;
QFile temp(ui->chosenWriteFile->text());
if (temp.exists())
{
qint64 tmpLen = temp.size();
if (tmpLen > 0)
{
readLen = static_cast<uint32_t>(tmpLen);
}
else
{
readLen = 0;
}
}
p->readSIMM(verifyBuffer, readLen);
qDebug() << "Reading from SIMM for verification...";
}
else
@ -410,7 +429,47 @@ void MainWindow::programmerReadStatusChanged(ReadStatus newStatus)
if (memcmp(fileBytesPtr, readBytesPtr, fileBytes.count()) != 0)
{
QMessageBox::warning(this, "Verify error", "The data read back from the SIMM did not match the data written to it.");
// Now let's do some trickery and figure out which chip is acting up (or chips)
uint8_t badICMask = 0;
// Keep a list of which chips are reading bad data back
for (int x = 0; (x < fileBytes.count()) && (badICMask != 0xF); x++)
{
if (fileBytesPtr[x] != readBytesPtr[x])
{
// OK, we found a mismatched byte. Now look at
// which byte (0-3) it is in each 4-byte group.
// If it's byte 0, it's the MOST significant byte
// because the 68k is big endian. IC4 contains the
// MSB, so IC4 is the first chip, IC3 second, and
// so on. That's why I subtract it from 3 --
// 0 through 3 get mapped to 3 through 0.
badICMask |= (1 << (3 - (x % 4)));
}
}
// Make a comma-separated list of IC names from this list
QString icList;
bool first = true;
for (int x = 0; x < 4; x++)
{
if (badICMask & (1 << x))
{
if (first)
{
// not IC0 through IC3; IC1 through IC4.
// that's why I add one.
icList.append(QString("IC%1").arg(x+1));
first = false;
}
else
{
icList.append(QString(", IC%1").arg(x+1));
}
}
}
QMessageBox::warning(this, "Verify error", "The data read back from the SIMM did not match the data written to it. Bad data on chips: " + icList);
}
else
{
@ -419,7 +478,7 @@ void MainWindow::programmerReadStatusChanged(ReadStatus newStatus)
}
else
{
QMessageBox::warning(this, "Verify error", "The data read back from the SIMM did not match the data written to it.");
QMessageBox::warning(this, "Verify error", "The data read back from the SIMM did not match the data written to it--wrong amount of data read back.");
}
}

View File

@ -183,11 +183,31 @@ Programmer::~Programmer()
delete serialPort;
}
void Programmer::readSIMM(QIODevice *device)
void Programmer::readSIMM(QIODevice *device, uint32_t len)
{
readDevice = device;
lenRead = 0;
lenRemaining = _simmCapacity;
// Len == 0 means read the entire SIMM
if (len == 0)
{
lenRemaining = _simmCapacity;
trueLenToRead = _simmCapacity;
}
else if (len % READ_CHUNK_SIZE)
{
// We have to read a full chunk of data, so we read a little bit
// past the actual length requested but only return the amount
// requested.
uint32_t lastExtraChunk = (len % READ_CHUNK_SIZE);
lenRemaining = len - lastExtraChunk + READ_CHUNK_SIZE;
trueLenToRead = len;
}
else // already a multiple of READ_CHUNK_SIZE, no correction needed
{
lenRemaining = len;
trueLenToRead = len;
}
startProgrammerCommand(ReadChips, ReadSIMMWaitingStartReply);
}
@ -206,7 +226,6 @@ void Programmer::writeToSIMM(QIODevice *device)
lenWritten = 0;
writeLenRemaining = writeDevice->size();
//startProgrammerCommand(EraseChips, WriteSIMMWaitingEraseReply);
// Based on the SIMM size, tell the programmer board.
uint8_t setSizeCommand;
if (SIMMCapacity() > 2*1024*1024)
@ -254,6 +273,10 @@ void Programmer::handleChar(uint8_t c)
{
case CommandReplyOK:
// If we got an OK reply, we're ready to go, so start...
// Special case: Send out notification we are starting an erase command.
// I don't have any hooks into the process between now and the erase reply.
emit writeStatusChanged(WriteErasing);
sendByte(EraseChips);
curState = WriteSIMMWaitingEraseReply;
break;
@ -278,6 +301,9 @@ void Programmer::handleChar(uint8_t c)
// doesn't need updating -- it just didn't know how to handle
// the "set size" command. But that's OK -- it only supports
// the size we requested, so nothing's wrong.
// Special case: Send out notification we are starting an erase command.
// I don't have any hooks into the process between now and the erase reply.
emit writeStatusChanged(WriteErasing);
sendByte(EraseChips);
curState = WriteSIMMWaitingEraseReply;
}
@ -479,7 +505,7 @@ void Programmer::handleChar(uint8_t c)
{
case ProgrammerReadOK:
curState = ReadSIMMWaitingData;
emit readTotalLengthChanged(_simmCapacity);
emit readTotalLengthChanged(lenRemaining);
emit readCompletionLengthChanged(0);
readChunkLenRemaining = READ_CHUNK_SIZE;
break;
@ -492,7 +518,12 @@ void Programmer::handleChar(uint8_t c)
}
break;
case ReadSIMMWaitingData:
readDevice->write((const char *)&c, 1);
// Only keep adding to the readback if we need to
if (lenRead < trueLenToRead)
{
readDevice->write((const char *)&c, 1);
}
lenRead++;
if (--readChunkLenRemaining == 0)
{
@ -564,12 +595,6 @@ void Programmer::handleChar(uint8_t c)
emit startStatusChanged(ProgrammerInitialized);
curState = nextState;
sendByte(nextSendByte);
// Special case: Send out notification we are starting an erase command.
// I don't have any hooks into the process between now and the erase reply.
if (nextSendByte == EraseChips)
{
emit writeStatusChanged(WriteErasing);
}
break;
// TODO: Otherwise, raise an error?
}
@ -986,12 +1011,6 @@ void Programmer::portDiscovered_internal()
openPort();
curState = nextState;
sendByte(nextSendByte);
// Special case: Send out notification we are starting an erase command.
// I don't have any hooks into the process between now and the erase reply.
if (nextSendByte == EraseChips)
{
emit writeStatusChanged(WriteErasing);
}
}
else if (curState == BootloaderStateAwaitingPlugToBootloader)
{

View File

@ -99,7 +99,7 @@ class Programmer : public QObject
public:
explicit Programmer(QObject *parent = 0);
virtual ~Programmer();
void readSIMM(QIODevice *device);
void readSIMM(QIODevice *device, uint32_t len = 0);
void writeToSIMM(QIODevice *device);
void runElectricalTest();
QString electricalTestPinName(uint8_t index);
@ -154,6 +154,7 @@ private:
uint32_t readChunkLenRemaining;
uint32_t lenRead;
uint32_t trueLenToRead;
uint32_t lenRemaining;
int identificationCounter;