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
717
mainwindow.cpp
717
mainwindow.cpp
@ -35,7 +35,11 @@ static Programmer *p;
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent) :
|
||||
QMainWindow(parent),
|
||||
ui(new Ui::MainWindow)
|
||||
ui(new Ui::MainWindow),
|
||||
writeFile(NULL),
|
||||
readFile(NULL),
|
||||
writeBuffer(NULL),
|
||||
readBuffer(NULL)
|
||||
{
|
||||
initializing = true;
|
||||
// Make default QSettings use these settings
|
||||
@ -46,6 +50,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
|
||||
p = new Programmer();
|
||||
ui->setupUi(this);
|
||||
hideFlashIndividualControls();
|
||||
ui->pages->setCurrentWidget(ui->notConnectedPage);
|
||||
ui->actionUpdate_firmware->setEnabled(false);
|
||||
|
||||
@ -122,9 +127,6 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
ui->statusLabel->setText("");
|
||||
ui->cancelButton->setEnabled(false);
|
||||
|
||||
readFile = NULL;
|
||||
writeFile = NULL;
|
||||
|
||||
connect(p, SIGNAL(writeStatusChanged(WriteStatus)), SLOT(programmerWriteStatusChanged(WriteStatus)));
|
||||
connect(p, SIGNAL(writeTotalLengthChanged(uint32_t)), SLOT(programmerWriteTotalLengthChanged(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()));
|
||||
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;
|
||||
}
|
||||
|
||||
@ -177,6 +210,18 @@ void MainWindow::on_selectReadFileButton_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)
|
||||
{
|
||||
readFile->close();
|
||||
@ -204,6 +249,18 @@ void MainWindow::on_readFromSIMMButton_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)
|
||||
{
|
||||
writeFile->close();
|
||||
@ -273,7 +330,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
||||
switch (newStatus)
|
||||
{
|
||||
case WriteErasing:
|
||||
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;
|
||||
case WriteCompleteNoVerify:
|
||||
if (writeFile)
|
||||
@ -284,7 +348,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
||||
}
|
||||
|
||||
QMessageBox::information(this, "Write complete", "The write operation finished.");
|
||||
ui->pages->setCurrentWidget(ui->controlPage);
|
||||
|
||||
returnToControlPage();
|
||||
if (writeBuffer)
|
||||
{
|
||||
writeBuffer->close();
|
||||
delete writeBuffer;
|
||||
writeBuffer = NULL;
|
||||
}
|
||||
break;
|
||||
case WriteCompleteVerifyOK:
|
||||
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.");
|
||||
ui->pages->setCurrentWidget(ui->controlPage);
|
||||
break;
|
||||
|
||||
returnToControlPage();
|
||||
if (writeBuffer)
|
||||
{
|
||||
writeBuffer->close();
|
||||
delete writeBuffer;
|
||||
writeBuffer = NULL;
|
||||
}
|
||||
break;
|
||||
case WriteVerifying:
|
||||
resetAndShowStatusPage();
|
||||
break;
|
||||
@ -311,8 +388,15 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
||||
delete writeFile;
|
||||
writeFile = NULL;
|
||||
}
|
||||
ui->pages->setCurrentWidget(ui->controlPage);
|
||||
|
||||
returnToControlPage();
|
||||
QMessageBox::warning(this, "Verify error", "An error occurred reading the SIMM contents for verification.");
|
||||
if (writeBuffer)
|
||||
{
|
||||
writeBuffer->close();
|
||||
delete writeBuffer;
|
||||
writeBuffer = NULL;
|
||||
}
|
||||
break;
|
||||
case WriteVerifyCancelled:
|
||||
if (writeFile)
|
||||
@ -322,8 +406,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
||||
writeFile = NULL;
|
||||
}
|
||||
|
||||
ui->pages->setCurrentWidget(ui->controlPage);
|
||||
returnToControlPage();
|
||||
QMessageBox::warning(this, "Verify cancelled", "The verify operation was cancelled.");
|
||||
if (writeBuffer)
|
||||
{
|
||||
writeBuffer->close();
|
||||
delete writeBuffer;
|
||||
writeBuffer = NULL;
|
||||
}
|
||||
break;
|
||||
case WriteVerifyTimedOut:
|
||||
if (writeFile)
|
||||
@ -333,8 +423,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
||||
writeFile = NULL;
|
||||
}
|
||||
|
||||
ui->pages->setCurrentWidget(ui->controlPage);
|
||||
returnToControlPage();
|
||||
QMessageBox::warning(this, "Verify timed out", "The verify operation timed out.");
|
||||
if (writeBuffer)
|
||||
{
|
||||
writeBuffer->close();
|
||||
delete writeBuffer;
|
||||
writeBuffer = NULL;
|
||||
}
|
||||
break;
|
||||
case WriteVerificationFailure:
|
||||
if (writeFile)
|
||||
@ -347,6 +443,12 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
||||
// The verify failure code is somewhat complicated so it's best to put
|
||||
// it elsewhere.
|
||||
handleVerifyFailureReply();
|
||||
if (writeBuffer)
|
||||
{
|
||||
writeBuffer->close();
|
||||
delete writeBuffer;
|
||||
writeBuffer = NULL;
|
||||
}
|
||||
break;
|
||||
case WriteError:
|
||||
if (writeFile)
|
||||
@ -356,8 +458,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
||||
writeFile = NULL;
|
||||
}
|
||||
|
||||
ui->pages->setCurrentWidget(ui->controlPage);
|
||||
returnToControlPage();
|
||||
QMessageBox::warning(this, "Write error", "An error occurred writing to the SIMM.");
|
||||
if (writeBuffer)
|
||||
{
|
||||
writeBuffer->close();
|
||||
delete writeBuffer;
|
||||
writeBuffer = NULL;
|
||||
}
|
||||
break;
|
||||
case WriteNeedsFirmwareUpdateBiggerSIMM:
|
||||
if (writeFile)
|
||||
@ -367,8 +475,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
||||
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.");
|
||||
if (writeBuffer)
|
||||
{
|
||||
writeBuffer->close();
|
||||
delete writeBuffer;
|
||||
writeBuffer = NULL;
|
||||
}
|
||||
break;
|
||||
case WriteNeedsFirmwareUpdateVerifyWhileWrite:
|
||||
if (writeFile)
|
||||
@ -378,8 +492,48 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
||||
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.");
|
||||
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;
|
||||
case WriteCancelled:
|
||||
if (writeFile)
|
||||
@ -389,8 +543,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
||||
writeFile = NULL;
|
||||
}
|
||||
|
||||
ui->pages->setCurrentWidget(ui->controlPage);
|
||||
returnToControlPage();
|
||||
QMessageBox::warning(this, "Write cancelled", "The write operation was cancelled.");
|
||||
if (writeBuffer)
|
||||
{
|
||||
writeBuffer->close();
|
||||
delete writeBuffer;
|
||||
writeBuffer = NULL;
|
||||
}
|
||||
break;
|
||||
case WriteEraseComplete:
|
||||
ui->statusLabel->setText("Writing SIMM...");
|
||||
@ -403,8 +563,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
||||
writeFile = NULL;
|
||||
}
|
||||
|
||||
ui->pages->setCurrentWidget(ui->controlPage);
|
||||
returnToControlPage();
|
||||
QMessageBox::warning(this, "Write error", "An error occurred erasing the SIMM.");
|
||||
if (writeBuffer)
|
||||
{
|
||||
writeBuffer->close();
|
||||
delete writeBuffer;
|
||||
writeBuffer = NULL;
|
||||
}
|
||||
break;
|
||||
case WriteTimedOut:
|
||||
if (writeFile)
|
||||
@ -414,8 +580,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
||||
writeFile = NULL;
|
||||
}
|
||||
|
||||
ui->pages->setCurrentWidget(ui->controlPage);
|
||||
returnToControlPage();
|
||||
QMessageBox::warning(this, "Write timed out", "The write operation timed out.");
|
||||
if (writeBuffer)
|
||||
{
|
||||
writeBuffer->close();
|
||||
delete writeBuffer;
|
||||
writeBuffer = NULL;
|
||||
}
|
||||
break;
|
||||
case WriteFileTooBig:
|
||||
if (writeFile)
|
||||
@ -425,8 +597,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
||||
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.");
|
||||
if (writeBuffer)
|
||||
{
|
||||
writeBuffer->close();
|
||||
delete writeBuffer;
|
||||
writeBuffer = NULL;
|
||||
}
|
||||
break;
|
||||
case WriteEraseBlockWrongSize:
|
||||
if (writeFile)
|
||||
@ -436,8 +614,14 @@ void MainWindow::programmerWriteStatusChanged(WriteStatus newStatus)
|
||||
writeFile = NULL;
|
||||
}
|
||||
|
||||
ui->pages->setCurrentWidget(ui->controlPage);
|
||||
returnToControlPage();
|
||||
QMessageBox::warning(this, "Bad erase size", "The programmer cannot handle the erase size you chose.");
|
||||
if (writeBuffer)
|
||||
{
|
||||
writeBuffer->close();
|
||||
delete writeBuffer;
|
||||
writeBuffer = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -523,9 +707,18 @@ void MainWindow::programmerReadStatusChanged(ReadStatus newStatus)
|
||||
delete readFile;
|
||||
readFile = NULL;
|
||||
}
|
||||
if (readBuffer)
|
||||
{
|
||||
finishMultiRead();
|
||||
}
|
||||
|
||||
ui->pages->setCurrentWidget(ui->controlPage);
|
||||
returnToControlPage();
|
||||
QMessageBox::information(this, "Read complete", "The read operation finished.");
|
||||
if (readBuffer)
|
||||
{
|
||||
delete readBuffer;
|
||||
readBuffer = NULL;
|
||||
}
|
||||
break;
|
||||
case ReadError:
|
||||
if (readFile)
|
||||
@ -535,8 +728,13 @@ void MainWindow::programmerReadStatusChanged(ReadStatus newStatus)
|
||||
readFile = NULL;
|
||||
}
|
||||
|
||||
ui->pages->setCurrentWidget(ui->controlPage);
|
||||
returnToControlPage();
|
||||
QMessageBox::warning(this, "Read error", "An error occurred reading from the SIMM.");
|
||||
if (readBuffer)
|
||||
{
|
||||
delete readBuffer;
|
||||
readBuffer = NULL;
|
||||
}
|
||||
break;
|
||||
case ReadCancelled:
|
||||
if (readFile)
|
||||
@ -546,8 +744,13 @@ void MainWindow::programmerReadStatusChanged(ReadStatus newStatus)
|
||||
readFile = NULL;
|
||||
}
|
||||
|
||||
ui->pages->setCurrentWidget(ui->controlPage);
|
||||
returnToControlPage();
|
||||
QMessageBox::warning(this, "Read cancelled", "The read operation was cancelled.");
|
||||
if (readBuffer)
|
||||
{
|
||||
delete readBuffer;
|
||||
readBuffer = NULL;
|
||||
}
|
||||
break;
|
||||
case ReadTimedOut:
|
||||
if (readFile)
|
||||
@ -557,8 +760,13 @@ void MainWindow::programmerReadStatusChanged(ReadStatus newStatus)
|
||||
readFile = NULL;
|
||||
}
|
||||
|
||||
ui->pages->setCurrentWidget(ui->controlPage);
|
||||
returnToControlPage();
|
||||
QMessageBox::warning(this, "Read timed out", "The read operation timed out.");
|
||||
if (readBuffer)
|
||||
{
|
||||
delete readBuffer;
|
||||
readBuffer = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -668,7 +876,7 @@ void MainWindow::on_identifyButton_clicked()
|
||||
|
||||
void MainWindow::programmerBoardConnected()
|
||||
{
|
||||
ui->pages->setCurrentWidget(ui->controlPage);
|
||||
returnToControlPage();
|
||||
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);
|
||||
}
|
||||
|
||||
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_flashIndividualEnterButton_clicked();
|
||||
void on_returnNormalButton_clicked();
|
||||
|
||||
void updateFlashIndividualControlsEnabled();
|
||||
void selectIndividualWriteFileClicked();
|
||||
void selectIndividualReadFileClicked();
|
||||
|
||||
void on_multiFlashChipsButton_clicked();
|
||||
void on_multiReadChipsButton_clicked();
|
||||
void finishMultiRead();
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
bool initializing;
|
||||
@ -93,9 +104,16 @@ private:
|
||||
QFile *writeFile;
|
||||
QFile *readFile;
|
||||
QString electricalTestString;
|
||||
QBuffer *writeBuffer;
|
||||
QBuffer *readBuffer;
|
||||
|
||||
void resetAndShowStatusPage();
|
||||
void handleVerifyFailureReply();
|
||||
|
||||
void hideFlashIndividualControls();
|
||||
void showFlashIndividualControls();
|
||||
|
||||
void returnToControlPage();
|
||||
};
|
||||
|
||||
#endif // MAINWINDOW_H
|
||||
|
296
mainwindow.ui
296
mainwindow.ui
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>557</width>
|
||||
<height>405</height>
|
||||
<height>444</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -24,7 +24,7 @@
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="pages">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>3</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="controlPage">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
@ -174,6 +174,13 @@
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="flashIndividualEnterButton">
|
||||
<property name="text">
|
||||
<string>Flash individual chips...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
@ -207,7 +214,7 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
@ -276,6 +283,289 @@
|
||||
</item>
|
||||
</layout>
|
||||
</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>
|
||||
</item>
|
||||
</layout>
|
||||
|
131
programmer.cpp
131
programmer.cpp
@ -28,6 +28,8 @@ typedef enum ProgrammerCommandState
|
||||
|
||||
WriteSIMMWaitingSetSizeReply,
|
||||
WriteSIMMWaitingSetVerifyModeReply,
|
||||
WriteSIMMWaitingSetChipMaskReply,
|
||||
WriteSIMMWaitingSetChipMaskValueReply,
|
||||
WriteSIMMWaitingEraseReply,
|
||||
WriteSIMMWaitingWriteReply,
|
||||
WriteSIMMWaitingFinishReply,
|
||||
@ -65,6 +67,8 @@ typedef enum ProgrammerCommandState
|
||||
|
||||
WritePortionWaitingSetSizeReply,
|
||||
WritePortionWaitingSetVerifyModeReply,
|
||||
WritePortionWaitingSetChipMaskReply,
|
||||
WritePortionWaitingSetChipMaskValueReply,
|
||||
WritePortionWaitingEraseReply,
|
||||
WritePortionWaitingEraseConfirmation,
|
||||
WritePortionWaitingEraseResult,
|
||||
@ -96,7 +100,8 @@ typedef enum ProgrammerCommand
|
||||
SetNoVerifyWhileWriting,
|
||||
ErasePortion,
|
||||
WriteChipsAt,
|
||||
ReadChipsAt
|
||||
ReadChipsAt,
|
||||
SetChipsMask
|
||||
} ProgrammerCommand;
|
||||
|
||||
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;
|
||||
writeChipMask = chipsMask;
|
||||
if (writeDevice->size() > SIMMCapacity())
|
||||
{
|
||||
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;
|
||||
writeChipMask = chipsMask;
|
||||
if ((writeDevice->size() > SIMMCapacity()) ||
|
||||
(startOffset + length > SIMMCapacity()))
|
||||
{
|
||||
@ -451,20 +458,16 @@ void Programmer::handleChar(uint8_t c)
|
||||
switch (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);
|
||||
// If we got an OK reply, we're good. Now try to set the chip mask.
|
||||
if (curState == WriteSIMMWaitingSetVerifyModeReply)
|
||||
{
|
||||
sendByte(EraseChips);
|
||||
curState = WriteSIMMWaitingEraseReply;
|
||||
sendByte(SetChipsMask);
|
||||
curState = WriteSIMMWaitingSetChipMaskReply;
|
||||
}
|
||||
else if (curState == WritePortionWaitingSetVerifyModeReply)
|
||||
{
|
||||
sendByte(ErasePortion);
|
||||
curState = WritePortionWaitingEraseReply;
|
||||
sendByte(SetChipsMask);
|
||||
curState = WritePortionWaitingSetChipMaskReply;
|
||||
}
|
||||
break;
|
||||
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 "set verify mode" command. But that's OK -- we don't need
|
||||
// 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.
|
||||
// I don't have any hooks into the process between now and the erase reply.
|
||||
emit writeStatusChanged(WriteErasing);
|
||||
if (curState == WriteSIMMWaitingSetVerifyModeReply)
|
||||
if (curState == WriteSIMMWaitingSetChipMaskReply)
|
||||
{
|
||||
sendByte(EraseChips);
|
||||
curState = WriteSIMMWaitingEraseReply;
|
||||
}
|
||||
else if (curState == WritePortionWaitingSetVerifyModeReply)
|
||||
else if (curState == WritePortionWaitingSetChipMaskReply)
|
||||
{
|
||||
sendByte(ErasePortion);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1569,6 +1656,17 @@ void Programmer::doVerifyAfterWriteCompare()
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
@ -1577,6 +1675,11 @@ void Programmer::doVerifyAfterWriteCompare()
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
emitStatus = WriteCompleteVerifyOK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Wrong amount of data read back for some reason...shouldn't ever happen,
|
||||
// but I'll call it a verification failure.
|
||||
|
@ -63,7 +63,8 @@ typedef enum WriteStatus
|
||||
WriteVerifyTimedOut,
|
||||
WriteCompleteVerifyOK,
|
||||
WriteEraseBlockWrongSize,
|
||||
WriteNeedsFirmwareUpdateErasePortion
|
||||
WriteNeedsFirmwareUpdateErasePortion,
|
||||
WriteNeedsFirmwareUpdateIndividualChips
|
||||
} WriteStatus;
|
||||
|
||||
typedef enum ElectricalTestStatus
|
||||
@ -119,8 +120,8 @@ public:
|
||||
explicit Programmer(QObject *parent = 0);
|
||||
virtual ~Programmer();
|
||||
void readSIMM(QIODevice *device, uint32_t len = 0);
|
||||
void writeToSIMM(QIODevice *device);
|
||||
void writeToSIMM(QIODevice *device, uint32_t startOffset, uint32_t length);
|
||||
void writeToSIMM(QIODevice *device, uint8_t chipsMask = 0x0F);
|
||||
void writeToSIMM(QIODevice *device, uint32_t startOffset, uint32_t length, uint8_t chipsMask = 0x0F);
|
||||
void runElectricalTest();
|
||||
QString electricalTestPinName(uint8_t index);
|
||||
void identifySIMMChips();
|
||||
@ -200,6 +201,7 @@ private:
|
||||
|
||||
uint32_t writeOffset;
|
||||
uint32_t writeLength;
|
||||
uint8_t writeChipMask;
|
||||
|
||||
void openPort();
|
||||
void closePort();
|
||||
|
Loading…
Reference in New Issue
Block a user