almost ready to merge into master
[avrdudequi:avrdudequi.git] / avrdudequi.cpp
1 /***************************************************************************
2  *   Copyright (C) 2011 by Maurilio                                        *
3  *   mau_ri_tec@yahoo.it                                                   *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20
21 #include "avrdudequi.h"
22 #include "ui_avrdudequi.h"
23 #include <QDebug>
24 #include <QVariant>
25 #include <QFileDialog>
26 #include <QDir>
27 #include "programmerdataview.h"
28 #include <QGroupBox>
29
30
31 AvrDudeQui::AvrDudeQui(QWidget *parent) :
32     QMainWindow(parent),
33     ui(new Ui::AvrDudeQui),
34     minimumStep(0), currentPath(QDir::homePath())
35 {
36     ui->setupUi(this);
37
38     enableButtonWrite(false);
39     enableButtonRead(true);
40
41     ui->ckBoxOnFlash->setEnabled(false);
42     ui->ckBoxOnEEprom->setEnabled(false);
43     ui->ckBoxOnFuse->setEnabled(false);
44     ui->ckBoxOnLockBit->setEnabled(false);
45     cBoxMcuChanged(ui->cBoxMcu->currentIndex());
46
47     connect(ui->tbClearLE, SIGNAL(clicked()), this, SLOT(clearFlashEdit()));
48     connect(ui->writeButton, SIGNAL(clicked()), this, SLOT(writeData()));
49     connect(ui->readButton, SIGNAL(clicked()), this, SLOT(readData()));
50
51     connect(ui->ckBoxOnFlash, SIGNAL(toggled(bool)), this, SLOT(operateModeChanged()));
52     connect(ui->ckBoxOnFuse, SIGNAL(toggled(bool)), this, SLOT(operateModeChanged()));
53     connect(ui->ckBoxOnLockBit, SIGNAL(toggled(bool)), this, SLOT(operateModeChanged()));
54     connect(ui->ckBoxOnEEprom, SIGNAL(toggled(bool)), this, SLOT(operateModeChanged()));
55     connect(ui->cBoxMcu, SIGNAL(currentIndexChanged(int)), this, SLOT(cBoxMcuChanged(int)));
56
57     theProgrammer = Programmer::instance();
58     theProgrammer->setParent(this);
59
60     ProgrammerDataView *programmerDataView = ProgrammerDataView::instance();
61     programmerDataView->setContainer(ui->gBoxProgrammer);
62
63     connect(theProgrammer, SIGNAL(programmerChanged(QString)), this, SLOT(cBoxProgChanged(QString)));
64
65     theMcu = Mcu::instance();
66     theMcu->setParent(this);
67     connect(theMcu, SIGNAL(currentWidgetChanged(QWidget*)), this, SLOT(changeWidget(QWidget*)));
68
69     connect(ui->actionOpenHexProgram, SIGNAL(triggered()), this, SLOT(loadHex()));
70     connect(ui->tbBrowseFile, SIGNAL(clicked()), this, SLOT(loadHex()));
71     connect(ui->flashFile, SIGNAL(textChanged(QString)), this, SLOT(noEdit()));
72
73     theMcu->loadEmptyWidget();
74     //windowBaseSize = sizeHint();
75     resize(QSize(955,850));
76     connect(ui->splitter, SIGNAL(splitterMoved(int,int)), this, SLOT(splitterMoved(int,int)));
77
78 }
79
80 AvrDudeQui::~AvrDudeQui()
81 {
82     delete ui;
83 }
84
85 void AvrDudeQui::noEdit()
86 {
87    ui->flashFile->setText(flashFileName);
88 }
89
90 void AvrDudeQui::operateModeChanged()
91 {
92     updateChange();
93 }
94
95 void AvrDudeQui::clearFlashEdit()
96 {
97     flashFileName.clear();
98     noEdit();
99     ui->ckBoxOnFlash->setEnabled(false);
100     ui->ckBoxOnFlash->setChecked(false);
101     ui->flashFile->setToolTip(flashFileName);
102 }
103
104 void AvrDudeQui::loadHex()
105 {
106     flashFileName = QFileDialog::getOpenFileName(this,
107         tr("Open ihex file"), currentPath, tr("ihex files (*.hex)"));
108     if (flashFileName.isEmpty()) {
109         if (!ui->flashFile->text().isEmpty())
110             flashFileName = ui->flashFile->text();
111         return;
112     }
113     ui->flashFile->setToolTip(flashFileName);
114     currentPath = QDir(flashFileName).absolutePath();
115     ui->flashFile->blockSignals(true);
116     ui->flashFile->setText(flashFileName);
117     ui->flashFile->blockSignals(false);
118     ui->ckBoxOnFlash->setEnabled(true);
119     ui->ckBoxOnFlash->setChecked(true);
120 }
121
122
123
124 void AvrDudeQui::populate()
125 {
126     theProgrammer->fillProgrammer(ui->cBoxProgrammer);
127     theMcu->fillMcu(ui->cBoxMcu);
128 }
129
130 void AvrDudeQui::cBoxProgChanged(const QString &name)
131 {
132     ProgrammerDataView *programmerDataView = ProgrammerDataView::instance();
133     programmerDataView->viewData(name);
134
135     QList<int> splitterSizes = ui->splitter->sizes();
136     splitterSizes[0] = ui->gBoxProgrammer->layout()->totalSizeHint().width() + 55;
137     ui->splitter->setSizes(splitterSizes);
138     updateChange();
139 }
140
141 void AvrDudeQui::splitterMoved(int a0, int a1)
142 {
143     Q_UNUSED(a1)
144     //splitterWidgetSize = ui->splitter->sizes();
145     //qDebug() << a0;
146     //qDebug() << "ui->splitter->sizeHint()" << ui->splitter->minimumSizeHint();
147     //qDebug() << "ui->splitter.size()" << ui->splitter->size();
148     //qDebug() << sizeHint();
149     //qDebug() << size();
150     //
151
152 }
153
154
155 void AvrDudeQui::cBoxMcuChanged(int idx)
156 {
157     ui->mcu_info->setText("Mcu type: " + ui->cBoxMcu->itemText(idx));
158
159 }
160
161 void AvrDudeQui::changeWidget(QWidget *mcuWidget)
162 {
163
164     if (mcuWidget)
165         ui->splitter->addWidget(mcuWidget);
166
167     updateChange();
168 }
169
170
171 void AvrDudeQui::updateChange()
172 {
173
174     if (!theProgrammer->isValid() || theMcu->getMcu().isEmpty()) {
175         enableButtonWrite(false);
176         enableButtonRead(false);
177         ui->ckBoxOnFuse->setDisabled(true);
178
179     } else {
180         enableButtonRead(true);
181         ui->ckBoxOnFuse->setDisabled(false);
182         ui->ckBoxOnLockBit->setDisabled(false);
183
184         if (ui->ckBoxOnFlash->isChecked()
185                 || ui->ckBoxOnFuse->isChecked()
186                 || ui->ckBoxOnLockBit->isChecked())
187             {
188                 enableButtonWrite(true);
189             } else {
190             enableButtonWrite(false);
191         }
192     }
193
194 }
195
196 void AvrDudeQui::writeData()
197 {
198     progData = theProgrammer->dataMap();
199
200     QString commandLine = "";
201     QString command = theMcu->getBackEnd();
202     QString arg_mcu = " -p " + theMcu->getMcu();
203     QString arg_programmer = " -c " + progData->value("id.dudeid");
204     QString arg_port = " -P " + progData->value("device.device_file");
205     QString arg_baudrate = " -b " + progData->value("device.baudrate");
206     QString arg_bitclock = " -B " + progData->value("opt.bitclock.period");
207
208     commandLine = command
209                 + arg_mcu
210                 + arg_programmer
211                 + arg_port;
212     if (!progData->value("device.baudrate").isEmpty())
213         commandLine += arg_baudrate;
214     if (!progData->value("opt.bitclock").isEmpty())
215         commandLine += arg_bitclock;
216
217     if (ui->ckBoxOnFlash->isChecked())
218         commandLine += " -U flash:w:" + flashFileName;
219     if (ui->ckBoxOnFuse->isChecked()) {
220         QList<QMap<QString, QString> > m_allFuses = theMcu->getAllFuse();
221
222         for (int i=0; i<m_allFuses.count(); i++) {
223
224             commandLine += " -U " + m_allFuses.at(i).value("FuseArg")
225                         + ":w:" + m_allFuses.at(i).value("FuseValue") + ":m";
226         }
227     }
228
229     //qDebug() << commandLine;
230     RunProcessDialog dialog(commandLine, this);
231     int result = dialog.exec();
232 //    qDebug() << "result" << result;
233 }
234
235 void AvrDudeQui::readData()
236 {
237
238     progData = theProgrammer->dataMap();
239     QString commandLine = "";
240     QString command = theMcu->getBackEnd();
241     QString arg_mcu = " -p " + theMcu->getMcu();
242     QString arg_programmer = " -c " + progData->value("id.dudeid");
243     QString arg_port = " -P " + progData->value("device.device_file");
244     QString arg_baudrate = " -b " + progData->value("device.baudrate");
245     QString arg_bitclock = " -B " + progData->value("opt.bitclock.period");
246
247     commandLine = command
248                 + arg_mcu
249                 + arg_programmer
250                 + arg_port;
251
252     if (!progData->value("device.baudrate").isEmpty())
253         commandLine += arg_baudrate;
254     if (!progData->value("opt.bitclock").isEmpty())
255         commandLine += arg_bitclock;
256
257     if (ui->ckBoxOnFuse->isChecked()) {
258         QList<QMap<QString, QString> > m_allFuses = theMcu->getAllFuse();
259
260         for (int i=0; i<m_allFuses.count(); i++) {
261
262             commandLine += " -U " + m_allFuses.at(i).value("FuseArg") + ":r:-:h";
263         }
264     }
265
266     // crea il comando per operare sui lockbit solo se ckBoxOnLockBit รจ selezionato
267     if (ui->ckBoxOnLockBit->isChecked()) {
268         commandLine += " -U lock:r:-:h";
269
270     }
271
272     qDebug() << commandLine;
273     //commandLine += " -v";
274     RunProcessDialog dialog(commandLine, this);
275     int result = dialog.exec();
276     if (!result) {
277         ParserOutput parserOutput(dialog.getOutput());
278         if(ui->ckBoxOnFuse->isChecked()) {
279             QMap<QString, QString> fuses = parserOutput.getAllFuseValue();
280             theMcu->setFuses(fuses);
281         }
282
283         if (ui->ckBoxOnLockBit->isChecked()) {
284             QMap<QString, QString> lockBit = parserOutput.getLockBitValue();
285             qDebug() << "lockBit da map vale:" << lockBit;
286             theMcu->setLockBit(lockBit);
287         }
288
289     }
290 }
291
292 void AvrDudeQui::enableButtonRead(bool tf = false)
293 {
294     ui->readButton->setEnabled(tf);
295 }
296
297 void AvrDudeQui::enableButtonWrite(bool tf = false)
298 {
299     ui->writeButton->setEnabled(tf);
300 }
301