Browse Source

software_update

master
Ivan Olenichev 2 years ago
parent
commit
1daeb9c0c8
  1. 1340
      Software/i2c_keyboard_detection.cpp
  2. 111
      Software/i2c_keyboard_detection.h
  3. 40
      Software/i2c_keyboard_detection.pro
  4. 336
      Software/i2c_keyboard_detection.pro.user
  5. 280
      Software/i2c_keyboard_detection.pro.user.22
  6. 271
      Software/i2c_keyboard_detection.pro.user.4.8-pre1
  7. 336
      Software/i2c_keyboard_detection.pro.user.8de61b0
  8. 557
      Software/i2c_keyboard_detection.ui
  9. 11
      Software/main.cpp
  10. 64
      Software/qmk_kbd_list.cpp

1340
Software/i2c_keyboard_detection.cpp

@ -0,0 +1,1340 @@
#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");
}

111
Software/i2c_keyboard_detection.h

@ -0,0 +1,111 @@
#ifndef I2C_KEYBOARD_DETECTION_H
#define I2C_KEYBOARD_DETECTION_H
#include <QMainWindow>
#include <qserialport.h>
#include <qserialportinfo.h>
#include <qprocess.h>
#include <qthread.h>
#include "qmk_kbd_list.h"
#include "qmk_parser.h"
namespace Ui {
class i2c_keyboard_detection;
}
class i2c_keyboard_detection : public QMainWindow
{
Q_OBJECT
public:
explicit i2c_keyboard_detection(QWidget *parent = 0);
~i2c_keyboard_detection();
private slots:
void comDataReceived();
void displayMatrix();
void qmkKbdSelected(int rev, int keymap);
void processReadyRead();
void processFinished(int result, QProcess::ExitStatus exitStatus);
void processError(QProcess::ProcessError error);
void on_keyList_itemSelectionChanged();
void keyPressEvent(QKeyEvent *event);
virtual void resizeEvent(QResizeEvent *event) override;
void on_comRefleshList_clicked();
void on_comConnect_clicked();
void on_enSendKeyToReport_clicked(bool checked);
void on_saveKbdReport_clicked();
void on_openConnectionsFile_clicked();
void on_clearKbdReport_clicked();
void on_swapColumnsAndRows_clicked();
void on_mergeRows_clicked();
void on_setFnKey_clicked();
void on_openMatrixKbdFile_clicked();
void on_generateFwBinFile_clicked();