You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1341 lines
54 KiB
1341 lines
54 KiB
#include "i2c_keyboard_detection.h"
|
|
#include "ui_i2c_keyboard_detection.h"
|
|
|
|
#include <qfile.h>
|
|
#include <qevent.h>
|
|
|
|
#include <qmessagebox.h>
|
|
#include <qfiledialog.h>
|
|
|
|
#include <qdatetime.h>
|
|
|
|
i2c_keyboard_detection::i2c_keyboard_detection(QWidget *parent) :
|
|
QMainWindow(parent),
|
|
ui(new Ui::i2c_keyboard_detection)
|
|
{
|
|
ui->setupUi(this);
|
|
QObject::connect(&m_com, SIGNAL(readyRead()), this, SLOT(comDataReceived()));
|
|
QFile fileKbdCodes("hid_codes.txt"/*"hid_keyboard_codes.h"*/);
|
|
if (!fileKbdCodes.open(QFile::ReadOnly))
|
|
return;
|
|
m_keyComments.clear();
|
|
ui->keyList->clear();
|
|
while(1) {
|
|
QString currentStr = QString(fileKbdCodes.readLine());
|
|
if (currentStr.length() == 0)
|
|
break;
|
|
#if 1
|
|
currentStr = currentStr.left(currentStr.indexOf("//"));
|
|
QStringList currentStrDiv = currentStr.split(QRegExp("\\s"));
|
|
for (int i = (currentStrDiv.length() - 1); i >= 0; i--)
|
|
{
|
|
if(currentStrDiv[i] == "")
|
|
currentStrDiv.removeAt(i);
|
|
}
|
|
if (currentStrDiv.length() != 2)
|
|
continue;
|
|
bool isKbdCode;
|
|
int kbdCode = currentStrDiv[1].toInt(&isKbdCode, 16);
|
|
if (!isKbdCode)
|
|
{
|
|
QMessageBox::warning(this, "UNCORRECT HID CODES FILE", "Code " + currentStrDiv[1] + " is not hex");
|
|
break;
|
|
}
|
|
if (m_kbdCodes.contains(kbdCode))
|
|
{
|
|
QMessageBox::warning(this, "UNCORRECT HID CODES FILE", "One HID code used two times, code " + QString::number(kbdCode, 16));
|
|
break;
|
|
}
|
|
m_kbdCodes.push_back(kbdCode);
|
|
QString addedElement = currentStrDiv[0] + " (" + QString::number(kbdCode,16) + ")";
|
|
ui->keyList->addItem(addedElement);
|
|
#else
|
|
QString strComment = currentStr.right(currentStr.length() - currentStr.indexOf("//"));
|
|
currentStr = currentStr.left(currentStr.indexOf("//"));
|
|
QStringList strWords = currentStr.split(QRegExp("\\s"));
|
|
for (int i = (strWords.length() - 1); i >= 0; i--)
|
|
{
|
|
if (strWords[i].length() == 0)
|
|
strWords.removeAt(i);
|
|
}
|
|
if (strWords.length() != 3)
|
|
continue;
|
|
if (strWords[0] != "#define")
|
|
continue;
|
|
if (!strWords[2].startsWith("0x"))
|
|
continue;
|
|
strWords[2] = strWords[2].right(2);
|
|
bool isKbdCode;
|
|
int kbdCode = strWords[2].toInt(&isKbdCode, 16);
|
|
if (!isKbdCode)
|
|
continue;
|
|
if (strWords[1].contains("KEY_"))
|
|
strWords[1] = strWords[1].right(strWords[1].length()-4);
|
|
QString addedElement = strWords[1] + " (" + QString::number(kbdCode,16) + ")";
|
|
ui->keyList->addItem(addedElement);
|
|
m_keyComments.push_back(strComment);
|
|
#endif
|
|
}
|
|
ui->label_keyComment->setText(QString::number(m_kbdCodes.length()) + " keys in list");
|
|
fileKbdCodes.close();
|
|
ui->generatedMatrixTable->setShowGrid(true); // Включаем сетку
|
|
// Разрешаем выделение только одного элемента
|
|
ui->generatedMatrixTable->setSelectionMode(QAbstractItemView::SingleSelection);
|
|
//
|
|
ui->generatedMatrixTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
|
//int res = system("iceprog hardware.bin");
|
|
//qDebug ("Result: %u", res);
|
|
//ui->keyList->event();
|
|
QObject::connect(ui->normalMatrixMode, SIGNAL(toggled(bool)), this, SLOT(displayMatrix()));
|
|
QObject::connect(ui->fnMatrixMode, SIGNAL(toggled(bool)), this, SLOT(displayMatrix()));
|
|
|
|
//m_fpgaFwGeneratorTrd.start();
|
|
//m_fpgaFwGenerator.moveToThread(&m_fpgaFwGeneratorTrd);
|
|
m_fpgaFwGenerator = new QProcess(Q_NULLPTR/*this*/);
|
|
m_fpgaFwGenerator->setProcessChannelMode(QProcess::ProcessChannelMode::MergedChannels);
|
|
QObject::connect(m_fpgaFwGenerator, SIGNAL(readyRead()), this, SLOT(processReadyRead()));
|
|
QObject::connect(m_fpgaFwGenerator, SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(processFinished(int,QProcess::ExitStatus)));
|
|
QObject::connect(m_fpgaFwGenerator, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
|
|
|
|
QObject::connect(&m_uiKbdList, SIGNAL(kbdSelected(int, int)), this, SLOT(qmkKbdSelected(int, int)));
|
|
}
|
|
|
|
i2c_keyboard_detection::~i2c_keyboard_detection()
|
|
{
|
|
delete ui;
|
|
}
|
|
|
|
void i2c_keyboard_detection::keyPressEvent(QKeyEvent *e)
|
|
{
|
|
qDebug("Key pressed: %u", e->nativeScanCode());
|
|
// Qt::Key_S;
|
|
}
|
|
|
|
void i2c_keyboard_detection::on_keyList_itemSelectionChanged()
|
|
{
|
|
qDebug ("Current key item changed! Now %u", ui->keyList->currentRow());
|
|
if (ui->keyList->currentRow() < 0)
|
|
return;
|
|
/*ui->keyList->setToolTip*///ui->label_keyComment->setText(m_keyComments.at(ui->keyList->currentRow()));
|
|
QString currentKey = ui->keyList->currentItem()->text();
|
|
for (int i = 0; i < m_kbdDetectReport.length(); i++)
|
|
{
|
|
if ((m_kbdDetectReport[i].split("\t").at(0) == currentKey) && (ui->enSendKeyToReport->isChecked()))
|
|
QMessageBox::warning(this, "KEY IS ALREADY ADDED", "This key was already added to report. When you press some key, old value will be lost");
|
|
}
|
|
}
|
|
|
|
void i2c_keyboard_detection::on_comRefleshList_clicked()
|
|
{
|
|
QList<QSerialPortInfo> comList = QSerialPortInfo::availablePorts();
|
|
ui->comList->clear();
|
|
for (int i = 0; i < comList.length(); i++)
|
|
ui->comList->addItem(comList.at(i).portName());
|
|
}
|
|
|
|
void i2c_keyboard_detection::on_comConnect_clicked()
|
|
{
|
|
QWidget* widgets_locked[] = { ui->comList, ui->comRefleshList };
|
|
QWidget* widgets_unlocked[] = { };
|
|
if (ui->comConnect->text() == "Connect") {
|
|
m_com.setPortName(ui->comList->currentText());
|
|
if (m_com.open(QSerialPort::ReadWrite)) {
|
|
m_com.setParity(QSerialPort::NoParity);
|
|
m_com.setDataBits(QSerialPort::Data8);
|
|
m_com.setStopBits(QSerialPort::OneStop);
|
|
m_com.setFlowControl(QSerialPort::NoFlowControl);
|
|
m_com.setBaudRate(115200);
|
|
ui->comConnect->setText("Disconnect");
|
|
m_kbdDetectBytes.clear();
|
|
m_kbdDetectData.clear();
|
|
m_isFirstComMsg = true;
|
|
}
|
|
else
|
|
QMessageBox::warning(this, "COM OPEN ERROR", "Com " + ui->comList->currentText() + " cannot open!");
|
|
}
|
|
else {
|
|
m_com.close();
|
|
ui->comConnect->setText("Connect");
|
|
}
|
|
for (int i = 0; i < sizeof(widgets_locked)/sizeof(QWidget*); i++)
|
|
widgets_locked[i]->setEnabled(!m_com.isOpen());
|
|
for (int i = 0; i < sizeof(widgets_unlocked)/sizeof(QWidget*); i++)
|
|
widgets_unlocked[i]->setEnabled(m_com.isOpen());
|
|
}
|
|
|
|
void i2c_keyboard_detection::comDataReceived()
|
|
{
|
|
QByteArray dataFromCom = m_com.readAll();
|
|
for (int i = 0; i < dataFromCom.length(); i++)
|
|
{
|
|
if (dataFromCom[i] == 0xFF)
|
|
{
|
|
if (m_kbdDetectBytes.length() != 5)
|
|
{
|
|
//on_comConnect_clicked();
|
|
if (m_isFirstComMsg)
|
|
m_isFirstComMsg = false;
|
|
else
|
|
QMessageBox::warning(this, "COM PROTOCOL ERROR", "Received start, but last frame is not complete");
|
|
}
|
|
m_kbdDetectBytes.clear();
|
|
}
|
|
else
|
|
{
|
|
m_kbdDetectBytes.push_back(dataFromCom[i]);
|
|
if (m_kbdDetectBytes.length() > 5)
|
|
{
|
|
if (m_com.isOpen())
|
|
on_comConnect_clicked();
|
|
QMessageBox::warning(this, "COM PROTOCOL ERROR", "Received extra byte of frame");
|
|
}
|
|
else if (m_kbdDetectBytes.length() == 5)
|
|
{
|
|
int64_t result = ((((int64_t)m_kbdDetectBytes[4]) & 0xFF) << 0) |
|
|
((((int64_t)m_kbdDetectBytes[3]) & 0xFF) << 8) | ((((int64_t)m_kbdDetectBytes[2]) & 0xFF) << 16) |
|
|
((((int64_t)m_kbdDetectBytes[1]) & 0xFF) << 24) | ((((int64_t)m_kbdDetectBytes[0]) & 0xFF) << 32);
|
|
//m_kbdDetectBytes.clear();
|
|
if (result != 0)
|
|
{
|
|
for (int k = 0; k < m_kbdDetectData.length(); k++) {
|
|
if (m_kbdDetectData[k] == result)
|
|
return; // RECEIVING IN PROCESS, WAIT TERMINATION FRAME, THIS FRAME WAS ALREADY ADDED
|
|
}
|
|
m_kbdDetectData.push_back(result);
|
|
return; // RECEIVING IN PROCESS, WAIT TERMINATION FRAME
|
|
}
|
|
// TERMINATION FRAME PROCESSING START
|
|
QString currentStatus;
|
|
QVector<int> connectedLines;
|
|
if (m_kbdDetectData.length() == 0)
|
|
currentStatus = "No keys are pressed";
|
|
else {
|
|
currentStatus = "Detected connections: ";
|
|
for (int k = 0; k < m_kbdDetectData.length(); k++) {
|
|
//currentKbdReport = currentKbdReport + QString::number(last_kbd_data[k]) + ", ";
|
|
for (quint64 n = 0; n < 34; n++) {
|
|
quint64 mask = 1;
|
|
mask = mask << n;
|
|
if ((m_kbdDetectData[k] & mask) != 0)
|
|
{
|
|
currentStatus = currentStatus + QString::number(n) + " ";
|
|
connectedLines.push_back(n);
|
|
}
|
|
}
|
|
currentStatus = currentStatus + ", ";
|
|
}
|
|
currentStatus = currentStatus.left(currentStatus.length() - 2);
|
|
m_kbdDetectData.clear();
|
|
}
|
|
currentStatus = currentStatus + " (" + QTime::currentTime().toString("HH:mm:ss.zzz") + ")";
|
|
ui->labelKeyboardStatus->setText(currentStatus);
|
|
if ((connectedLines.length() != 0) && (ui->enSendKeyToReport->isChecked()) && (ui->keyList->currentRow() >= 0))
|
|
{
|
|
QString currentKey = ui->keyList->currentItem()->text();
|
|
for (int k = (m_kbdDetectReport.length() - 1); k >=0; k--)
|
|
{
|
|
if (m_kbdDetectReport[k].split("\t").at(0) == currentKey)
|
|
m_kbdDetectReport.remove(k);
|
|
}
|
|
for (int k = 0; k < connectedLines.length(); k++)
|
|
currentKey = currentKey + "\t" + QString::number(connectedLines[k]);
|
|
m_kbdDetectReport.push_front(currentKey);
|
|
QString tarReport;
|
|
tarReport = "Now " + QString::number(m_kbdDetectReport.length()) + " keys added\n";
|
|
for (int k = 0; k < m_kbdDetectReport.length(); k++)
|
|
tarReport = tarReport + m_kbdDetectReport[k] + "\n";
|
|
ui->kbdReport->setText(tarReport);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void i2c_keyboard_detection::on_enSendKeyToReport_clicked(bool checked)
|
|
{
|
|
if (checked)
|
|
on_keyList_itemSelectionChanged();
|
|
}
|
|
|
|
void i2c_keyboard_detection::on_saveKbdReport_clicked()
|
|
{
|
|
QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "kbd_connections.txt", tr("*.txt"));
|
|
if (fileName == "")
|
|
return;
|
|
QFile savedFile(fileName);
|
|
if (!savedFile.open(QFile::WriteOnly))
|
|
{
|
|
QMessageBox::warning(this, "CANNOT SAVE FILE", "Can't open file for save report");
|
|
return;
|
|
}
|
|
QString tarReport;
|
|
for (int k = 0; k < m_kbdDetectReport.length(); k++)
|
|
tarReport = tarReport + m_kbdDetectReport[k] + "\n";
|
|
if (savedFile.exists())
|
|
savedFile.resize(0);
|
|
savedFile.write(tarReport.toUtf8());
|
|
savedFile.close();
|
|
}
|
|
|
|
void i2c_keyboard_detection::on_openConnectionsFile_clicked()
|
|
{
|
|
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "kbd_connections.txt", tr("*.txt"));
|
|
if (fileName == "")
|
|
return;
|
|
QFile openedFile(fileName);
|
|
if (!openedFile.open(QFile::ReadOnly))
|
|
{
|
|
QMessageBox::warning(this, "CANNOT OPEN FILE", "Can't open file for save report");
|
|
return;
|
|
}
|
|
QVector<QString> keyNames;
|
|
QVector<int> keyIo;
|
|
while(1)
|
|
{
|
|
QString currentStr = QString(openedFile.readLine());
|
|
if (currentStr.length() == 0)
|
|
break;
|
|
QStringList strWords = currentStr.split("\t");
|
|
if (strWords.length() != 3)
|
|
{
|
|
openedFile.close();
|
|
QMessageBox::warning(this, "UNCORRECT FILE OPENED", "Uncorrect data in file: str without 2 tabs");
|
|
return;
|
|
}
|
|
if ((strWords[0].indexOf("(") == -1) || (strWords[0].indexOf(")") == -1))
|
|
{
|
|
openedFile.close();
|
|
QMessageBox::warning(this, "UNCORRECT FILE OPENED", "Uncorrect data in file: uncorrect key description (no hex key value)");
|
|
return;
|
|
}
|
|
else if ((strWords[0] [strWords[0].length()-1] != ")") || ((strWords[0][strWords[0].length()-3] != "(") && (strWords[0][strWords[0].length()-4] != "(")))
|
|
{
|
|
openedFile.close();
|
|
QMessageBox::warning(this, "UNCORRECT FILE OPENED", "Uncorrect data in file: uncorrect key description (no hex key value)");
|
|
return;
|
|
}
|
|
else if (strWords[0][strWords[0].length()-3] == "(")
|
|
strWords[0].insert(strWords[0].length() - 2, "0");
|
|
keyNames.push_back(strWords[0]);
|
|
int pin1Num, pin2Num;
|
|
bool pinCorr1, pinCorr2;
|
|
pin1Num = strWords[1].toInt(&pinCorr1, 10);
|
|
pin2Num = strWords[2].toInt(&pinCorr2, 10);
|
|
if ((pinCorr1 == false) || (pinCorr2 == false))
|
|
{
|
|
openedFile.close();
|
|
QMessageBox::warning(this, "UNCORRECT FILE OPENED", "Uncorrect data in file: uncorrect pin number");
|
|
return;
|
|
}
|
|
keyIo.push_back(pin1Num);
|
|
keyIo.push_back(pin2Num);
|
|
}
|
|
openedFile.close();
|
|
QVector<int> allIoNumbers;
|
|
for (int i = 0; i < keyIo.length(); i++)
|
|
{
|
|
if (allIoNumbers.indexOf(keyIo[i]) == -1)
|
|
allIoNumbers.push_back(keyIo[i]);
|
|
}
|
|
qSort(allIoNumbers);
|
|
|
|
QVector<QVector<int>> ioConnections(allIoNumbers.length());
|
|
for (int i = 0; i < ioConnections.length(); i++)
|
|
{
|
|
ioConnections[i].clear();
|
|
for (int j = 0; j < keyIo.length(); j++)
|
|
{
|
|
if (allIoNumbers[i] == keyIo[j])
|
|
{
|
|
int num2;
|
|
if ((j % 2) == 0)
|
|
num2 = j + 1;
|
|
else
|
|
num2 = j - 1;
|
|
if (keyIo[num2] == allIoNumbers[i])
|
|
{
|
|
QMessageBox::warning(this, "UNCORRECT FILE OPENED", "Uncorrect data in file: pin numbers of one key are the same!");
|
|
return;
|
|
}
|
|
if (ioConnections[i].indexOf(keyIo[num2]) == -1)
|
|
ioConnections[i].push_back(keyIo[num2]);
|
|
}
|
|
}
|
|
}
|
|
|
|
QVector<QVector<QVector<QString>>> allGeneratedMatrixes;
|
|
QVector<QVector<int>> allGeneratedColumns;
|
|
QVector<QVector<int>> allGeneratedRows;
|
|
for (int i = 0; i < allIoNumbers.length(); i++)
|
|
{
|
|
int currentColumnCnt = 0;
|
|
int currentRowCnt = 0;
|
|
QVector<int> currentColumn(1, allIoNumbers[i]);
|
|
QVector<int> currentRow;
|
|
while(1)
|
|
{
|
|
if (currentColumnCnt == currentColumn.length())
|
|
{
|
|
qDebug ("Warning, not all IO sorted!");
|
|
break;
|
|
}
|
|
for (int j = currentColumnCnt; j < currentColumn.length(); j++)
|
|
{
|
|
int ioIndex = allIoNumbers.indexOf(currentColumn[j]);
|
|
if (ioIndex == -1)
|
|
{
|
|
QMessageBox::warning(this, "CRITICAL ALGORITM ERROR", "Need more engeneers-programmists!");
|
|
return;
|
|
}
|
|
for (int k = 0; k < ioConnections[ioIndex].length(); k++)
|
|
{
|
|
if (currentRow.indexOf(ioConnections[ioIndex][k]) == -1)
|
|
currentRow.push_back(ioConnections[ioIndex][k]);
|
|
}
|
|
}
|
|
currentColumnCnt = currentColumn.length();
|
|
|
|
if ((currentRow.length() + currentColumn.length()) == allIoNumbers.length())
|
|
break;
|
|
|
|
if (currentRowCnt == currentRow.length())
|
|
{
|
|
qDebug ("Warning, not all IO sorted!");
|
|
break;
|
|
}
|
|
for (int j = currentRowCnt; j < currentRow.length(); j++)
|
|
{
|
|
int ioIndex = allIoNumbers.indexOf(currentRow[j]);
|
|
if (ioIndex == -1)
|
|
{
|
|
QMessageBox::warning(this, "CRITICAL ALGORITM ERROR", "Need more engeneers-programmists!");
|
|
return;
|
|
}
|
|
for (int k = 0; k < ioConnections[ioIndex].length(); k++)
|
|
{
|
|
if (currentColumn.indexOf(ioConnections[ioIndex][k]) == -1)
|
|
currentColumn.push_back(ioConnections[ioIndex][k]);
|
|
}
|
|
}
|
|
currentRowCnt = currentRow.length();
|
|
|
|
if ((currentRow.length() + currentColumn.length()) == allIoNumbers.length())
|
|
break;
|
|
}
|
|
qSort(currentColumn);
|
|
qSort(currentRow);
|
|
qDebug ("Columns and rows are sorted!");
|
|
if (currentColumn.length() != currentRow.length())
|
|
{
|
|
if (currentColumn.length() > currentRow.length()/*currentRow.indexOf(allIoNumbers[0]) == -1*/)
|
|
{
|
|
QVector<int> temp(currentRow);
|
|
currentRow = currentColumn;
|
|
currentColumn = temp;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (currentRow.indexOf(allIoNumbers[0]) == -1)
|
|
{
|
|
QVector<int> temp(currentRow);
|
|
currentRow = currentColumn;
|
|
currentColumn = temp;
|
|
}
|
|
}
|
|
|
|
if ((!allGeneratedRows.contains(currentRow)) || (!allGeneratedColumns.contains(currentColumn)))
|
|
{
|
|
allGeneratedRows.push_back(currentRow);
|
|
allGeneratedColumns.push_back(currentColumn);
|
|
QVector<QVector<QString>> currentMatrix(currentRow.length());
|
|
for (int j = 0; j < currentRow.length(); j++)
|
|
{
|
|
currentMatrix[j].resize(currentColumn.length());
|
|
currentMatrix[j].fill("(00)");
|
|
for (int k = 0; k < currentColumn.length(); k++)
|
|
{
|
|
for (int n = 0; n < (keyIo.length() / 2); n++)
|
|
{
|
|
if (((currentColumn[k] == keyIo[2*n]) && (currentRow[j] == keyIo[2*n+1])) ||
|
|
((currentColumn[k] == keyIo[2*n+1]) && (currentRow[j] == keyIo[2*n])))
|
|
{
|
|
if (currentMatrix[j][k] != "(00)")
|
|
{
|
|
QMessageBox::warning(this, "CRITICAL ALGORITM ERROR",
|
|
QString("More than one pin with column %1 and row %2 detected").arg(currentColumn[j]).arg(currentRow[k]));
|
|
return;
|
|
}
|
|
currentMatrix[j][k] = keyNames[n];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
allGeneratedMatrixes.push_back(currentMatrix);
|
|
}
|
|
}
|
|
if (allGeneratedMatrixes.length() != 1)
|
|
{
|
|
QMessageBox::warning(this, "ALGORITM WARNING", "More than one matrix is generated, this option is not added yet");
|
|
return;
|
|
}
|
|
QString tarMatrix = "\t";
|
|
for (int i = 0; i < allGeneratedColumns[0].length(); i++)
|
|
tarMatrix = tarMatrix + QString::number(allGeneratedColumns[0][i]) + "\t";
|
|
for (int i = 0; i < allGeneratedRows[0].length(); i++)
|
|
{
|
|
tarMatrix = tarMatrix + "\n" + QString::number(allGeneratedRows[0][i]);
|
|
for (int j = 0; j < allGeneratedColumns[0].length(); j++)
|
|
tarMatrix = tarMatrix + "\t" + allGeneratedMatrixes[0][i][j];
|
|
}
|
|
m_generatedMatrix = allGeneratedMatrixes[0];
|
|
m_generatedFnMatrix = allGeneratedMatrixes[0];
|
|
|
|
m_generatedColumns.resize(allGeneratedColumns[0].length());
|
|
for (int i = 0; i < allGeneratedColumns[0].length(); i++)
|
|
m_generatedColumns[i] = QString::number(allGeneratedColumns[0][i]);
|
|
m_generatedRows.resize(allGeneratedRows[0].length());
|
|
for (int i = 0; i < allGeneratedRows[0].length(); i++)
|
|
m_generatedRows[i] = QString::number(allGeneratedRows[0][i]);
|
|
//m_generatedColumns = allGeneratedColumns[0];
|
|
//m_generatedRows = allGeneratedRows[0];
|
|
|
|
displayMatrix();
|
|
}
|
|
|
|
void i2c_keyboard_detection::on_clearKbdReport_clicked()
|
|
{
|
|
m_kbdDetectReport.clear();
|
|
ui->kbdReport->clear();
|
|
}
|
|
|
|
void i2c_keyboard_detection::resizeEvent(QResizeEvent *event)
|
|
{
|
|
static bool isStarted = false;
|
|
if (!isStarted)
|
|
{
|
|
isStarted = true;
|
|
return;
|
|
}
|
|
int dx = event->size().width() - event->oldSize().width();
|
|
int dy = event->size().height() - event->oldSize().height();
|
|
ui->tabWidget->resize(ui->tabWidget->size().width() + dx, ui->tabWidget->size().height() + dy);
|
|
ui->kbdReport->resize(ui->kbdReport->size().width() + dx, ui->kbdReport->size().height() + dy);
|
|
ui->generatedMatrixTable->resize(ui->generatedMatrixTable->size().width() + dx, ui->generatedMatrixTable->size().height() + dy);
|
|
QRect viewRect = ui->generatedMatrixTable->rect();
|
|
if (ui->generatedMatrixTable->columnCount() < 1)
|
|
return;
|
|
int columnWidth = (viewRect.width() - 100) / ui->generatedMatrixTable->columnCount();
|
|
for (int i = 0; i < ui->generatedMatrixTable->columnCount(); i++)
|
|
ui->generatedMatrixTable->setColumnWidth(i, columnWidth);
|
|
//ui->generatedMatrixTable->setFixedWidth(columnWidth*ui->generatedMatrixTable->columnCount());
|
|
}
|
|
|
|
void i2c_keyboard_detection::displayMatrix()
|
|
{
|
|
if ((m_generatedColumns.length() < 1) || (m_generatedRows.length() < 1) || (m_generatedMatrix.length() < 1))
|
|
return;
|
|
|
|
//
|
|
ui->generatedMatrixTable->clear();
|
|
ui->generatedMatrixTable->setRowCount(m_generatedRows.length());
|
|
ui->generatedMatrixTable->setColumnCount(m_generatedColumns.length()); // Указываем число колонок
|
|
|
|
QStringList matrixHeaders;
|
|
for (int i = 0; i < m_generatedColumns.length(); i++)
|
|
matrixHeaders.push_back(m_generatedColumns[i]);
|
|
// Устанавливаем заголовки колонок
|
|
ui->generatedMatrixTable->setHorizontalHeaderLabels(matrixHeaders);
|
|
|
|
int notEmptyElementsNum = 0;
|
|
for(int i = 0; i < m_generatedRows.length(); i++){
|
|
// Вставляем строку
|
|
//ui->generatedMatrixTable->insertRow(i);
|
|
for (int j = 0; j < m_generatedColumns.length(); j++)
|
|
{
|
|
QTableWidgetItem* newItem;
|
|
if (ui->normalMatrixMode->isChecked())
|
|
{
|
|
newItem = new QTableWidgetItem(m_generatedMatrix[i][j]);
|
|
if (m_generatedMatrix[i][j].contains("Fn"))
|
|
newItem->setBackground( QBrush ( QColor(170, 200, 255) ) );
|
|
}
|
|
else
|
|
{
|
|
newItem = new QTableWidgetItem(m_generatedFnMatrix[i][j]);
|
|
if (m_generatedFnMatrix[i][j] != m_generatedMatrix[i][j])
|
|
newItem->setBackground( QBrush ( QColor(170, 200, 255) ) );
|
|
if (m_generatedFnMatrix[i][j].contains("Fn"))
|
|
newItem->setBackground( QBrush ( QColor(170, 200, 255) ) );
|
|
}
|
|
if (m_generatedMatrix[i][j] == "(00)")
|
|
newItem->setBackground( QBrush ( QColor(180, 180, 180) ) );
|
|
else
|
|
notEmptyElementsNum++;
|
|
ui->generatedMatrixTable->setItem(i,j, newItem);
|
|
}
|
|
}
|
|
matrixHeaders.clear();
|
|
for (int i = 0; i < m_generatedRows.length(); i++)
|
|
matrixHeaders.push_back(m_generatedRows[i]);
|
|
ui->generatedMatrixTable->setVerticalHeaderLabels(matrixHeaders);
|
|
|
|
QRect viewRect = ui->generatedMatrixTable->rect();
|
|
int columnWidth = (viewRect.width() - 50) / m_generatedColumns.length();//Calculate first column's width as 80% of QTableView's width.
|
|
for (int i = 0; i < m_generatedColumns.length(); i++)
|
|
ui->generatedMatrixTable->setColumnWidth(i, columnWidth);
|
|
m_generatedNotEmptyElements = notEmptyElementsNum;
|
|
QString matrixInfo = QString("%1 columns, %2 rows, %3 elements").arg(m_generatedColumns.length()).arg(m_generatedRows.length()).arg(notEmptyElementsNum);
|
|
ui->label_matrixInfo->setText(matrixInfo);
|
|
|
|
// CALC ROW MERGING
|
|
QStringList rowMergingVariants;
|
|
for (int i = 0; i < (m_generatedMatrix.length() - 1); i++)
|
|
{
|
|
for (int j = (i + 1); j < m_generatedMatrix.length(); j++)
|
|
{
|
|
bool sameColumnsDetected = false;
|
|
for (int k = 0; k < m_generatedMatrix[i].length(); k++)
|
|
{
|
|
if ((m_generatedMatrix[i][k] != "(00)") && (m_generatedMatrix[j][k] != "(00)"))
|
|
sameColumnsDetected = true;
|
|
}
|
|
if (!sameColumnsDetected)
|
|
rowMergingVariants.push_back(m_generatedRows[i] + " + " + m_generatedRows[j]);
|
|
}
|
|
}
|
|
ui->mergingVariants->clear();
|
|
ui->mergingVariants->addItems(rowMergingVariants);
|
|
|
|
if ((m_diodeDirection >= 0) && (m_diodeDirection < ui->diodeDirection->count()))
|
|
ui->diodeDirection->setCurrentIndex(m_diodeDirection);
|
|
}
|
|
|
|
void i2c_keyboard_detection::on_swapColumnsAndRows_clicked()
|
|
{
|
|
QVector<QString> newColumns(m_generatedRows);
|
|
QVector<QString> newRows(m_generatedColumns);
|
|
QVector<QVector<QString>> newMatrix(newRows.length());
|
|
for (int i = 0; i < newMatrix.length(); i++)
|
|
{
|
|
newMatrix[i].resize(newColumns.length());
|
|
for (int j = 0; j < newColumns.length(); j++)
|
|
newMatrix[i][j] = m_generatedMatrix[j][i];
|
|
}
|
|
m_generatedMatrix = newMatrix;
|
|
for (int i = 0; i < newMatrix.length(); i++)
|
|
{
|
|
newMatrix[i].resize(newColumns.length());
|
|
for (int j = 0; j < newColumns.length(); j++)
|
|
newMatrix[i][j] = m_generatedFnMatrix[j][i];
|
|
}
|
|
m_generatedFnMatrix = newMatrix;
|
|
m_generatedRows = newRows;
|
|
m_generatedColumns = newColumns;
|
|
displayMatrix();
|
|
}
|
|
|
|
void i2c_keyboard_detection::on_mergeRows_clicked()
|
|
{
|
|
int index1, index2;
|
|
QStringList indexes = ui->mergingVariants->currentText().split(" + ");
|
|
if (indexes.length() != 2)
|
|
return;
|
|
index1 = m_generatedRows.indexOf(indexes[0]);
|
|
index2 = m_generatedRows.indexOf(indexes[1]);
|
|
QVector<QString> newRow(m_generatedColumns.length());
|
|
QVector<QString> newFnRow(m_generatedColumns.length());
|
|
for (int i = 0; i < m_generatedColumns.length(); i++)
|
|
{
|
|
if (m_generatedMatrix[index1][i] == "(00)")
|
|
{
|
|
newRow[i] = m_generatedMatrix[index2][i];
|
|
newFnRow[i] = m_generatedFnMatrix[index2][i];
|
|
}
|
|
else
|
|
{
|
|
newRow[i] = m_generatedMatrix[index1][i];
|
|
newFnRow[i] = m_generatedFnMatrix[index1][i];
|
|
}
|
|
}
|
|
m_generatedRows.remove(index2);
|
|
m_generatedRows[index1] = indexes[0] + "+" + indexes[1];
|
|
m_generatedMatrix.remove(index2);
|
|
m_generatedMatrix[index1] = newRow;
|
|
m_generatedFnMatrix.remove(index2);
|
|
m_generatedFnMatrix[index1] = newFnRow;
|
|
displayMatrix();
|
|
}
|
|
|
|
void i2c_keyboard_detection::on_setFnKey_clicked()
|
|
{
|
|
if (ui->generatedMatrixTable->selectedRanges().length() < 1)
|
|
return;
|
|
int row = ui->generatedMatrixTable->selectedRanges()[0].topRow();
|
|
int column = ui->generatedMatrixTable->selectedRanges()[0].leftColumn();
|
|
m_generatedFnMatrix[row][column] = ui->keyList->currentItem()->text();
|
|
displayMatrix();
|
|
}
|
|
|
|
void i2c_keyboard_detection::on_openMatrixKbdFile_clicked()
|
|
{
|
|
if ((m_generatedColumns.length() > 8) || (m_generatedRows.length() > 16) || (m_generatedColumns.length() == 0) || (m_generatedRows.length() == 0))
|
|
{
|
|
QMessageBox::warning(this, "INPUT DATA IS INCORRECT", "Columns num more than 8, or rows num more than 16, or columns are empty, or rows are empty");
|
|
return;
|
|
}
|
|
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File matrix_kbd.v"), "", tr("matrix_kbd.v"));
|
|
if (fileName == "")
|
|
return;
|
|
QFile openedFile(fileName);
|
|
if (!openedFile.open(QFile::ReadWrite))
|
|
{
|
|
QMessageBox::warning(this, "CANNOT OPEN FILE", "Can't open file for save report");
|
|
return;
|
|
}
|
|
QVector<QString> linesFromFile;
|
|
int declarationsCounter = 0;
|
|
int assignKbdRcStart = 0;
|
|
int assignColumnsStart = 0;
|
|
int kbdCodesRamStart = 0;
|
|
int kbdFnCodesRamStart = 0;
|
|
int kbdColumnsSbIoStart = 0; // TODO: ADD SEEKING OF THIS
|
|
int kbdRowsSbIoStart = 0; // TODO: ADD SEEKING OF THIS
|
|
while(1) {
|
|
QString currentStr = QString(openedFile.readLine());
|
|
if (currentStr.length() == 0)
|
|
break;
|
|
linesFromFile.push_back(currentStr);
|
|
int len = linesFromFile.length();
|
|
if ((linesFromFile[len - 1].contains("wire ")) && (linesFromFile[len - 1].contains(" KBD_ROWS_EN")))
|
|
declarationsCounter++;
|
|
else if ((linesFromFile[len - 1].contains("wire ")) && (linesFromFile[len - 1].contains(" KBD_ROWS_IN")))
|
|
declarationsCounter++;
|
|
else if ((linesFromFile[len - 1].contains("reg ")) && (linesFromFile[len - 1].contains(" KBD_ROWS_OUT")))
|
|
declarationsCounter++;
|
|
else if ((linesFromFile[len - 1].contains("reg ")) && (linesFromFile[len - 1].contains(" KBD_COLUMNS_EN")))
|
|
declarationsCounter++;
|
|
else if ((linesFromFile[len - 1].contains("wire ")) && (linesFromFile[len - 1].contains(" KBD_COLUMNS_IN")))
|
|
declarationsCounter++;
|
|
else if ((linesFromFile[len - 1].contains("reg ")) && (linesFromFile[len - 1].contains(" KBD_COLUMNS_OUT")))
|
|
declarationsCounter++;
|
|
else if (linesFromFile[len - 1].contains("assign KBD_ROWS_EN["))
|
|
{
|
|
assignKbdRcStart = len - 1;
|
|
linesFromFile.remove(len - 1);
|
|
}
|
|
else if (linesFromFile[len - 1].contains("assign COLUMNS["))
|
|
{
|
|
assignColumnsStart = len - 1;
|
|
linesFromFile.remove(len - 1);
|
|
}
|
|
else if (len > 12)
|
|
{
|
|
if ( (linesFromFile[len - 4].contains(".INIT_7(")) && (linesFromFile[len - 5].contains(".INIT_6(")) &&
|
|
(linesFromFile[len - 6].contains(".INIT_5(")) && (linesFromFile[len - 7].contains(".INIT_4(")) &&
|
|
(linesFromFile[len - 8].contains(".INIT_3(")) && (linesFromFile[len - 9].contains(".INIT_2(")) &&
|
|
(linesFromFile[len - 10].contains(".INIT_1(")) && (linesFromFile[len - 11].contains(".INIT_0(")) &&
|
|
(linesFromFile[len - 12].contains("SB_RAM40_4K #(")) )
|
|
{
|
|
if ((linesFromFile[len - 1].contains(") kbd_codes (")) && (kbdCodesRamStart == 0))
|
|
kbdCodesRamStart = len - 11;
|
|
else if ((linesFromFile[len - 1].contains(") kbd_codes_fn (")) && (kbdFnCodesRamStart == 0))
|
|
kbdFnCodesRamStart = len - 11;
|
|
else
|
|
{
|
|
QMessageBox::warning(this, "FILE ERROR!", "More than 2 RAM tables or uncorrect RAM tables in file!");
|
|
openedFile.close();
|
|
return;
|
|
}
|
|
}
|
|
else if ( (linesFromFile[len - 5].contains("SB_IO #(")) && (linesFromFile[len - 4].contains(".PIN_TYPE(6'b")) &&
|
|
(linesFromFile[len - 3].contains(".PULLUP(1'b")) && (linesFromFile[len - 1].contains(".PACKAGE_PIN(")) )
|
|
{
|
|
if ((linesFromFile[len - 2].contains("kbd_columns")) && (kbdColumnsSbIoStart == 0))
|
|
kbdColumnsSbIoStart = len - 1;
|
|
else if ((linesFromFile[len - 2].contains("kbd_rows")) && (kbdRowsSbIoStart == 0))
|
|
kbdRowsSbIoStart = len - 1;
|
|
else
|
|
{
|
|
QMessageBox::warning(this, "FILE ERROR!", "More than 2 SB IO or uncorrect SB IO in file!");
|
|
openedFile.close();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if ( (!((kbdRowsSbIoStart > kbdColumnsSbIoStart) && (kbdColumnsSbIoStart > kbdFnCodesRamStart) &&
|
|
(kbdFnCodesRamStart > kbdCodesRamStart) && (kbdCodesRamStart > assignKbdRcStart) && (assignKbdRcStart > assignColumnsStart)) ) ||
|
|
(kbdFnCodesRamStart == 0) || (kbdCodesRamStart == 0) || (assignColumnsStart == 0) ||
|
|
(assignKbdRcStart == 0) || (kbdColumnsSbIoStart == 0) || (kbdRowsSbIoStart == 0) || (declarationsCounter != 6) )
|
|
{
|
|
QMessageBox::warning(this, "FILE ERROR!", "KBD_RC or COLUMNS assigns, or RAM tables not found, or are in incorrect order");
|
|
openedFile.close();
|
|
return;
|
|
}
|
|
// TODO: ADD LIST WITH ALL COLUMNS AND ROWS (PHY, NOT LOGICAL)
|
|
QVector<QString> allColumnIo;
|
|
QVector<QString> allRowIo;
|
|
foreach (QString column, m_generatedColumns)
|
|
{
|
|
QStringList columnData = column.split("+");
|
|
foreach (QString oneColumnPin, columnData)
|
|
allColumnIo.push_back(oneColumnPin);
|
|
}
|
|
foreach (QString row, m_generatedRows)
|
|
{
|
|
QStringList rowData = row.split("+");
|
|
foreach (QString oneRowPin, rowData)
|
|
allRowIo.push_back(oneRowPin);
|
|
}
|
|
for (int i = 0; i < linesFromFile.length(); i++)
|
|
{
|
|
// TODO: CORRECT ALL THIS DECLARATIONS
|
|
if ((linesFromFile[i].contains("wire ")) && (linesFromFile[i].contains(" KBD_ROWS_EN")))
|
|
linesFromFile[i] = QString(" wire [%1:0] KBD_ROWS_EN;\n").arg(allRowIo.size() - 1);
|
|
else if ((linesFromFile[i].contains("wire ")) && (linesFromFile[i].contains(" KBD_ROWS_IN")))
|
|
linesFromFile[i] = QString(" wire [%1:0] KBD_ROWS_IN;\n").arg(allRowIo.size() - 1);
|
|
else if ((linesFromFile[i].contains("reg ")) && (linesFromFile[i].contains(" KBD_ROWS_OUT")))
|
|
linesFromFile[i] = QString(" reg [%1:0] KBD_ROWS_OUT = 0;\n").arg(allRowIo.size() - 1);
|
|
else if ((linesFromFile[i].contains("reg ")) && (linesFromFile[i].contains(" KBD_COLUMNS_EN")))
|
|
linesFromFile[i] = QString(" reg [%1:0] KBD_COLUMNS_EN = 0;\n").arg(allColumnIo.size() - 1);
|
|
else if ((linesFromFile[i].contains("wire ")) && (linesFromFile[i].contains(" KBD_COLUMNS_IN")))
|
|
linesFromFile[i] = QString(" wire [%1:0] KBD_COLUMNS_IN;\n").arg(allColumnIo.size() - 1);
|
|
else if ((linesFromFile[i].contains("reg ")) && (linesFromFile[i].contains(" KBD_COLUMNS_OUT")))
|
|
linesFromFile[i] = QString(" reg [%1:0] KBD_COLUMNS_OUT = 0;\n").arg(allColumnIo.size() - 1);
|
|
}
|
|
// TODO: ADD CORRECTION OF KBD_COLUMNS SB_IO AND KBD_ROWS SB_IO (LIST OF RC_IO)
|
|
// TODO: CORRECT ALL ASSIGNS AS IT IS IN NEW FW
|
|
QString ioPackagePin = "\t\t.PACKAGE_PIN( { ";
|
|
// foreach(QString rowIo, allRowIo)
|
|
// ioPackagePin += QString("KBD_RC[%1], ").arg(rowIo);
|
|
for (int i = (allRowIo.size() - 1); i >= 0; i--)
|
|
ioPackagePin += QString("KBD_RC[%1], ").arg(allRowIo[i]);
|
|
ioPackagePin.resize(ioPackagePin.size() - 2);
|
|
ioPackagePin += " } ),\n";
|
|
linesFromFile[kbdRowsSbIoStart] = ioPackagePin;
|
|
linesFromFile[kbdRowsSbIoStart - 1] = QString(" ) kbd_rows [%1:0] (\n").arg(allRowIo.size() - 1);
|
|
|
|
ioPackagePin = "\t\t.PACKAGE_PIN( { ";
|
|
// foreach(QString columnIo, allColumnIo)
|
|
// ioPackagePin += QString("KBD_RC[%1], ").arg(columnIo);
|
|
for (int i = (allColumnIo.size() - 1); i >= 0; i--)
|
|
ioPackagePin += QString("KBD_RC[%1], ").arg(allColumnIo[i]);
|
|
ioPackagePin.resize(ioPackagePin.size() - 2);
|
|
ioPackagePin += " } ),\n";
|
|
linesFromFile[kbdColumnsSbIoStart] = ioPackagePin;
|
|
linesFromFile[kbdColumnsSbIoStart - 1] = QString(" ) kbd_columns [%1:0] (\n").arg(allColumnIo.size() - 1);
|
|
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
QString ramCodes = QString("\t\t.INIT_%1(256'h").arg(i);
|
|
QString ramCodesFn = ramCodes;
|
|
if (i >= m_generatedColumns.length())
|
|
{
|
|
ramCodes = ramCodes + "0000_0000_0000_0000_0000_0000_0000_0000__0000_0000_0000_0000_0000_0000_0000_0000";
|
|
ramCodesFn = ramCodesFn + "0000_0000_0000_0000_0000_0000_0000_0000__0000_0000_0000_0000_0000_0000_0000_0000";
|
|
continue;
|
|
}
|
|
for (int j = 15; j >= 0; j--)
|
|
{
|
|
if (j < m_generatedRows.length())
|
|
{
|
|
ramCodes = ramCodes + "00" + m_generatedMatrix[j][i].mid(m_generatedMatrix[j][i].length() - 3, 2) + "_";
|
|
ramCodesFn = ramCodesFn + "00" + m_generatedFnMatrix[j][i].mid(m_generatedFnMatrix[j][i].length() - 3, 2) + "_";
|
|
}
|
|
else
|
|
{
|
|
ramCodes = ramCodes + "0000_";
|
|
ramCodesFn = ramCodesFn + "0000_";
|
|
}
|
|
if (j == 8)
|
|
{
|
|
ramCodes = ramCodes + "_";
|
|
ramCodesFn = ramCodesFn + "_";
|
|
}
|
|
else if (j == 0)
|
|
{
|
|
ramCodes.resize(ramCodes.length() - 1);
|
|
ramCodesFn.resize(ramCodesFn.length() - 1);
|
|
}
|
|
}
|
|
linesFromFile[kbdCodesRamStart+i] = ramCodes + "),\n";
|
|
linesFromFile[kbdFnCodesRamStart+i] = ramCodesFn + "),\n";
|
|
}
|
|
|
|
#if 1
|
|
for (int i = (allRowIo.length() - 1); i >= 0; i--)
|
|
{
|
|
for (int j = 0; j < m_generatedRows.length(); j++)
|
|
{
|
|
QStringList currentRowIo = m_generatedRows[j].split("+");
|
|
if (currentRowIo.contains(allRowIo[i]))
|
|
linesFromFile.insert(assignKbdRcStart, QString(" assign KBD_ROWS_EN[%1] = ROWS_EN[%2];\n").arg(i).arg(j));
|
|
}
|
|
}
|
|
for (int i = 7; i >= 0; i--)
|
|
{
|
|
if (i >= m_generatedColumns.length())
|
|
linesFromFile.insert(assignColumnsStart, QString(" assign COLUMNS[%1] = 0;\n").arg(i));
|
|
else
|
|
{
|
|
QStringList columnsList = m_generatedColumns[i].split("+");
|
|
QString insertedStr = QString(" assign COLUMNS[%1] = ").arg(i);
|
|
foreach (QString columnIo, columnsList)
|
|
insertedStr = insertedStr + QString("KBD_COLUMNS_IN[%1] & ").arg(allColumnIo.indexOf(columnIo));
|
|
insertedStr.resize(insertedStr.length() - 3);
|
|
insertedStr = insertedStr + ";\n";
|
|
linesFromFile.insert(assignColumnsStart, insertedStr);
|
|
}
|
|
}
|
|
#else
|
|
for (int i = 7; i >= 0; i--)
|
|
{
|
|
if (i >= m_generatedColumns.length())
|
|
linesFromFile.insert(assignColumnsStart, QString(" assign COLUMNS[%1] = 0;\n").arg(i));
|
|
else
|
|
{
|
|
QStringList columnsList = m_generatedColumns[i].split("+");
|
|
QString insertedStr = QString(" assign COLUMNS[%1] = ").arg(i);
|
|
for (int j = 0; j < columnsList.length(); j++)
|
|
insertedStr = insertedStr + "KBD_RC_IN[" + columnsList[j] + "] & ";
|
|
insertedStr.resize(insertedStr.length() - 3);
|
|
insertedStr = insertedStr + ";\n";
|
|
linesFromFile.insert(assignColumnsStart, insertedStr);
|
|
}
|
|
}
|
|
for (int i = 33; i >=0; i--)
|
|
{
|
|
bool isFound = false;
|
|
for (int j = 0; j < m_generatedRows.length(); j++)
|
|
{
|
|
QStringList rowList = m_generatedRows[j].split("+");
|
|
for (int k = 0; k < rowList.length(); k++)
|
|
{
|
|
int num = rowList[k].toInt();
|
|
if (num == i)
|
|
{
|
|
linesFromFile.insert(assignKbdRcStart, QString(" assign KBD_RC_EN[%1] = ROWS_EN[%2];\n").arg(i).arg(j));
|
|
if (isFound)
|
|
{
|
|
QMessageBox::warning(this, "ALGORITM ERROR!", "Need more coders");
|
|
openedFile.close();
|
|
return;
|
|
}
|
|
isFound = true;
|
|
}
|
|
}
|
|
}
|
|
if (!isFound)
|
|
linesFromFile.insert(assignKbdRcStart, QString(" assign KBD_RC_EN[%1] = 0;\n").arg(i));
|
|
}
|
|
#endif
|
|
|
|
openedFile.close();
|
|
openedFile.open(QFile::WriteOnly);
|
|
|
|
QString tarText;
|
|
for (int i = 0; i < linesFromFile.length(); i++)
|
|
tarText = tarText + linesFromFile[i];
|
|
openedFile.write(tarText.toUtf8());
|
|
openedFile.close();
|
|
QWidget* unlockingWidgets[] = { ui->generateFwBinFile, ui->burnFileToFpga, ui->generateBinApio,
|
|
ui->generateBinArachne, ui->generateBinNextPnr, ui->fpgaCommandOutput };
|
|
for (int i = 0; i < (sizeof(unlockingWidgets) / sizeof(QWidget*)); i++)
|
|
unlockingWidgets[i]->setEnabled(true);
|
|
QFileInfo currentFile(openedFile.fileName());
|
|
ui->fpgaProjectPath->setText(currentFile.dir().absolutePath());
|
|
}
|
|
|
|
void i2c_keyboard_detection::on_generateFwBinFile_clicked()
|
|
{
|
|
ui->fpgaCommandOutput->clear();
|
|
QString program = ui->fpgaProjectPath->text();
|
|
QStringList args;
|
|
#if 0
|
|
QStringList sysVar;
|
|
QFile sysVarFile("sys_var.txt");
|
|
if (!sysVarFile.open(QFile::ReadOnly))
|
|
{
|
|
QMessageBox::warning(this, "PROCESS ERROR!", "CANT OPEN FILE SYS_VAR.TXT!");
|
|
return;
|
|
}
|
|
while(1)
|
|
{
|
|
QString line = sysVarFile.readLine();
|
|
if (line.length() == 0)
|
|
break;
|
|
sysVar.push_back(line);
|
|
}
|
|
sysVarFile.close();
|
|
m_fpgaFwGenerator.setEnvironment(sysVar);
|
|
#endif
|
|
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
|
|
//env.insert("TMPDIR", "C:\\MyApp\\temp"); // Добавляет переменную окружения
|
|
//env.insert("PATH", env.value("Path") + ";C:\\Bin");
|
|
//process.setProcessEnvironment(env);
|
|
//process.start("myapp");
|
|
//m_fpgaFwGenerator.setProcessEnvironment(env);
|
|
#if 1
|
|
if (ui->generateBinApio->isChecked())
|
|
{
|
|
program = "apio";//program + "/apio build";
|
|
//args << "build";
|
|
}
|
|
else if (ui->generateBinArachne)
|
|
program = "make";//program + "make";
|
|
else if (ui->generateBinNextPnr)
|
|
{
|
|
program = "make nextpnr";//program + "make";
|
|
args << "nextpnr";
|
|
}
|
|
args.clear();
|
|
//args.push_back("make");
|
|
//args.push_back("nextpnr");
|
|
|
|
// QString cmd = "yosys";
|
|
// args << "-q" << "-p" << "synth_ice40" << "top.v" << "i2c_slave.v" << "matrix_kbd.v" << "ram.v" << "simple_filter.v" << "uart.v" << "descriptors.v";
|
|
|
|
// QString cmd = "arachne-pnr";
|
|
// args << "-d" << "1k" << "-P" << "tq144" << "-p" << "inouts.pcf" << "i2c_kbd_alt.blif" << "-o" << "i2c_kbd_alt.asc";
|
|
|
|
// QString cmd = "yosys";
|
|
// args << "-q" << "-p" << "synth_ice40 -json i2_kbd_alt.json" << "top.v" << "i2c_slave.v" << "matrix_kbd.v" << "ram.v" << "simple_filter.v" << "uart.v" << "descriptors.v";
|
|
|
|
// QString cmd = "nextpnr-ice40";
|
|
// args << "--hx1k" << "--json" << "i2_kbd_alt.json" << "--pcf" << "inouts.pcf" << "--asc" << "i2c_kbd_alt.asc";
|
|
|
|
QString cmd = "icebox_explain";
|
|
args << "i2c_kbd_alt.asc > i2c_kbd_alt.ex";
|
|
|
|
m_fpgaFwGenerator->setWorkingDirectory("/home/t-bird/i2c_keyboard/i2c_keyboard_ice40"/*ui->fpgaProjectPath->text()*/);
|
|
m_fpgaFwGenerator->start(cmd, args);
|
|
//QThread::msleep(500);
|
|
//m_fpgaFwGenerator->write("ls");
|
|
//m_fpgaFwGenerator->write(program.toLatin1()/*, args*/);
|
|
#endif
|
|
//system("apio");
|
|
}
|
|
|
|
void i2c_keyboard_detection::processReadyRead()
|
|
{
|
|
QString output = m_fpgaFwGenerator->readAll();
|
|
ui->fpgaCommandOutput->append(output);
|
|
}
|
|
|
|
void i2c_keyboard_detection::processFinished(int result, QProcess::ExitStatus exitStatus)
|
|
{
|
|
QMessageBox::about(this, "PROCESS FINISHED", QString("Result %1, exit status %2").arg(result).arg(exitStatus));
|
|
}
|
|
|
|
void i2c_keyboard_detection::processError(QProcess::ProcessError error)
|
|
{
|
|
QMessageBox::about(this, "PROCESS ERROR", QString("Error %1").arg(error));
|
|
}
|
|
|
|
void i2c_keyboard_detection::on_saveMatrixFile_clicked()
|
|
{
|
|
QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"),
|
|
QString("matrix_%1x%2_%3.txt").arg(m_generatedColumns.length()).arg(m_generatedRows.length()).arg(m_generatedNotEmptyElements), tr("*.txt"));
|
|
if (fileName == "")
|
|
return;
|
|
QFile savedFile(fileName);
|
|
if (!savedFile.open(QFile::WriteOnly))
|
|
{
|
|
QMessageBox::warning(this, "CANNOT SAVE FILE", "Can't save file with matrixes");
|
|
return;
|
|
}
|
|
QString matrixText = "Normal matrix:\n\n";
|
|
for (int i = 0; i < m_generatedColumns.length(); i++)
|
|
matrixText = matrixText + "\t" + m_generatedColumns[i];
|
|
for (int j = 0; j < m_generatedRows.length(); j++)
|
|
{
|
|
matrixText = matrixText + "\n";
|
|
matrixText = matrixText + m_generatedRows[j];
|
|
for (int i = 0; i < m_generatedColumns.length(); i++)
|
|
matrixText = matrixText + "\t" + m_generatedMatrix[j][i];
|
|
}
|
|
matrixText = matrixText + "\n\n\nFn matrix:\n\n";
|
|
for (int i = 0; i < m_generatedColumns.length(); i++)
|
|
matrixText = matrixText + "\t" + m_generatedColumns[i];
|
|
for (int j = 0; j < m_generatedRows.length(); j++)
|
|
{
|
|
matrixText = matrixText + "\n";
|
|
matrixText = matrixText + m_generatedRows[j];
|
|
for (int i = 0; i < m_generatedColumns.length(); i++)
|
|
matrixText = matrixText + "\t" + m_generatedFnMatrix[j][i];
|
|
}
|
|
savedFile.write(matrixText.toUtf8());
|
|
savedFile.close();
|
|
}
|
|
|
|
void i2c_keyboard_detection::on_openMatrixFile_clicked()
|
|
{
|
|
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "matrix.txt", tr("*.txt"));
|
|
if (fileName == "")
|
|
return;
|
|
QFile openedFile(fileName);
|
|
if (!openedFile.open(QFile::ReadOnly))
|
|
{
|
|
QMessageBox::warning(this, "CANNOT OPEN FILE", "Can't open matrix file");
|
|
return;
|
|
}
|
|
QVector<QString> textLines;
|
|
QVector<QStringList> textElements;
|
|
while(1)
|
|
{
|
|
QString currentStr = QString(openedFile.readLine());
|
|
if (currentStr.length() == 0)
|
|
break;
|
|
if (currentStr[currentStr.length() - 1] == "\n")
|
|
currentStr.resize(currentStr.length() - 1);
|
|
QStringList currentStrList = currentStr.split("\t");
|
|
textLines.push_back(currentStr);
|
|
textElements.push_back(currentStrList);
|
|
}
|
|
openedFile.close();
|
|
int rowNum = (textLines.length() - 8) / 2;
|
|
if (textLines.length() < 10)
|
|
{
|
|
QMessageBox::warning(this, "UNCORRECT FILE OPENED", "This file not contain correct matrixes!");
|
|
return;
|
|
}
|
|
QStringList columns = textLines[2].split("\t");
|
|
if ((textLines[0] != "Normal matrix:") || (textLines[5 + rowNum] != "Fn matrix:") || (textLines[2] != textLines[7 + rowNum]))
|
|
{
|
|
QMessageBox::warning(this, "UNCORRECT FILE OPENED", "This file not contain correct matrixes!");
|
|
return;
|
|
}
|
|
for (int i = 3; i < textElements.length(); i++)
|
|
{
|
|
if ((i > (2+rowNum)) && (i < (7+rowNum)))
|
|
continue;
|
|
if (textElements[i].length() != textElements[3].length())
|
|
{
|
|
QMessageBox::warning(this, "UNCORRECT FILE OPENED", "This file not contain correct matrixes!");
|
|
return;
|
|
}
|
|
}
|
|
m_generatedRows.resize(rowNum);
|
|
m_generatedColumns.resize(columns.length() - 1);
|
|
m_generatedMatrix.resize(rowNum);
|
|
m_generatedFnMatrix.resize(rowNum);
|
|
for (int i = 0; i < (columns.length() - 1); i++)
|
|
m_generatedColumns[i] = columns[i + 1];
|
|
for (int i = 0; i < rowNum; i++)
|
|
{
|
|
m_generatedRows[i] = textElements[i + 3][0];
|
|
QVector<QString> matrixRow(m_generatedColumns.length());
|
|
for (int j = 0; j < m_generatedColumns.length(); j++)
|
|
matrixRow[j] = textElements[i + 3][j + 1];
|
|
m_generatedMatrix[i] = matrixRow;
|
|
for (int j = 0; j < m_generatedColumns.length(); j++)
|
|
matrixRow[j] = textElements[i + rowNum + 8][j + 1];
|
|
m_generatedFnMatrix[i] = matrixRow;
|
|
}
|
|
displayMatrix();
|
|
}
|
|
|
|
void i2c_keyboard_detection::on_addNewKey_clicked()
|
|
{
|
|
QString addedElement = ui->newKeyName->text() + " (" + QString::number(ui->newKeyCode->value(),16) + ")";
|
|
ui->keyList->addItem(addedElement);
|
|
}
|
|
|
|
void i2c_keyboard_detection::on_openQmkKbd_clicked()
|
|
{
|
|
QString dirName = QFileDialog::getExistingDirectory(this, "Open QMK keyboard directory");
|
|
if (dirName.size() == 0)
|
|
return;
|
|
QDir qmkDir(dirName);
|
|
QDir keymapsDir(dirName + "/keymaps");
|
|
|
|
if (!keymapsDir.exists())
|
|
{
|
|
QMessageBox::warning(this, "UNCORRECT DIR OPENED", "This dir not contains keymap folder!");
|
|
return;
|
|
}
|
|
|
|
QFile layoutFile(dirName + "/" + qmkDir.dirName() + ".h");
|
|
if (!layoutFile.exists())
|
|
{
|
|
QMessageBox::warning(this, "UNCORRECT DIR OPENED", "This dir not contains layout file (" + keymapsDir.dirName() + ".h)!");
|
|
return;
|
|
}
|
|
|
|
QFile configFile(dirName + "/config.h");
|
|
if (!configFile.exists())
|
|
{
|
|
QMessageBox::warning(this, "UNCORRECT DIR OPENED", "This dir not contains config file (" + keymapsDir.dirName() + ".h)!");
|
|
return;
|
|
}
|
|
|
|
QFileInfoList qmkDirList = qmkDir.entryInfoList();
|
|
QFileInfoList qmkKbdList = keymapsDir.entryInfoList();
|
|
|
|
m_qmkRevisions.clear();
|
|
m_qmkKeymaps.clear();
|
|
|
|
m_qmkRevisions.push_back(qmkDir.absolutePath());
|
|
|
|
foreach (QFileInfo info, qmkDirList)
|
|
{
|
|
if ((info.isDir()) && (info.baseName() != "keymaps") && (info.fileName() != ".") && (info.fileName() != ".."))
|
|
m_qmkRevisions.push_back(info);
|
|
}
|
|
foreach (QFileInfo info, qmkKbdList) {
|
|
if ((info.isDir()) && (info.fileName() != ".") && (info.fileName() != ".."))
|
|
m_qmkKeymaps.push_back(info);
|
|
}
|
|
m_uiKbdList.setInfo(m_qmkRevisions, m_qmkKeymaps);
|
|
m_uiKbdList.show();
|
|
this->setEnabled(false);
|
|
}
|
|
|
|
void i2c_keyboard_detection::qmkKbdSelected(int rev, int keymap)
|
|
{
|
|
this->setEnabled(true);
|
|
if ((rev < 0) || (keymap < 0) || (rev >= m_qmkRevisions.size()) || (keymap >= m_qmkKeymaps.size()))
|
|
return;
|
|
|
|
QString mainLayoutFileName = m_qmkRevisions[0].absoluteFilePath() + "/" + m_qmkRevisions[0].fileName() + ".h";
|
|
QFile mainLayoutFile(mainLayoutFileName);
|
|
if (!mainLayoutFile.open(QFile::ReadOnly))
|
|
{
|
|
QMessageBox::warning(this, "UNCORRECT DIR OPENED", "This dir not contains layout file (" + mainLayoutFileName + ")!");
|
|
return;
|
|
}
|
|
QString mainLayout = QString(mainLayoutFile.readAll());
|
|
mainLayoutFile.close();
|
|
|
|
QString revLayout = "";
|
|
if (rev != 0)
|
|
{
|
|
QString revLayoutFileName = m_qmkRevisions[rev].absoluteFilePath() + "/" + m_qmkRevisions[rev].fileName() + ".h";
|
|
QFile revLayoutFile(revLayoutFileName);
|
|
if (revLayoutFile.open(QFile::ReadOnly))
|
|
{
|
|
revLayout = QString(revLayoutFile.readAll());
|
|
revLayoutFile.close();
|
|
}
|
|
else
|
|
QMessageBox::warning(this, "WARNING", "THIS REVISION NOT HAS OWN LAYOUT FILE");
|
|
}
|
|
|
|
QString mainConfigFileName = m_qmkRevisions[0].absoluteFilePath() + "/config.h";
|
|
QFile mainConfigFile(mainConfigFileName);
|
|
if (!mainConfigFile.open(QFile::ReadOnly))
|
|
{
|
|
QMessageBox::warning(this, "UNCORRECT DIR OPENED", "This dir not contains config file (" + mainConfigFileName + ")!");
|
|
return;
|
|
}
|
|
QString mainConfig = QString(mainConfigFile.readAll());
|
|
mainConfigFile.close();
|
|
|
|
QString revConfig = "";
|
|
if (rev != 0)
|
|
{
|
|
QString revConfigFileName = m_qmkRevisions[rev].absoluteFilePath() + "/config.h";
|
|
QFile revConfigFile(revConfigFileName);
|
|
if (revConfigFile.open(QFile::ReadOnly))
|
|
{
|
|
revConfig = QString(revConfigFile.readAll());
|
|
revConfigFile.close();
|
|
}
|
|
else
|
|
QMessageBox::warning(this, "WARNING", "THIS REVISION NOT HAS OWN CONFIG FILE");
|
|
}
|
|
|
|
QString keymapConfig = "";
|
|
QString keymapConfigFileName = m_qmkKeymaps[keymap].absoluteFilePath() + "/config.h";
|
|
QFile keymapConfigFile(keymapConfigFileName);
|
|
if (keymapConfigFile.open(QFile::ReadOnly))
|
|
{
|
|
keymapConfig = QString(keymapConfigFile.readAll());
|
|
keymapConfigFile.close();
|
|
}
|
|
else
|
|
QMessageBox::warning(this, "WARNING", "THIS KEYMAP NOT HAS OWN CONFIG FILE");
|
|
|
|
QString keymapFileName = m_qmkKeymaps[keymap].absoluteFilePath() + "/keymap.c";
|
|
QFile keymapFile(keymapFileName);
|
|
if (!keymapFile.open(QFile::ReadOnly))
|
|
{
|
|
QMessageBox::warning(this, "UNCORRECT DIR OPENED", "This dir not contains keymap file (" + keymapFileName + ")!");
|
|
return;
|
|
}
|
|
QString keymapSrc = QString(keymapFile.readAll());
|
|
keymapFile.close();
|
|
|
|
QString keycodeFileNameEnd = "/tmk_core/common/keycode.h";
|
|
QString keycodeFileNameBegin = m_qmkRevisions[0].absoluteFilePath() + "/../..";
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
if (QFile(keycodeFileNameBegin + keycodeFileNameEnd).exists())
|
|
break;
|
|
keycodeFileNameBegin += "/..";
|
|
}
|
|
|
|
QFile keycodeFile(keycodeFileNameBegin + keycodeFileNameEnd);
|
|
if (!keycodeFile.open(QFile::ReadOnly))
|
|
{
|
|
QMessageBox::warning(this, "UNCORRECT DIR OPENED", "This dir not contains keycodes file!");
|
|
return;
|
|
}
|
|
QString keyCodes = QString(keycodeFile.readAll());
|
|
keycodeFile.close();
|
|
|
|
QString error = m_qmkParser.parseFiles(mainLayout, revLayout, mainConfig, revConfig, keymapConfig, keymapSrc, keyCodes, true);
|
|
|
|
if (!error.isEmpty())
|
|
{
|
|
QMessageBox::warning(this, "PARSING ERROR", error);
|
|
return;
|
|
}
|
|
|
|
m_generatedColumns = m_qmkParser.getColumns();
|
|
m_generatedRows = m_qmkParser.getRows();
|
|
m_diodeDirection = m_qmkParser.getDiodeDirection();
|
|
QVector<QVector<int>> matrix = m_qmkParser.getMatrix();
|
|
QVector<QVector<int>> fnMatrix = m_qmkParser.getFnMatrix();
|
|
|
|
QVector<QString> uiKeyNames;
|
|
QVector<int> uiKeyCodes;
|
|
|
|
for (int i = 0; i < ui->keyList->count(); i++)
|
|
{
|
|
QString keyDesc = ui->keyList->item(i)->text();
|
|
uiKeyNames.push_back(keyDesc);
|
|
keyDesc = keyDesc.mid(keyDesc.lastIndexOf("(") + 1, keyDesc.lastIndexOf(")") - keyDesc.lastIndexOf("(") - 1);
|
|
uiKeyCodes.push_back(keyDesc.toInt(Q_NULLPTR, 16));
|
|
}
|
|
|
|
m_generatedMatrix.clear();
|
|
m_generatedFnMatrix.clear();
|
|
m_generatedMatrix.resize(m_generatedRows.size());
|
|
m_generatedFnMatrix.resize(m_generatedRows.size());
|
|
for (int i = 0; i < m_generatedRows.size(); i++)
|
|
{
|
|
m_generatedMatrix[i].resize(m_generatedColumns.size());
|
|
m_generatedFnMatrix[i].resize(m_generatedColumns.size());
|
|
for (int j = 0; j < m_generatedColumns.size(); j++)
|
|
{
|
|
for (int k = 0; k < uiKeyCodes.size(); k++)
|
|
{
|
|
if (matrix[i][j] == uiKeyCodes[k])
|
|
m_generatedMatrix[i][j] = uiKeyNames[k];
|
|
if (fnMatrix[i][j] == uiKeyCodes[k])
|
|
m_generatedFnMatrix[i][j] = uiKeyNames[k];
|
|
}
|
|
if ((m_generatedMatrix[i][j].isEmpty()) && ((matrix[i][j] == 0) || (matrix[i][j] == 1)))
|
|
m_generatedMatrix[i][j] = "(00)";
|
|
if ((m_generatedFnMatrix[i][j].isEmpty()) && ((fnMatrix[i][j] == 0) || (fnMatrix[i][j] == 1)))
|
|
m_generatedFnMatrix[i][j] = "(00)";
|
|
}
|
|
}
|
|
|
|
displayMatrix();
|
|
|
|
qDebug("222");
|
|
}
|