Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: fll mbed-rtos mbed
Diff: fll.cpp
- 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);
+ }
+ }
+}
