Merge branch 'master' of github.com:collin80/SavvyCAN
Merge changes from git to local copy - merge in warning fixes.
This commit is contained in:
+9
-3
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
+61
-71
@@ -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-");
|
||||
@@ -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 - 1));
|
||||
|
||||
//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 + ": ";
|
||||
|
||||
+29
-21
@@ -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);
|
||||
|
||||
+27
-4
@@ -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;
|
||||
|
||||
+8
-1
@@ -52,7 +52,7 @@
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,0">
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,0,0">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
@@ -195,6 +195,13 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbLiveMode">
|
||||
<property name="text">
|
||||
<string>Live Mode (No Playback)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cbSync">
|
||||
<property name="sizePolicy">
|
||||
|
||||
Reference in New Issue
Block a user