diff --git a/Software/i2c_keyboard_detection.cpp b/Software/i2c_keyboard_detection.cpp new file mode 100644 index 0000000..89b9833 --- /dev/null +++ b/Software/i2c_keyboard_detection.cpp @@ -0,0 +1,1340 @@ +#include "i2c_keyboard_detection.h" +#include "ui_i2c_keyboard_detection.h" + +#include +#include + +#include +#include + +#include + +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 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 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 keyNames; + QVector 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 allIoNumbers; + for (int i = 0; i < keyIo.length(); i++) + { + if (allIoNumbers.indexOf(keyIo[i]) == -1) + allIoNumbers.push_back(keyIo[i]); + } + qSort(allIoNumbers); + + QVector> 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>> allGeneratedMatrixes; + QVector> allGeneratedColumns; + QVector> allGeneratedRows; + for (int i = 0; i < allIoNumbers.length(); i++) + { + int currentColumnCnt = 0; + int currentRowCnt = 0; + QVector currentColumn(1, allIoNumbers[i]); + QVector 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 temp(currentRow); + currentRow = currentColumn; + currentColumn = temp; + } + } + else + { + if (currentRow.indexOf(allIoNumbers[0]) == -1) + { + QVector temp(currentRow); + currentRow = currentColumn; + currentColumn = temp; + } + } + + if ((!allGeneratedRows.contains(currentRow)) || (!allGeneratedColumns.contains(currentColumn))) + { + allGeneratedRows.push_back(currentRow); + allGeneratedColumns.push_back(currentColumn); + QVector> 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 newColumns(m_generatedRows); + QVector newRows(m_generatedColumns); + QVector> 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 newRow(m_generatedColumns.length()); + QVector 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 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 allColumnIo; + QVector 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 textLines; + QVector 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 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> matrix = m_qmkParser.getMatrix(); + QVector> fnMatrix = m_qmkParser.getFnMatrix(); + + QVector uiKeyNames; + QVector 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"); +} diff --git a/Software/i2c_keyboard_detection.h b/Software/i2c_keyboard_detection.h new file mode 100644 index 0000000..0fb2705 --- /dev/null +++ b/Software/i2c_keyboard_detection.h @@ -0,0 +1,111 @@ +#ifndef I2C_KEYBOARD_DETECTION_H +#define I2C_KEYBOARD_DETECTION_H + +#include + +#include + +#include + +#include +#include + +#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(); + + void on_saveMatrixFile_clicked(); + + void on_openMatrixFile_clicked(); + + void on_addNewKey_clicked(); + + void on_openQmkKbd_clicked(); + +private: + +private: + Ui::i2c_keyboard_detection *ui; + + QVector m_kbdCodes; + + QStringList m_keyComments; + + QSerialPort m_com; + bool m_isFirstComMsg; + + QByteArray m_kbdDetectBytes; + + QVector m_kbdDetectData; + + QVector m_kbdDetectReport; + + QVector m_generatedColumns; + QVector m_generatedRows; + QVector > m_generatedMatrix; + QVector > m_generatedFnMatrix; + int m_generatedNotEmptyElements; + int m_diodeDirection; // 0 - no diodes, 1 - (+) COL and (-) ROW, 2 - (-) COL and (+) ROW + + const QString m_emptyMatrixValue = "(0)"; + + QProcess* m_fpgaFwGenerator; + QThread m_fpgaFwGeneratorTrd; + + qmk_kbd_list m_uiKbdList; + + QFileInfoList m_qmkRevisions; + QFileInfoList m_qmkKeymaps; + + qmk_parser m_qmkParser; +}; + +#endif // I2C_KEYBOARD_DETECTION_H diff --git a/Software/i2c_keyboard_detection.pro b/Software/i2c_keyboard_detection.pro new file mode 100644 index 0000000..a8b3778 --- /dev/null +++ b/Software/i2c_keyboard_detection.pro @@ -0,0 +1,40 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2019-05-02T17:45:44 +# +#------------------------------------------------- + +QT += core gui +QT += serialport + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = i2c_keyboard_detection +TEMPLATE = app + +# The following define makes your compiler emit warnings if you use +# any feature of Qt which has been marked as deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +# You can also make your code fail to compile if you use deprecated APIs. +# In order to do so, uncomment the following line. +# You can also select to disable deprecated APIs only up to a certain version of Qt. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + + +SOURCES += \ + main.cpp \ + i2c_keyboard_detection.cpp \ + qmk_kbd_list.cpp \ + qmk_parser.cpp + +HEADERS += \ + i2c_keyboard_detection.h \ + qmk_kbd_list.h \ + qmk_parser.h + +FORMS += \ + i2c_keyboard_detection.ui \ + qmk_kbd_list.ui diff --git a/Software/i2c_keyboard_detection.pro.user b/Software/i2c_keyboard_detection.pro.user new file mode 100644 index 0000000..0725ade --- /dev/null +++ b/Software/i2c_keyboard_detection.pro.user @@ -0,0 +1,336 @@ + + + + + + EnvironmentId + {5d81e9f4-89a7-42bb-b237-ce95b4035b68} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + {e15e5c3d-04e8-4edb-91aa-5a00a5eb5973} + 0 + 0 + 0 + + /home/t-bird/i2c_keyboard/build-i2c_keyboard_detection-Desktop-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Сборка + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Сборка + + ProjectExplorer.BuildSteps.Build + + + + true + Сборка + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Очистка + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Отладка + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + /home/t-bird/i2c_keyboard/build-i2c_keyboard_detection-Desktop-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + false + + + true + Сборка + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Сборка + + ProjectExplorer.BuildSteps.Build + + + + true + Сборка + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Очистка + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Выпуск + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + /home/t-bird/i2c_keyboard/build-i2c_keyboard_detection-Desktop-Profile + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + true + false + + + true + Сборка + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Сборка + + ProjectExplorer.BuildSteps.Build + + + + true + Сборка + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Очистка + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Профилирование + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 3 + + + 0 + Установка + + ProjectExplorer.BuildSteps.Deploy + + 1 + Локальная установка + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + i2c_keyboard_detection + + Qt4ProjectManager.Qt4RunConfiguration:/home/t-bird/i2c_keyboard/i2c_keyboard_detection/i2c_keyboard_detection.pro + true + + i2c_keyboard_detection.pro + false + + /home/t-bird/i2c_keyboard/build-i2c_keyboard_detection-Desktop-Debug + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 18 + + + Version + 18 + + diff --git a/Software/i2c_keyboard_detection.pro.user.22 b/Software/i2c_keyboard_detection.pro.user.22 new file mode 100644 index 0000000..effb82f --- /dev/null +++ b/Software/i2c_keyboard_detection.pro.user.22 @@ -0,0 +1,280 @@ + + + + + + EnvironmentId + {5d81e9f4-89a7-42bb-b237-ce95b4035b68} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + true + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + {e15e5c3d-04e8-4edb-91aa-5a00a5eb5973} + 1 + 0 + 0 + + /home/t-bird/i2c_keyboard/build-i2c_keyboard_detection-Desktop-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + false + + + true + Сборка + + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Сборка + + ProjectExplorer.BuildSteps.Build + + + + true + Сборка + + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Очистка + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Отладка + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + /home/t-bird/i2c_keyboard/build-i2c_keyboard_detection-Desktop-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + false + + + true + Сборка + + Qt4ProjectManager.MakeStep + + false + + + false + + 2 + Сборка + + ProjectExplorer.BuildSteps.Build + + + + true + Сборка + + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Очистка + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Выпуск + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 2 + + + 0 + Развёртывание + + ProjectExplorer.BuildSteps.Deploy + + 1 + Локальная установка + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + dwarf + + cpu-cycles + + + 250 + -F + true + 4096 + false + false + 0 + + true + + false + false + false + false + true + 0.01 + 10 + true + kcachegrind + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + i2c_keyboard_detection + + Qt4ProjectManager.Qt4RunConfiguration:/home/t-bird/i2c_keyboard/i2c_keyboard_detection/i2c_keyboard_detection.pro + + 3768 + false + true + false + false + false + true + false + + /home/t-bird/i2c_keyboard/build-i2c_keyboard_detection-Desktop-Release + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 22 + + + Version + 22 + + diff --git a/Software/i2c_keyboard_detection.pro.user.4.8-pre1 b/Software/i2c_keyboard_detection.pro.user.4.8-pre1 new file mode 100644 index 0000000..bf197c4 --- /dev/null +++ b/Software/i2c_keyboard_detection.pro.user.4.8-pre1 @@ -0,0 +1,271 @@ + + + + + + EnvironmentId + {5d81e9f4-89a7-42bb-b237-ce95b4035b68} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + {e15e5c3d-04e8-4edb-91aa-5a00a5eb5973} + 1 + 0 + 0 + + /home/t-bird/i2c_keyboard/build-i2c_keyboard_detection-Desktop-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + false + false + + + true + Сборка + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Сборка + + ProjectExplorer.BuildSteps.Build + + + + true + Сборка + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Очистка + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Отладка + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + /home/t-bird/i2c_keyboard/build-i2c_keyboard_detection-Desktop-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + true + + false + false + false + + + true + Сборка + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Сборка + + ProjectExplorer.BuildSteps.Build + + + + true + Сборка + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Очистка + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Выпуск + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 2 + + + 0 + Установка + + ProjectExplorer.BuildSteps.Deploy + + 1 + Локальная установка + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + i2c_keyboard_detection + + Qt4ProjectManager.Qt4RunConfiguration:/home/t-bird/i2c_keyboard/i2c_keyboard_detection/i2c_keyboard_detection.pro + + i2c_keyboard_detection.pro + false + false + + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 18 + + + Version + 18 + + diff --git a/Software/i2c_keyboard_detection.pro.user.8de61b0 b/Software/i2c_keyboard_detection.pro.user.8de61b0 new file mode 100644 index 0000000..c4269ea --- /dev/null +++ b/Software/i2c_keyboard_detection.pro.user.8de61b0 @@ -0,0 +1,336 @@ + + + + + + EnvironmentId + {8de61b0b-889e-44b1-81ae-c7cc2e380f6b} + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + 80 + true + true + 1 + true + false + 0 + true + true + 0 + 8 + true + 1 + true + true + true + false + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + {e8ce154f-37ea-423d-8395-8f2a740f7982} + 0 + 0 + 0 + + /home/t-bird/i2c_keyboard/build-i2c_keyboard_detection-Desktop-Debug + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + false + false + + + true + Сборка + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Сборка + + ProjectExplorer.BuildSteps.Build + + + + true + Сборка + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Очистка + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Отладка + + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + /home/t-bird/i2c_keyboard/build-i2c_keyboard_detection-Desktop-Release + + + true + qmake + + QtProjectManager.QMakeBuildStep + false + + false + false + false + + + true + Сборка + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Сборка + + ProjectExplorer.BuildSteps.Build + + + + true + Сборка + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Очистка + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Выпуск + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + + /home/t-bird/i2c_keyboard/build-i2c_keyboard_detection-Desktop-Profile + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + + false + true + false + + + true + Сборка + + Qt4ProjectManager.MakeStep + + -w + -r + + false + + + + 2 + Сборка + + ProjectExplorer.BuildSteps.Build + + + + true + Сборка + + Qt4ProjectManager.MakeStep + + -w + -r + + true + clean + + + 1 + Очистка + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Профилирование + + Qt4ProjectManager.Qt4BuildConfiguration + 0 + true + + 3 + + + 0 + Установка + + ProjectExplorer.BuildSteps.Deploy + + 1 + Локальная установка + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + false + false + 1000 + + true + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + i2c_keyboard_detection + + Qt4ProjectManager.Qt4RunConfiguration:/home/t-bird/i2c_keyboard/i2c_keyboard_detection/i2c_keyboard_detection.pro + true + + i2c_keyboard_detection.pro + false + + /home/t-bird/i2c_keyboard/build-i2c_keyboard_detection-Desktop-Debug + 3768 + false + true + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.FileVersion + 18 + + + Version + 18 + + diff --git a/Software/i2c_keyboard_detection.ui b/Software/i2c_keyboard_detection.ui new file mode 100644 index 0000000..813082c --- /dev/null +++ b/Software/i2c_keyboard_detection.ui @@ -0,0 +1,557 @@ + + + i2c_keyboard_detection + + + + 0 + 0 + 1312 + 781 + + + + Qt::TabFocus + + + i2c_keyboard_detection + + + + + + 220 + 10 + 1081 + 691 + + + + 1 + + + + Keyboard connections detection + + + + + 280 + 50 + 651 + 591 + + + + + + + 50 + 10 + 111 + 31 + + + + + + + 10 + 40 + 261 + 31 + + + + Status: no keys pressed + + + + + + 10 + 10 + 31 + 31 + + + + R + + + + + + 280 + 10 + 311 + 29 + + + + Wait selected key and add it to report + + + + + + 170 + 10 + 97 + 31 + + + + Connect + + + + + + 650 + 10 + 121 + 31 + + + + Save to file + + + + + + 780 + 10 + 97 + 31 + + + + Clear + + + + + + Matrix Generator + + + + + 10 + 10 + 341 + 31 + + + + Open connections file and generate matrix + + + + + + 10 + 90 + 1061 + 551 + + + + + + + 930 + 0 + 141 + 29 + + + + &Normal matrix + + + true + + + + + + 930 + 20 + 91 + 21 + + + + FN m&ode + + + + + + 230 + 50 + 191 + 31 + + + + Swap columns and rows + + + + + + 10 + 50 + 211 + 31 + + + + Set Fn key code from table + + + + + + 430 + 50 + 151 + 31 + + + + + + + 590 + 50 + 111 + 31 + + + + Connect rows + + + + + + 710 + 52 + 221 + 31 + + + + + + + + + + 360 + 10 + 151 + 31 + + + + Open matrix file + + + + + + 750 + 10 + 141 + 31 + + + + Save matrix file + + + + + + 520 + 10 + 221 + 31 + + + + Open QMK keyboard folder + + + + + + 940 + 50 + 131 + 31 + + + + + No diodes + + + + + Col2Row + + + + + Row2Col + + + + + + + Firmware generator + + + + + 10 + 10 + 271 + 31 + + + + Open matrix_kbd.v and modify it + + + + + false + + + + 10 + 50 + 171 + 31 + + + + Generate bin file + + + + + + 290 + 10 + 641 + 31 + + + + + + false + + + + 190 + 50 + 61 + 29 + + + + &Apio + + + true + + + + + false + + + + 260 + 50 + 171 + 29 + + + + &Yosys+Arachne-pnr + + + + + false + + + + 440 + 50 + 141 + 29 + + + + Yosys+&Nextpnr + + + + + false + + + + 580 + 50 + 351 + 31 + + + + Open file and program FPGA + + + + + + 10 + 90 + 921 + 551 + + + + + + + + + 10 + 670 + 201 + 32 + + + + Code + + + 1 + + + 254 + + + 254 + + + 16 + + + + + + 10 + 10 + 201 + 551 + + + + true + + + + + + 10 + 640 + 51 + 31 + + + + Name + + + + + + 10 + 600 + 201 + 31 + + + + WaitCursor + + + Qt::ClickFocus + + + Add new key + + + + + + 60 + 640 + 151 + 31 + + + + + + + 10 + 560 + 201 + 23 + + + + Key comment + + + + + + + 0 + 0 + 1312 + 23 + + + + + + TopToolBarArea + + + false + + + + + + + + diff --git a/Software/main.cpp b/Software/main.cpp new file mode 100644 index 0000000..68c4129 --- /dev/null +++ b/Software/main.cpp @@ -0,0 +1,11 @@ +#include "i2c_keyboard_detection.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + i2c_keyboard_detection w; + w.show(); + + return a.exec(); +} diff --git a/Software/qmk_kbd_list.cpp b/Software/qmk_kbd_list.cpp new file mode 100644 index 0000000..eded00f --- /dev/null +++ b/Software/qmk_kbd_list.cpp @@ -0,0 +1,64 @@ +#include "qmk_kbd_list.h" +#include "ui_qmk_kbd_list.h" + +qmk_kbd_list::qmk_kbd_list(QWidget *parent) : + QWidget(parent), + ui(new Ui::qmk_kbd_list) +{ + ui->setupUi(this); +} + +qmk_kbd_list::~qmk_kbd_list() +{ + delete ui; +} + +void qmk_kbd_list::setInfo(QFileInfoList revisions, QFileInfoList keymaps) +{ + m_revisions = revisions; + m_keymaps = keymaps; + ui->revList->clear(); + ui->keymapList->clear(); + foreach (QFileInfo info, revisions) + ui->revList->addItem(info.fileName()); + foreach (QFileInfo info, keymaps) + ui->keymapList->addItem(info.fileName()); + if(revisions.size() != 0) + ui->revList->setCurrentRow(0); + if(keymaps.size() != 0) + ui->keymapList->setCurrentRow(0); + m_currentRev = -1; + m_currentKeymap = -1; +} + +QFileInfo qmk_kbd_list::getRev() +{ + +} + +QFileInfo qmk_kbd_list::getKeymap() +{ + +} + +void qmk_kbd_list::on_ok_clicked() +{ +// m_isShowing = false; +// if ((ui->revList->currentRow() < 0) || (ui->keymapList->currentRow() < 0)) +// emit kbdSelected(QFileInfo(""), QFileInfo("")); +// else +// emit kbdSelected(m_revisions[ui->revList->currentRow()], m_keymaps[ui->keymapList->currentRow()]); + m_currentRev = ui->revList->currentRow(); + m_currentKeymap = ui->keymapList->currentRow(); + this->close(); +} + +void qmk_kbd_list::on_cancel_clicked() +{ + this->close(); +} + +void qmk_kbd_list::closeEvent(QCloseEvent *e) +{ + emit kbdSelected(m_currentRev, m_currentKeymap); +}