Labrador/Desktop_Interface/i2cdecoder.cpp

226 lines
6.1 KiB
C++
Raw Normal View History

2018-07-24 00:21:21 +01:00
#include "i2cdecoder.h"
2018-08-08 00:19:30 +01:00
using namespace i2c;
i2cDecoder::i2cDecoder(isoBuffer* sda_in, isoBuffer* scl_in, QPlainTextEdit* console_in)
: QObject(nullptr)
, sda(sda_in)
, scl(scl_in)
, console(console_in)
2018-07-24 00:21:21 +01:00
{
2018-11-05 23:15:48 +00:00
serialBuffer = new isoBufferBuffer(I2C_BUFFER_LENGTH);
updateTimer = new QTimer();
updateTimer->setTimerType(Qt::PreciseTimer);
updateTimer->start(CONSOLE_UPDATE_TIMER_PERIOD);
connect(updateTimer, &QTimer::timeout, this, &i2cDecoder::updateConsole);
}
i2cDecoder::~i2cDecoder()
{
// TODO: Is a lock needed here? Destructors should never be called more than once but...
delete updateTimer;
delete serialBuffer;
2018-07-24 00:21:21 +01:00
}
2018-11-03 23:47:25 +00:00
void i2cDecoder::reset()
{
2018-11-03 23:49:10 +00:00
qDebug () << "Resetting I2C";
2018-11-04 00:31:48 +00:00
Isobuffer refactor (#64) * make isobuffer.cpp follow the common bracket style * Add a few utility functions to isoBuffer, and reorganize and comment isobuffer.h * refactor a few functions in isoBuffer using the newly added functions * Clean up isoBuffer::readBuffer. Requires particular attention during review * remove unused variable isoBuffer::firstTime * Fix formatting and add a comment to isoBuffer::maybeOutputSampleToFile * move invariant out of loop in isoBuffer::writeBuffer_short * Substantially refactor isoBuffer::readBuffer * change spaces to tabs on isoBuffer.h * spaces to tabs on isobuffer.cpp and isobuffer.h, but properly * Enforce const correctness on some methods of isoBuffer * Add some comments to isobuffer.cpp * Remove duplication in isoBuffer::cap_xnfromxxx functions by extracting common functionality to a free function * Format isobuffer.h and isobuffer.cpp * add inserted count to isoBuffer * further modification to isoBuffer::readBuffer * Correct a comment in isoBuffer::readBuffer * add an anonymous namespace with file-wide constants * remove isoBuffer::openFile, and move initialization isoBuffer to initializer list * add lines between if statements in isoBuffer::insertIntoBuffer * add spaces after // to some comments * extract common functionality from writeBuffer_xxx functions to function template * update header file to reflect previous commits * make isoBuffer::return nullptr in a troublesome case * add space after // to some other comments * Make capSample a member function of isoBuffer, delete a macro in isobuffer.cpp * clean up various comments and declarations in isobuffer.cpp * make isoBuffer::gainBuffer work for any gain value * make enableFileIO use the constant definitions made in a recent commit * Remove type argument from isoBuffer::serialManage * make isoBuffer::readBuffer return a zero-filled buffer instead of null * Remove isoBuffer::glitchInsert * Add a bunch of TODOs to isobuffer.cpp and isobuffer.h * Rename member variables of isoBuffer to have an m_ prefix * Move isoBuffer::capSample comparison functors to anonymous namespace * Make CONSOLE_UPDATE_TIMER_PERIOD on isobuffer.h a constexpr intead of a macro
2019-01-23 05:13:40 +00:00
if (sda->m_back != scl->m_back)
2018-11-04 00:31:48 +00:00
{
// Perhaps the data could be saved, but just resetting them seems much safer
sda->clearBuffer();
scl->clearBuffer();
}
Isobuffer refactor (#64) * make isobuffer.cpp follow the common bracket style * Add a few utility functions to isoBuffer, and reorganize and comment isobuffer.h * refactor a few functions in isoBuffer using the newly added functions * Clean up isoBuffer::readBuffer. Requires particular attention during review * remove unused variable isoBuffer::firstTime * Fix formatting and add a comment to isoBuffer::maybeOutputSampleToFile * move invariant out of loop in isoBuffer::writeBuffer_short * Substantially refactor isoBuffer::readBuffer * change spaces to tabs on isoBuffer.h * spaces to tabs on isobuffer.cpp and isobuffer.h, but properly * Enforce const correctness on some methods of isoBuffer * Add some comments to isobuffer.cpp * Remove duplication in isoBuffer::cap_xnfromxxx functions by extracting common functionality to a free function * Format isobuffer.h and isobuffer.cpp * add inserted count to isoBuffer * further modification to isoBuffer::readBuffer * Correct a comment in isoBuffer::readBuffer * add an anonymous namespace with file-wide constants * remove isoBuffer::openFile, and move initialization isoBuffer to initializer list * add lines between if statements in isoBuffer::insertIntoBuffer * add spaces after // to some comments * extract common functionality from writeBuffer_xxx functions to function template * update header file to reflect previous commits * make isoBuffer::return nullptr in a troublesome case * add space after // to some other comments * Make capSample a member function of isoBuffer, delete a macro in isobuffer.cpp * clean up various comments and declarations in isobuffer.cpp * make isoBuffer::gainBuffer work for any gain value * make enableFileIO use the constant definitions made in a recent commit * Remove type argument from isoBuffer::serialManage * make isoBuffer::readBuffer return a zero-filled buffer instead of null * Remove isoBuffer::glitchInsert * Add a bunch of TODOs to isobuffer.cpp and isobuffer.h * Rename member variables of isoBuffer to have an m_ prefix * Move isoBuffer::capSample comparison functors to anonymous namespace * Make CONSOLE_UPDATE_TIMER_PERIOD on isobuffer.h a constexpr intead of a macro
2019-01-23 05:13:40 +00:00
serialPtr_bit = sda->m_back * 8;
2018-11-04 00:31:48 +00:00
2018-11-05 23:15:48 +00:00
{
std::lock_guard<std::mutex> lock(mutex);
serialBuffer->clear();
2018-11-05 23:15:48 +00:00
}
2018-11-03 23:47:25 +00:00
}
2018-07-24 00:21:21 +01:00
void i2cDecoder::run()
{
// qDebug() << "i2cDecoder::run()";
Isobuffer refactor (#64) * make isobuffer.cpp follow the common bracket style * Add a few utility functions to isoBuffer, and reorganize and comment isobuffer.h * refactor a few functions in isoBuffer using the newly added functions * Clean up isoBuffer::readBuffer. Requires particular attention during review * remove unused variable isoBuffer::firstTime * Fix formatting and add a comment to isoBuffer::maybeOutputSampleToFile * move invariant out of loop in isoBuffer::writeBuffer_short * Substantially refactor isoBuffer::readBuffer * change spaces to tabs on isoBuffer.h * spaces to tabs on isobuffer.cpp and isobuffer.h, but properly * Enforce const correctness on some methods of isoBuffer * Add some comments to isobuffer.cpp * Remove duplication in isoBuffer::cap_xnfromxxx functions by extracting common functionality to a free function * Format isobuffer.h and isobuffer.cpp * add inserted count to isoBuffer * further modification to isoBuffer::readBuffer * Correct a comment in isoBuffer::readBuffer * add an anonymous namespace with file-wide constants * remove isoBuffer::openFile, and move initialization isoBuffer to initializer list * add lines between if statements in isoBuffer::insertIntoBuffer * add spaces after // to some comments * extract common functionality from writeBuffer_xxx functions to function template * update header file to reflect previous commits * make isoBuffer::return nullptr in a troublesome case * add space after // to some other comments * Make capSample a member function of isoBuffer, delete a macro in isobuffer.cpp * clean up various comments and declarations in isobuffer.cpp * make isoBuffer::gainBuffer work for any gain value * make enableFileIO use the constant definitions made in a recent commit * Remove type argument from isoBuffer::serialManage * make isoBuffer::readBuffer return a zero-filled buffer instead of null * Remove isoBuffer::glitchInsert * Add a bunch of TODOs to isobuffer.cpp and isobuffer.h * Rename member variables of isoBuffer to have an m_ prefix * Move isoBuffer::capSample comparison functors to anonymous namespace * Make CONSOLE_UPDATE_TIMER_PERIOD on isobuffer.h a constexpr intead of a macro
2019-01-23 05:13:40 +00:00
while (serialDistance(sda) > SERIAL_DELAY * sda->m_sampleRate_bit)
2018-08-02 09:27:09 +01:00
{
updateBitValues();
runStateMachine();
2018-11-05 22:50:36 +00:00
serialPtr_bit ++;
if (serialPtr_bit >= (sda->m_bufferLen * 8))
serialPtr_bit -= (sda->m_bufferLen * 8);
2018-08-02 09:27:09 +01:00
}
2018-07-24 00:21:21 +01:00
}
int i2cDecoder::serialDistance(isoBuffer* buffer)
{
Isobuffer refactor (#64) * make isobuffer.cpp follow the common bracket style * Add a few utility functions to isoBuffer, and reorganize and comment isobuffer.h * refactor a few functions in isoBuffer using the newly added functions * Clean up isoBuffer::readBuffer. Requires particular attention during review * remove unused variable isoBuffer::firstTime * Fix formatting and add a comment to isoBuffer::maybeOutputSampleToFile * move invariant out of loop in isoBuffer::writeBuffer_short * Substantially refactor isoBuffer::readBuffer * change spaces to tabs on isoBuffer.h * spaces to tabs on isobuffer.cpp and isobuffer.h, but properly * Enforce const correctness on some methods of isoBuffer * Add some comments to isobuffer.cpp * Remove duplication in isoBuffer::cap_xnfromxxx functions by extracting common functionality to a free function * Format isobuffer.h and isobuffer.cpp * add inserted count to isoBuffer * further modification to isoBuffer::readBuffer * Correct a comment in isoBuffer::readBuffer * add an anonymous namespace with file-wide constants * remove isoBuffer::openFile, and move initialization isoBuffer to initializer list * add lines between if statements in isoBuffer::insertIntoBuffer * add spaces after // to some comments * extract common functionality from writeBuffer_xxx functions to function template * update header file to reflect previous commits * make isoBuffer::return nullptr in a troublesome case * add space after // to some other comments * Make capSample a member function of isoBuffer, delete a macro in isobuffer.cpp * clean up various comments and declarations in isobuffer.cpp * make isoBuffer::gainBuffer work for any gain value * make enableFileIO use the constant definitions made in a recent commit * Remove type argument from isoBuffer::serialManage * make isoBuffer::readBuffer return a zero-filled buffer instead of null * Remove isoBuffer::glitchInsert * Add a bunch of TODOs to isobuffer.cpp and isobuffer.h * Rename member variables of isoBuffer to have an m_ prefix * Move isoBuffer::capSample comparison functors to anonymous namespace * Make CONSOLE_UPDATE_TIMER_PERIOD on isobuffer.h a constexpr intead of a macro
2019-01-23 05:13:40 +00:00
int back_bit = buffer->m_back * 8;
int bufferEnd_bit = buffer->m_bufferLen * 8;
2018-08-02 09:27:09 +01:00
if (back_bit >= serialPtr_bit)
2018-07-24 00:21:21 +01:00
return back_bit - serialPtr_bit;
else
return bufferEnd_bit - serialPtr_bit + back_bit;
}
2018-07-31 00:05:58 +01:00
void i2cDecoder::updateBitValues(){
previousSdaValue = currentSdaValue;
previousSclValue = currentSclValue;
2018-07-31 00:05:58 +01:00
int coord_byte = serialPtr_bit/8;
int coord_bit = serialPtr_bit - (8*coord_byte);
Isobuffer refactor (#64) * make isobuffer.cpp follow the common bracket style * Add a few utility functions to isoBuffer, and reorganize and comment isobuffer.h * refactor a few functions in isoBuffer using the newly added functions * Clean up isoBuffer::readBuffer. Requires particular attention during review * remove unused variable isoBuffer::firstTime * Fix formatting and add a comment to isoBuffer::maybeOutputSampleToFile * move invariant out of loop in isoBuffer::writeBuffer_short * Substantially refactor isoBuffer::readBuffer * change spaces to tabs on isoBuffer.h * spaces to tabs on isobuffer.cpp and isobuffer.h, but properly * Enforce const correctness on some methods of isoBuffer * Add some comments to isobuffer.cpp * Remove duplication in isoBuffer::cap_xnfromxxx functions by extracting common functionality to a free function * Format isobuffer.h and isobuffer.cpp * add inserted count to isoBuffer * further modification to isoBuffer::readBuffer * Correct a comment in isoBuffer::readBuffer * add an anonymous namespace with file-wide constants * remove isoBuffer::openFile, and move initialization isoBuffer to initializer list * add lines between if statements in isoBuffer::insertIntoBuffer * add spaces after // to some comments * extract common functionality from writeBuffer_xxx functions to function template * update header file to reflect previous commits * make isoBuffer::return nullptr in a troublesome case * add space after // to some other comments * Make capSample a member function of isoBuffer, delete a macro in isobuffer.cpp * clean up various comments and declarations in isobuffer.cpp * make isoBuffer::gainBuffer work for any gain value * make enableFileIO use the constant definitions made in a recent commit * Remove type argument from isoBuffer::serialManage * make isoBuffer::readBuffer return a zero-filled buffer instead of null * Remove isoBuffer::glitchInsert * Add a bunch of TODOs to isobuffer.cpp and isobuffer.h * Rename member variables of isoBuffer to have an m_ prefix * Move isoBuffer::capSample comparison functors to anonymous namespace * Make CONSOLE_UPDATE_TIMER_PERIOD on isobuffer.h a constexpr intead of a macro
2019-01-23 05:13:40 +00:00
unsigned char dataByteSda = sda->m_buffer[coord_byte];
unsigned char dataByteScl = scl->m_buffer[coord_byte];
2018-11-04 00:31:48 +00:00
unsigned char mask = (0x01 << coord_bit);
currentSdaValue = dataByteSda & mask;
2018-07-31 00:05:58 +01:00
currentSclValue = dataByteScl & mask;
}
2018-08-02 09:27:09 +01:00
void i2cDecoder::runStateMachine()
{
2018-11-03 23:07:15 +00:00
edge sdaEdge = edgeDetection(currentSdaValue, previousSdaValue);
edge sclEdge = edgeDetection(currentSclValue, previousSclValue);
2018-09-04 09:55:03 +01:00
2018-08-08 09:58:41 +01:00
if ((sdaEdge == edge::rising) && (sclEdge == edge::falling)) // INVALID STATE TRANSITION
{
state = transmissionState::unknown;
qDebug() << "Dumping I2C state and aborting...";
2018-11-04 00:31:48 +00:00
for (int i=31; i>=0; i--)
Isobuffer refactor (#64) * make isobuffer.cpp follow the common bracket style * Add a few utility functions to isoBuffer, and reorganize and comment isobuffer.h * refactor a few functions in isoBuffer using the newly added functions * Clean up isoBuffer::readBuffer. Requires particular attention during review * remove unused variable isoBuffer::firstTime * Fix formatting and add a comment to isoBuffer::maybeOutputSampleToFile * move invariant out of loop in isoBuffer::writeBuffer_short * Substantially refactor isoBuffer::readBuffer * change spaces to tabs on isoBuffer.h * spaces to tabs on isobuffer.cpp and isobuffer.h, but properly * Enforce const correctness on some methods of isoBuffer * Add some comments to isobuffer.cpp * Remove duplication in isoBuffer::cap_xnfromxxx functions by extracting common functionality to a free function * Format isobuffer.h and isobuffer.cpp * add inserted count to isoBuffer * further modification to isoBuffer::readBuffer * Correct a comment in isoBuffer::readBuffer * add an anonymous namespace with file-wide constants * remove isoBuffer::openFile, and move initialization isoBuffer to initializer list * add lines between if statements in isoBuffer::insertIntoBuffer * add spaces after // to some comments * extract common functionality from writeBuffer_xxx functions to function template * update header file to reflect previous commits * make isoBuffer::return nullptr in a troublesome case * add space after // to some other comments * Make capSample a member function of isoBuffer, delete a macro in isobuffer.cpp * clean up various comments and declarations in isobuffer.cpp * make isoBuffer::gainBuffer work for any gain value * make enableFileIO use the constant definitions made in a recent commit * Remove type argument from isoBuffer::serialManage * make isoBuffer::readBuffer return a zero-filled buffer instead of null * Remove isoBuffer::glitchInsert * Add a bunch of TODOs to isobuffer.cpp and isobuffer.h * Rename member variables of isoBuffer to have an m_ prefix * Move isoBuffer::capSample comparison functors to anonymous namespace * Make CONSOLE_UPDATE_TIMER_PERIOD on isobuffer.h a constexpr intead of a macro
2019-01-23 05:13:40 +00:00
qDebug("%02x\t%02x", sda->m_buffer[serialPtr_bit/8 - i] & 0xFF, scl->m_buffer[serialPtr_bit/8 - i] & 0xFF);
throw std::runtime_error("unknown i2c transmission state");
return;
2018-08-08 09:58:41 +01:00
}
if ((sdaEdge == edge::rising) && (sclEdge == edge::held_high)) // START
{
stopCondition();
return;
}
2018-08-08 09:58:41 +01:00
if ((sdaEdge == edge::falling) && (sclEdge == edge::held_high)) // STOP
{
startCondition();
return;
}
2018-08-08 09:35:26 +01:00
switch (state)
{
case transmissionState::idle:
return;
case transmissionState::address:
decodeAddress(sdaEdge, sclEdge);
break;
case transmissionState::data:
decodeData(sdaEdge, sclEdge);
break;
}
2018-08-02 09:27:09 +01:00
}
2018-08-08 00:19:30 +01:00
edge i2cDecoder::edgeDetection(uint8_t current, uint8_t prev)
{
if (current && prev)
return edge::held_high;
if (!current && !prev)
return edge::held_low;
if (current && !prev)
return edge::rising;
2018-09-04 09:55:03 +01:00
if (!current && prev)
2018-08-08 00:19:30 +01:00
return edge::falling;
2018-09-04 09:55:03 +01:00
throw std::runtime_error("i2c Edge Detection critical failure");
2018-08-08 00:19:30 +01:00
}
2018-08-08 09:35:26 +01:00
void i2cDecoder::decodeAddress(edge sdaEdge, edge sclEdge)
{
2018-08-08 10:14:08 +01:00
// Read in the next bit.
2018-11-05 22:50:36 +00:00
if (sclEdge == edge::rising && sdaEdge == edge::held_high && currentBitIndex++ < addressBitStreamLength)
2018-11-05 23:46:47 +00:00
currentBitStream = (currentBitStream << 1) | 0x0001;
2018-11-05 22:50:36 +00:00
else if (sclEdge == edge::rising && sdaEdge == edge::held_low && currentBitIndex++ < addressBitStreamLength)
2018-11-05 23:46:47 +00:00
currentBitStream = (currentBitStream << 1) & 0xFFFE;
2018-11-05 22:50:36 +00:00
else
return;
if (currentBitIndex == addressBitStreamLength)
{
qDebug() << "Finished Address Decode";
2018-11-05 23:46:47 +00:00
if (currentBitStream & 0b0000000000000010)
serialBuffer->insert("READ: ");
else
serialBuffer->insert("WRITE: ");
serialBuffer->insert_hex((uint8_t)((currentBitStream & 0b0000000111111100) >> 2));
serialBuffer->insert(' ');
2018-11-05 23:46:47 +00:00
if (currentBitStream & 0b0000000000000001)
serialBuffer->insert("(NACK)");
consoleStateInvalid = true;
2018-11-05 23:46:47 +00:00
// Prepare for next bit
currentBitIndex = 0;
currentBitStream = 0x0000;
state = transmissionState::data;
2018-11-05 22:50:36 +00:00
}
2018-08-08 09:35:26 +01:00
}
void i2cDecoder::decodeData(edge sdaEdge, edge sclEdge)
{
2018-11-05 23:46:47 +00:00
// Read in the next bit.
if (sclEdge == edge::rising && sdaEdge == edge::held_high && currentBitIndex++ < dataBitStreamLength)
currentBitStream = (currentBitStream << 1) | 0x0001;
else if (sclEdge == edge::rising && sdaEdge == edge::held_low && currentBitIndex++ < dataBitStreamLength)
currentBitStream = (currentBitStream << 1) & 0xFFFE;
else
return;
if (currentBitIndex == dataBitStreamLength)
{
qDebug() << "Finished Data byte Decode";
serialBuffer->insert_hex((uint8_t)((currentBitStream & 0b0000000111111110) >> 1));
serialBuffer->insert(' ');
2018-11-05 23:46:47 +00:00
if (currentBitStream & 0b0000000000000001)
serialBuffer->insert("(NACK)");
2018-11-05 23:46:47 +00:00
consoleStateInvalid = true;
// Prepare for next bit
currentBitIndex = 0;
currentBitStream = 0x0000;
}
2018-08-08 09:35:26 +01:00
}
2018-08-08 09:58:41 +01:00
void i2cDecoder::startCondition()
{
2018-08-08 10:14:08 +01:00
currentBitIndex = 0;
2018-11-05 23:46:47 +00:00
currentBitStream = 0x0000;
2018-08-08 10:14:08 +01:00
state = transmissionState::address;
2018-11-03 23:07:15 +00:00
qDebug() << "I2C START";
2018-08-08 09:58:41 +01:00
}
void i2cDecoder::stopCondition()
{
2018-11-05 23:46:47 +00:00
state = transmissionState::idle;
serialBuffer->insert('\n');
2018-11-03 23:07:15 +00:00
qDebug() << "I2C STOP";
2018-08-08 09:58:41 +01:00
}
2018-08-12 07:21:05 +01:00
2018-11-05 23:15:48 +00:00
void i2cDecoder::updateConsole(){
std::lock_guard<std::mutex> lock(mutex);
if (!consoleStateInvalid)
return;
console->setPlainText(QString::fromLocal8Bit(serialBuffer->begin(), serialBuffer->size()));
Isobuffer refactor (#64) * make isobuffer.cpp follow the common bracket style * Add a few utility functions to isoBuffer, and reorganize and comment isobuffer.h * refactor a few functions in isoBuffer using the newly added functions * Clean up isoBuffer::readBuffer. Requires particular attention during review * remove unused variable isoBuffer::firstTime * Fix formatting and add a comment to isoBuffer::maybeOutputSampleToFile * move invariant out of loop in isoBuffer::writeBuffer_short * Substantially refactor isoBuffer::readBuffer * change spaces to tabs on isoBuffer.h * spaces to tabs on isobuffer.cpp and isobuffer.h, but properly * Enforce const correctness on some methods of isoBuffer * Add some comments to isobuffer.cpp * Remove duplication in isoBuffer::cap_xnfromxxx functions by extracting common functionality to a free function * Format isobuffer.h and isobuffer.cpp * add inserted count to isoBuffer * further modification to isoBuffer::readBuffer * Correct a comment in isoBuffer::readBuffer * add an anonymous namespace with file-wide constants * remove isoBuffer::openFile, and move initialization isoBuffer to initializer list * add lines between if statements in isoBuffer::insertIntoBuffer * add spaces after // to some comments * extract common functionality from writeBuffer_xxx functions to function template * update header file to reflect previous commits * make isoBuffer::return nullptr in a troublesome case * add space after // to some other comments * Make capSample a member function of isoBuffer, delete a macro in isobuffer.cpp * clean up various comments and declarations in isobuffer.cpp * make isoBuffer::gainBuffer work for any gain value * make enableFileIO use the constant definitions made in a recent commit * Remove type argument from isoBuffer::serialManage * make isoBuffer::readBuffer return a zero-filled buffer instead of null * Remove isoBuffer::glitchInsert * Add a bunch of TODOs to isobuffer.cpp and isobuffer.h * Rename member variables of isoBuffer to have an m_ prefix * Move isoBuffer::capSample comparison functors to anonymous namespace * Make CONSOLE_UPDATE_TIMER_PERIOD on isobuffer.h a constexpr intead of a macro
2019-01-23 05:13:40 +00:00
if(sda->m_serialAutoScroll){
2018-11-05 23:15:48 +00:00
QTextCursor c = console->textCursor();
c.movePosition(QTextCursor::End);
console->setTextCursor(c);
}
consoleStateInvalid = false;
}