Frame Level Language for controlling DUALSHOCK2

Dependents:   koibumi2000

Committer:
amutake
Date:
Thu Feb 19 06:59:49 2015 +0000
Revision:
0:a436e2063a3d
fll is now a library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
amutake 0:a436e2063a3d 1 // Frame Level Language
amutake 0:a436e2063a3d 2 // implementation
amutake 0:a436e2063a3d 3
amutake 0:a436e2063a3d 4 #include "mbed.h"
amutake 0:a436e2063a3d 5 #include "rtos.h"
amutake 0:a436e2063a3d 6 #include "fll.h"
amutake 0:a436e2063a3d 7
amutake 0:a436e2063a3d 8 #include <stdint.h>
amutake 0:a436e2063a3d 9
amutake 0:a436e2063a3d 10 void invoke_sinkrun(const void *p);
amutake 0:a436e2063a3d 11
amutake 0:a436e2063a3d 12 // if you want to debug by `printf`, uncomment next line and put `pc.printf("...", ...);` into certain position.
amutake 0:a436e2063a3d 13 // Serial pc(USBTX, USBRX);
amutake 0:a436e2063a3d 14
amutake 0:a436e2063a3d 15 // ----
amutake 0:a436e2063a3d 16 // Sink
amutake 0:a436e2063a3d 17 // ----
amutake 0:a436e2063a3d 18 Sink::Sink(Producer* src, rtos::Mail<button_t, MAIL_BOX_SIZE>* box, Mutex* mut)
amutake 0:a436e2063a3d 19 {
amutake 0:a436e2063a3d 20 source = src;
amutake 0:a436e2063a3d 21 mail_box = box;
amutake 0:a436e2063a3d 22 mutex = mut;
amutake 0:a436e2063a3d 23 paused = true;
amutake 0:a436e2063a3d 24 temporary_size = 0;
amutake 0:a436e2063a3d 25
amutake 0:a436e2063a3d 26 }
amutake 0:a436e2063a3d 27
amutake 0:a436e2063a3d 28 void Sink::run()
amutake 0:a436e2063a3d 29 {
amutake 0:a436e2063a3d 30 button_t *btn;
amutake 0:a436e2063a3d 31 while(1) {
amutake 0:a436e2063a3d 32 if (paused) {
amutake 0:a436e2063a3d 33 continue;
amutake 0:a436e2063a3d 34 }
amutake 0:a436e2063a3d 35 mutex->lock();
amutake 0:a436e2063a3d 36 btn = mail_box->alloc();
amutake 0:a436e2063a3d 37 if(!btn) {
amutake 0:a436e2063a3d 38 mutex->unlock();
amutake 0:a436e2063a3d 39 continue;
amutake 0:a436e2063a3d 40 }
amutake 0:a436e2063a3d 41 *btn = source->await();
amutake 0:a436e2063a3d 42 mail_box->put(btn);
amutake 0:a436e2063a3d 43 mutex->unlock();
amutake 0:a436e2063a3d 44 }
amutake 0:a436e2063a3d 45 }
amutake 0:a436e2063a3d 46
amutake 0:a436e2063a3d 47 void Sink::resume()
amutake 0:a436e2063a3d 48 {
amutake 0:a436e2063a3d 49 if (!paused) {
amutake 0:a436e2063a3d 50 return;
amutake 0:a436e2063a3d 51 }
amutake 0:a436e2063a3d 52 button_t *btn;
amutake 0:a436e2063a3d 53 mutex->lock();
amutake 0:a436e2063a3d 54 for (int i = 0; i < temporary_size; i++) {
amutake 0:a436e2063a3d 55 btn = mail_box->alloc();
amutake 0:a436e2063a3d 56 *btn = temporary[i];
amutake 0:a436e2063a3d 57 mail_box->put(btn);
amutake 0:a436e2063a3d 58 }
amutake 0:a436e2063a3d 59 mutex->unlock();
amutake 0:a436e2063a3d 60 paused = false;
amutake 0:a436e2063a3d 61 }
amutake 0:a436e2063a3d 62
amutake 0:a436e2063a3d 63 void Sink::pause()
amutake 0:a436e2063a3d 64 {
amutake 0:a436e2063a3d 65 if (paused) {
amutake 0:a436e2063a3d 66 return;
amutake 0:a436e2063a3d 67 }
amutake 0:a436e2063a3d 68 paused = true;
amutake 0:a436e2063a3d 69 mutex->lock();
amutake 0:a436e2063a3d 70 osEvent e;
amutake 0:a436e2063a3d 71 int i = 0;
amutake 0:a436e2063a3d 72 do {
amutake 0:a436e2063a3d 73 e = mail_box->get(0);
amutake 0:a436e2063a3d 74 if(e.status == osEventMail) {
amutake 0:a436e2063a3d 75 mail_box->free((button_t*)e.value.p);
amutake 0:a436e2063a3d 76 temporary[i++] = *(button_t*)(e.value.p);
amutake 0:a436e2063a3d 77 }
amutake 0:a436e2063a3d 78 } while (e.status == osEventMail);
amutake 0:a436e2063a3d 79 temporary_size = i;
amutake 0:a436e2063a3d 80 mutex->unlock();
amutake 0:a436e2063a3d 81 }
amutake 0:a436e2063a3d 82
amutake 0:a436e2063a3d 83 void Sink::restart()
amutake 0:a436e2063a3d 84 {
amutake 0:a436e2063a3d 85 mutex->lock();
amutake 0:a436e2063a3d 86 osEvent e;
amutake 0:a436e2063a3d 87 do {
amutake 0:a436e2063a3d 88 e = mail_box->get(0);
amutake 0:a436e2063a3d 89 if(e.status == osEventMail) {
amutake 0:a436e2063a3d 90 mail_box->free((button_t*)e.value.p);
amutake 0:a436e2063a3d 91 }
amutake 0:a436e2063a3d 92 } while (e.status == osEventMail);
amutake 0:a436e2063a3d 93 // reset source
amutake 0:a436e2063a3d 94 source->reset();
amutake 0:a436e2063a3d 95 temporary_size = 0;
amutake 0:a436e2063a3d 96 mutex->unlock();
amutake 0:a436e2063a3d 97 }
amutake 0:a436e2063a3d 98
amutake 0:a436e2063a3d 99 void Sink::reset(Producer* src)
amutake 0:a436e2063a3d 100 {
amutake 0:a436e2063a3d 101 mutex->lock();
amutake 0:a436e2063a3d 102 // consume current (and actually old) buffer
amutake 0:a436e2063a3d 103 osEvent e;
amutake 0:a436e2063a3d 104 do {
amutake 0:a436e2063a3d 105 e = mail_box->get(0);
amutake 0:a436e2063a3d 106 if(e.status == osEventMail) {
amutake 0:a436e2063a3d 107 mail_box->free((button_t*)e.value.p);
amutake 0:a436e2063a3d 108 }
amutake 0:a436e2063a3d 109 } while (e.status == osEventMail);
amutake 0:a436e2063a3d 110 // update source
amutake 0:a436e2063a3d 111 source = src;
amutake 0:a436e2063a3d 112 mutex->unlock();
amutake 0:a436e2063a3d 113 }
amutake 0:a436e2063a3d 114
amutake 0:a436e2063a3d 115 // ------
amutake 0:a436e2063a3d 116 // Output
amutake 0:a436e2063a3d 117 // ------
amutake 0:a436e2063a3d 118 Output::Output(rtos::Mail<button_t, MAIL_BOX_SIZE>* box, FLL *f)
amutake 0:a436e2063a3d 119 {
amutake 0:a436e2063a3d 120 mail_box = box;
amutake 0:a436e2063a3d 121 fll = f;
amutake 0:a436e2063a3d 122 }
amutake 0:a436e2063a3d 123
amutake 0:a436e2063a3d 124 void Output::run()
amutake 0:a436e2063a3d 125 {
amutake 0:a436e2063a3d 126 osEvent e = mail_box->get(0);
amutake 0:a436e2063a3d 127 if (e.status == osEventMail) { // getting is success
amutake 0:a436e2063a3d 128 button_t b = *(button_t*)(e.value.p);
amutake 0:a436e2063a3d 129 mail_box->free((button_t*)e.value.p);
amutake 0:a436e2063a3d 130 fll->press(b);
amutake 0:a436e2063a3d 131 } else {
amutake 0:a436e2063a3d 132 fll->press(0); // if mail box is empty
amutake 0:a436e2063a3d 133 }
amutake 0:a436e2063a3d 134 }
amutake 0:a436e2063a3d 135
amutake 0:a436e2063a3d 136 FLL::FLL(Producer* p)
amutake 0:a436e2063a3d 137 {
amutake 0:a436e2063a3d 138 producer = p;
amutake 0:a436e2063a3d 139
amutake 0:a436e2063a3d 140 // button_no -> pin (R1 to L1)
amutake 0:a436e2063a3d 141 PinName ps[] = {
amutake 0:a436e2063a3d 142 p5, p6, p7, p8, p9,
amutake 0:a436e2063a3d 143 p10, p11, p12, p13, p14, p15,
amutake 0:a436e2063a3d 144 p16, p17, p18, p19,
amutake 0:a436e2063a3d 145 };
amutake 0:a436e2063a3d 146
amutake 0:a436e2063a3d 147 for(int i = 0; i < BUTTON_NUM; i++) {
amutake 0:a436e2063a3d 148 off[i] = 1;
amutake 0:a436e2063a3d 149 pin[i] = new DigitalOut(ps[i], off[i]);
amutake 0:a436e2063a3d 150 }
amutake 0:a436e2063a3d 151 }
amutake 0:a436e2063a3d 152
amutake 0:a436e2063a3d 153 FLL::~FLL()
amutake 0:a436e2063a3d 154 {
amutake 0:a436e2063a3d 155 for(int i = 0; i < BUTTON_NUM; i++) {
amutake 0:a436e2063a3d 156 delete pin[i];
amutake 0:a436e2063a3d 157 }
amutake 0:a436e2063a3d 158 }
amutake 0:a436e2063a3d 159
amutake 0:a436e2063a3d 160 void FLL::press(button_t btn)
amutake 0:a436e2063a3d 161 {
amutake 0:a436e2063a3d 162 for(int i = 0; i < BUTTON_NUM; i++) {
amutake 0:a436e2063a3d 163 if ((btn >> i) & 0x1) {
amutake 0:a436e2063a3d 164 pin[i]->write(!off[i]);
amutake 0:a436e2063a3d 165 } else {
amutake 0:a436e2063a3d 166 pin[i]->write(off[i]);
amutake 0:a436e2063a3d 167 }
amutake 0:a436e2063a3d 168 }
amutake 0:a436e2063a3d 169 }
amutake 0:a436e2063a3d 170
amutake 0:a436e2063a3d 171 void FLL::run()
amutake 0:a436e2063a3d 172 {
amutake 0:a436e2063a3d 173
amutake 0:a436e2063a3d 174 Mail<button_t, MAIL_BOX_SIZE>* mail_box = new Mail<button_t, MAIL_BOX_SIZE>();
amutake 0:a436e2063a3d 175 Mutex* mutex = new Mutex();
amutake 0:a436e2063a3d 176 Sink* sink = new Sink(producer, mail_box, mutex);
amutake 0:a436e2063a3d 177 Output* output = new Output(mail_box, this);
amutake 0:a436e2063a3d 178
amutake 0:a436e2063a3d 179 InterruptIn reset_pin(p21);
amutake 0:a436e2063a3d 180 InterruptIn resume_pin(p22);
amutake 0:a436e2063a3d 181 InterruptIn pause_pin(p23);
amutake 0:a436e2063a3d 182 reset_pin.rise(sink, &Sink::restart);
amutake 0:a436e2063a3d 183 resume_pin.rise(sink, &Sink::resume);
amutake 0:a436e2063a3d 184 pause_pin.rise(sink, &Sink::pause);
amutake 0:a436e2063a3d 185
amutake 0:a436e2063a3d 186 Thread th(invoke_sinkrun, (void *)sink);
amutake 0:a436e2063a3d 187
amutake 0:a436e2063a3d 188 Ticker ticker;
amutake 0:a436e2063a3d 189 ticker.attach(output, &Output::run, FRAME);
amutake 0:a436e2063a3d 190
amutake 0:a436e2063a3d 191 Thread::wait(osWaitForever);
amutake 0:a436e2063a3d 192 }
amutake 0:a436e2063a3d 193
amutake 0:a436e2063a3d 194 static void invoke_sinkrun(const void *p)
amutake 0:a436e2063a3d 195 {
amutake 0:a436e2063a3d 196 ((Sink*)p)->run();
amutake 0:a436e2063a3d 197 }