Shohei Yasutake / Mbed 2 deprecated koibumi2000

Dependencies:   fll mbed-rtos mbed

Revision:
0:c80e972b4c59
Child:
1:1abcd83947bf
diff -r 000000000000 -r c80e972b4c59 fll.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fll.cpp	Fri Feb 13 13:19:29 2015 +0000
@@ -0,0 +1,217 @@
+// Frame Level Language
+// implementation
+
+#include "mbed.h"
+#include "rtos.h"
+#include <stdint.h>
+#include <vector>
+#include "fll.h"
+
+// ------
+// Source
+// ------
+Source::Source(std::vector<button>* bs, bool l)
+{
+    button_seq = bs;
+    loop = l;
+    i = 0;
+}
+
+// TODO: without loop
+button Source::await()
+{
+    int size = button_seq->size();
+    if (size == 0) {
+        return 0;
+    } else if (i >= size) {
+        i = 0;
+        return button_seq->at(0);
+    } else {
+        return button_seq->at(i++);
+    }
+}
+
+// ----
+// Flow
+// ----
+button Flow::await()
+{
+    std::vector<button> bs;
+    for (int k = 0; k < sources.size(); k++) {
+        button b = sources[k]->await();
+        bs.push_back(b);
+    }
+    return fold(bs);
+}
+
+// -----
+// Carry
+// -----
+Carry::Carry()
+{
+    btn = Carry::none;
+}
+
+bool Carry::is_empty()
+{
+    if (btn & Carry::none) { // TODO: 冗長
+        return true;
+    } else {
+        return false;
+    }
+}
+button Carry::get()
+{
+    return btn;
+}
+void Carry::set(button b)
+{
+    btn = b;
+}
+void Carry::empty()
+{
+    btn = Carry::none;
+}
+
+// ----
+// Sink
+// ----
+Sink::Sink(Source* src, rtos::Mail<button, QUEUE_SIZE>* q, Mutex* mut)
+{
+    source = src;
+    carry = new Carry();
+    queue = q;
+    queueMutex = mut;
+}
+
+// 何ミリ秒かごとに呼ばれる
+void Sink::run()
+{
+    for (int i = 0; i < 8; i++) { // FIXME: 8?
+        button* btn = queue->alloc();
+        // carry がないならストリームから Pull
+        if (carry->is_empty()) {
+            *btn = source->await();
+        } else {
+            *btn = carry->get();
+        }
+        queueMutex->lock();
+        osStatus status = queue->put(btn);
+        queueMutex->unlock();
+        if (status != osOK) {
+            carry->set(*btn);
+            break;
+        }
+    }
+}
+
+void Sink::reset(Source* src)
+{
+    queueMutex->lock();
+    // queue を空にする
+    osEvent e;
+    do {
+        e = queue->get();
+    } while (e.status == osOK);
+    // source の更新
+    source = src;
+    queueMutex->unlock();
+}
+
+// ------
+// Output
+// ------
+Output::Output(rtos::Mail<button, QUEUE_SIZE>* q)
+{
+    queue = q;
+}
+
+void Output::run()
+{
+    osEvent e = queue->get();
+    if (e.status == osEventMessage) {
+        button b = (button)e.value.v;
+        press(b);
+    } else {
+        press(0); // Mail になかった
+    }
+}
+
+// fll_keymap.cpp
+//
+// | uint16 bit | button | mbed pin | low/high |
+// +------------+--------+----------+----------+
+// |     0x0000 |        |          |          |
+// |     0x0000 |        |          |          |
+// |     0x0000 |        |          |          |
+// |     0x0000 |        |          |          |
+// |     0x0000 |        |          |          |
+// |     0x0000 |        |          |          |
+// |     0x0000 |        |          |          |
+// |     0x0000 |        |          |          |
+// |     0x0000 |        |          |          |
+// |     0x0000 |        |          |          |
+// |     0x0000 |        |          |          |
+// |     0x0000 |        |          |          |
+// |     0x0000 |        |          |          |
+// |     0x0000 |        |          |          |
+// +------------+--------+----------+----------+
+//
+// Examples:
+//   0000 0000 0000 0000 === nothing is pressed
+//   0010 0100 1000 0001 === ?, ?, ? and ? are pressed
+typedef struct _table {
+    button mask; // 0000 0000 0000 0001 ~ 0010 0000 0000 0000
+    DigitalOut *pin; // pin5~pin19
+    int on; // 1 or 0
+} table;
+
+DigitalOut pinR2(p10);
+DigitalOut pinR1(p5);
+DigitalOut pinTriangle(p6);
+DigitalOut pinCircle(p7);
+DigitalOut pinCross(p8);
+DigitalOut pinSquare(p9);
+DigitalOut pinStart(p11);
+DigitalOut pinAnalog(p12);
+DigitalOut pinSelect(p13);
+DigitalOut pinRight(p18);
+DigitalOut pinDown(p16);
+DigitalOut pinLeft(p17);
+DigitalOut pinUp(p15);
+DigitalOut pinL1(p19);
+DigitalOut pinL2(p14);
+
+table tables[] = {
+    { R1, &pinR1, 0 },
+    { B_TRIANGLE, &pinTriangle, 0 },
+    { B_CIRCLE, &pinCircle, 0 },
+    { B_CROSS, &pinCross, 0 },
+    { B_SQUARE, &pinSquare, 0 },
+    { B_R2, &pinR2, 0 },
+    { B_START, &pinStart, 0 },
+    { B_ANALOG, &pinAnalog, 0 },
+    { B_SELECT, &pinSelect, 0 },
+    { B_L2, &pinL2, 0 },
+    { B_UP, &pinUp, 0 },
+    { B_DOWN, &pinDown, 0 },
+    { B_LEFT, &pinLeft, 0 },
+    { B_RIGHT, &pinRight, 0 },
+    { B_L1, &pinL1, 0 }
+};
+
+// Serial pc(USBTX, USBRX);
+// pc.printf("0x%02x\n", btn);
+
+// 押されるボタンを押す
+void press(button btn)
+{
+    for (int i = 0; i < sizeof(tables)/sizeof(table); i++) {
+        table t = tables[i];
+        if (btn & t.mask) {
+            t.pin->write(t.on);
+        } else {
+            t.pin->write(1 - t.on);
+        }
+    }
+}