I messed up the merge, so pushing it over to another repo so I don't lose it. Will tidy up and remove later
Dependencies: BufferedSerial FatFileSystemCpp mbed
Diff: LTCDecode.cpp
- Revision:
- 9:7214e3c3e5f8
- Parent:
- 1:dd1f7e162f91
- Child:
- 10:053bac3e326b
diff -r 961bb15570a1 -r 7214e3c3e5f8 LTCDecode.cpp --- a/LTCDecode.cpp Tue Feb 16 09:53:54 2021 +0000 +++ b/LTCDecode.cpp Thu Feb 18 18:15:48 2021 +0000 @@ -1,119 +1,88 @@ #include "LTCDecode.h" -const float FrameRates[] = {0, 23.976, 24, 25, 29.97, 30, - 47.95, 48, 50, 59.94, 60, 10000000 - }; -const double FramePeriods[] = {1000000, 1000000 / 23.976, 1000000 / 24, - 1000000 / 25, 1000000 / 29.97, 1000000 / 30, - 1000000 / 47.95, 1000000 / 48, 1000000 / 50, - 1000000 / 59.94, 1000000 / 60, 10 - }; -const int numberOfRates = 11; + +const uint32_t minBitPeriodUS = + (uint32_t)((1000000.0f / 2400) / 1.1f); // allow for 10% time error +const uint32_t maxMidSymbolTimeUS = (uint32_t)( + ((1000000.0f / (1920 * 2))) * 1.1f); // allow for 10% time error LTCDecode::LTCDecode(const PinName pin) : _LTCIn(pin) { LTCsynced = false; - newBitsWrite = 0; - bitCounter = 0; - dwordCounter = 0; - newBitsRead = 0; - markCount = 0; - + inputTimer.reset(); + inputTimer.start(); + FrameCallback = NULL; } -void LTCDecode::setInputTimer(Timer *inputTimer) +void LTCDecode::enable(bool enable) { - _inputTimer = inputTimer; - _LTCIn.fall(callback(this, <CDecode::LTCOnEdge)); - _LTCIn.rise(callback(this, <CDecode::LTCOnEdge)); + LTCsynced = false; + if (enable) { + inputTimer.start(); + inputTimer.reset(); + _LTCIn.fall(callback(this, <CDecode::LTCOnEdge)); + _LTCIn.rise(callback(this, <CDecode::LTCOnEdge)); + } else { + inputTimer.stop(); + _LTCIn.fall(NULL); + _LTCIn.rise(NULL); + } } void LTCDecode::LTCOnEdge() { - uint32_t transitionTime = _inputTimer->read_us(); + uint32_t transitionTime = inputTimer.read_us(); uint32_t period = (transitionTime - lastTransition); lastTransition = transitionTime; - if (period > - maxMidSymbolTimeUS) { // time since last transition is > maximum time for + bool gotSync = false; + + if (period > maxMidSymbolTimeUS) { // time since last transition is > maximum time for // a 1, must be a zero and start of the next bit. // printf("Z"); - bitTimes[newBitsWrite] = lastBitStart; lastBitStart = transitionTime; - newBitBuffer[newBitsWrite++] = false; - if (newBitsWrite == _newBitBufferSize_) - newBitsWrite = 0; + addBitToBuffer(false); // can't be an end of frame, they must end on a 1 return; } + // if it's not a 0 it must be a 1 but are we at the end of the bit yet? if ((transitionTime - lastBitStart)> minBitPeriodUS) { // end of a bit - // printf("N"); - bitTimes[newBitsWrite] = lastBitStart; lastBitStart = transitionTime; - newBitBuffer[newBitsWrite++] = true; - if (newBitsWrite == _newBitBufferSize_) - newBitsWrite = 0; - return; + gotSync = addBitToBuffer(false); // can't be an end of frame, they must end on a 1 + if (gotSync) { + LTCsynced = true; + decodeTime(); + if (FrameCallback) + FrameCallback.call(); + } } } -bool LTCDecode::searchForSync() +// add a bit. Return true if we got the end of frame pattern +bool LTCDecode::addBitToBuffer(bool bit) { - while (!LTCsynced && (newBitsRead != newBitsWrite)) { - LTCBuffer[0] = LTCBuffer[0] << 1; - if (newBitBuffer[newBitsRead++]) - LTCBuffer[0] |= 0x01; - if (_newBitBufferSize_ == newBitsRead) - newBitsRead = 0; - if ((LTCBuffer[0] & 0x0000FFFF) == 0x3FFD) { - LTCsynced = true; - memset(LTCBuffer, 0, 3 * sizeof(uint32_t)); - } - } - return LTCsynced; + LTCBuffer[0] = LTCBuffer[0]>> 1; + if (LTCBuffer[1] &= 0x01) + LTCBuffer[0] |= 0x80000000; + + LTCBuffer[1] = LTCBuffer[1]>> 1; + if (LTCBuffer[2] &= 0x01) + LTCBuffer[1] |= 0x80000000; + + LTCBuffer[2] = LTCBuffer[2]>> 1; + if (bit) + LTCBuffer[2]|= 0x80000000; + + // frame sync patterin is 1011 1111 1111 1100 + // if it's a valid sync we will have it just received (buffer2 top bits) and the one from the last frame still in the buffer as the low 16 bits of buffer 0. + return ((((LTCBuffer[2]>>16) & 0x0000FFFF) == 0xBFFC) && ((LTCBuffer[0] & 0x0000FFFF) == 0xBFFC)); } -bool LTCDecode::readWaitingData() +void LTCDecode::decodeTime() { - while (newBitsRead != newBitsWrite) { - timeOfBit = bitTimes[newBitsRead]; - - if ((bitCounter == 0) && (dwordCounter == 0)) - frameStartTime = timeOfBit; - - if (newBitBuffer[newBitsRead++]) - LTCBuffer[dwordCounter] |= (1 << bitCounter); - - if (_newBitBufferSize_ == newBitsRead) - newBitsRead = 0; - - bitCounter++; - if (32 == bitCounter) { - dwordCounter++; - bitCounter = 0; - } - - if ((2 == dwordCounter) && (16 == bitCounter)) { - bitCounter = 0; - dwordCounter = 0; - if ((LTCBuffer[2] & 0xFFFF) != 0xBFFC) { - LTCsynced = false; - return true; - } else { - lastFrame.frame = LTCBuffer[0] & 0xf; - lastFrame.frame += ((LTCBuffer[0] >> 8) & 0x3) * 10; - lastFrame.seconds = (LTCBuffer[0] >> 16) & 0xf; - lastFrame.seconds += ((LTCBuffer[0] >> 24) & 0x7) * 10; - lastFrame.minutes = LTCBuffer[1] & 0xf; - lastFrame.minutes += ((LTCBuffer[1] >> 8) & 0x7) * 10; - lastFrame.hours = (LTCBuffer[1] >> 16) & 0xf; - lastFrame.hours += ((LTCBuffer[1] >> 24) & 0x3) * 10; - lastFrame.frameDrop = (LTCBuffer[0] & (1 << 10)) == (1 << 10); - lastFrame.frameStartTime = frameStartTime; - memset(LTCBuffer, 0, 3 * sizeof(uint32_t)); - return true; - } - } - } - return false; + _frame = LTCBuffer[0]>>16 & 0x0f + ((LTCBuffer[0] >> 24) & 0x03) * 10; + _seconds = LTCBuffer[1]>>0 & 0x0f + ((LTCBuffer[1] >> 8) & 0x07) * 10; + _minutes = LTCBuffer[1]>>16 & 0x0f + ((LTCBuffer[1] >> 24) & 0x07) * 10; + _hours = LTCBuffer[2]>>0 & 0x0f + ((LTCBuffer[2] >> 8) & 0x03) * 10; + _frameDrop = (LTCBuffer[0] & (1<<26)); }