mirror of https://github.com/EspoTek/Labrador.git
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
This commit is contained in:
parent
4499db10bf
commit
015d41624d
|
@ -20,14 +20,14 @@ void i2cDecoder::reset()
|
|||
{
|
||||
qDebug () << "Resetting I2C";
|
||||
|
||||
if (sda->back != scl->back)
|
||||
if (sda->m_back != scl->m_back)
|
||||
{
|
||||
// Perhaps the data could be saved, but just resetting them seems much safer
|
||||
sda->clearBuffer();
|
||||
scl->clearBuffer();
|
||||
}
|
||||
|
||||
serialPtr_bit = sda->back * 8;
|
||||
serialPtr_bit = sda->m_back * 8;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
|
@ -40,20 +40,20 @@ void i2cDecoder::reset()
|
|||
void i2cDecoder::run()
|
||||
{
|
||||
// qDebug() << "i2cDecoder::run()";
|
||||
while (serialDistance(sda) > SERIAL_DELAY * sda->sampleRate_bit)
|
||||
while (serialDistance(sda) > SERIAL_DELAY * sda->m_sampleRate_bit)
|
||||
{
|
||||
updateBitValues();
|
||||
runStateMachine();
|
||||
serialPtr_bit ++;
|
||||
if (serialPtr_bit > (sda->bufferEnd * 8))
|
||||
serialPtr_bit -= (sda->bufferEnd * 8);
|
||||
if (serialPtr_bit > (sda->m_bufferEnd * 8))
|
||||
serialPtr_bit -= (sda->m_bufferEnd * 8);
|
||||
}
|
||||
}
|
||||
|
||||
int i2cDecoder::serialDistance(isoBuffer* buffer)
|
||||
{
|
||||
int back_bit = buffer->back * 8;
|
||||
int bufferEnd_bit = buffer->bufferEnd * 8;
|
||||
int back_bit = buffer->m_back * 8;
|
||||
int bufferEnd_bit = buffer->m_bufferEnd * 8;
|
||||
if (back_bit >= serialPtr_bit)
|
||||
return back_bit - serialPtr_bit;
|
||||
else
|
||||
|
@ -66,8 +66,8 @@ void i2cDecoder::updateBitValues(){
|
|||
|
||||
int coord_byte = serialPtr_bit/8;
|
||||
int coord_bit = serialPtr_bit - (8*coord_byte);
|
||||
unsigned char dataByteSda = sda->buffer[coord_byte];
|
||||
unsigned char dataByteScl = scl->buffer[coord_byte];
|
||||
unsigned char dataByteSda = sda->m_buffer[coord_byte];
|
||||
unsigned char dataByteScl = scl->m_buffer[coord_byte];
|
||||
unsigned char mask = (0x01 << coord_bit);
|
||||
currentSdaValue = dataByteSda & mask;
|
||||
currentSclValue = dataByteScl & mask;
|
||||
|
@ -91,7 +91,7 @@ void i2cDecoder::runStateMachine()
|
|||
state = transmissionState::unknown;
|
||||
qDebug() << "Dumping I2C state and aborting...";
|
||||
for (int i=31; i>=0; i--)
|
||||
qDebug("%02x\t%02x", sda->buffer[serialPtr_bit/8 - i] & 0xFF, scl->buffer[serialPtr_bit/8 - i] & 0xFF);
|
||||
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;
|
||||
}
|
||||
|
@ -217,7 +217,7 @@ void i2cDecoder::updateConsole(){
|
|||
return;
|
||||
|
||||
console->setPlainText(QString::fromLocal8Bit(serialBuffer->begin(), serialBuffer->size()));
|
||||
if(sda->serialAutoScroll){
|
||||
if(sda->m_serialAutoScroll){
|
||||
QTextCursor c = console->textCursor();
|
||||
c.movePosition(QTextCursor::End);
|
||||
console->setTextCursor(c);
|
||||
|
|
|
@ -2,391 +2,343 @@
|
|||
#include "isodriver.h"
|
||||
#include "uartstyledecoder.h"
|
||||
|
||||
isoBuffer::isoBuffer(QWidget *parent, int bufferLen, isoDriver *caller, unsigned char channel_value) : QWidget(parent)
|
||||
{
|
||||
buffer = (short *) calloc(bufferLen*2, sizeof(short));
|
||||
bufferEnd = bufferLen-1;
|
||||
samplesPerSecond = (double) bufferLen/(double)21;
|
||||
samplesPerSecond = samplesPerSecond/375*VALID_DATA_PER_375;
|
||||
sampleRate_bit = samplesPerSecond * 8;
|
||||
virtualParent = caller;
|
||||
channel = channel_value;
|
||||
namespace {
|
||||
static char const * fileHeaderFormat =
|
||||
"EspoTek Labrador DAQ V1.0 Output File\n"
|
||||
"Averaging = %d\n"
|
||||
"Mode = %d\n";
|
||||
|
||||
constexpr auto kSamplesSeekingCap = 20;
|
||||
|
||||
#ifdef INVERT_MM
|
||||
constexpr auto fX0Comp = std::greater<int> {};
|
||||
constexpr auto fX1X2Comp = std::less<int> {};
|
||||
#else
|
||||
constexpr auto fX0Comp = std::less<int> {};
|
||||
constexpr auto fX1X2Comp = std::greater<int> {};
|
||||
#endif
|
||||
|
||||
constexpr auto kTopMultimeter = 2048;
|
||||
}
|
||||
void isoBuffer::openFile(QString newFile)
|
||||
|
||||
isoBuffer::isoBuffer(QWidget* parent, int bufferLen, isoDriver* caller, unsigned char channel_value)
|
||||
: QWidget(parent)
|
||||
, m_buffer((short*)calloc(bufferLen*2, sizeof(short)))
|
||||
, m_bufferEnd(bufferLen-1)
|
||||
, m_samplesPerSecond(bufferLen/21.0/375*VALID_DATA_PER_375)
|
||||
, m_sampleRate_bit(bufferLen/21.0/375*VALID_DATA_PER_375*8)
|
||||
, m_virtualParent(caller)
|
||||
, m_channel(channel_value)
|
||||
{
|
||||
if (fptr != NULL){
|
||||
fclose(fptr);
|
||||
}
|
||||
if (newFile.isEmpty()){
|
||||
fptr = NULL;
|
||||
}
|
||||
else {
|
||||
QByteArray temp = newFile.toLatin1();
|
||||
char *fileName = temp.data();
|
||||
fptr = fopen(fileName, "w");
|
||||
if (fptr == NULL) qFatal("Null fptr in isoBuffer::openFile");
|
||||
qDebug() << "opening file" << fileName;
|
||||
qDebug() << "fptr = " << fptr;
|
||||
}
|
||||
}
|
||||
|
||||
void isoBuffer::insertIntoBuffer(short item)
|
||||
{
|
||||
m_buffer[m_back] = item;
|
||||
m_back++;
|
||||
m_insertedCount++;
|
||||
|
||||
if (m_insertedCount > m_bufferEnd)
|
||||
{
|
||||
m_insertedCount = m_bufferEnd+1;
|
||||
}
|
||||
|
||||
if (m_back > m_bufferEnd)
|
||||
{
|
||||
m_back = 0;
|
||||
}
|
||||
}
|
||||
|
||||
short isoBuffer::bufferAt(int idx) const
|
||||
{
|
||||
return m_buffer[m_back - idx];
|
||||
}
|
||||
|
||||
bool isoBuffer::maybeOutputSampleToFile(double convertedSample)
|
||||
{
|
||||
/*
|
||||
* This function adds a sample to an accumulator and bumps the sample count.
|
||||
* After the sample count hits some threshold, the accumulated sample is
|
||||
* outputted to a file. If this 'saturates' the file, then fileIO is disabled.
|
||||
*/
|
||||
m_average_sample_temp += convertedSample;
|
||||
m_fileIO_sampleCount++;
|
||||
|
||||
// Check to see if we can write a new sample to file
|
||||
if (m_fileIO_sampleCount == m_fileIO_maxIncrementedSampleValue)
|
||||
{
|
||||
char numStr[32];
|
||||
sprintf(numStr,"%7.5f, ", m_average_sample_temp/((double)m_fileIO_maxIncrementedSampleValue));
|
||||
m_currentFile->write(numStr);
|
||||
m_currentColumn++;
|
||||
if (m_currentColumn >= COLUMN_BREAK)
|
||||
{
|
||||
m_currentFile->write("\n");
|
||||
m_currentColumn = 0;
|
||||
}
|
||||
|
||||
// Reset the average and sample count for next data point
|
||||
m_fileIO_sampleCount = 0;
|
||||
m_average_sample_temp = 0;
|
||||
|
||||
// Check to see if we've reached the max file size.
|
||||
if (m_fileIO_max_file_size != 0) // value of 0 means "no limit"
|
||||
{
|
||||
m_fileIO_numBytesWritten += 9; // 7 chars for the number, 1 for the comma and 1 for the space = 9 bytes per sample.
|
||||
if (m_fileIO_numBytesWritten >= m_fileIO_max_file_size)
|
||||
{
|
||||
m_fileIOEnabled = false; // Just in case signalling fails.
|
||||
fileIOinternalDisable();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T, typename Function>
|
||||
void isoBuffer::writeBuffer(T* data, int len, int TOP, Function transform)
|
||||
{
|
||||
for (int i = 0; i < len; ++i)
|
||||
{
|
||||
insertIntoBuffer(transform(data[i]));
|
||||
}
|
||||
|
||||
// Output to CSV
|
||||
if (m_fileIOEnabled)
|
||||
{
|
||||
bool isUsingAC = m_channel == 1
|
||||
? m_virtualParent->AC_CH1
|
||||
: m_virtualParent->AC_CH2;
|
||||
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
double convertedSample = sampleConvert(data[i], TOP, isUsingAC);
|
||||
|
||||
bool keepOutputting = maybeOutputSampleToFile(convertedSample);
|
||||
|
||||
if (!keepOutputting) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void isoBuffer::writeBuffer_char(char* data, int len)
|
||||
{
|
||||
double convertedSample;
|
||||
for (int i=0; i<len;i++){
|
||||
//qDebug() << "i = " << i;
|
||||
buffer[back] = (short) data[i];
|
||||
if (back == bufferEnd){
|
||||
back = 0;
|
||||
firstTime = false;
|
||||
}
|
||||
else back++;
|
||||
|
||||
//Output to CSV
|
||||
if(fileIOEnabled){
|
||||
//Current sample
|
||||
convertedSample = sampleConvert(data[i], 128, channel==1 ? virtualParent->AC_CH1 : virtualParent->AC_CH2);
|
||||
|
||||
//Accumulate
|
||||
average_sample_temp += convertedSample;
|
||||
fileIO_sampleCount++;
|
||||
//Check to see if we can write a new sample to file
|
||||
if(fileIO_sampleCount == fileIO_maxIncrementedSampleValue){
|
||||
char numStr[32];
|
||||
sprintf(numStr,"%7.5f, ", average_sample_temp/((double)fileIO_maxIncrementedSampleValue));
|
||||
currentFile->write(numStr);
|
||||
currentColumn++;
|
||||
if (currentColumn >= COLUMN_BREAK){
|
||||
currentFile->write("\n");
|
||||
currentColumn = 0;
|
||||
}
|
||||
|
||||
//Reset the average and sample count for next data point
|
||||
fileIO_sampleCount = 0;
|
||||
average_sample_temp = 0;
|
||||
|
||||
//Check to see if we've reached the max file size.
|
||||
if(fileIO_max_file_size != 0){ //value of 0 means "no limit"
|
||||
fileIO_numBytesWritten += 9; //7 chars for the number, 1 for the comma and 1 for the space = 9 bytes per sample.
|
||||
if(fileIO_numBytesWritten >= fileIO_max_file_size){
|
||||
fileIOEnabled = false; //Just in case signalling fails.
|
||||
fileIOinternalDisable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
writeBuffer(data, len, 128, [](char item) -> short {return item;});
|
||||
}
|
||||
|
||||
void isoBuffer::writeBuffer_short(short* data, int len)
|
||||
{
|
||||
//for (int i=(len-1);i>-1;i--){
|
||||
for (int i=0; i<len;i++){
|
||||
//qDebug() << "i = " << i;
|
||||
buffer[back] = (short) data[i] >> 4; //Because it's a left adjust value!
|
||||
if (back == bufferEnd){
|
||||
back = 0;
|
||||
firstTime = false;
|
||||
}
|
||||
else back++;
|
||||
|
||||
|
||||
double convertedSample;
|
||||
//Output to CSV
|
||||
if(fileIOEnabled){
|
||||
//Current sample
|
||||
convertedSample = sampleConvert((data[i] >> 4), 2048, channel==1 ? virtualParent->AC_CH1 : virtualParent->AC_CH2);
|
||||
|
||||
//Accumulate
|
||||
average_sample_temp += convertedSample;
|
||||
fileIO_sampleCount++;
|
||||
//Check to see if we can write a new sample to file
|
||||
if(fileIO_sampleCount == fileIO_maxIncrementedSampleValue){
|
||||
char numStr[32];
|
||||
sprintf(numStr,"%7.5f, ", average_sample_temp/((double)fileIO_maxIncrementedSampleValue));
|
||||
currentFile->write(numStr);
|
||||
currentColumn++;
|
||||
if (currentColumn >= COLUMN_BREAK){
|
||||
currentFile->write("\n");
|
||||
currentColumn = 0;
|
||||
}
|
||||
|
||||
//Reset the average and sample count for next data point
|
||||
fileIO_sampleCount = 0;
|
||||
average_sample_temp = 0;
|
||||
|
||||
//Check to see if we've reached the max file size.
|
||||
if(fileIO_max_file_size != 0){ //value of 0 means "no limit"
|
||||
fileIO_numBytesWritten += 9; //7 chars for the number, 1 for the comma and 1 for the space = 9 bytes per sample.
|
||||
if(fileIO_numBytesWritten >= fileIO_max_file_size){
|
||||
fileIOEnabled = false; //Just in case signalling fails.
|
||||
fileIOinternalDisable();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
writeBuffer(data, len, 2048, [](short item) -> short {return item >> 4;});
|
||||
}
|
||||
|
||||
|
||||
short *isoBuffer::readBuffer(double sampleWindow, int numSamples, bool singleBit, double delayOffset)
|
||||
short* isoBuffer::readBuffer(double sampleWindow, int numSamples, bool singleBit, double delayOffset)
|
||||
{
|
||||
//ignore singleBit for now
|
||||
double timeBetweenSamples = (double) sampleWindow * (double) samplesPerSecond / (double) numSamples;
|
||||
double accumulatedDelay = 0;
|
||||
int delaySamples = (int)((double)delayOffset * (double)samplesPerSecond);
|
||||
/* Refactor Note:
|
||||
*
|
||||
* Refactoring this function took a few passes were i made some assumptions:
|
||||
* - round() should be replaced by floor() where it was used
|
||||
* - int(floor(x)) and int(x) are equivalent (since we are always positive)
|
||||
* - free(NULL) is a no-op. This is mandated by the C standard, and virtually all
|
||||
* implementations comply. A few known exceptions are:
|
||||
* - PalmOS
|
||||
* - 3BSD
|
||||
* - UNIX 7
|
||||
* I do not know of any non-compliant somewhat modern implementations.
|
||||
*
|
||||
* The expected behavior is to cycle backwards over the buffer, taking into
|
||||
* acount only the part of the buffer that has things stored, with a stride
|
||||
* of timeBetweenSamples steps, and insert the touched elements into readData.
|
||||
*
|
||||
* ~Sebastian Mestre
|
||||
*/
|
||||
const double timeBetweenSamples = sampleWindow * m_samplesPerSecond / numSamples;
|
||||
const int delaySamples = delayOffset * m_samplesPerSecond;
|
||||
|
||||
int front = back - 1 - delaySamples;
|
||||
if (front < 0) front = 0;
|
||||
int idx, subIdx;
|
||||
if(readData!=NULL) free(readData);
|
||||
readData = (short *) calloc(numSamples, sizeof(short));
|
||||
free(m_readData);
|
||||
|
||||
if(singleBit){
|
||||
for (int i=0; i<numSamples;i++){
|
||||
if (timeBetweenSamples > (double) front){
|
||||
accumulatedDelay -= (double) front;
|
||||
front = bufferEnd;
|
||||
}
|
||||
m_readData = (short*) calloc(numSamples, sizeof(short));
|
||||
|
||||
idx = (int) floor(((double) front - accumulatedDelay));
|
||||
subIdx = (int) floor(8*(((double) front - accumulatedDelay) - floor(((double) front - accumulatedDelay))));
|
||||
// TODO: replace by return nullptr and add error handling upstream
|
||||
if(delaySamples+1 > m_insertedCount)
|
||||
{
|
||||
return m_readData;
|
||||
}
|
||||
|
||||
//qDebug() << "subIdx = " << subIdx;
|
||||
double itr = delaySamples + 1;
|
||||
for (int i = 0; i < numSamples; i++)
|
||||
{
|
||||
while (itr > m_insertedCount)
|
||||
itr -= m_insertedCount;
|
||||
|
||||
if (idx < 0){
|
||||
accumulatedDelay--;
|
||||
accumulatedDelay -= (double) front;
|
||||
front = bufferEnd;
|
||||
idx = (int) round(((double) front - accumulatedDelay));
|
||||
}
|
||||
readData[i] = buffer[idx] & (1 << subIdx);
|
||||
m_readData[i] = bufferAt(int(itr));
|
||||
|
||||
accumulatedDelay += timeBetweenSamples;
|
||||
}
|
||||
}else{
|
||||
for (int i=0; i<numSamples;i++){
|
||||
if (timeBetweenSamples > (double) front){
|
||||
accumulatedDelay -= (double) front;
|
||||
front = bufferEnd;
|
||||
}
|
||||
if (singleBit)
|
||||
{
|
||||
int subIdx = 8*(-itr-floor(-itr));
|
||||
m_readData[i] &= (1 << subIdx);
|
||||
}
|
||||
|
||||
idx = (int) round(((double) front - accumulatedDelay));
|
||||
if (idx < 0){
|
||||
accumulatedDelay--;
|
||||
accumulatedDelay -= (double) front;
|
||||
front = bufferEnd;
|
||||
idx = (int) round(((double) front - accumulatedDelay));
|
||||
}
|
||||
readData[i] = buffer[idx];
|
||||
itr += timeBetweenSamples;
|
||||
}
|
||||
|
||||
accumulatedDelay += timeBetweenSamples;
|
||||
}
|
||||
}
|
||||
|
||||
return readData;
|
||||
return m_readData;
|
||||
}
|
||||
|
||||
void isoBuffer::clearBuffer()
|
||||
{
|
||||
for (int i=0; i<bufferEnd;i++){
|
||||
buffer[i] = 0;
|
||||
}
|
||||
for (int i = 0; i < m_bufferEnd; i++)
|
||||
{
|
||||
m_buffer[i] = 0;
|
||||
}
|
||||
|
||||
back = 0;
|
||||
firstTime = true;
|
||||
m_back = 0;
|
||||
}
|
||||
|
||||
void isoBuffer::gainBuffer(int gain_log)
|
||||
{
|
||||
qDebug() << "Buffer shifted by" << gain_log;
|
||||
for (int i=0; i<bufferEnd; i++){
|
||||
if (gain_log == -1) buffer[i] *= 2;
|
||||
else buffer[i] /= 2;
|
||||
}
|
||||
qDebug() << "Buffer shifted by" << gain_log;
|
||||
for (int i = 0; i < m_bufferEnd; i++)
|
||||
{
|
||||
if (gain_log < 0)
|
||||
m_buffer[i] <<= -gain_log;
|
||||
else
|
||||
m_buffer[i] >>= gain_log;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void isoBuffer::glitchInsert(short type)
|
||||
void isoBuffer::enableFileIO(QFile* file, int samplesToAverage, qulonglong max_file_size)
|
||||
{
|
||||
|
||||
// Open the file
|
||||
file->open(QIODevice::WriteOnly);
|
||||
m_currentFile = file;
|
||||
|
||||
// Add the header
|
||||
char headerLine[256];
|
||||
sprintf(headerLine, fileHeaderFormat, samplesToAverage, m_virtualParent->driver->deviceMode);
|
||||
m_currentFile->write(headerLine);
|
||||
|
||||
// Set up the isoBuffer for DAQ
|
||||
m_fileIO_maxIncrementedSampleValue = samplesToAverage;
|
||||
m_fileIO_max_file_size = max_file_size;
|
||||
m_fileIO_sampleCount = 0;
|
||||
m_fileIO_numBytesWritten = 0;
|
||||
m_average_sample_temp = 0;
|
||||
|
||||
// Enable DAQ
|
||||
m_fileIOEnabled = true;
|
||||
|
||||
qDebug("File IO enabled, averaging %d samples, max file size %lluMB", samplesToAverage, max_file_size/1000000);
|
||||
qDebug() << max_file_size;
|
||||
return;
|
||||
}
|
||||
|
||||
void isoBuffer::enableFileIO(QFile *file, int samplesToAverage, qulonglong max_file_size){
|
||||
|
||||
//Open the file
|
||||
file->open(QIODevice::WriteOnly);
|
||||
currentFile = file;
|
||||
|
||||
//Add the header
|
||||
char headerLine[256];
|
||||
sprintf(headerLine, "EspoTek Labrador DAQ V1.0 Output File\nAveraging = %d\nMode = %d\n", samplesToAverage, virtualParent->driver->deviceMode);
|
||||
currentFile->write(headerLine);
|
||||
|
||||
//Set up the isoBuffer for DAQ
|
||||
fileIO_maxIncrementedSampleValue = samplesToAverage;
|
||||
fileIO_max_file_size = max_file_size;
|
||||
fileIO_sampleCount = 0;
|
||||
fileIO_numBytesWritten = 0;
|
||||
average_sample_temp = 0;
|
||||
|
||||
//Enable DAQ
|
||||
fileIOEnabled = true;
|
||||
|
||||
qDebug("File IO enabled, averaging %d samples, max file size %uMB", samplesToAverage, max_file_size/1000000);
|
||||
qDebug() << max_file_size;
|
||||
return;
|
||||
void isoBuffer::disableFileIO()
|
||||
{
|
||||
m_fileIOEnabled = false;
|
||||
m_currentColumn = 0;
|
||||
m_currentFile->close();
|
||||
return;
|
||||
}
|
||||
|
||||
void isoBuffer::disableFileIO(){
|
||||
fileIOEnabled = false;
|
||||
currentColumn = 0;
|
||||
currentFile->close();
|
||||
return;
|
||||
}
|
||||
double isoBuffer::sampleConvert(short sample, int TOP, bool AC) const
|
||||
{
|
||||
double scope_gain = (double)(m_virtualParent->driver->scopeGain);
|
||||
|
||||
double isoBuffer::sampleConvert(short sample, int TOP, bool AC){
|
||||
|
||||
double scope_gain = (double)(virtualParent->driver->scopeGain);
|
||||
double voltageLevel;
|
||||
|
||||
voltageLevel = (sample * (vcc/2)) / (frontendGain*scope_gain*TOP);
|
||||
if (virtualParent->driver->deviceMode != 7) voltageLevel += voltage_ref;
|
||||
#ifdef INVERT_MM
|
||||
if(virtualParent->driver->deviceMode == 7) voltageLevel *= -1;
|
||||
#endif
|
||||
|
||||
if(AC){
|
||||
voltageLevel -= virtualParent->currentVmean; //This is old (1 frame in past) value and might not be good for signals with large variations in DC level (although the cap should filter that anyway)??
|
||||
}
|
||||
return voltageLevel;
|
||||
}
|
||||
|
||||
|
||||
|
||||
short isoBuffer::inverseSampleConvert(double voltageLevel, int TOP, bool AC){
|
||||
|
||||
double scope_gain = (double)(virtualParent->driver->scopeGain);
|
||||
short sample;
|
||||
|
||||
if(AC){
|
||||
voltageLevel += virtualParent->currentVmean; //This is old (1 frame in past) value and might not be good for signals with large variations in DC level (although the cap should filter that anyway)??
|
||||
}
|
||||
double voltageLevel = (sample * (vcc/2)) / (m_frontendGain*scope_gain*TOP);
|
||||
if (m_virtualParent->driver->deviceMode != 7) voltageLevel += m_voltage_ref;
|
||||
#ifdef INVERT_MM
|
||||
if(virtualParent->driver->deviceMode == 7) voltageLevel *= -1;
|
||||
#endif
|
||||
if (virtualParent->driver->deviceMode != 7) voltageLevel -= voltage_ref;
|
||||
|
||||
//voltageLevel = (sample * (vcc/2)) / (frontendGain*scope_gain*TOP);
|
||||
sample = (voltageLevel * (frontendGain*scope_gain*TOP))/(vcc/2);
|
||||
return sample;
|
||||
}
|
||||
|
||||
#define NUM_SAMPLES_SEEKING_CAP (20)
|
||||
|
||||
#ifdef INVERT_MM
|
||||
#define X0_COMPARISON_CAP >
|
||||
#define X1_X2_COMPARISON_CAP <
|
||||
#else
|
||||
#define X0_COMPARISON_CAP <
|
||||
#define X1_X2_COMPARISON_CAP >
|
||||
if (m_virtualParent->driver->deviceMode == 7) voltageLevel *= -1;
|
||||
#endif
|
||||
|
||||
//For capacitance measurement. x0, x1 and x2 are all various time points used to find the RC coefficient.
|
||||
int isoBuffer::cap_x0fromLast(double seconds, double vbot){
|
||||
int samplesInPast = seconds * samplesPerSecond;
|
||||
if(back < samplesInPast){
|
||||
return -1; //too hard, not really important
|
||||
}
|
||||
short vbot_s = inverseSampleConvert(vbot, 2048, 0);
|
||||
qDebug() << "vbot_s (x0) = " << vbot_s;
|
||||
|
||||
int num_found = 0;
|
||||
for(int i=samplesInPast; i; i--){
|
||||
short currentSample = buffer[back - i];
|
||||
if(currentSample X0_COMPARISON_CAP vbot_s){
|
||||
num_found++;
|
||||
} else num_found--;
|
||||
if(num_found < 0){
|
||||
num_found = 0;
|
||||
}
|
||||
if (num_found > NUM_SAMPLES_SEEKING_CAP){
|
||||
return samplesInPast-i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
if (AC)
|
||||
{
|
||||
// This is old (1 frame in past) value and might not be good for signals with
|
||||
// large variations in DC level (although the cap should filter that anyway)??
|
||||
voltageLevel -= m_virtualParent->currentVmean;
|
||||
}
|
||||
return voltageLevel;
|
||||
}
|
||||
|
||||
int isoBuffer::cap_x1fromLast(double seconds, int x0, double vbot){
|
||||
int samplesInPast = seconds * samplesPerSecond;
|
||||
samplesInPast -= x0;
|
||||
if(back < samplesInPast){
|
||||
return -1; //too hard, not really important
|
||||
}
|
||||
short vbot_s = inverseSampleConvert(vbot, 2048, 0);
|
||||
qDebug() << "vbot_s (x1) = " << vbot_s;
|
||||
short isoBuffer::inverseSampleConvert(double voltageLevel, int TOP, bool AC) const
|
||||
{
|
||||
double scope_gain = m_virtualParent->driver->scopeGain;
|
||||
|
||||
int num_found = 0;
|
||||
for(int i=samplesInPast; i; i--){
|
||||
short currentSample = buffer[back - i];
|
||||
if(currentSample X1_X2_COMPARISON_CAP vbot_s){
|
||||
num_found++;
|
||||
} else num_found--;
|
||||
if(num_found < 0){
|
||||
num_found = 0;
|
||||
}
|
||||
if (num_found > NUM_SAMPLES_SEEKING_CAP){
|
||||
return samplesInPast-i + x0;
|
||||
}
|
||||
if (AC)
|
||||
{
|
||||
// This is old (1 frame in past) value and might not be good for signals with
|
||||
// large variations in DC level (although the cap should filter that anyway)??
|
||||
voltageLevel += m_virtualParent->currentVmean;
|
||||
}
|
||||
|
||||
}
|
||||
return -1;
|
||||
#ifdef INVERT_MM
|
||||
if (m_virtualParent->driver->deviceMode == 7) voltageLevel *= -1;
|
||||
#endif
|
||||
if (m_virtualParent->driver->deviceMode != 7) voltageLevel -= m_voltage_ref;
|
||||
|
||||
// voltageLevel = (sample * (vcc/2)) / (frontendGain*scope_gain*TOP);
|
||||
short sample = (voltageLevel * (m_frontendGain*scope_gain*TOP))/(vcc/2);
|
||||
return sample;
|
||||
}
|
||||
|
||||
int isoBuffer::cap_x2fromLast(double seconds, int x1, double vtop){
|
||||
int samplesInPast = seconds * samplesPerSecond;
|
||||
samplesInPast -= x1;
|
||||
if(back < samplesInPast){
|
||||
return -1; //too hard, not really important
|
||||
}
|
||||
short vtop_s = inverseSampleConvert(vtop, 2048, 0);
|
||||
qDebug() << "vtop_s (x2) = " << vtop_s;
|
||||
template<typename Function>
|
||||
int isoBuffer::capSample(int offset, int target, double seconds, double value, Function comp)
|
||||
{
|
||||
int samples = seconds * m_samplesPerSecond;
|
||||
|
||||
int num_found = 0;
|
||||
for(int i=samplesInPast; i; i--){
|
||||
short currentSample = buffer[back - i];
|
||||
if(currentSample X1_X2_COMPARISON_CAP vtop_s){
|
||||
num_found++;
|
||||
} else num_found--;
|
||||
if(num_found < 0){
|
||||
num_found = 0;
|
||||
}
|
||||
if (num_found > NUM_SAMPLES_SEEKING_CAP){
|
||||
return samplesInPast-i + x1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
if (m_back < samples + offset) return -1;
|
||||
|
||||
short sample = inverseSampleConvert(value, 2048, 0);
|
||||
|
||||
int found = 0;
|
||||
for (int i = samples + offset; i--;)
|
||||
{
|
||||
short currentSample = bufferAt(i);
|
||||
if (comp(currentSample, sample))
|
||||
found = found + 1;
|
||||
else
|
||||
found = std::max(0, found-1);
|
||||
|
||||
if (found > target)
|
||||
return samples - i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void isoBuffer::serialManage(double baudRate, int type, UartParity parity){
|
||||
//Types:
|
||||
// 0 - standard UART, no parity
|
||||
// 1 - standard UART, with parity bit
|
||||
// 100 - I2C
|
||||
if(decoder == NULL){
|
||||
decoder = new uartStyleDecoder(this);
|
||||
connect(decoder, SIGNAL(wireDisconnected(int)), virtualParent, SLOT(serialNeedsDisabling(int)));
|
||||
}
|
||||
if(stopDecoding){
|
||||
decoder->updateTimer->start(CONSOLE_UPDATE_TIMER_PERIOD);
|
||||
stopDecoding = false;
|
||||
}
|
||||
decoder->setParityMode(parity);
|
||||
decoder->serialDecode(baudRate);
|
||||
// For capacitance measurement. x0, x1 and x2 are all various time points used to find the RC coefficient.
|
||||
int isoBuffer::cap_x0fromLast(double seconds, double vbot)
|
||||
{
|
||||
return capSample(0, kSamplesSeekingCap, seconds, vbot, fX0Comp);
|
||||
}
|
||||
|
||||
int isoBuffer::cap_x1fromLast(double seconds, int x0, double vbot)
|
||||
{
|
||||
return capSample(-x0, kSamplesSeekingCap, seconds, vbot, fX1X2Comp);
|
||||
}
|
||||
|
||||
int isoBuffer::cap_x2fromLast(double seconds, int x1, double vtop)
|
||||
{
|
||||
return capSample(-x1, kSamplesSeekingCap, seconds, vtop, fX1X2Comp);
|
||||
}
|
||||
|
||||
void isoBuffer::serialManage(double baudRate, UartParity parity)
|
||||
{
|
||||
if (m_decoder == NULL)
|
||||
{
|
||||
m_decoder = new uartStyleDecoder(this);
|
||||
// TODO: Look into using the type safe version of connect.
|
||||
// NOTE: I believe Qt has a type-safe version of this, without the macros and the
|
||||
// explicit signature and stuff, i think it uses member-function pointers instead.
|
||||
connect(m_decoder, SIGNAL(wireDisconnected(int)), m_virtualParent, SLOT(serialNeedsDisabling(int)));
|
||||
}
|
||||
if (m_stopDecoding)
|
||||
{
|
||||
m_decoder->updateTimer->start(CONSOLE_UPDATE_TIMER_PERIOD);
|
||||
m_stopDecoding = false;
|
||||
}
|
||||
m_decoder->setParityMode(parity);
|
||||
m_decoder->serialDecode(baudRate);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef ISOBUFFER_H
|
||||
#define ISOBUFFER_H
|
||||
|
||||
// TODO: Make object macros constexprs or globals
|
||||
// TODO: Move headers used only in implementation to isobuffer.cpp
|
||||
#include <QWidget>
|
||||
#include <QString>
|
||||
#include <QByteArray>
|
||||
|
@ -18,62 +20,99 @@ class isoDriver;
|
|||
class uartStyleDecoder;
|
||||
enum class UartParity : uint8_t;
|
||||
|
||||
//isoBuffer is a generic class that enables O(1) read times (!!!) on all read/write operations, while maintaining a huge buffer size.
|
||||
//Imagine it as a circular buffer, but with access functions specifically designed for isochronous data from an Xmega.
|
||||
// isoBuffer is a generic class that enables O(1) read times (!!!) on all
|
||||
// read/write operations, while maintaining a huge buffer size.
|
||||
// Imagine it as a circular buffer, but with access functions specifically
|
||||
// designed for isochronous data from an Xmega.
|
||||
|
||||
#define CONSOLE_UPDATE_TIMER_PERIOD (ISO_PACKETS_PER_CTX * 4)
|
||||
constexpr auto CONSOLE_UPDATE_TIMER_PERIOD = ISO_PACKETS_PER_CTX * 4;
|
||||
|
||||
// TODO: Make private what should be private
|
||||
// TODO: Add m_ prefix to member variables
|
||||
// TODO: Change integer types to cstdint types
|
||||
class isoBuffer : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
isoBuffer(QWidget *parent = 0, int bufferLen = 0, isoDriver *caller = 0, unsigned char channel_value = 0);
|
||||
//Generic Functions
|
||||
void openFile(QString newFile);
|
||||
void writeBuffer_char(char *data, int len);
|
||||
void writeBuffer_short(short *data, int len);
|
||||
short *readBuffer(double sampleWindow, int numSamples, bool singleBit, double delayOffset);
|
||||
void clearBuffer();
|
||||
void gainBuffer(int gain_log);
|
||||
void glitchInsert(short type);
|
||||
double sampleConvert(short sample, int TOP, bool AC);
|
||||
short inverseSampleConvert(double voltageLevel, int TOP, bool AC);
|
||||
int cap_x0fromLast(double seconds, double vbot);
|
||||
int cap_x1fromLast(double seconds, int x0, double vbot);
|
||||
int cap_x2fromLast(double seconds, int x1, double vtop);
|
||||
void serialManage(double baudRate, int type, UartParity parity);
|
||||
//Generic Vars
|
||||
QPlainTextEdit *console1, *console2;
|
||||
bool serialAutoScroll = true;
|
||||
unsigned char channel = 255;
|
||||
double voltage_ref = 1.65;
|
||||
double frontendGain = (R4 / (R3 + R4));
|
||||
int samplesPerSecond;
|
||||
int sampleRate_bit;
|
||||
int bufferEnd, back = 0;
|
||||
short *buffer, *readData = NULL;
|
||||
uartStyleDecoder *decoder = NULL;
|
||||
bool stopDecoding = false;
|
||||
// TODO: Add consoles as constructor arguments
|
||||
isoBuffer(QWidget* parent = 0, int bufferLen = 0, isoDriver* caller = 0, unsigned char channel_value = 0);
|
||||
// TODO?: Add a destructor
|
||||
|
||||
// Basic buffer operations
|
||||
short bufferAt(int idx) const;
|
||||
void insertIntoBuffer(short item);
|
||||
void clearBuffer();
|
||||
void gainBuffer(int gain_log);
|
||||
|
||||
// Advanced buffer operations
|
||||
private:
|
||||
//Generic Vars
|
||||
bool firstTime = true;
|
||||
//File I/O
|
||||
bool fileIOEnabled = false;
|
||||
FILE* fptr = NULL;
|
||||
QFile *currentFile;
|
||||
int fileIO_maxIncrementedSampleValue;
|
||||
int fileIO_sampleCount;
|
||||
qulonglong fileIO_max_file_size;
|
||||
qulonglong fileIO_numBytesWritten;
|
||||
//isoDriver *parent;
|
||||
unsigned int currentColumn = 0;
|
||||
isoDriver *virtualParent;
|
||||
double average_sample_temp;
|
||||
template<typename T, typename Function>
|
||||
void writeBuffer(T* data, int len, int TOP, Function transform);
|
||||
public:
|
||||
void writeBuffer_char(char* data, int len);
|
||||
void writeBuffer_short(short* data, int len);
|
||||
|
||||
// TODO: Change return value to unique_ptr
|
||||
short* readBuffer(double sampleWindow, int numSamples, bool singleBit, double delayOffset);
|
||||
|
||||
// file I/O
|
||||
bool maybeOutputSampleToFile(double convertedSample);
|
||||
double sampleConvert(short sample, int TOP, bool AC) const;
|
||||
short inverseSampleConvert(double voltageLevel, int TOP, bool AC) const;
|
||||
|
||||
private:
|
||||
template<typename Function>
|
||||
int capSample(int offset, int target, double seconds, double value, Function comp);
|
||||
public:
|
||||
int cap_x0fromLast(double seconds, double vbot);
|
||||
int cap_x1fromLast(double seconds, int x0, double vbot);
|
||||
int cap_x2fromLast(double seconds, int x1, double vtop);
|
||||
void serialManage(double baudRate, UartParity parity);
|
||||
|
||||
// ---- MEMBER VARIABLES ----
|
||||
|
||||
// Presentantion?
|
||||
// NOTE: it seems like these are never initialized but they are used as though they were...
|
||||
QPlainTextEdit* m_console1;
|
||||
QPlainTextEdit* m_console2;
|
||||
unsigned char m_channel = 255;
|
||||
bool m_serialAutoScroll = true;
|
||||
|
||||
// Conversion And Sampling
|
||||
double m_voltage_ref = 1.65;
|
||||
double m_frontendGain = (R4 / (R3 + R4));
|
||||
int m_samplesPerSecond;
|
||||
int m_sampleRate_bit;
|
||||
|
||||
// Internal Storage
|
||||
int m_back = 0;
|
||||
int m_insertedCount = 0;
|
||||
int m_bufferEnd;
|
||||
// TODO: Change buffer to be a unique_ptr
|
||||
short* m_buffer;
|
||||
short* m_readData = NULL;
|
||||
|
||||
// UARTS decoding
|
||||
uartStyleDecoder* m_decoder = NULL;
|
||||
// TODO: change this to keepDecoding
|
||||
bool m_stopDecoding = false;
|
||||
private:
|
||||
// File I/O
|
||||
bool m_fileIOEnabled = false;
|
||||
FILE* m_fptr = NULL;
|
||||
QFile* m_currentFile;
|
||||
int m_fileIO_maxIncrementedSampleValue;
|
||||
int m_fileIO_sampleCount;
|
||||
qulonglong m_fileIO_max_file_size;
|
||||
qulonglong m_fileIO_numBytesWritten;
|
||||
unsigned int m_currentColumn = 0;
|
||||
isoDriver* m_virtualParent;
|
||||
double m_average_sample_temp;
|
||||
signals:
|
||||
void fileIOinternalDisable();
|
||||
void fileIOinternalDisable();
|
||||
public slots:
|
||||
void enableFileIO(QFile *file, int samplesToAverage, qulonglong max_file_size);
|
||||
void disableFileIO();
|
||||
void enableFileIO(QFile* file, int samplesToAverage, qulonglong max_file_size);
|
||||
void disableFileIO();
|
||||
};
|
||||
|
||||
#endif // ISOBUFFER_H
|
||||
|
|
|
@ -90,10 +90,10 @@ void isoDriver::timerTick(void){
|
|||
if (deviceMode_prev != 1)
|
||||
clearBuffers(false, true, false);
|
||||
|
||||
internalBuffer375_CH2->channel = 1;
|
||||
internalBuffer375_CH2->m_channel = 1;
|
||||
frameActionGeneric(1,2);
|
||||
if(serialDecodeEnabled_CH1 && serialType == 0){
|
||||
internalBuffer375_CH2->serialManage(baudRate_CH1, 0, parity_CH1);
|
||||
internalBuffer375_CH2->serialManage(baudRate_CH1, parity_CH1);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
|
@ -110,7 +110,7 @@ void isoDriver::timerTick(void){
|
|||
|
||||
frameActionGeneric(2,0);
|
||||
if(serialDecodeEnabled_CH1 && serialType == 0){
|
||||
internalBuffer375_CH1->serialManage(baudRate_CH1, 0, parity_CH1);
|
||||
internalBuffer375_CH1->serialManage(baudRate_CH1, parity_CH1);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
|
@ -119,13 +119,13 @@ void isoDriver::timerTick(void){
|
|||
if (deviceMode_prev != 4)
|
||||
clearBuffers(false, true, false);
|
||||
|
||||
internalBuffer375_CH2->channel = 2;
|
||||
internalBuffer375_CH2->m_channel = 2;
|
||||
frameActionGeneric(2,2);
|
||||
if(serialDecodeEnabled_CH1 && serialType == 0){
|
||||
internalBuffer375_CH1->serialManage(baudRate_CH1, 0, parity_CH1);
|
||||
internalBuffer375_CH1->serialManage(baudRate_CH1, parity_CH1);
|
||||
}
|
||||
if(serialDecodeEnabled_CH2 && serialType == 0){
|
||||
internalBuffer375_CH2->serialManage(baudRate_CH2, 0, parity_CH2);
|
||||
internalBuffer375_CH2->serialManage(baudRate_CH2, parity_CH2);
|
||||
}
|
||||
if (serialDecodeEnabled_CH1 && serialType == 1)
|
||||
{
|
||||
|
@ -1169,7 +1169,7 @@ void isoDriver::multimeterStats(){
|
|||
qDebug() << "x2 = " << cap_x2;
|
||||
qDebug() << "dt = " << cap_x2-cap_x1;
|
||||
|
||||
double dt = (double)(cap_x2-cap_x1)/internalBuffer375_CH1->samplesPerSecond;
|
||||
double dt = (double)(cap_x2-cap_x1)/internalBuffer375_CH1->m_samplesPerSecond;
|
||||
double Cm = -dt/(seriesResistance * log((vcc-cap_vtop)/(vcc-cap_vbot)));
|
||||
qDebug() << "Cm = " << Cm;
|
||||
|
||||
|
@ -1555,7 +1555,7 @@ void isoDriver::setSerialType(unsigned char type)
|
|||
{
|
||||
if (twoWire)
|
||||
delete twoWire;
|
||||
twoWire = new i2c::i2cDecoder(internalBuffer375_CH1, internalBuffer375_CH2, internalBuffer375_CH1->console1);
|
||||
twoWire = new i2c::i2cDecoder(internalBuffer375_CH1, internalBuffer375_CH2, internalBuffer375_CH1->m_console1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,11 +41,11 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
ui->voltageInfoRmsDisplay_CH1->display(6.00);
|
||||
connectDisplaySignals();
|
||||
|
||||
ui->controller_iso->internalBuffer375_CH1->console1 = ui->console1;
|
||||
ui->controller_iso->internalBuffer375_CH1->console2 = ui->console2;
|
||||
ui->controller_iso->internalBuffer375_CH1->m_console1 = ui->console1;
|
||||
ui->controller_iso->internalBuffer375_CH1->m_console2 = ui->console2;
|
||||
|
||||
ui->controller_iso->internalBuffer375_CH2->console1 = ui->console1;
|
||||
ui->controller_iso->internalBuffer375_CH2->console2 = ui->console2;
|
||||
ui->controller_iso->internalBuffer375_CH2->m_console1 = ui->console1;
|
||||
ui->controller_iso->internalBuffer375_CH2->m_console2 = ui->console2;
|
||||
initShortcuts();
|
||||
|
||||
ui->debugButton1->setVisible(0);
|
||||
|
@ -1204,12 +1204,12 @@ void MainWindow::readSettingsFile(){
|
|||
ui->controller_iso->ch2_ref = 3.3 - calibrate_vref_ch2;
|
||||
ui->controller_iso->frontendGain_CH1 = calibrate_gain_ch1;
|
||||
ui->controller_iso->frontendGain_CH2 = calibrate_gain_ch2;
|
||||
ui->controller_iso->internalBuffer375_CH1->voltage_ref = 3.3 - calibrate_vref_ch1;
|
||||
ui->controller_iso->internalBuffer750->voltage_ref = 3.3 - calibrate_vref_ch1;
|
||||
ui->controller_iso->internalBuffer375_CH2->voltage_ref = 3.3 - calibrate_vref_ch2;
|
||||
ui->controller_iso->internalBuffer375_CH1->frontendGain = calibrate_gain_ch1;
|
||||
ui->controller_iso->internalBuffer750->frontendGain = calibrate_gain_ch1;
|
||||
ui->controller_iso->internalBuffer375_CH2->frontendGain = calibrate_gain_ch2;
|
||||
ui->controller_iso->internalBuffer375_CH1->m_voltage_ref = 3.3 - calibrate_vref_ch1;
|
||||
ui->controller_iso->internalBuffer750->m_voltage_ref = 3.3 - calibrate_vref_ch1;
|
||||
ui->controller_iso->internalBuffer375_CH2->m_voltage_ref = 3.3 - calibrate_vref_ch2;
|
||||
ui->controller_iso->internalBuffer375_CH1->m_frontendGain = calibrate_gain_ch1;
|
||||
ui->controller_iso->internalBuffer750->m_frontendGain = calibrate_gain_ch1;
|
||||
ui->controller_iso->internalBuffer375_CH2->m_frontendGain = calibrate_gain_ch2;
|
||||
|
||||
if(!dt_AlreadyAskedAboutCalibration && ((calibrate_vref_ch1 == 1.65) || (calibrate_vref_ch2 == 1.65) || (calibrate_gain_ch1 == R4/(R3+R4)) || (calibrate_gain_ch2 == R4/(R3+R4)))){
|
||||
//Prompt user to calibrate if no calibration data found.
|
||||
|
@ -1698,12 +1698,12 @@ void MainWindow::on_actionCalibrate_triggered()
|
|||
ui->controller_iso->ch2_ref = 1.65;
|
||||
ui->controller_iso->frontendGain_CH1 = (R4/(R3+R4));
|
||||
ui->controller_iso->frontendGain_CH2 = (R4/(R3+R4));
|
||||
ui->controller_iso->internalBuffer375_CH1->voltage_ref = 1.65;
|
||||
ui->controller_iso->internalBuffer750->voltage_ref = 1.65;
|
||||
ui->controller_iso->internalBuffer375_CH2->voltage_ref = 1.65;
|
||||
ui->controller_iso->internalBuffer375_CH1->frontendGain = R4/(R3+R4);
|
||||
ui->controller_iso->internalBuffer750->frontendGain = R4/(R3+R4);
|
||||
ui->controller_iso->internalBuffer375_CH2->frontendGain = R4/(R3+R4);
|
||||
ui->controller_iso->internalBuffer375_CH1->m_voltage_ref = 1.65;
|
||||
ui->controller_iso->internalBuffer750->m_voltage_ref = 1.65;
|
||||
ui->controller_iso->internalBuffer375_CH2->m_voltage_ref = 1.65;
|
||||
ui->controller_iso->internalBuffer375_CH1->m_frontendGain = R4/(R3+R4);
|
||||
ui->controller_iso->internalBuffer750->m_frontendGain = R4/(R3+R4);
|
||||
ui->controller_iso->internalBuffer375_CH2->m_frontendGain = R4/(R3+R4);
|
||||
|
||||
settings->setValue("CalibrateVrefCH1", 1.65);
|
||||
settings->setValue("CalibrateVrefCH2", 1.65);
|
||||
|
@ -1733,9 +1733,9 @@ void MainWindow::calibrateStage2(){
|
|||
ui->controller_iso->ch1_ref = 3.3 - vref_CH1;
|
||||
ui->controller_iso->ch2_ref = 3.3 - vref_CH2;
|
||||
|
||||
ui->controller_iso->internalBuffer375_CH1->voltage_ref = 3.3 - vref_CH1;
|
||||
ui->controller_iso->internalBuffer750->voltage_ref = 3.3 - vref_CH1;
|
||||
ui->controller_iso->internalBuffer375_CH2->voltage_ref = 3.3 - vref_CH2;
|
||||
ui->controller_iso->internalBuffer375_CH1->m_voltage_ref = 3.3 - vref_CH1;
|
||||
ui->controller_iso->internalBuffer750->m_voltage_ref = 3.3 - vref_CH1;
|
||||
ui->controller_iso->internalBuffer375_CH2->m_voltage_ref = 3.3 - vref_CH2;
|
||||
|
||||
settings->setValue("CalibrateVrefCH1", vref_CH1);
|
||||
settings->setValue("CalibrateVrefCH2", vref_CH2);
|
||||
|
@ -1769,9 +1769,9 @@ void MainWindow::calibrateStage3(){
|
|||
ui->controller_iso->frontendGain_CH2 = (vref_CH2 - vMeasured_CH2)*(ui->controller_iso->frontendGain_CH2)/vref_CH2;
|
||||
qDebug() << "New gain (CH1) = " << ui->controller_iso->frontendGain_CH1;
|
||||
|
||||
ui->controller_iso->internalBuffer375_CH1->frontendGain = (vref_CH1 - vMeasured_CH1)*(ui->controller_iso->frontendGain_CH1)/vref_CH1;
|
||||
ui->controller_iso->internalBuffer750->frontendGain = (vref_CH1 - vMeasured_CH1)*(ui->controller_iso->frontendGain_CH1)/vref_CH1;
|
||||
ui->controller_iso->internalBuffer375_CH2->frontendGain = (vref_CH2 - vMeasured_CH2)*(ui->controller_iso->frontendGain_CH2)/vref_CH2;
|
||||
ui->controller_iso->internalBuffer375_CH1->m_frontendGain = (vref_CH1 - vMeasured_CH1)*(ui->controller_iso->frontendGain_CH1)/vref_CH1;
|
||||
ui->controller_iso->internalBuffer750->m_frontendGain = (vref_CH1 - vMeasured_CH1)*(ui->controller_iso->frontendGain_CH1)/vref_CH1;
|
||||
ui->controller_iso->internalBuffer375_CH2->m_frontendGain = (vref_CH2 - vMeasured_CH2)*(ui->controller_iso->frontendGain_CH2)/vref_CH2;
|
||||
settings->setValue("CalibrateGainCH1", ui->controller_iso->frontendGain_CH1);
|
||||
settings->setValue("CalibrateGainCH2", ui->controller_iso->frontendGain_CH2);
|
||||
calibrationMessages->setText("Oscilloscope Calibration complete.");
|
||||
|
|
|
@ -7,7 +7,7 @@ uartStyleDecoder::uartStyleDecoder(QObject *parent_in) : QObject(parent_in)
|
|||
parent = (isoBuffer *) parent_in;
|
||||
|
||||
// Begin decoding SAMPLE_DELAY seconds in the past.
|
||||
serialPtr_bit = (int)(parent->back * 8 - SERIAL_DELAY * parent->sampleRate_bit + parent->bufferEnd * 8) % (parent->bufferEnd*8);
|
||||
serialPtr_bit = (int)(parent->m_back * 8 - SERIAL_DELAY * parent->m_sampleRate_bit + parent->m_bufferEnd * 8) % (parent->m_bufferEnd*8);
|
||||
|
||||
updateTimer = new QTimer();
|
||||
updateTimer->setTimerType(Qt::PreciseTimer);
|
||||
|
@ -16,8 +16,8 @@ uartStyleDecoder::uartStyleDecoder(QObject *parent_in) : QObject(parent_in)
|
|||
|
||||
serialBuffer = new isoBufferBuffer(SERIAL_BUFFER_LENGTH);
|
||||
|
||||
if(parent->channel == 1) console = parent->console1;
|
||||
else if(parent->channel == 2) console = parent->console2;
|
||||
if(parent->m_channel == 1) console = parent->m_console1;
|
||||
else if(parent->m_channel == 2) console = parent->m_console2;
|
||||
else qFatal("Nonexistant console requested in uartStyleDecoder::serialDecode");
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ void uartStyleDecoder::updateConsole(){
|
|||
//qDebug() << serialBuffer->size();
|
||||
|
||||
console->setPlainText(QString::fromLocal8Bit(serialBuffer->begin(), serialBuffer->size()));
|
||||
if(parent->serialAutoScroll){
|
||||
if(parent->m_serialAutoScroll){
|
||||
//http://stackoverflow.com/questions/21059678/how-can-i-set-auto-scroll-for-a-qtgui-qtextedit-in-pyqt4 DANKON
|
||||
QTextCursor c = console->textCursor();
|
||||
c.movePosition(QTextCursor::End);
|
||||
|
@ -50,7 +50,7 @@ void uartStyleDecoder::serialDecode(double baudRate)
|
|||
/*if(stopDecoding){
|
||||
return;
|
||||
}*/
|
||||
double dist_seconds = (double)serialDistance()/(parent->sampleRate_bit);
|
||||
double dist_seconds = (double)serialDistance()/(parent->m_sampleRate_bit);
|
||||
double bitPeriod_seconds = 1/baudRate;
|
||||
|
||||
// Used to check for wire disconnects. You should get at least one "1" for a stop bit.
|
||||
|
@ -76,22 +76,22 @@ void uartStyleDecoder::serialDecode(double baudRate)
|
|||
// Update the pointer, accounting for jitter
|
||||
updateSerialPtr(baudRate, uart_bit);
|
||||
// Calculate stopping condition
|
||||
dist_seconds = (double)serialDistance()/(parent->sampleRate_bit);
|
||||
dist_seconds = (double)serialDistance()/(parent->m_sampleRate_bit);
|
||||
}
|
||||
|
||||
//Not a single stop bit, or idle bit, in the whole stream. Wire must be disconnected.
|
||||
if(allZeroes){
|
||||
qDebug() << "Wire Disconnect detected!";
|
||||
wireDisconnected(parent->channel);
|
||||
parent->stopDecoding = true;
|
||||
wireDisconnected(parent->m_channel);
|
||||
parent->m_stopDecoding = true;
|
||||
updateTimer->stop();
|
||||
}
|
||||
}
|
||||
|
||||
int uartStyleDecoder::serialDistance()
|
||||
{
|
||||
int back_bit = parent->back * 8;
|
||||
int bufferEnd_bit = parent->bufferEnd * 8;
|
||||
int back_bit = parent->m_back * 8;
|
||||
int bufferEnd_bit = parent->m_bufferEnd * 8;
|
||||
if(back_bit >= serialPtr_bit){
|
||||
return back_bit - serialPtr_bit;
|
||||
}else return bufferEnd_bit - serialPtr_bit + back_bit;
|
||||
|
@ -103,20 +103,20 @@ void uartStyleDecoder::updateSerialPtr(double baudRate, unsigned char current_bi
|
|||
jitterCompensationNeeded = jitterCompensationProcedure(baudRate, current_bit);
|
||||
}
|
||||
|
||||
int distance_between_bits = (parent->sampleRate_bit)/baudRate;
|
||||
int distance_between_bits = (parent->m_sampleRate_bit)/baudRate;
|
||||
if(uartTransmitting){
|
||||
serialPtr_bit += distance_between_bits;
|
||||
} else serialPtr_bit += (distance_between_bits - 1); //Less than one baud period so that it will always see that start bit.
|
||||
|
||||
if (serialPtr_bit > (parent->bufferEnd * 8)){
|
||||
serialPtr_bit -= (parent->bufferEnd * 8);
|
||||
if (serialPtr_bit > (parent->m_bufferEnd * 8)){
|
||||
serialPtr_bit -= (parent->m_bufferEnd * 8);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char uartStyleDecoder::getNextUartBit(){
|
||||
int coord_byte = serialPtr_bit/8;
|
||||
int coord_bit = serialPtr_bit - (8*coord_byte);
|
||||
unsigned char dataByte = parent->buffer[coord_byte];
|
||||
unsigned char dataByte = parent->m_buffer[coord_byte];
|
||||
unsigned char mask = (0x01 << coord_bit);
|
||||
return ((dataByte & mask) ? 1 : 0);
|
||||
}
|
||||
|
@ -155,14 +155,14 @@ bool uartStyleDecoder::jitterCompensationProcedure(double baudRate, unsigned cha
|
|||
|
||||
//Can't be bothered dealing with the corner case where the serial pointer is at the very start of the buffer.
|
||||
//Just return and try again next time.
|
||||
int left_coord = serialPtr_bit - (parent->sampleRate_bit)/baudRate;
|
||||
int left_coord = serialPtr_bit - (parent->m_sampleRate_bit)/baudRate;
|
||||
//qDebug() << "left_coord =" << left_coord;
|
||||
if (left_coord < 0){
|
||||
return true; //Don't want to read out of bounds!!
|
||||
}
|
||||
|
||||
//The usual case, when transmitting anyway.
|
||||
unsigned char left_byte = (parent->buffer[left_coord/8] & 0xff);
|
||||
unsigned char left_byte = (parent->m_buffer[left_coord/8] & 0xff);
|
||||
//Only run when a zero is detected in the leftmost symbol.
|
||||
if(left_byte != 255){
|
||||
//Step back, one sample at a time, to the 0->1 transition point
|
||||
|
@ -172,7 +172,7 @@ bool uartStyleDecoder::jitterCompensationProcedure(double baudRate, unsigned cha
|
|||
serialPtr_bit--;
|
||||
}
|
||||
//Jump the pointer forward by half a uart bit period, and return "done!".
|
||||
serialPtr_bit += (parent->sampleRate_bit/baudRate)/2;
|
||||
serialPtr_bit += (parent->m_sampleRate_bit/baudRate)/2;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue