SMPTE timedode (LTC) decode library for mbed

Dependents:   LTC_SMPTE_sample

SMPTE timedode (LTC) decode library

SMPTEタイムコードをデコード(受信)・エンコード(送信)するライブラリです。

平衡/不平衡/サウンド等によるLTC信号は、適当な回路で整形して入力してください。
出力は適当なドライバ回路を設けてください。

簡易的なプログラムのため、細かいフラグなどは無視しています。

LPC1768 専用、Timer 2 を占有します。

Sample

Import programLTC_SMPTE_sample

SMPTE timedode (LTC) decode library for mbed https://developer.mbed.org/users/okini3939/code/LTC_SMPTE/

LTC_SMPTE.cpp

Committer:
okini3939
Date:
2015-11-16
Revision:
0:8d19e2158eb4
Child:
1:63ceee4bfd05

File content as of revision 0:8d19e2158eb4:

/**
 * SMPTE timedode (LTC) decode library for mbed
 * Copyright (c) 2015 Suga
 * Released under the MIT License: http://mbed.org/license/mit
 */
/** @file
 * @brief SMPTE timedode (LTC) decode library for mbed
 */

#include "LTC_SMPTE.h"

// pulse width: 416.7us(30fps)
// 80bit x 30frame/s --> 416.7us/bit
#define ONE_TIME_MIN  100
#define ONE_TIME_MAX  250
#define ZERO_TIME_MIN 300
#define ZERO_TIME_MAX 500

LTC_SMPTE::LTC_SMPTE (PinName input) : _input(input) {

    mode = 0;
    count = 0;
    oneflg = 0;
    direction = 0;
    received = 0;

    _input.mode(PullUp);
    _input.fall(this, &LTC_SMPTE::isr_change);
    _input.rise(this, &LTC_SMPTE::isr_change);
    _timer.start();
}

void LTC_SMPTE::isr_change () {
    int b, t;

    t = _timer.read_us();
    _timer.reset();

    if (t >= ONE_TIME_MIN && t < ONE_TIME_MAX) {
        if (oneflg == 0) {
            oneflg = 1;
            return;
        } else {
            oneflg = 0;
            b = 1;
        }
    } else
    if (t >= ZERO_TIME_MIN && t < ZERO_TIME_MAX) {
        oneflg = 0;
        b = 0;
    } else {
        return;
    }

    if (mode == 0) {
        // sync word
        if (b) {
            // 1
            if (count == 12) {
                // error
                count = 0;
            } else
            if (count == 13) {
                // fwd
                direction = 1;
                count = 0;
                mode = 1;
                bit = 1;
            } else {
                count ++;
            }
        } else {
            // 0
            if (count == 12) {
                count ++;
            } else
            if (count == 13) {
                // rev
                direction = -1;
                count = 0;
                mode = 1;
                bit = 1;
            } else {
                // error
                count = 0;
            }
        }

    } else {
        // time code
        if (b) {
            code[count] |= bit; // 1
        } else {
            code[count] &= ~bit; // 0
        }
        bit <<= 1;
        if (bit >= 0x100) {
            bit = 1;
            count ++;
            if (count >= 8) {
                count = 0;
                mode = 0;
                parse_code();
            }
        }
    }
}

void LTC_SMPTE::parse_code () {
    frame = (code[1] & 0x03) * 10 + (code[0] & 0x0f);
    sec   = (code[3] & 0x07) * 10 + (code[2] & 0x0f);
    min   = (code[5] & 0x07) * 10 + (code[4] & 0x0f);
    hour  = (code[7] & 0x03) * 10 + (code[6] & 0x0f);
    drop  = code[1] & (1<<2) ? 1 : 0;
    received = 1;
}

void LTC_SMPTE::read (int *hour, int *min, int *sec, int *frame, int *dir) {
    *hour = this->hour;
    *min = this->min;
    *sec = this->sec;
    *frame = this->frame;
    if (dir) *dir = this->direction;
    received = 0;
}

int LTC_SMPTE::isReceived () {
    return received;
}