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

LTCDecode.cpp

Committer:
AndyA
Date:
2021-02-18
Revision:
9:7214e3c3e5f8
Parent:
1:dd1f7e162f91
Child:
10:053bac3e326b

File content as of revision 9:7214e3c3e5f8:

#include "LTCDecode.h"


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;
    inputTimer.reset();
    inputTimer.start();
    FrameCallback = NULL;
}

void LTCDecode::enable(bool enable)
{
    LTCsynced = false;
    if (enable) {
        inputTimer.start();
        inputTimer.reset();
        _LTCIn.fall(callback(this, &LTCDecode::LTCOnEdge));
        _LTCIn.rise(callback(this, &LTCDecode::LTCOnEdge));
    } else {
        inputTimer.stop();
        _LTCIn.fall(NULL);
        _LTCIn.rise(NULL);
    }
}

void LTCDecode::LTCOnEdge()
{
    uint32_t transitionTime = inputTimer.read_us();
    uint32_t period = (transitionTime - lastTransition);
    lastTransition = transitionTime;
    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");
        lastBitStart = transitionTime;
        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
        lastBitStart = transitionTime;
        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();
        }
    }
}

// add a bit. Return true if we got the end of frame pattern
bool LTCDecode::addBitToBuffer(bool bit)
{
    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));
}

void LTCDecode::decodeTime()
{
    _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));
}