SMPTE timedode (LTC) decode library for mbed
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/
Diff: LTC_SMPTE.cpp
- Revision:
- 0:8d19e2158eb4
- Child:
- 1:63ceee4bfd05
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LTC_SMPTE.cpp Mon Nov 16 12:51:43 2015 +0000 @@ -0,0 +1,129 @@ +/** + * 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, <C_SMPTE::isr_change); + _input.rise(this, <C_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; +}