diff --git a/SavvyCAN.pro.user b/SavvyCAN.pro.user index 900f1ec..3f8dc26 100644 --- a/SavvyCAN.pro.user +++ b/SavvyCAN.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/canframemodel.cpp b/canframemodel.cpp index 08d1bca..5d3086f 100644 --- a/canframemodel.cpp +++ b/canframemodel.cpp @@ -34,7 +34,7 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const return QString::number(thisFrame.timestamp); break; case 1: //id - return QString::number(thisFrame.ID, 16); + return QString::number(thisFrame.ID, 16).toUpper().rightJustified(2,'0'); break; case 2: //ext return QString::number(thisFrame.extended); @@ -48,7 +48,7 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const case 5: //data for (int i = 0; i < thisFrame.len; i++) { - tempString.append(QString::number(thisFrame.data[i], 16)); + tempString.append(QString::number(thisFrame.data[i], 16).toUpper().rightJustified(2,'0')); tempString.append(" "); } return tempString; @@ -93,14 +93,14 @@ QVariant CANFrameModel::headerData(int section, Qt::Orientation orientation, } else - return QString::number(section); + return QString::number(section + 1); } -void CANFrameModel::addFrame(CANFrame &frame) +void CANFrameModel::addFrame(CANFrame &frame, bool autoRefresh = false) { - //beginInsertRows(QModelIndex(), frames.count() + 1, frames.count() + 1); + if (autoRefresh) beginInsertRows(QModelIndex(), frames.count() + 1, frames.count() + 1); frames.append(frame); - //endInsertRows(); + if (autoRefresh) endInsertRows(); } void CANFrameModel::sendRefresh() @@ -109,6 +109,13 @@ void CANFrameModel::sendRefresh() endInsertRows(); } +void CANFrameModel::sendRefresh(int pos) +{ + beginInsertRows(QModelIndex(), pos, pos); + endInsertRows(); +} + + void CANFrameModel::clearFrames() { beginRemoveRows(QModelIndex(), 0, frames.count()); diff --git a/canframemodel.h b/canframemodel.h index 47d1101..66c372b 100644 --- a/canframemodel.h +++ b/canframemodel.h @@ -18,8 +18,9 @@ public: int role = Qt::DisplayRole) const; int CANFrameModel::columnCount(const QModelIndex &) const; - void addFrame(CANFrame &frame); + void addFrame(CANFrame &, bool); void sendRefresh(); + void sendRefresh(int); void clearFrames(); diff --git a/mainwindow.cpp b/mainwindow.cpp index 0eb66c7..d59caa6 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -33,6 +33,9 @@ MainWindow::MainWindow(QWidget *parent) : } port = new QSerialPort(this); + + rx_state = IDLE; + rx_step = 0; } MainWindow::~MainWindow() @@ -40,9 +43,9 @@ MainWindow::~MainWindow() delete ui; } -void MainWindow::addFrameToDisplay(CANFrame &frame) +void MainWindow::addFrameToDisplay(CANFrame &frame, bool autoRefresh = false) { - model->addFrame(frame); + model->addFrame(frame, autoRefresh); } void MainWindow::loadCRTDFile(QString filename) @@ -231,7 +234,126 @@ void MainWindow::connButtonPress() output.append(0xE7); port->write(output); ///isConnected = true; + connect(port, SIGNAL(readyRead()), this, SLOT(readSerialData())); } +} +void MainWindow::readSerialData() +{ + QByteArray data = port->readAll(); + unsigned char c; + ui->statusBar->showMessage(tr("Got data from serial. Len = %0").arg(data.length())); + for (int i = 0; i < data.length(); i++) + { + c = data.at(i); + procRXChar(c); + } +} + +void MainWindow::procRXChar(unsigned char c) +{ + switch (rx_state) + { + case IDLE: + if (c == 0xF1) rx_state = GET_COMMAND; + break; + case GET_COMMAND: + switch (c) + { + case 0: //receiving a can frame + rx_state = BUILD_CAN_FRAME; + rx_step = 0; + break; + case 1: //we don't accept time sync commands from the firmware + rx_state = IDLE; + break; + case 2: //process a return reply for digital input states. + rx_state = GET_DIG_INPUTS; + rx_step = 0; + break; + case 3: //process a return reply for analog inputs + rx_state = GET_ANALOG_INPUTS; + break; + case 4: //we set digital outputs we don't accept replies so nothing here. + rx_state = IDLE; + break; + case 5: //we set canbus specs we don't accept replies. + rx_state = IDLE; + break; + } + break; + case BUILD_CAN_FRAME: + switch (rx_step) + { + case 0: + buildFrame.timestamp = c; + break; + case 1: + buildFrame.timestamp |= (uint)(c << 8); + break; + case 2: + buildFrame.timestamp |= (uint)c << 16; + break; + case 3: + buildFrame.timestamp |= (uint)c << 24; + break; + case 4: + buildFrame.ID = c; + break; + case 5: + buildFrame.ID |= c << 8; + break; + case 6: + buildFrame.ID |= c << 16; + break; + case 7: + buildFrame.ID |= c << 24; + if ((buildFrame.ID & 1 << 31) == 1 << 31) + { + buildFrame.ID &= 0x7FFFFFFF; + buildFrame.extended = true; + } + else buildFrame.extended = false; + break; + case 8: + buildFrame.len = c & 0xF; + if (buildFrame.len > 8) buildFrame.len = 8; + buildFrame.bus = (c & 0xF0) >> 4; + break; + default: + if (rx_step < buildFrame.len + 9) + { + buildFrame.data[rx_step - 9] = c; + } + else + { + rx_state = IDLE; + rx_step = 0; + addFrameToDisplay(buildFrame, true); + } + break; + } + rx_step++; + break; + case GET_ANALOG_INPUTS: //get 9 bytes - 2 per analog input plus checksum + switch (rx_step) + { + case 0: + break; + } + rx_step++; + break; + case GET_DIG_INPUTS: //get two bytes. One for digital in status and one for checksum. + switch (rx_step) + { + case 0: + break; + case 1: + rx_state = IDLE; + break; + } + rx_step++; + break; + } } diff --git a/mainwindow.h b/mainwindow.h index b49e886..092ee22 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -10,6 +10,18 @@ namespace Ui { class MainWindow; } +enum STATE //keep this enum synchronized with the Arduino firmware project +{ + IDLE, + GET_COMMAND, + BUILD_CAN_FRAME, + TIME_SYNC, + GET_DIG_INPUTS, + GET_ANALOG_INPUTS, + SET_DIG_OUTPUTS, + SETUP_CANBUS +}; + class MainWindow : public QMainWindow { Q_OBJECT @@ -21,17 +33,23 @@ public: private slots: void handleLoadFile(); void connButtonPress(); + void readSerialData(); private: Ui::MainWindow *ui; CANFrameModel *model; QSerialPort *port; + QByteArray inputBuffer; + STATE rx_state; + int rx_step; + CANFrame buildFrame; void loadCRTDFile(QString); void loadNativeCSVFile(QString); void loadGenericCSVFile(QString); void loadLogFile(QString); void loadMicrochipFile(QString); - void addFrameToDisplay(CANFrame &); + void addFrameToDisplay(CANFrame &, bool); + void procRXChar(unsigned char); }; #endif // MAINWINDOW_H diff --git a/mainwindow.ui b/mainwindow.ui index 9598433..c065db8 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -35,6 +35,13 @@ 400 + + + 11 + 50 + false + + true