#include "isobuffer.h" #include "isodriver.h" isoBuffer::isoBuffer(int bufferLen, isoDriver *caller, unsigned char channel_value) { buffer = (short *) calloc(bufferLen*2, sizeof(short)); bufferEnd = bufferLen-1; samplesPerSecond = (double) bufferLen/(double)21; samplesPerSecond = samplesPerSecond/375*VALID_DATA_PER_375; parent = caller; channel = channel_value; } void isoBuffer::openFile(QString newFile) { 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::writeBuffer_char(char* data, int len) { double convertedSample; for (int i=0; iwrite(numStr); currentColumn++; if (currentColumn > COLUMN_BREAK){ currentFile->write("\n"); currentColumn = 0; } } } return; } void isoBuffer::writeBuffer_short(short* data, int len) { //for (int i=(len-1);i>-1;i--){ for (int i=0; i (bitPeriod_seconds + SERIAL_DELAY)){ tempPtr = (unsigned short *) readBuffer(0, 1, false, dist_seconds - bitPeriod_seconds); tempShort = *(tempPtr); tempShort = tempShort & 0xff; tempChar = tempShort & (1 << serialPhase) ? 0 : 1; if(serialDecodingSymbol){ //if((tempShort != 0) && (tempShort!= 255)) qDebug() << "tempShort = " << tempShort; qDebug() << numOnes(tempShort); decodeSymbol(numOnes(tempShort) > 4); } else serialDecodingSymbol = (numOnes(tempShort) < 8); marchSerialPtr(bitPeriod_seconds * samplesPerSecond); dist_seconds = (double)serialDistance()/samplesPerSecond; } } int isoBuffer::serialDistance() { if(back >= serialPtr){ return back - serialPtr; }else return bufferEnd - serialPtr + back; } void isoBuffer::serialBegin() { serialPtr = back; } void isoBuffer::decodeSymbol(unsigned char newBit) //Slow but works. { if(symbolCurrent == symbolMax){ //Last bit in symbol console -> insertPlainText(QString(QChar((char)symbol))); if(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); console->setTextCursor(c); // txtedit.ensureCursorVisible(); // you might need this also } symbolCurrent++; return; } if(symbolCurrent > symbolMax){ //Wait for stop bit. Stops over the top calculation when you get a string of zeroes... if(newBit == 1){ serialDecodingSymbol = false; symbolCurrent = 0; symbol = 0; } return; } //otherwise symbol |= newBit << symbolCurrent; symbolCurrent++; } void isoBuffer::marchSerialPtr(int bitPeriod_samples) { int halfPeriod = bitPeriod_samples * 0.6; int sampleDistance = -1; serialPtr += bitPeriod_samples; if(serialPtr >= bufferEnd){ serialPtr -= bufferEnd; } if(!serialDecodingSymbol){ return; } if((serialPtr <= halfPeriod) || (serialPtr > (bufferEnd - halfPeriod))) return; //Don't bother readjusting. Too hard. //otherwise... if(buffer[serialPtr] != buffer[serialPtr - halfPeriod]){ //use LHS to calibrate for (int i=halfPeriod;i>=0;i--){ if(buffer[serialPtr] == buffer[serialPtr-i]){ sampleDistance = i; break; } } if(sampleDistance != -1) serialPtr += (bitPeriod_samples/2) - sampleDistance; } if(sampleDistance == -1){ if(buffer[serialPtr] != buffer[serialPtr + halfPeriod]){ //same as above but with RHS for (int i=halfPeriod;i>=0;i--){ if(buffer[serialPtr] == buffer[serialPtr+i]){ sampleDistance = i; break; } } if(sampleDistance != -1) serialPtr -= (bitPeriod_samples/2) - sampleDistance; } } } unsigned char isoBuffer::numOnes(unsigned short var){ return ((var&0x01) ? 1 : 0) + ((var&0x02) ? 1 : 0) + ((var&0x04) ? 1 : 0) + ((var&0x08) ? 1 : 0) + ((var&0x10) ? 1 : 0) + ((var&0x20) ? 1 : 0) + ((var&0x40) ? 1 : 0) + ((var&0x80) ? 1 : 0); } void isoBuffer::enableFileIO(QFile *file){ file->open(QIODevice::WriteOnly); currentFile = file; fileIOEnabled = true; return; } void isoBuffer::disableFileIO(){ fileIOEnabled = false; currentColumn = 0; currentFile->close(); return; } double isoBuffer::sampleConvert(short sample, int TOP, bool AC){ double scope_gain = (double)(parent->driver->scopeGain); double voltageLevel; voltageLevel = (sample * (vcc/2)) / (R4/(R3+R4)*scope_gain*TOP); if (parent->driver->deviceMode != 7) voltageLevel += vcc*(R2/(R1+R2)); #ifdef INVERT_MM if(parent->driver->deviceMode == 7) voltageLevel *= -1; #endif if(AC){ voltageLevel -= parent->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; }