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.
Diff: fll.cpp
- Revision:
- 0:a436e2063a3d
diff -r 000000000000 -r a436e2063a3d fll.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/fll.cpp Thu Feb 19 06:59:49 2015 +0000
@@ -0,0 +1,197 @@
+// 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;
+ paused = true;
+ temporary_size = 0;
+
+}
+
+void Sink::run()
+{
+ button_t *btn;
+ while(1) {
+ if (paused) {
+ continue;
+ }
+ mutex->lock();
+ btn = mail_box->alloc();
+ if(!btn) {
+ mutex->unlock();
+ continue;
+ }
+ *btn = source->await();
+ mail_box->put(btn);
+ mutex->unlock();
+ }
+}
+
+void Sink::resume()
+{
+ if (!paused) {
+ return;
+ }
+ button_t *btn;
+ mutex->lock();
+ for (int i = 0; i < temporary_size; i++) {
+ btn = mail_box->alloc();
+ *btn = temporary[i];
+ mail_box->put(btn);
+ }
+ mutex->unlock();
+ paused = false;
+}
+
+void Sink::pause()
+{
+ if (paused) {
+ return;
+ }
+ paused = true;
+ mutex->lock();
+ osEvent e;
+ int i = 0;
+ do {
+ e = mail_box->get(0);
+ if(e.status == osEventMail) {
+ mail_box->free((button_t*)e.value.p);
+ temporary[i++] = *(button_t*)(e.value.p);
+ }
+ } while (e.status == osEventMail);
+ temporary_size = i;
+ mutex->unlock();
+}
+
+void Sink::restart()
+{
+ mutex->lock();
+ osEvent e;
+ do {
+ e = mail_box->get(0);
+ if(e.status == osEventMail) {
+ mail_box->free((button_t*)e.value.p);
+ }
+ } while (e.status == osEventMail);
+ // reset source
+ source->reset();
+ temporary_size = 0;
+ 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[] = {
+ p5, p6, p7, p8, p9,
+ p10, p11, p12, p13, p14, p15,
+ p16, p17, p18, p19,
+ };
+
+ for(int i = 0; i < BUTTON_NUM; i++) {
+ off[i] = 1;
+ pin[i] = new DigitalOut(ps[i], off[i]);
+ }
+}
+
+FLL::~FLL()
+{
+ for(int i = 0; i < BUTTON_NUM; i++) {
+ delete pin[i];
+ }
+}
+
+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);
+ Output* output = new Output(mail_box, this);
+
+ InterruptIn reset_pin(p21);
+ InterruptIn resume_pin(p22);
+ InterruptIn pause_pin(p23);
+ reset_pin.rise(sink, &Sink::restart);
+ resume_pin.rise(sink, &Sink::resume);
+ pause_pin.rise(sink, &Sink::pause);
+
+ Thread th(invoke_sinkrun, (void *)sink);
+
+ Ticker ticker;
+ ticker.attach(output, &Output::run, FRAME);
+
+ Thread::wait(osWaitForever);
+}
+
+static void invoke_sinkrun(const void *p)
+{
+ ((Sink*)p)->run();
+}
\ No newline at end of file
