Shohei Yasutake / Mbed 2 deprecated koibumi2000

Dependencies:   fll mbed-rtos mbed

fll.cpp

Committer:
amutake
Date:
2015-02-14
Revision:
9:0d6631edfc32
Parent:
8:d16a0fcc2735
Child:
11:21b3b0494baa

File content as of revision 9:0d6631edfc32:

// Frame Level Language
// implementation

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

// if you want to debug by `printf`, uncomment next line and put `pc.printf("...", ...);` into certain position.
// Serial pc(USBTX, USBRX);

// ----
// Sink
// ----
Sink::Sink(Producer* src, rtos::Mail<button_t, MAIL_BOX_SIZE>* box, Mutex* mut)
{
    source = src;
    mail_box = box;
    mutex = mut;
}

void Sink::run()
{
    button_t *btn;
    while(1) {
        mutex->lock();
        btn = mail_box->alloc();
        if(!btn) {
            mutex->unlock();
            continue;
        }
        *btn = source->await();
        mail_box->put(btn);
        mutex->unlock();
    }
}

void Sink::reset(Producer* src)
{
    mutex->lock();
    // consume current (and actually old) buffer
    osEvent e;
    do {
        e = mail_box->get(0);
        if(e.status == osEventMail) {
            mail_box->free((button_t*)e.value.p);
        }
    } while (e.status == osEventMail);
    // update source
    source = src;
    mutex->unlock();
}

// ------
// Output
// ------
Output::Output(rtos::Mail<button_t, MAIL_BOX_SIZE>* box)
{
    mail_box = box;
}

void Output::run()
{
    osEvent e = mail_box->get(0);
    if (e.status == osEventMail) { // getting is success 
        button_t b = *(button_t*)(e.value.p);
        mail_box->free((button_t*)e.value.p);
        press(b);
    } else {
        press(0); // if mail box is empty
    }
}

// --------------------
// button_t -> mbed pin
// --------------------
typedef struct _table {
    button_t 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);

// button-pin mapping table
table tables[] = {
    { R1, &pinR1, 0 },
    { TRIANGLE, &pinTriangle, 0 },
    { CIRCLE, &pinCircle, 0 },
    { CROSS, &pinCross, 0 },
    { SQUARE, &pinSquare, 0 },
    { R2, &pinR2, 0 },
    { START, &pinStart, 0 },
    { ANALOG, &pinAnalog, 0 },
    { SELECT, &pinSelect, 0 },
    { L2, &pinL2, 0 },
    { UP, &pinUp, 0 },
    { DOWN, &pinDown, 0 },
    { LEFT, &pinLeft, 0 },
    { RIGHT, &pinRight, 0 },
    { L1, &pinL1, 0 }
};

void press(button_t btn)
{
    table t;
    for (int i = 0; i < sizeof(tables)/sizeof(table); i++) {
        t = tables[i];
        if (btn & t.mask) {
            t.pin->write(t.on);
        } else {
            t.pin->write(1 - t.on);
        }
    }
}

// ----
// main
// ----
void invoke_sinkrun(const void *p) {
    ((Sink*)p)->run();
}

void fll_run(Producer* producer) {
    Mail<button_t, MAIL_BOX_SIZE>* mail_box = new Mail<button_t, MAIL_BOX_SIZE>();
    Mutex* mutex = new Mutex();

    Sink* sink = new Sink(producer, mail_box, mutex);

    Ticker ticker;
    Output* output = new Output(mail_box);

    Thread th(invoke_sinkrun, (void *)sink);
    ticker.attach(output, &Output::run, FRAME);

    Thread::wait(osWaitForever);
}