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/

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, &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;
+}