From dd07e1b359e82ded2ce97ae7e3c55075bdf901bd Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 25 Aug 2015 19:47:02 -0400 Subject: [PATCH 1/5] Add the actual bit numbers in gray on the bit grid control. --- candatagrid.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/candatagrid.cpp b/candatagrid.cpp index dff5487..11e8a8e 100644 --- a/candatagrid.cpp +++ b/candatagrid.cpp @@ -69,9 +69,11 @@ void CANDataGrid::paintEvent(QPaintEvent *event) //the next left most column has "0 1 2 3 4 5 6 7" written down along the grid painter.setPen(QPen(Qt::black)); - QFont theFont; - theFont.setPixelSize(qMin(xSector, ySector) - 10); - painter.setFont(theFont); + QFont mainFont; + mainFont.setPixelSize(qMin(xSector, ySector) - 10); + painter.setFont(mainFont); + QFont smallFont; + smallFont.setPixelSize(qMin(xSector, ySector) - 15); painter.drawText(QRect(viewport.left(), viewport.top(), xSpan, ySector), Qt::AlignCenter, tr("BITS")); @@ -95,6 +97,9 @@ void CANDataGrid::paintEvent(QPaintEvent *event) //bits that used to be set but now are unset are red, bits that used to be unset but now are set //are green + painter.setPen(QPen(Qt::gray)); + //painter.setFont(smallFont); + for (y = 0; y < 8; y++) { thisByte = data[y]; @@ -131,6 +136,7 @@ void CANDataGrid::paintEvent(QPaintEvent *event) //painter.fillRect(viewport.left() + (x+2) * xSector, viewport.top() + (y+2) * ySector, xSector, ySector, redBrush); painter.drawRect(viewport.left() + (x+2) * xSector, viewport.top() + (y+2) * ySector, xSector, ySector); + painter.drawText(viewport.left() + (x+2) * xSector + (xSector / 3), viewport.top() + (y + 3) * ySector - (ySector / 3), QString::number(y * 8 + (7-x))); } } upperLeft.setX(viewport.left() + 2 * xSector); From 9d3608cd904d24f360710da19d54594d889b07f7 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 25 Aug 2015 19:47:25 -0400 Subject: [PATCH 2/5] Allow flowview to work in realtime like many of the other windows can do. --- flowviewwindow.cpp | 31 +++++++++++++++++++++++++++---- flowviewwindow.ui | 9 ++++++++- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/flowviewwindow.cpp b/flowviewwindow.cpp index 51e9747..acd6ebf 100644 --- a/flowviewwindow.cpp +++ b/flowviewwindow.cpp @@ -156,9 +156,11 @@ void FlowViewWindow::plottableDoubleClick(QCPAbstractPlottable* plottable, QMous void FlowViewWindow::gotCenterTimeID(int32_t ID, double timestamp) { - if (secondsMode) timestamp *= 1000000.0; //frames always store timestamp in microseconds + uint64_t t_stamp; - qDebug() << "timestamp: " << timestamp; + t_stamp = timestamp * 1000000l; + + qDebug() << "timestamp: " << t_stamp; changeID(QString::number(ID)); //to be sure we're focused on the proper ID @@ -175,7 +177,7 @@ void FlowViewWindow::gotCenterTimeID(int32_t ID, double timestamp) int bestIdx = -1; for (int i = 0; i < frameCache.count(); i++) { - if (frameCache[i].timestamp > timestamp) + if (frameCache[i].timestamp > t_stamp) { bestIdx = i - 1; break; @@ -286,6 +288,7 @@ void FlowViewWindow::saveFileFlow() void FlowViewWindow::updatedFrames(int numFrames) { + CANFrame thisFrame; if (numFrames == -1) //all frames deleted. Kill the display { ui->listFrameID->clear(); @@ -313,6 +316,26 @@ void FlowViewWindow::updatedFrames(int numFrames) } else //just got some new frames. See if they are relevant. { + int refID = frameCache[0].ID; + bool needRefresh = false; + for (int i = modelFrames->count() - numFrames; i < modelFrames->count(); i++) + { + thisFrame = modelFrames->at(i); + if (thisFrame.ID == refID) + { + frameCache.append(thisFrame); + if (ui->cbLiveMode->checkState() == Qt::Checked) + { + currentPosition = frameCache.count() - 1; + needRefresh = true; + } + } + } + if (needRefresh) + { + updateDataView(); + if (ui->cbSync->checkState() == Qt::Checked) emit sendCenterTimeID(frameCache[currentPosition].ID, frameCache[currentPosition].timestamp / 1000000.0); + } } } @@ -489,7 +512,7 @@ void FlowViewWindow::changeLooping(bool check) void FlowViewWindow::timerTriggered() { - if (!playbackActive) + if (!playbackActive || (ui->cbLiveMode->checkState() == Qt::Checked)) { playbackTimer->stop(); return; diff --git a/flowviewwindow.ui b/flowviewwindow.ui index e06b7ae..2ea56f3 100644 --- a/flowviewwindow.ui +++ b/flowviewwindow.ui @@ -52,7 +52,7 @@ - + @@ -195,6 +195,13 @@ + + + + Live Mode (No Playback) + + + From b06d6ad9adf8f03bb0856730a8375c1e1a6480c9 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 25 Aug 2015 20:14:00 -0400 Subject: [PATCH 3/5] Fix a bug where intel and motorola format specifiers were reversed when loading and saving DBC files, fixed the dbc signal editor to properly set and show signals. That was broken too. Version is updated. There are still fixes to do so look for the next commit. --- config.h | 2 +- dbchandler.cpp | 16 +++++++-------- dbcsignaleditor.cpp | 50 ++++++++++++++++++++++++++------------------- 3 files changed, 38 insertions(+), 30 deletions(-) diff --git a/config.h b/config.h index 78ef3db..b2ee918 100644 --- a/config.h +++ b/config.h @@ -1,7 +1,7 @@ #ifndef CONFIG #define CONFIG -#define VERSION 136 +#define VERSION 137 //try to keep this in sync. //SavvyCAN will complain if you connect a GVRET board with a revision diff --git a/dbchandler.cpp b/dbchandler.cpp index 0c1dc71..c1f350e 100644 --- a/dbchandler.cpp +++ b/dbchandler.cpp @@ -87,12 +87,12 @@ void DBCHandler::loadDBCFile(QString filename) } switch (val) { - case 0: - sig.intelByteOrder = true; - break; - case 1: + case 0: //big endian mode sig.intelByteOrder = false; break; + case 1: //little endian mode + sig.intelByteOrder = true; + break; case 2: sig.valType = SP_FLOAT; break; @@ -344,12 +344,12 @@ void DBCHandler::saveDBCFile(QString filename) switch (sig.valType) { case UNSIGNED_INT: - if (sig.intelByteOrder) msgOutput.append("0+"); - else msgOutput.append("1+"); + if (sig.intelByteOrder) msgOutput.append("1+"); + else msgOutput.append("0+"); break; case SIGNED_INT: - if (sig.intelByteOrder) msgOutput.append("0-"); - else msgOutput.append("1-"); + if (sig.intelByteOrder) msgOutput.append("1-"); + else msgOutput.append("0-"); break; case SP_FLOAT: msgOutput.append("2-"); diff --git a/dbcsignaleditor.cpp b/dbcsignaleditor.cpp index 7008da8..40d4d09 100644 --- a/dbcsignaleditor.cpp +++ b/dbcsignaleditor.cpp @@ -345,33 +345,41 @@ void DBCSignalEditor::fillSignalForm(DBC_SIGNAL *sig) ui->txtUnitName->setText(sig->unitName); memset(bitpattern, 0, 8); //clear it out first. - int startBit, endBit, startByte, bitWithinByteStart; + + int startBit, endBit; startBit = sig->startBit; - startByte = startBit / 8; - bitWithinByteStart = startBit % 8; - if (!sig->intelByteOrder) - { - bitWithinByteStart = 7 - bitWithinByteStart; - startBit = (startByte * 8) + bitWithinByteStart; - } - endBit = startBit + sig->signalSize - 1; - if (endBit > 63) - { - endBit = 63; - } - - //bitpattern[startBit / 8] |= 1 << (startBit % 8); + bitpattern[startBit / 8] |= 1 << (startBit % 8); //make the start bit a different color to set it apart ui->bitfield->setReference(bitpattern, false); - for (int y = startBit; y <= endBit; y++) + if (sig->intelByteOrder) { - int byt = y / 8; - bitpattern[byt] |= 1 << (y % 8); - } - ui->bitfield->updateData(bitpattern, true); + endBit = startBit + sig->signalSize - 1; + if (startBit < 0) startBit = 0; + if (endBit > 63) endBit = 63; + for (int y = startBit; y <= endBit; y++) + { + int byt = y / 8; + bitpattern[byt] |= 1 << (y % 8); + } + } + else //big endian / motorola format + { + //much more irritating than the intel version... + int size = sig->signalSize; + while (size > 0) + { + int byt = startBit / 8; + bitpattern[byt] |= 1 << (startBit % 8); + size--; + if ((startBit % 8) == 0) startBit += 15; + else startBit--; + } + } + + ui->bitfield->updateData(bitpattern, true); ui->cbIntelFormat->setChecked(sig->intelByteOrder); switch (sig->valType) @@ -447,7 +455,7 @@ void DBCSignalEditor::clickSignalList(int row) void DBCSignalEditor::bitfieldClicked(int x, int y) { - int bit = (x) + (y * 8); + int bit = (7 - x) + (y * 8); if (currentSignal == NULL) return; currentSignal->startBit = bit; fillSignalForm(currentSignal); From 4d498bf0be435ddf887a695e06bebf8880ad9226 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 25 Aug 2015 21:14:06 -0400 Subject: [PATCH 4/5] Made the dbc handler process signals the way that they're supposed to be (cross your fingers). --- dbchandler.cpp | 116 ++++++++++++++++++++++--------------------------- 1 file changed, 53 insertions(+), 63 deletions(-) diff --git a/dbchandler.cpp b/dbchandler.cpp index c1f350e..9a4c5b2 100644 --- a/dbchandler.cpp +++ b/dbchandler.cpp @@ -502,85 +502,77 @@ void DBCHandler::listDebugging() } -//Vector uses a special format for bit ordering. It pretends that the bits are numbered -//0 to 63 in ascending order of bits as if a 64 bit integer were stored lowest first -//and highest bit last. -//0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Vector bit ordering -//7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 Normal bitwise ordering within bytes -//0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 Reversed bit order used by Vector -//0 1 2 3 Byte ordering (same either way) -//A 16 bit integer would be stored Low first high second for intel format and high first, low second for motorola +/* + The way that the DBC file format works is kind of weird... For intel format signals you count up +from the start bit to the end bit which is (startbit + signallength - 1). At each point +bits are numbered in a sawtooth manner. What that means is that the very first bit is 0 and you count up +from there all of the way to 63 with each byte being 8 bits so bit 0 is the lowest bit in the first byte +and 8 is the lowest bit in the next byte up. The whole thing looks like this: + Bits + 7 6 5 4 3 2 1 0 + + 0 7 6 5 4 3 2 1 0 +b 1 15 14 13 12 11 10 9 8 +y 2 23 22 21 20 19 18 17 16 +t 3 31 30 29 28 27 26 25 24 +e 4 39 38 37 36 35 34 33 32 +s 5 47 46 45 44 43 42 41 40 + 6 55 54 53 52 51 50 49 48 + 7 63 62 61 60 59 58 57 56 + + For intel format you start at the start bit and keep counting up. If you have a signal size of 8 + and start at bit 12 then the bits are 12, 13, 14, 15, 16, 17, 18, 19 which spans across two bytes. + In this format each bit is worth twice as much as the last and you just keep counting up. + Bit 12 is worth 1, 13 is worth 2, 14 is worth 4, etc all of the way to bit 19 is worth 128. + + Motorola format turns most everything on its head. You count backward from the start bit but + only within the current byte. If you are about to exit the current byte you go one higher and then keep + going backward as before. Using the same example as for intel, start bit of 12 and a signal length of 8. + So, the bits are 12, 11, 10, 9, 8, 23, 22, 21. Yes, that's confusing. They now go in reverse value order too. + Bit 12 is worth 128, 11 is worth 64, etc until bit 21 is worth 1. +*/ -//For intel format invert the starting bit within a byte. -//Otherwise, iterate over the bytes that it encompasses -//For intel format this works nicely as it means you can just go through the list getting higher and higher -//values for each bit as you go. -//For motorola it is backwards but only partially. For each byte you can go through and it's higher as you go -//but, at each byte boundary the next byte is lower than the multiplier for the last. QString DBCHandler::processSignal(const CANFrame &frame, const DBC_SIGNAL &sig) { - int startBit, endBit, startByte, endByte, bitWithinByteStart, bitWithinByteEnd; - int result = 0; - int multiplier; - int bitsToGo; - - startBit = sig.startBit; - startByte = startBit / 8; - bitWithinByteStart = startBit % 8; - if (!sig.intelByteOrder) - { - bitWithinByteStart = 7 - bitWithinByteStart; - startBit = (startByte * 8) + bitWithinByteStart; - } + int64_t result = 0; + int bit; + int sigSize; if (sig.valType == STRING) { QString buildString; + int startByte = sig.signalSize / 8; int bytes = sig.signalSize / 8; for (int x = 0; x < bytes; x++) buildString.append(frame.data[startByte + x]); return buildString; } - endBit = startBit + sig.signalSize - 1; - endByte = endBit / 8; - bitWithinByteEnd = endBit % 8; - bitsToGo = sig.signalSize - 1; + sigSize = sig.signalSize; - multiplier = 1; - if (!sig.intelByteOrder) + if (sig.intelByteOrder) { - for (int y = startByte; y < endByte; y++) multiplier *= 256; + bit = sig.startBit; + for (int bitpos = 0; bitpos < sigSize; bitpos++) + { + if (frame.data[bit / 8] & (1 << (bit % 8))) + result += (1ULL << bitpos); + + bit++; + } } - - //qDebug() << "Signal Name: " << sig.name; - //qDebug() << "Intel Order: " << sig.intelByteOrder; - //qDebug() << "start byte: " << startByte; - //qDebug() << "End Byte: " << endByte; - - int sBit, eBit; - sBit = bitWithinByteStart; - eBit = sBit + bitsToGo; - if (eBit > 7) eBit = 7; - bitsToGo -= (eBit - sBit + 1); - for (int b = startByte; b <= endByte; b++) + else //motorola / big endian mode { - //qDebug() << "Byte: " << frame.data[b]; - //qDebug() << "S: " << sBit; - //qDebug() << "E: " << eBit; - //process this byte - result += processByte(frame.data[b], sBit, eBit) * multiplier; + bit = sig.startBit; + for (int bitpos = 0; bitpos < sigSize; bitpos++) + { + if (frame.data[bit / 8] & (1 << (bit % 8))) + result += (1ULL << (sigSize - bitpos)); - //add to multiplier - if (sig.intelByteOrder) - multiplier = multiplier << 8; - else - multiplier = multiplier >> 8; + if ((bit % 8) == 0) + bit += 15; + else bit--; - //Prepare sBit and eBit for next byte - sBit = 0; //fresh byte so we start at the beginning now - eBit = sBit + bitsToGo; - if (eBit > 7) eBit = 7; - bitsToGo -= (eBit - sBit + 1); + } } if (sig.valType == SIGNED_INT) @@ -613,8 +605,6 @@ QString DBCHandler::processSignal(const CANFrame &frame, const DBC_SIGNAL &sig) double endResult = ((double)result * sig.factor) + sig.bias; result = (int) endResult; - //qDebug() << "Result: " << result; - QString outputString; outputString = sig.name + ": "; From c14c68f2febea057cd5dca8f6193cded3838284e Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Wed, 26 Aug 2015 18:19:02 -0400 Subject: [PATCH 5/5] Correct math bug in big endian calcs (for dbc) --- dbchandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dbchandler.cpp b/dbchandler.cpp index 9a4c5b2..39a361c 100644 --- a/dbchandler.cpp +++ b/dbchandler.cpp @@ -566,7 +566,7 @@ QString DBCHandler::processSignal(const CANFrame &frame, const DBC_SIGNAL &sig) for (int bitpos = 0; bitpos < sigSize; bitpos++) { if (frame.data[bit / 8] & (1 << (bit % 8))) - result += (1ULL << (sigSize - bitpos)); + result += (1ULL << (sigSize - bitpos - 1)); if ((bit % 8) == 0) bit += 15;