mirror of
https://github.com/steve-chamberlin/mac-rom-simm-programmer.software.git
synced 2025-01-02 17:30:22 +00:00
Got it working so you can flash and read chips on the SIMM individually.
This commit is contained in:
parent
8f60d21c0c
commit
6110068d04
719
mainwindow.cpp
719
mainwindow.cpp
@ -35,7 +35,11 @@ static Programmer *p;
|
|||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent) :
|
MainWindow::MainWindow(QWidget *parent) :
|
||||||
QMainWindow(parent),
|
QMainWindow(parent),
|
||||||
ui(new Ui::MainWindow)
|
ui(new Ui::MainWindow),
|
||||||
|
writeFile(NULL),
|
||||||
|
readFile(NULL),
|
||||||
|
writeBuffer(NULL),
|
||||||
|
readBuffer(NULL)
|
||||||
{
|
{
|
||||||
initializing = true;
|
initializing = true;
|
||||||
// Make default QSettings use these settings
|
// Make default QSettings use these settings
|
||||||
@ -46,6 +50,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
|
|
||||||
p = new Programmer();
|
p = new Programmer();
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
hideFlashIndividualControls();
|
||||||
ui->pages->setCurrentWidget(ui->notConnectedPage);
|
ui->pages->setCurrentWidget(ui->notConnectedPage);
|
||||||
ui->actionUpdate_firmware->setEnabled(false);
|
ui->actionUpdate_firmware->setEnabled(false);
|
||||||
|
|
||||||
@ -122,9 +127,6 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
ui->statusLabel->setText("");
|
ui->statusLabel->setText("");
|
||||||
ui->cancelButton->setEnabled(false);
|
ui->cancelButton->setEnabled(false);
|
||||||
|
|
||||||
readFile = NULL;
|
|
||||||
writeFile = NULL;
|
|
||||||
|
|
||||||
connect(p, SIGNAL(writeStatusChanged(WriteStatus)), SLOT(programmerWriteStatusChanged(WriteStatus)));
|
connect(p, SIGNAL(writeStatusChanged(WriteStatus)), SLOT(programmerWriteStatusChanged(WriteStatus)));
|
||||||
connect(p, SIGNAL(writeTotalLengthChanged(uint32_t)), SLOT(programmerWriteTotalLengthChanged(uint32_t)));
|
connect(p, SIGNAL(writeTotalLengthChanged(uint32_t)), SLOT(programmerWriteTotalLengthChanged(uint32_t)));
|
||||||
connect(p, SIGNAL(writeCompletionLengthChanged(uint32_t)), SLOT(programmerWriteCompletionLengthChanged(uint32_t)));
|
connect(p, SIGNAL(writeCompletionLengthChanged(uint32_t)), SLOT(programmerWriteCompletionLengthChanged(uint32_t)));
|
||||||
@ -144,6 +146,37 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
connect(p, SIGNAL(programmerBoardDisconnectedDuringOperation()), SLOT(programmerBoardDisconnectedDuringOperation()));
|
connect(p, SIGNAL(programmerBoardDisconnectedDuringOperation()), SLOT(programmerBoardDisconnectedDuringOperation()));
|
||||||
p->startCheckingPorts();
|
p->startCheckingPorts();
|
||||||
|
|
||||||
|
// Set up the multi chip flasher UI -- connect signals
|
||||||
|
connect(ui->chosenFlashIC1File, SIGNAL(textEdited(QString)), SLOT(updateFlashIndividualControlsEnabled()));
|
||||||
|
connect(ui->chosenFlashIC2File, SIGNAL(textEdited(QString)), SLOT(updateFlashIndividualControlsEnabled()));
|
||||||
|
connect(ui->chosenFlashIC3File, SIGNAL(textEdited(QString)), SLOT(updateFlashIndividualControlsEnabled()));
|
||||||
|
connect(ui->chosenFlashIC4File, SIGNAL(textEdited(QString)), SLOT(updateFlashIndividualControlsEnabled()));
|
||||||
|
|
||||||
|
connect(ui->chosenReadIC1File, SIGNAL(textEdited(QString)), SLOT(updateFlashIndividualControlsEnabled()));
|
||||||
|
connect(ui->chosenReadIC2File, SIGNAL(textEdited(QString)), SLOT(updateFlashIndividualControlsEnabled()));
|
||||||
|
connect(ui->chosenReadIC3File, SIGNAL(textEdited(QString)), SLOT(updateFlashIndividualControlsEnabled()));
|
||||||
|
connect(ui->chosenReadIC4File, SIGNAL(textEdited(QString)), SLOT(updateFlashIndividualControlsEnabled()));
|
||||||
|
|
||||||
|
connect(ui->flashIC1CheckBox, SIGNAL(clicked()), SLOT(updateFlashIndividualControlsEnabled()));
|
||||||
|
connect(ui->flashIC2CheckBox, SIGNAL(clicked()), SLOT(updateFlashIndividualControlsEnabled()));
|
||||||
|
connect(ui->flashIC3CheckBox, SIGNAL(clicked()), SLOT(updateFlashIndividualControlsEnabled()));
|
||||||
|
connect(ui->flashIC4CheckBox, SIGNAL(clicked()), SLOT(updateFlashIndividualControlsEnabled()));
|
||||||
|
|
||||||
|
connect(ui->readIC1CheckBox, SIGNAL(clicked()), SLOT(updateFlashIndividualControlsEnabled()));
|
||||||
|
connect(ui->readIC2CheckBox, SIGNAL(clicked()), SLOT(updateFlashIndividualControlsEnabled()));
|
||||||
|
connect(ui->readIC3CheckBox, SIGNAL(clicked()), SLOT(updateFlashIndividualControlsEnabled()));
|
||||||
|
connect(ui->readIC4CheckBox, SIGNAL(clicked()), SLOT(updateFlashIndividualControlsEnabled()));
|
||||||
|
|
||||||
|
connect(ui->selectFlashIC1Button, SIGNAL(clicked()), SLOT(selectIndividualWriteFileClicked()));
|
||||||
|
connect(ui->selectFlashIC2Button, SIGNAL(clicked()), SLOT(selectIndividualWriteFileClicked()));
|
||||||
|
connect(ui->selectFlashIC3Button, SIGNAL(clicked()), SLOT(selectIndividualWriteFileClicked()));
|
||||||
|
connect(ui->selectFlashIC4Button, SIGNAL(clicked()), SLOT(selectIndividualWriteFileClicked()));
|
||||||
|
|
||||||
|
connect(ui->selectReadIC1Button, SIGNAL(clicked()), SLOT(selectIndividualReadFileClicked()));
|
||||||
|
connect(ui->selectReadIC2Button, SIGNAL(clicked()), SLOT(selectIndividualReadFileClicked()));
|
||||||
|
connect(ui->selectReadIC3Button, SIGNAL(clicked()), SLOT(selectIndividualReadFileClicked()));
|
||||||
|
connect(ui->selectReadIC4Button, SIGNAL(clicked()), SLOT(selectIndividualReadFileClicked()));
|
||||||
|
|
||||||
initializing = false;
|
initializing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,6 +210,18 @@ void MainWindow::on_selectReadFileButton_clicked()
|
|||||||
|
|
||||||
void MainWindow::on_readFromSIMMButton_clicked()
|
void MainWindow::on_readFromSIMMButton_clicked()
|
||||||
{
|
{
|
||||||
|
// Ensure we don't think we're in buffer writing/reading mode...we're reading to
|
||||||
|
// an actual file.
|
||||||
|
if (writeBuffer)
|
||||||
|
{
|
||||||
|
delete writeBuffer;
|
||||||
|
writeBuffer = NULL;
|
||||||
|
}
|
||||||
|
if (readBuffer)
|
||||||
|
{
|
||||||
|
delete readBuffer;
|
||||||
|
readBuffer = NULL;
|
||||||
|
}
|
||||||
if (readFile)
|
if (readFile)
|
||||||
{
|
{
|
||||||
readFile->close();
|
readFile->close();
|
||||||
@ -204,6 +249,18 @@ void MainWindow::on_readFromSIMMButton_clicked()
|
|||||||
|
|
||||||
void MainWindow::on_writeToSIMMButton_clicked()
|
void MainWindow::on_writeToSIMMButton_clicked()
|
||||||
{
|
{
|
||||||
|
// Ensure we don't think we're in buffer writing/reading mode...we're writing
|
||||||
|
// an actual file.
|
||||||
|
if (writeBuffer)
|
||||||
|
{
|
||||||
|
delete writeBuffer;
|
||||||
|
writeBuffer = NULL;
|
||||||
|
}
|
||||||
|
if (readBuffer)
|
||||||
|
{
|
||||||
|
delete readBuffer;
|
||||||
|
readBuffer = NULL;
|
||||||
|
}
|
||||||
if (writeFile)
|
if (writeFile)
|
||||||
{
|
{
|
||||||
writeFile->close();
|
writeFile->close();
|
||||||
@ -273,7 +330,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
|||||||
switch (newStatus)
|
switch (newStatus)
|
||||||
{
|
{
|
||||||
case WriteErasing:
|
case WriteErasing:
|
||||||
ui->statusLabel->setText("Erasing SIMM (this may take a few seconds)...");
|
if (writeBuffer)
|
||||||
|
{
|
||||||
|
ui->statusLabel->setText("Erasing chip(s) to be flashed (this may take a few seconds)...");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->statusLabel->setText("Erasing SIMM (this may take a few seconds)...");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WriteCompleteNoVerify:
|
case WriteCompleteNoVerify:
|
||||||
if (writeFile)
|
if (writeFile)
|
||||||
@ -284,7 +348,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QMessageBox::information(this, "Write complete", "The write operation finished.");
|
QMessageBox::information(this, "Write complete", "The write operation finished.");
|
||||||
ui->pages->setCurrentWidget(ui->controlPage);
|
|
||||||
|
returnToControlPage();
|
||||||
|
if (writeBuffer)
|
||||||
|
{
|
||||||
|
writeBuffer->close();
|
||||||
|
delete writeBuffer;
|
||||||
|
writeBuffer = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WriteCompleteVerifyOK:
|
case WriteCompleteVerifyOK:
|
||||||
if (writeFile)
|
if (writeFile)
|
||||||
@ -295,9 +366,15 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QMessageBox::information(this, "Write complete", "The write operation finished, and the contents were verified successfully.");
|
QMessageBox::information(this, "Write complete", "The write operation finished, and the contents were verified successfully.");
|
||||||
ui->pages->setCurrentWidget(ui->controlPage);
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
returnToControlPage();
|
||||||
|
if (writeBuffer)
|
||||||
|
{
|
||||||
|
writeBuffer->close();
|
||||||
|
delete writeBuffer;
|
||||||
|
writeBuffer = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case WriteVerifying:
|
case WriteVerifying:
|
||||||
resetAndShowStatusPage();
|
resetAndShowStatusPage();
|
||||||
break;
|
break;
|
||||||
@ -311,8 +388,15 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
|||||||
delete writeFile;
|
delete writeFile;
|
||||||
writeFile = NULL;
|
writeFile = NULL;
|
||||||
}
|
}
|
||||||
ui->pages->setCurrentWidget(ui->controlPage);
|
|
||||||
|
returnToControlPage();
|
||||||
QMessageBox::warning(this, "Verify error", "An error occurred reading the SIMM contents for verification.");
|
QMessageBox::warning(this, "Verify error", "An error occurred reading the SIMM contents for verification.");
|
||||||
|
if (writeBuffer)
|
||||||
|
{
|
||||||
|
writeBuffer->close();
|
||||||
|
delete writeBuffer;
|
||||||
|
writeBuffer = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WriteVerifyCancelled:
|
case WriteVerifyCancelled:
|
||||||
if (writeFile)
|
if (writeFile)
|
||||||
@ -322,8 +406,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
|||||||
writeFile = NULL;
|
writeFile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->pages->setCurrentWidget(ui->controlPage);
|
returnToControlPage();
|
||||||
QMessageBox::warning(this, "Verify cancelled", "The verify operation was cancelled.");
|
QMessageBox::warning(this, "Verify cancelled", "The verify operation was cancelled.");
|
||||||
|
if (writeBuffer)
|
||||||
|
{
|
||||||
|
writeBuffer->close();
|
||||||
|
delete writeBuffer;
|
||||||
|
writeBuffer = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WriteVerifyTimedOut:
|
case WriteVerifyTimedOut:
|
||||||
if (writeFile)
|
if (writeFile)
|
||||||
@ -333,8 +423,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
|||||||
writeFile = NULL;
|
writeFile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->pages->setCurrentWidget(ui->controlPage);
|
returnToControlPage();
|
||||||
QMessageBox::warning(this, "Verify timed out", "The verify operation timed out.");
|
QMessageBox::warning(this, "Verify timed out", "The verify operation timed out.");
|
||||||
|
if (writeBuffer)
|
||||||
|
{
|
||||||
|
writeBuffer->close();
|
||||||
|
delete writeBuffer;
|
||||||
|
writeBuffer = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WriteVerificationFailure:
|
case WriteVerificationFailure:
|
||||||
if (writeFile)
|
if (writeFile)
|
||||||
@ -347,6 +443,12 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
|||||||
// The verify failure code is somewhat complicated so it's best to put
|
// The verify failure code is somewhat complicated so it's best to put
|
||||||
// it elsewhere.
|
// it elsewhere.
|
||||||
handleVerifyFailureReply();
|
handleVerifyFailureReply();
|
||||||
|
if (writeBuffer)
|
||||||
|
{
|
||||||
|
writeBuffer->close();
|
||||||
|
delete writeBuffer;
|
||||||
|
writeBuffer = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WriteError:
|
case WriteError:
|
||||||
if (writeFile)
|
if (writeFile)
|
||||||
@ -356,8 +458,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
|||||||
writeFile = NULL;
|
writeFile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->pages->setCurrentWidget(ui->controlPage);
|
returnToControlPage();
|
||||||
QMessageBox::warning(this, "Write error", "An error occurred writing to the SIMM.");
|
QMessageBox::warning(this, "Write error", "An error occurred writing to the SIMM.");
|
||||||
|
if (writeBuffer)
|
||||||
|
{
|
||||||
|
writeBuffer->close();
|
||||||
|
delete writeBuffer;
|
||||||
|
writeBuffer = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WriteNeedsFirmwareUpdateBiggerSIMM:
|
case WriteNeedsFirmwareUpdateBiggerSIMM:
|
||||||
if (writeFile)
|
if (writeFile)
|
||||||
@ -367,8 +475,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
|||||||
writeFile = NULL;
|
writeFile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->pages->setCurrentWidget(ui->controlPage);
|
returnToControlPage();
|
||||||
QMessageBox::warning(this, "Firmware update needed", "The programmer board needs a firmware update to support a larger SIMM. Please update the firmware and try again.");
|
QMessageBox::warning(this, "Firmware update needed", "The programmer board needs a firmware update to support a larger SIMM. Please update the firmware and try again.");
|
||||||
|
if (writeBuffer)
|
||||||
|
{
|
||||||
|
writeBuffer->close();
|
||||||
|
delete writeBuffer;
|
||||||
|
writeBuffer = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WriteNeedsFirmwareUpdateVerifyWhileWrite:
|
case WriteNeedsFirmwareUpdateVerifyWhileWrite:
|
||||||
if (writeFile)
|
if (writeFile)
|
||||||
@ -378,8 +492,48 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
|||||||
writeFile = NULL;
|
writeFile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->pages->setCurrentWidget(ui->controlPage);
|
returnToControlPage();
|
||||||
QMessageBox::warning(this, "Firmware update needed", "The programmer board needs a firmware update to support the \"verify while writing\" capability. Please update the firmware and try again.");
|
QMessageBox::warning(this, "Firmware update needed", "The programmer board needs a firmware update to support the \"verify while writing\" capability. Please update the firmware and try again.");
|
||||||
|
if (writeBuffer)
|
||||||
|
{
|
||||||
|
writeBuffer->close();
|
||||||
|
delete writeBuffer;
|
||||||
|
writeBuffer = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WriteNeedsFirmwareUpdateErasePortion:
|
||||||
|
if (writeFile)
|
||||||
|
{
|
||||||
|
writeFile->close();
|
||||||
|
delete writeFile;
|
||||||
|
writeFile = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
returnToControlPage();
|
||||||
|
QMessageBox::warning(this, "Firmware update needed", "The programmer board needs a firmware update to support the \"erase only a portion of the SIMM\" capability. Please update the firmware and try again.");
|
||||||
|
if (writeBuffer)
|
||||||
|
{
|
||||||
|
writeBuffer->close();
|
||||||
|
delete writeBuffer;
|
||||||
|
writeBuffer = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WriteNeedsFirmwareUpdateIndividualChips:
|
||||||
|
if (writeFile)
|
||||||
|
{
|
||||||
|
writeFile->close();
|
||||||
|
delete writeFile;
|
||||||
|
writeFile = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
returnToControlPage();
|
||||||
|
QMessageBox::warning(this, "Firmware update needed", "The programmer board needs a firmware update to support the \"program individual chips\" capability. Please update the firmware and try again.");
|
||||||
|
if (writeBuffer)
|
||||||
|
{
|
||||||
|
writeBuffer->close();
|
||||||
|
delete writeBuffer;
|
||||||
|
writeBuffer = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WriteCancelled:
|
case WriteCancelled:
|
||||||
if (writeFile)
|
if (writeFile)
|
||||||
@ -389,8 +543,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
|||||||
writeFile = NULL;
|
writeFile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->pages->setCurrentWidget(ui->controlPage);
|
returnToControlPage();
|
||||||
QMessageBox::warning(this, "Write cancelled", "The write operation was cancelled.");
|
QMessageBox::warning(this, "Write cancelled", "The write operation was cancelled.");
|
||||||
|
if (writeBuffer)
|
||||||
|
{
|
||||||
|
writeBuffer->close();
|
||||||
|
delete writeBuffer;
|
||||||
|
writeBuffer = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WriteEraseComplete:
|
case WriteEraseComplete:
|
||||||
ui->statusLabel->setText("Writing SIMM...");
|
ui->statusLabel->setText("Writing SIMM...");
|
||||||
@ -403,8 +563,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
|||||||
writeFile = NULL;
|
writeFile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->pages->setCurrentWidget(ui->controlPage);
|
returnToControlPage();
|
||||||
QMessageBox::warning(this, "Write error", "An error occurred erasing the SIMM.");
|
QMessageBox::warning(this, "Write error", "An error occurred erasing the SIMM.");
|
||||||
|
if (writeBuffer)
|
||||||
|
{
|
||||||
|
writeBuffer->close();
|
||||||
|
delete writeBuffer;
|
||||||
|
writeBuffer = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WriteTimedOut:
|
case WriteTimedOut:
|
||||||
if (writeFile)
|
if (writeFile)
|
||||||
@ -414,8 +580,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
|||||||
writeFile = NULL;
|
writeFile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->pages->setCurrentWidget(ui->controlPage);
|
returnToControlPage();
|
||||||
QMessageBox::warning(this, "Write timed out", "The write operation timed out.");
|
QMessageBox::warning(this, "Write timed out", "The write operation timed out.");
|
||||||
|
if (writeBuffer)
|
||||||
|
{
|
||||||
|
writeBuffer->close();
|
||||||
|
delete writeBuffer;
|
||||||
|
writeBuffer = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WriteFileTooBig:
|
case WriteFileTooBig:
|
||||||
if (writeFile)
|
if (writeFile)
|
||||||
@ -425,8 +597,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
|||||||
writeFile = NULL;
|
writeFile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->pages->setCurrentWidget(ui->controlPage);
|
returnToControlPage();
|
||||||
QMessageBox::warning(this, "File too big", "The file you chose to write to the SIMM is too big according to the chip size you have selected.");
|
QMessageBox::warning(this, "File too big", "The file you chose to write to the SIMM is too big according to the chip size you have selected.");
|
||||||
|
if (writeBuffer)
|
||||||
|
{
|
||||||
|
writeBuffer->close();
|
||||||
|
delete writeBuffer;
|
||||||
|
writeBuffer = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case WriteEraseBlockWrongSize:
|
case WriteEraseBlockWrongSize:
|
||||||
if (writeFile)
|
if (writeFile)
|
||||||
@ -436,8 +614,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
|||||||
writeFile = NULL;
|
writeFile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->pages->setCurrentWidget(ui->controlPage);
|
returnToControlPage();
|
||||||
QMessageBox::warning(this, "Bad erase size", "The programmer cannot handle the erase size you chose.");
|
QMessageBox::warning(this, "Bad erase size", "The programmer cannot handle the erase size you chose.");
|
||||||
|
if (writeBuffer)
|
||||||
|
{
|
||||||
|
writeBuffer->close();
|
||||||
|
delete writeBuffer;
|
||||||
|
writeBuffer = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -523,9 +707,18 @@ void MainWindow::programmerReadStatusChanged(ReadStatus newStatus)
|
|||||||
delete readFile;
|
delete readFile;
|
||||||
readFile = NULL;
|
readFile = NULL;
|
||||||
}
|
}
|
||||||
|
if (readBuffer)
|
||||||
|
{
|
||||||
|
finishMultiRead();
|
||||||
|
}
|
||||||
|
|
||||||
ui->pages->setCurrentWidget(ui->controlPage);
|
returnToControlPage();
|
||||||
QMessageBox::information(this, "Read complete", "The read operation finished.");
|
QMessageBox::information(this, "Read complete", "The read operation finished.");
|
||||||
|
if (readBuffer)
|
||||||
|
{
|
||||||
|
delete readBuffer;
|
||||||
|
readBuffer = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ReadError:
|
case ReadError:
|
||||||
if (readFile)
|
if (readFile)
|
||||||
@ -535,8 +728,13 @@ void MainWindow::programmerReadStatusChanged(ReadStatus newStatus)
|
|||||||
readFile = NULL;
|
readFile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->pages->setCurrentWidget(ui->controlPage);
|
returnToControlPage();
|
||||||
QMessageBox::warning(this, "Read error", "An error occurred reading from the SIMM.");
|
QMessageBox::warning(this, "Read error", "An error occurred reading from the SIMM.");
|
||||||
|
if (readBuffer)
|
||||||
|
{
|
||||||
|
delete readBuffer;
|
||||||
|
readBuffer = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ReadCancelled:
|
case ReadCancelled:
|
||||||
if (readFile)
|
if (readFile)
|
||||||
@ -546,8 +744,13 @@ void MainWindow::programmerReadStatusChanged(ReadStatus newStatus)
|
|||||||
readFile = NULL;
|
readFile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->pages->setCurrentWidget(ui->controlPage);
|
returnToControlPage();
|
||||||
QMessageBox::warning(this, "Read cancelled", "The read operation was cancelled.");
|
QMessageBox::warning(this, "Read cancelled", "The read operation was cancelled.");
|
||||||
|
if (readBuffer)
|
||||||
|
{
|
||||||
|
delete readBuffer;
|
||||||
|
readBuffer = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ReadTimedOut:
|
case ReadTimedOut:
|
||||||
if (readFile)
|
if (readFile)
|
||||||
@ -557,8 +760,13 @@ void MainWindow::programmerReadStatusChanged(ReadStatus newStatus)
|
|||||||
readFile = NULL;
|
readFile = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->pages->setCurrentWidget(ui->controlPage);
|
returnToControlPage();
|
||||||
QMessageBox::warning(this, "Read timed out", "The read operation timed out.");
|
QMessageBox::warning(this, "Read timed out", "The read operation timed out.");
|
||||||
|
if (readBuffer)
|
||||||
|
{
|
||||||
|
delete readBuffer;
|
||||||
|
readBuffer = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -668,7 +876,7 @@ void MainWindow::on_identifyButton_clicked()
|
|||||||
|
|
||||||
void MainWindow::programmerBoardConnected()
|
void MainWindow::programmerBoardConnected()
|
||||||
{
|
{
|
||||||
ui->pages->setCurrentWidget(ui->controlPage);
|
returnToControlPage();
|
||||||
ui->actionUpdate_firmware->setEnabled(true);
|
ui->actionUpdate_firmware->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -794,6 +1002,467 @@ void MainWindow::handleVerifyFailureReply()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->pages->setCurrentWidget(ui->controlPage);
|
returnToControlPage();
|
||||||
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);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_flashIndividualEnterButton_clicked()
|
||||||
|
{
|
||||||
|
showFlashIndividualControls();
|
||||||
|
updateFlashIndividualControlsEnabled();
|
||||||
|
ui->pages->setCurrentWidget(ui->flashChipsPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_returnNormalButton_clicked()
|
||||||
|
{
|
||||||
|
hideFlashIndividualControls(); // to allow the window to be shrunk when not active
|
||||||
|
ui->pages->setCurrentWidget(ui->controlPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::hideFlashIndividualControls()
|
||||||
|
{
|
||||||
|
ui->chosenFlashIC1File->hide();
|
||||||
|
ui->chosenFlashIC2File->hide();
|
||||||
|
ui->chosenFlashIC3File->hide();
|
||||||
|
ui->chosenFlashIC4File->hide();
|
||||||
|
|
||||||
|
ui->chosenReadIC1File->hide();
|
||||||
|
ui->chosenReadIC2File->hide();
|
||||||
|
ui->chosenReadIC3File->hide();
|
||||||
|
ui->chosenReadIC4File->hide();
|
||||||
|
|
||||||
|
ui->flashIC1CheckBox->hide();
|
||||||
|
ui->flashIC2CheckBox->hide();
|
||||||
|
ui->flashIC3CheckBox->hide();
|
||||||
|
ui->flashIC4CheckBox->hide();
|
||||||
|
|
||||||
|
ui->readIC1CheckBox->hide();
|
||||||
|
ui->readIC2CheckBox->hide();
|
||||||
|
ui->readIC3CheckBox->hide();
|
||||||
|
ui->readIC4CheckBox->hide();
|
||||||
|
|
||||||
|
ui->selectFlashIC1Button->hide();
|
||||||
|
ui->selectFlashIC2Button->hide();
|
||||||
|
ui->selectFlashIC3Button->hide();
|
||||||
|
ui->selectFlashIC4Button->hide();
|
||||||
|
|
||||||
|
ui->selectReadIC1Button->hide();
|
||||||
|
ui->selectReadIC2Button->hide();
|
||||||
|
ui->selectReadIC3Button->hide();
|
||||||
|
ui->selectReadIC4Button->hide();
|
||||||
|
|
||||||
|
ui->multiFlashChipsButton->hide();
|
||||||
|
ui->multiReadChipsButton->hide();
|
||||||
|
|
||||||
|
ui->returnNormalButton->hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::showFlashIndividualControls()
|
||||||
|
{
|
||||||
|
ui->chosenFlashIC1File->show();
|
||||||
|
ui->chosenFlashIC2File->show();
|
||||||
|
ui->chosenFlashIC3File->show();
|
||||||
|
ui->chosenFlashIC4File->show();
|
||||||
|
|
||||||
|
ui->chosenReadIC1File->show();
|
||||||
|
ui->chosenReadIC2File->show();
|
||||||
|
ui->chosenReadIC3File->show();
|
||||||
|
ui->chosenReadIC4File->show();
|
||||||
|
|
||||||
|
ui->flashIC1CheckBox->show();
|
||||||
|
ui->flashIC2CheckBox->show();
|
||||||
|
ui->flashIC3CheckBox->show();
|
||||||
|
ui->flashIC4CheckBox->show();
|
||||||
|
|
||||||
|
ui->readIC1CheckBox->show();
|
||||||
|
ui->readIC2CheckBox->show();
|
||||||
|
ui->readIC3CheckBox->show();
|
||||||
|
ui->readIC4CheckBox->show();
|
||||||
|
|
||||||
|
ui->selectFlashIC1Button->show();
|
||||||
|
ui->selectFlashIC2Button->show();
|
||||||
|
ui->selectFlashIC3Button->show();
|
||||||
|
ui->selectFlashIC4Button->show();
|
||||||
|
|
||||||
|
ui->selectReadIC1Button->show();
|
||||||
|
ui->selectReadIC2Button->show();
|
||||||
|
ui->selectReadIC3Button->show();
|
||||||
|
ui->selectReadIC4Button->show();
|
||||||
|
|
||||||
|
ui->multiFlashChipsButton->show();
|
||||||
|
ui->multiReadChipsButton->show();
|
||||||
|
|
||||||
|
ui->returnNormalButton->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::updateFlashIndividualControlsEnabled()
|
||||||
|
{
|
||||||
|
int numWriteFilesChecked = 0;
|
||||||
|
int numReadFilesChecked = 0;
|
||||||
|
bool hasBadWriteFileName = false;
|
||||||
|
bool hasBadReadFileName = false;
|
||||||
|
|
||||||
|
QCheckBox * const flashBoxes[] = {ui->flashIC1CheckBox,
|
||||||
|
ui->flashIC2CheckBox,
|
||||||
|
ui->flashIC3CheckBox,
|
||||||
|
ui->flashIC4CheckBox};
|
||||||
|
QCheckBox * const readBoxes[] = {ui->readIC1CheckBox,
|
||||||
|
ui->readIC2CheckBox,
|
||||||
|
ui->readIC3CheckBox,
|
||||||
|
ui->readIC4CheckBox};
|
||||||
|
QPushButton * const flashSelectButtons[] = {ui->selectFlashIC1Button,
|
||||||
|
ui->selectFlashIC2Button,
|
||||||
|
ui->selectFlashIC3Button,
|
||||||
|
ui->selectFlashIC4Button};
|
||||||
|
QPushButton * const readSelectButtons[] = {ui->selectReadIC1Button,
|
||||||
|
ui->selectReadIC2Button,
|
||||||
|
ui->selectReadIC3Button,
|
||||||
|
ui->selectReadIC4Button};
|
||||||
|
QLineEdit * const flashChosenFileEdits[] = {ui->chosenFlashIC1File,
|
||||||
|
ui->chosenFlashIC2File,
|
||||||
|
ui->chosenFlashIC3File,
|
||||||
|
ui->chosenFlashIC4File};
|
||||||
|
QLineEdit * const readChosenFileEdits[] = {ui->chosenReadIC1File,
|
||||||
|
ui->chosenReadIC2File,
|
||||||
|
ui->chosenReadIC3File,
|
||||||
|
ui->chosenReadIC4File};
|
||||||
|
|
||||||
|
for (size_t x = 0; x < sizeof(flashBoxes)/sizeof(flashBoxes[0]); x++)
|
||||||
|
{
|
||||||
|
bool isChecked = flashBoxes[x]->isChecked();
|
||||||
|
|
||||||
|
flashChosenFileEdits[x]->setEnabled(isChecked);
|
||||||
|
flashSelectButtons[x]->setEnabled(isChecked);
|
||||||
|
if (isChecked)
|
||||||
|
{
|
||||||
|
numWriteFilesChecked++;
|
||||||
|
QFileInfo fi(flashChosenFileEdits[x]->text());
|
||||||
|
if (flashChosenFileEdits[x]->text().isEmpty() || !fi.exists() || !fi.isFile())
|
||||||
|
{
|
||||||
|
hasBadWriteFileName = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isChecked = readBoxes[x]->isChecked();
|
||||||
|
|
||||||
|
readChosenFileEdits[x]->setEnabled(isChecked);
|
||||||
|
readSelectButtons[x]->setEnabled(isChecked);
|
||||||
|
if (isChecked)
|
||||||
|
{
|
||||||
|
numReadFilesChecked++;
|
||||||
|
QFileInfo fi(readChosenFileEdits[x]->text());
|
||||||
|
if (readChosenFileEdits[x]->text().isEmpty() || !fi.dir().exists())
|
||||||
|
{
|
||||||
|
hasBadReadFileName = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// All of the individual controls should be handled; now do the two main
|
||||||
|
// buttons.
|
||||||
|
if ((numWriteFilesChecked == 0) || hasBadWriteFileName)
|
||||||
|
{
|
||||||
|
ui->multiFlashChipsButton->setEnabled(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->multiFlashChipsButton->setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((numReadFilesChecked == 0) || hasBadReadFileName)
|
||||||
|
{
|
||||||
|
ui->multiReadChipsButton->setEnabled(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->multiReadChipsButton->setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::selectIndividualWriteFileClicked()
|
||||||
|
{
|
||||||
|
QString filename = QFileDialog::getOpenFileName(this, "Select a file to write to the chip:");
|
||||||
|
if (!filename.isNull())
|
||||||
|
{
|
||||||
|
if (sender() == static_cast<QObject *>(ui->selectFlashIC1Button))
|
||||||
|
{
|
||||||
|
ui->chosenFlashIC1File->setText(filename);
|
||||||
|
}
|
||||||
|
else if (sender() == static_cast<QObject *>(ui->selectFlashIC2Button))
|
||||||
|
{
|
||||||
|
ui->chosenFlashIC2File->setText(filename);
|
||||||
|
}
|
||||||
|
else if (sender() == static_cast<QObject *>(ui->selectFlashIC3Button))
|
||||||
|
{
|
||||||
|
ui->chosenFlashIC3File->setText(filename);
|
||||||
|
}
|
||||||
|
else if (sender() == static_cast<QObject *>(ui->selectFlashIC4Button))
|
||||||
|
{
|
||||||
|
ui->chosenFlashIC4File->setText(filename);
|
||||||
|
}
|
||||||
|
updateFlashIndividualControlsEnabled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::selectIndividualReadFileClicked()
|
||||||
|
{
|
||||||
|
QString filename = QFileDialog::getSaveFileName(this, "Save binary file as:");
|
||||||
|
if (!filename.isNull())
|
||||||
|
{
|
||||||
|
if (sender() == static_cast<QObject *>(ui->selectReadIC1Button))
|
||||||
|
{
|
||||||
|
ui->chosenReadIC1File->setText(filename);
|
||||||
|
}
|
||||||
|
else if (sender() == static_cast<QObject *>(ui->selectReadIC2Button))
|
||||||
|
{
|
||||||
|
ui->chosenReadIC2File->setText(filename);
|
||||||
|
}
|
||||||
|
else if (sender() == static_cast<QObject *>(ui->selectReadIC3Button))
|
||||||
|
{
|
||||||
|
ui->chosenReadIC3File->setText(filename);
|
||||||
|
}
|
||||||
|
else if (sender() == static_cast<QObject *>(ui->selectReadIC4Button))
|
||||||
|
{
|
||||||
|
ui->chosenReadIC4File->setText(filename);
|
||||||
|
}
|
||||||
|
updateFlashIndividualControlsEnabled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_multiFlashChipsButton_clicked()
|
||||||
|
{
|
||||||
|
QCheckBox * const flashBoxes[] = {ui->flashIC1CheckBox,
|
||||||
|
ui->flashIC2CheckBox,
|
||||||
|
ui->flashIC3CheckBox,
|
||||||
|
ui->flashIC4CheckBox};
|
||||||
|
|
||||||
|
QLineEdit * const flashChosenFileEdits[] = {ui->chosenFlashIC1File,
|
||||||
|
ui->chosenFlashIC2File,
|
||||||
|
ui->chosenFlashIC3File,
|
||||||
|
ui->chosenFlashIC4File};
|
||||||
|
|
||||||
|
// Read up to four files and create a combined image that we flash using
|
||||||
|
// the standard procedure...
|
||||||
|
if (writeBuffer)
|
||||||
|
{
|
||||||
|
delete writeBuffer;
|
||||||
|
}
|
||||||
|
writeBuffer = new QBuffer();
|
||||||
|
qint64 maxSize = 0;
|
||||||
|
bool hadError = false;
|
||||||
|
uint8_t chipsMask = 0;
|
||||||
|
|
||||||
|
// Read each file and ensure it exists. Oh, and create the mask of which
|
||||||
|
// chips we're flashing.
|
||||||
|
QFile *files[sizeof(flashBoxes)/sizeof(flashBoxes[0])] = {NULL, NULL, NULL, NULL};
|
||||||
|
for (size_t x = 0; x < sizeof(files)/sizeof(files[0]); x++)
|
||||||
|
{
|
||||||
|
if (flashBoxes[x]->isChecked())
|
||||||
|
{
|
||||||
|
files[x] = new QFile(flashChosenFileEdits[x]->text());
|
||||||
|
if (!files[x]->exists())
|
||||||
|
{
|
||||||
|
hadError = true;
|
||||||
|
}
|
||||||
|
if (files[x]->size() > maxSize)
|
||||||
|
{
|
||||||
|
maxSize = files[x]->size();
|
||||||
|
}
|
||||||
|
files[x]->open(QFile::ReadOnly);
|
||||||
|
// Create our chip mask. chip mask is backward from IC numbering
|
||||||
|
// (bit 0 = IC4, bit 1 = IC3, ...)
|
||||||
|
chipsMask |= (1 << (3-x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there was an error or one of the files picked was too big,
|
||||||
|
// error out.
|
||||||
|
if (hadError || (maxSize > (p->SIMMCapacity() / 4)))
|
||||||
|
{
|
||||||
|
for (size_t x = 0; x < sizeof(files)/sizeof(files[0]); x++)
|
||||||
|
{
|
||||||
|
if (files[x]) delete files[x];
|
||||||
|
}
|
||||||
|
|
||||||
|
programmerWriteStatusChanged(WriteError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Combine the (up to four) files into a single
|
||||||
|
// interleaved file to send to the SIMM
|
||||||
|
writeBuffer->open(QFile::ReadWrite);
|
||||||
|
for (int x = 0; x < maxSize; x++)
|
||||||
|
{
|
||||||
|
// Go in reverse order through the files so the data is saved to
|
||||||
|
// the SIMM in the correct order
|
||||||
|
for (int y = (int)(sizeof(files)/sizeof(files[0])) - 1; y >= 0; y--)
|
||||||
|
{
|
||||||
|
char c = 0xFF;
|
||||||
|
if (files[y] && !files[y]->atEnd())
|
||||||
|
{
|
||||||
|
files[y]->getChar(&c);
|
||||||
|
|
||||||
|
}
|
||||||
|
writeBuffer->putChar(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Discard the temporary files
|
||||||
|
for (size_t x = 0; x < sizeof(files)/sizeof(files[0]); x++)
|
||||||
|
{
|
||||||
|
if (files[x])
|
||||||
|
{
|
||||||
|
files[x]->close();
|
||||||
|
delete files[x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now go back to the beginning of the file...
|
||||||
|
// and write it!
|
||||||
|
resetAndShowStatusPage();
|
||||||
|
writeBuffer->seek(0);
|
||||||
|
p->writeToSIMM(writeBuffer, chipsMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::on_multiReadChipsButton_clicked()
|
||||||
|
{
|
||||||
|
QCheckBox * const readBoxes[] = {ui->readIC1CheckBox,
|
||||||
|
ui->readIC2CheckBox,
|
||||||
|
ui->readIC3CheckBox,
|
||||||
|
ui->readIC4CheckBox};
|
||||||
|
|
||||||
|
QLineEdit * const readChosenFileEdits[] = {ui->chosenReadIC1File,
|
||||||
|
ui->chosenReadIC2File,
|
||||||
|
ui->chosenReadIC3File,
|
||||||
|
ui->chosenReadIC4File};
|
||||||
|
|
||||||
|
// Prepare to read the files; when the read is complete we will save
|
||||||
|
// the files as necessary
|
||||||
|
if (readBuffer)
|
||||||
|
{
|
||||||
|
delete readBuffer;
|
||||||
|
}
|
||||||
|
readBuffer = new QBuffer();
|
||||||
|
|
||||||
|
// Try to open each file to make sure it's writable first. Then close it.
|
||||||
|
bool hadError = false;
|
||||||
|
for (size_t x = 0; x < sizeof(readBoxes)/sizeof(readBoxes[0]); x++)
|
||||||
|
{
|
||||||
|
if (readBoxes[x]->isChecked())
|
||||||
|
{
|
||||||
|
QFile tmp(readChosenFileEdits[x]->text());
|
||||||
|
if (!tmp.open(QFile::ReadWrite))
|
||||||
|
{
|
||||||
|
hadError = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tmp.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there was an error creating one of the files, bail out.
|
||||||
|
if (hadError)
|
||||||
|
{
|
||||||
|
programmerReadStatusChanged(ReadError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open up the buffer to read into
|
||||||
|
readBuffer->open(QFile::ReadWrite);
|
||||||
|
|
||||||
|
// Now start reading it!
|
||||||
|
resetAndShowStatusPage();
|
||||||
|
p->readSIMM(readBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::finishMultiRead()
|
||||||
|
{
|
||||||
|
QCheckBox * const readBoxes[] = {ui->readIC1CheckBox,
|
||||||
|
ui->readIC2CheckBox,
|
||||||
|
ui->readIC3CheckBox,
|
||||||
|
ui->readIC4CheckBox};
|
||||||
|
|
||||||
|
QLineEdit * const readChosenFileEdits[] = {ui->chosenReadIC1File,
|
||||||
|
ui->chosenReadIC2File,
|
||||||
|
ui->chosenReadIC3File,
|
||||||
|
ui->chosenReadIC4File};
|
||||||
|
|
||||||
|
bool hadError = false;
|
||||||
|
|
||||||
|
QFile *files[sizeof(readBoxes)/sizeof(readBoxes[0])] = {NULL, NULL, NULL, NULL};
|
||||||
|
for (size_t x = 0; x < sizeof(files)/sizeof(files[0]); x++)
|
||||||
|
{
|
||||||
|
if (readBoxes[x]->isChecked())
|
||||||
|
{
|
||||||
|
files[x] = new QFile(readChosenFileEdits[x]->text());
|
||||||
|
if (!files[x]->open(QFile::WriteOnly))
|
||||||
|
{
|
||||||
|
hadError = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hadError)
|
||||||
|
{
|
||||||
|
for (size_t x = 0; x < sizeof(files)/sizeof(files[0]); x++)
|
||||||
|
{
|
||||||
|
if (files[x]) delete files[x];
|
||||||
|
}
|
||||||
|
|
||||||
|
programmerReadStatusChanged(ReadError);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take the final read file and de-interleave it into separate chip files
|
||||||
|
readBuffer->seek(0);
|
||||||
|
while (!readBuffer->atEnd())
|
||||||
|
{
|
||||||
|
// Go in reverse order through the files so the data is saved to the
|
||||||
|
// files in the correct order
|
||||||
|
for (int y = (int)(sizeof(files)/sizeof(files[0])) - 1; y >= 0; y--)
|
||||||
|
{
|
||||||
|
char c = 0xFF;
|
||||||
|
if (readBuffer->getChar(&c)) // grab a character...
|
||||||
|
{
|
||||||
|
// and as long as it was a success, stick it into the appropriate file
|
||||||
|
// (IF we have one), or discard it if we didn't care about the chip
|
||||||
|
// it went with.
|
||||||
|
if (files[y])
|
||||||
|
{
|
||||||
|
files[y]->putChar(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // no success? we're probably near end of SIMM. just discard it and close the file
|
||||||
|
{
|
||||||
|
files[y]->close();
|
||||||
|
delete files[y];
|
||||||
|
files[y] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the individual files that are remaining
|
||||||
|
for (size_t x = 0; x < sizeof(files)/sizeof(files[0]); x++)
|
||||||
|
{
|
||||||
|
if (files[x])
|
||||||
|
{
|
||||||
|
files[x]->close();
|
||||||
|
delete files[x];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::returnToControlPage()
|
||||||
|
{
|
||||||
|
// Depending on what we were doing, return to the correct page
|
||||||
|
if (writeBuffer || readBuffer)
|
||||||
|
{
|
||||||
|
ui->pages->setCurrentWidget(ui->flashChipsPage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->pages->setCurrentWidget(ui->controlPage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
18
mainwindow.h
18
mainwindow.h
@ -85,6 +85,17 @@ private slots:
|
|||||||
|
|
||||||
void on_howMuchToWriteBox_currentIndexChanged(int index);
|
void on_howMuchToWriteBox_currentIndexChanged(int index);
|
||||||
|
|
||||||
|
void on_flashIndividualEnterButton_clicked();
|
||||||
|
void on_returnNormalButton_clicked();
|
||||||
|
|
||||||
|
void updateFlashIndividualControlsEnabled();
|
||||||
|
void selectIndividualWriteFileClicked();
|
||||||
|
void selectIndividualReadFileClicked();
|
||||||
|
|
||||||
|
void on_multiFlashChipsButton_clicked();
|
||||||
|
void on_multiReadChipsButton_clicked();
|
||||||
|
void finishMultiRead();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
bool initializing;
|
bool initializing;
|
||||||
@ -93,9 +104,16 @@ private:
|
|||||||
QFile *writeFile;
|
QFile *writeFile;
|
||||||
QFile *readFile;
|
QFile *readFile;
|
||||||
QString electricalTestString;
|
QString electricalTestString;
|
||||||
|
QBuffer *writeBuffer;
|
||||||
|
QBuffer *readBuffer;
|
||||||
|
|
||||||
void resetAndShowStatusPage();
|
void resetAndShowStatusPage();
|
||||||
void handleVerifyFailureReply();
|
void handleVerifyFailureReply();
|
||||||
|
|
||||||
|
void hideFlashIndividualControls();
|
||||||
|
void showFlashIndividualControls();
|
||||||
|
|
||||||
|
void returnToControlPage();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MAINWINDOW_H
|
#endif // MAINWINDOW_H
|
||||||
|
296
mainwindow.ui
296
mainwindow.ui
@ -7,7 +7,7 @@
|
|||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>557</width>
|
<width>557</width>
|
||||||
<height>405</height>
|
<height>444</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
@ -24,7 +24,7 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QStackedWidget" name="pages">
|
<widget class="QStackedWidget" name="pages">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>3</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="controlPage">
|
<widget class="QWidget" name="controlPage">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
@ -174,6 +174,13 @@
|
|||||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="flashIndividualEnterButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Flash individual chips...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="horizontalSpacer">
|
<spacer name="horizontalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
@ -207,7 +214,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer_2">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
</property>
|
</property>
|
||||||
@ -276,6 +283,289 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QWidget" name="flashChipsPage">
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_14">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_4">
|
||||||
|
<property name="title">
|
||||||
|
<string>Flash file(s) to chips</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_13">
|
||||||
|
<item>
|
||||||
|
<layout class="QFormLayout" name="formLayout_4">
|
||||||
|
<property name="fieldGrowthPolicy">
|
||||||
|
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QCheckBox" name="flashIC1CheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Flash IC1:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_22">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="chosenFlashIC1File"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="selectFlashIC1Button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Select file...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QCheckBox" name="flashIC2CheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Flash IC2:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_23">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="chosenFlashIC2File"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="selectFlashIC2Button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Select file...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_24">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="chosenFlashIC3File"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="selectFlashIC3Button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Select file...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_25">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="chosenFlashIC4File"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="selectFlashIC4Button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Select file...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QCheckBox" name="flashIC3CheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Flash IC3:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QCheckBox" name="flashIC4CheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Flash IC4:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_26">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_8">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="multiFlashChipsButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Flash chip(s)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox_3">
|
||||||
|
<property name="title">
|
||||||
|
<string>Read files(s) from chips</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_12">
|
||||||
|
<item>
|
||||||
|
<layout class="QFormLayout" name="formLayout_3">
|
||||||
|
<property name="fieldGrowthPolicy">
|
||||||
|
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QCheckBox" name="readIC1CheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Read IC1:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_17">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="chosenReadIC1File"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="selectReadIC1Button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Select file...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QCheckBox" name="readIC2CheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Read IC2:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_18">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="chosenReadIC2File"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="selectReadIC2Button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Select file...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_19">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="chosenReadIC3File"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="selectReadIC3Button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Select file...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_20">
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="chosenReadIC4File"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="selectReadIC4Button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Select file...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QCheckBox" name="readIC3CheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Read IC3:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QCheckBox" name="readIC4CheckBox">
|
||||||
|
<property name="text">
|
||||||
|
<string>Read IC4:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_21">
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_7">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="multiReadChipsButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Read chip(s)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_29">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>This mode allows you to flash/read individual chips on a SIMM</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer_9">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="returnNormalButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Return to normal mode</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
133
programmer.cpp
133
programmer.cpp
@ -28,6 +28,8 @@ typedef enum ProgrammerCommandState
|
|||||||
|
|
||||||
WriteSIMMWaitingSetSizeReply,
|
WriteSIMMWaitingSetSizeReply,
|
||||||
WriteSIMMWaitingSetVerifyModeReply,
|
WriteSIMMWaitingSetVerifyModeReply,
|
||||||
|
WriteSIMMWaitingSetChipMaskReply,
|
||||||
|
WriteSIMMWaitingSetChipMaskValueReply,
|
||||||
WriteSIMMWaitingEraseReply,
|
WriteSIMMWaitingEraseReply,
|
||||||
WriteSIMMWaitingWriteReply,
|
WriteSIMMWaitingWriteReply,
|
||||||
WriteSIMMWaitingFinishReply,
|
WriteSIMMWaitingFinishReply,
|
||||||
@ -65,6 +67,8 @@ typedef enum ProgrammerCommandState
|
|||||||
|
|
||||||
WritePortionWaitingSetSizeReply,
|
WritePortionWaitingSetSizeReply,
|
||||||
WritePortionWaitingSetVerifyModeReply,
|
WritePortionWaitingSetVerifyModeReply,
|
||||||
|
WritePortionWaitingSetChipMaskReply,
|
||||||
|
WritePortionWaitingSetChipMaskValueReply,
|
||||||
WritePortionWaitingEraseReply,
|
WritePortionWaitingEraseReply,
|
||||||
WritePortionWaitingEraseConfirmation,
|
WritePortionWaitingEraseConfirmation,
|
||||||
WritePortionWaitingEraseResult,
|
WritePortionWaitingEraseResult,
|
||||||
@ -96,7 +100,8 @@ typedef enum ProgrammerCommand
|
|||||||
SetNoVerifyWhileWriting,
|
SetNoVerifyWhileWriting,
|
||||||
ErasePortion,
|
ErasePortion,
|
||||||
WriteChipsAt,
|
WriteChipsAt,
|
||||||
ReadChipsAt
|
ReadChipsAt,
|
||||||
|
SetChipsMask
|
||||||
} ProgrammerCommand;
|
} ProgrammerCommand;
|
||||||
|
|
||||||
typedef enum ProgrammerReply
|
typedef enum ProgrammerReply
|
||||||
@ -259,9 +264,10 @@ void Programmer::internalReadSIMM(QIODevice *device, uint32_t len, uint32_t offs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Programmer::writeToSIMM(QIODevice *device)
|
void Programmer::writeToSIMM(QIODevice *device, uint8_t chipsMask)
|
||||||
{
|
{
|
||||||
writeDevice = device;
|
writeDevice = device;
|
||||||
|
writeChipMask = chipsMask;
|
||||||
if (writeDevice->size() > SIMMCapacity())
|
if (writeDevice->size() > SIMMCapacity())
|
||||||
{
|
{
|
||||||
curState = WaitingForNextCommand;
|
curState = WaitingForNextCommand;
|
||||||
@ -288,9 +294,10 @@ void Programmer::writeToSIMM(QIODevice *device)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Programmer::writeToSIMM(QIODevice *device, uint32_t startOffset, uint32_t length)
|
void Programmer::writeToSIMM(QIODevice *device, uint32_t startOffset, uint32_t length, uint8_t chipsMask)
|
||||||
{
|
{
|
||||||
writeDevice = device;
|
writeDevice = device;
|
||||||
|
writeChipMask = chipsMask;
|
||||||
if ((writeDevice->size() > SIMMCapacity()) ||
|
if ((writeDevice->size() > SIMMCapacity()) ||
|
||||||
(startOffset + length > SIMMCapacity()))
|
(startOffset + length > SIMMCapacity()))
|
||||||
{
|
{
|
||||||
@ -451,20 +458,16 @@ void Programmer::handleChar(uint8_t c)
|
|||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case CommandReplyOK:
|
case CommandReplyOK:
|
||||||
// If we got an OK reply, we're ready to go, so start...
|
// If we got an OK reply, we're good. Now try to set the chip mask.
|
||||||
|
|
||||||
// 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);
|
|
||||||
if (curState == WriteSIMMWaitingSetVerifyModeReply)
|
if (curState == WriteSIMMWaitingSetVerifyModeReply)
|
||||||
{
|
{
|
||||||
sendByte(EraseChips);
|
sendByte(SetChipsMask);
|
||||||
curState = WriteSIMMWaitingEraseReply;
|
curState = WriteSIMMWaitingSetChipMaskReply;
|
||||||
}
|
}
|
||||||
else if (curState == WritePortionWaitingSetVerifyModeReply)
|
else if (curState == WritePortionWaitingSetVerifyModeReply)
|
||||||
{
|
{
|
||||||
sendByte(ErasePortion);
|
sendByte(SetChipsMask);
|
||||||
curState = WritePortionWaitingEraseReply;
|
curState = WritePortionWaitingSetChipMaskReply;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CommandReplyInvalid:
|
case CommandReplyInvalid:
|
||||||
@ -488,20 +491,104 @@ void Programmer::handleChar(uint8_t c)
|
|||||||
// the firmware doesn't need updating -- it just didn't know how to handle
|
// the firmware doesn't need updating -- it just didn't know how to handle
|
||||||
// the "set verify mode" command. But that's OK -- we don't need
|
// the "set verify mode" command. But that's OK -- we don't need
|
||||||
// that command if we're not verifying while writing.
|
// that command if we're not verifying while writing.
|
||||||
|
|
||||||
|
// So move onto the next thing to try.
|
||||||
|
if (curState == WriteSIMMWaitingSetVerifyModeReply)
|
||||||
|
{
|
||||||
|
sendByte(SetChipsMask);
|
||||||
|
curState = WriteSIMMWaitingSetChipMaskReply;
|
||||||
|
}
|
||||||
|
else if (curState == WritePortionWaitingSetVerifyModeReply)
|
||||||
|
{
|
||||||
|
sendByte(SetChipsMask);
|
||||||
|
curState = WritePortionWaitingSetChipMaskReply;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WriteSIMMWaitingSetChipMaskReply:
|
||||||
|
case WritePortionWaitingSetChipMaskReply:
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case CommandReplyOK:
|
||||||
|
// OK, now we can send the chip mask and move onto the next state
|
||||||
|
sendByte(writeChipMask);
|
||||||
|
if (curState == WriteSIMMWaitingSetChipMaskReply)
|
||||||
|
{
|
||||||
|
curState = WriteSIMMWaitingSetChipMaskValueReply;
|
||||||
|
}
|
||||||
|
else if (curState == WritePortionWaitingSetChipMaskReply)
|
||||||
|
{
|
||||||
|
curState = WritePortionWaitingSetChipMaskValueReply;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CommandReplyInvalid:
|
||||||
|
case CommandReplyError:
|
||||||
|
// Error reply. If we're trying to set a mask of 0x0F, no error, it
|
||||||
|
// just means the firmware's out of date and doesn't support setting
|
||||||
|
// custom chip masks. Ignore and move on.
|
||||||
|
if (writeChipMask == 0x0F)
|
||||||
|
{
|
||||||
|
// OK, erase the SIMM and get the ball rolling.
|
||||||
// Special case: Send out notification we are starting an erase command.
|
// 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.
|
// I don't have any hooks into the process between now and the erase reply.
|
||||||
emit writeStatusChanged(WriteErasing);
|
emit writeStatusChanged(WriteErasing);
|
||||||
if (curState == WriteSIMMWaitingSetVerifyModeReply)
|
if (curState == WriteSIMMWaitingSetChipMaskReply)
|
||||||
{
|
{
|
||||||
sendByte(EraseChips);
|
sendByte(EraseChips);
|
||||||
curState = WriteSIMMWaitingEraseReply;
|
curState = WriteSIMMWaitingEraseReply;
|
||||||
}
|
}
|
||||||
else if (curState == WritePortionWaitingSetVerifyModeReply)
|
else if (curState == WritePortionWaitingSetChipMaskReply)
|
||||||
{
|
{
|
||||||
sendByte(ErasePortion);
|
sendByte(ErasePortion);
|
||||||
curState = WritePortionWaitingEraseReply;
|
curState = WritePortionWaitingEraseReply;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Uh oh -- this is an old firmware that doesn't support custom
|
||||||
|
// chip masks. Let the caller know that the programmer board
|
||||||
|
// needs a firmware update.
|
||||||
|
qDebug() << "Programmer board needs firmware update.";
|
||||||
|
curState = WaitingForNextCommand;
|
||||||
|
closePort();
|
||||||
|
emit writeStatusChanged(WriteNeedsFirmwareUpdateIndividualChips);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WriteSIMMWaitingSetChipMaskValueReply:
|
||||||
|
case WritePortionWaitingSetChipMaskValueReply:
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case CommandReplyOK:
|
||||||
|
// OK, erase the SIMM and get the ball rolling.
|
||||||
|
// 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);
|
||||||
|
if (curState == WriteSIMMWaitingSetChipMaskValueReply)
|
||||||
|
{
|
||||||
|
sendByte(EraseChips);
|
||||||
|
curState = WriteSIMMWaitingEraseReply;
|
||||||
|
}
|
||||||
|
else if (curState == WritePortionWaitingSetChipMaskValueReply)
|
||||||
|
{
|
||||||
|
sendByte(ErasePortion);
|
||||||
|
curState = WritePortionWaitingEraseReply;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CommandReplyInvalid:
|
||||||
|
case CommandReplyError:
|
||||||
|
// Error after trying to set the value.
|
||||||
|
qDebug() << "Error reply setting chip mask.";
|
||||||
|
curState = WaitingForNextCommand;
|
||||||
|
closePort();
|
||||||
|
emit writeStatusChanged(WriteError);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1569,7 +1656,23 @@ void Programmer::doVerifyAfterWriteCompare()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emitStatus = WriteVerificationFailure;
|
// Now make sure we're not complaining about chips we didn't
|
||||||
|
// write to...this will zero out errors on chips we weren't
|
||||||
|
// flashing, but will leave errors intact for chips we did write.
|
||||||
|
// (the chip mask is backwards from the IC numbering...that's why
|
||||||
|
// I have to do this in a special way)
|
||||||
|
if ((writeChipMask & 0x01) == 0) _verifyBadChipMask &= ~0x08;
|
||||||
|
if ((writeChipMask & 0x02) == 0) _verifyBadChipMask &= ~0x04;
|
||||||
|
if ((writeChipMask & 0x04) == 0) _verifyBadChipMask &= ~0x02;
|
||||||
|
if ((writeChipMask & 0x08) == 0) _verifyBadChipMask &= ~0x01;
|
||||||
|
if (_verifyBadChipMask != 0)
|
||||||
|
{
|
||||||
|
emitStatus = WriteVerificationFailure;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
emitStatus = WriteCompleteVerifyOK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -63,7 +63,8 @@ typedef enum WriteStatus
|
|||||||
WriteVerifyTimedOut,
|
WriteVerifyTimedOut,
|
||||||
WriteCompleteVerifyOK,
|
WriteCompleteVerifyOK,
|
||||||
WriteEraseBlockWrongSize,
|
WriteEraseBlockWrongSize,
|
||||||
WriteNeedsFirmwareUpdateErasePortion
|
WriteNeedsFirmwareUpdateErasePortion,
|
||||||
|
WriteNeedsFirmwareUpdateIndividualChips
|
||||||
} WriteStatus;
|
} WriteStatus;
|
||||||
|
|
||||||
typedef enum ElectricalTestStatus
|
typedef enum ElectricalTestStatus
|
||||||
@ -119,8 +120,8 @@ public:
|
|||||||
explicit Programmer(QObject *parent = 0);
|
explicit Programmer(QObject *parent = 0);
|
||||||
virtual ~Programmer();
|
virtual ~Programmer();
|
||||||
void readSIMM(QIODevice *device, uint32_t len = 0);
|
void readSIMM(QIODevice *device, uint32_t len = 0);
|
||||||
void writeToSIMM(QIODevice *device);
|
void writeToSIMM(QIODevice *device, uint8_t chipsMask = 0x0F);
|
||||||
void writeToSIMM(QIODevice *device, uint32_t startOffset, uint32_t length);
|
void writeToSIMM(QIODevice *device, uint32_t startOffset, uint32_t length, uint8_t chipsMask = 0x0F);
|
||||||
void runElectricalTest();
|
void runElectricalTest();
|
||||||
QString electricalTestPinName(uint8_t index);
|
QString electricalTestPinName(uint8_t index);
|
||||||
void identifySIMMChips();
|
void identifySIMMChips();
|
||||||
@ -200,6 +201,7 @@ private:
|
|||||||
|
|
||||||
uint32_t writeOffset;
|
uint32_t writeOffset;
|
||||||
uint32_t writeLength;
|
uint32_t writeLength;
|
||||||
|
uint8_t writeChipMask;
|
||||||
|
|
||||||
void openPort();
|
void openPort();
|
||||||
void closePort();
|
void closePort();
|
||||||
|
Loading…
Reference in New Issue
Block a user