Shohei Yasutake / Mbed 2 deprecated koibumi2000

Dependencies:   fll mbed-rtos mbed

fll.cpp

Committer:
sierra
Date:
2015-02-13
Revision:
1:1abcd83947bf
Parent:
0:c80e972b4c59
Child:
2:165723d41023

File content as of revision 1:1abcd83947bf:

// Frame Level Language
// implementation

#include "mbed.h"
#include "rtos.h"
#include <stdint.h>
#include <vector>
#include "fll.h"

Serial pc(USBTX, USBRX);

// ------
// Source
// ------
Source::Source(button *bs, int s, bool l)
{
    button_seq = bs;
    size = s;
    loop = l;
    i = 0;
}

// TODO: without loop
button Source::await()
{
    if (size == 0) {
        return 0;
    } 
    
    i = i % size;
    return button_seq[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);
}


// ----
// Sink
// ----
Sink::Sink(Source* src, rtos::Mail<button, QUEUE_SIZE>* q, Mutex* mut)
{
    source = src;
    queue = q;
    queueMutex = mut;
}

// 何ミリ秒かごとに呼ばれる
void Sink::run()
{
    for (int i = 0; i < 8; i++) { // FIXME: 8?
        queueMutex->lock();
        button* btn = queue->alloc();
        if(!btn) break;
        *btn = source->await();
        queue->put(btn);
        queueMutex->unlock();
    }
}

void Sink::reset(Source* src)
{
    queueMutex->lock();
    // queue を空にする
    osEvent e;
    do {
        e = queue->get(0);
        if(e.status == osEventMail) {
            queue->free((button*)e.value.p);
        }
    } while (e.status == osEventMail);
    // source の更新
    source = src;
    queueMutex->unlock();
}

// ------
// Output
// ------
Output::Output(rtos::Mail<button, QUEUE_SIZE>* q)
{
    queue = q;
}

void Output::run()
{
    osEvent e = queue->get(0);
    if (e.status == osEventMail) {
        button b = *(button*)(e.value.p);
        press(b);
        queue->free((button*)e.value.p);
    } 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 }
};

// 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);
        }
    }
}