Shohei Yasutake / Mbed 2 deprecated koibumi2000

Dependencies:   fll mbed-rtos mbed

fll.cpp

Committer:
sierra
Date:
2015-02-17
Revision:
32:fdf9f6fca8a2
Parent:
31:2dbed2eea0f2
Child:
33:cc84b10e6c67

File content as of revision 32:fdf9f6fca8a2:

// Frame Level Language
// implementation

#include "mbed.h"
#include "rtos.h"
#include "fll.h"

#include <stdint.h>

void invoke_sinkrun(const void *p);

// 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, FLL *f)
{
    mail_box = box;
    fll = f;
}

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);
        fll->press(b);
    } else {
        fll->press(0); // if mail box is empty
    }
}

FLL::FLL(Producer* p)
{
    producer = p;
    
    // button_no -> pin (R1 to L1)
    PinName ps[] = {
        p10, p5, p6, p7, p8, p9,
        p11, p12, p13, p18, p16, p17, p15,
        p19, p14,
    };
    
    for(int i = 0; i < BUTTON_NUM; i++) {
        off[i] = new int(1);
        pin[i] = new DigitalOut(ps[i], *off[i]);
    }
}

FLL::~FLL()
{
    for(int i = 0; i < BUTTON_NUM; i++) {
        delete off[i];
        delete pin[i];
    }
}

// button-pin mapping table
void FLL::press(button_t btn)
{
    for(int i = 0; i < BUTTON_NUM; i++) {
        if ((btn >> i) & 0x1) {
            pin[i]->write(!(*off[i]));
        } else {
            pin[i]->write(*off[i]);
        }
    }
}

void FLL::run()
{
    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, this);

    Thread th(invoke_sinkrun, (void *)sink);
    DigitalIn pin20(p20);
    wait(1);
    while (1) {
        if (pin20.read() == 1) {
            break;
        }
    }
    ticker.attach(output, &Output::run, FRAME);

    Thread::wait(osWaitForever);
}

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