Balazs Racz / Mbed 2 deprecated LedStrip_test

Dependencies:   mbed

Committer:
bracz
Date:
Sun Sep 22 15:21:24 2013 +0000
Revision:
14:2f2f9eb5532f
Parent:
13:db79286e7ce6
Child:
15:c9b08298852f
morse works fine now.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bracz 0:109a7a5e3e6e 1 #include <queue>
juliogerchman 3:42efa00ffef4 2 #include <algorithm>
bracz 9:c3d4c7059979 3 #include <string>
bracz 0:109a7a5e3e6e 4
bracz 0:109a7a5e3e6e 5 #include "mbed.h"
bracz 0:109a7a5e3e6e 6
bracz 0:109a7a5e3e6e 7 DigitalOut myled(LED1);
bracz 4:5a2af711d510 8 DigitalOut led2(LED2);
bracz 0:109a7a5e3e6e 9
bracz 0:109a7a5e3e6e 10 Serial pc(USBTX, USBRX);
bracz 0:109a7a5e3e6e 11
bracz 0:109a7a5e3e6e 12 SPI spi(p5, p6, p20); // mosi, miso, sclk
bracz 0:109a7a5e3e6e 13 DigitalOut latch(p16);
bracz 0:109a7a5e3e6e 14 DigitalOut strobe(p17);
bracz 0:109a7a5e3e6e 15
juliogerchman 2:590e99f4a313 16 Ticker g_ticker;
juliogerchman 2:590e99f4a313 17
juliogerchman 2:590e99f4a313 18
bracz 1:1a0d5a780e57 19 #define LENGTH 160
bracz 1:1a0d5a780e57 20
bracz 0:109a7a5e3e6e 21 uint8_t strip[160];
bracz 0:109a7a5e3e6e 22
bracz 0:109a7a5e3e6e 23 #define BLACK 0x80
bracz 0:109a7a5e3e6e 24 #define BLUE (BLACK | 0x10)
bracz 0:109a7a5e3e6e 25 #define RED (BLACK | 0x04)
bracz 0:109a7a5e3e6e 26 #define GREEN (BLACK | 0x01)
bracz 0:109a7a5e3e6e 27 #define YELLOW (RED | GREEN)
bracz 0:109a7a5e3e6e 28 #define CYAN (GREEN | BLUE)
bracz 0:109a7a5e3e6e 29 #define MAGENTA (RED | BLUE)
bracz 0:109a7a5e3e6e 30 #define WHITE (RED | GREEN | BLUE)
bracz 0:109a7a5e3e6e 31
juliogerchman 2:590e99f4a313 32 #define FAST 0x40
juliogerchman 2:590e99f4a313 33
bracz 0:109a7a5e3e6e 34 uint8_t fade_result[] =
bracz 4:5a2af711d510 35 {0, 2, 3, 1};
bracz 4:5a2af711d510 36
bracz 0:109a7a5e3e6e 37
bracz 4:5a2af711d510 38 uint8_t google_colors[] = {BLUE, RED, YELLOW, BLUE, GREEN, RED};
bracz 4:5a2af711d510 39
bracz 4:5a2af711d510 40 uint8_t getbit(uint8_t from, uint8_t to)
bracz 4:5a2af711d510 41 {
bracz 0:109a7a5e3e6e 42 return fade_result[((from&1) << 1) | (to & 1)];
bracz 0:109a7a5e3e6e 43 }
bracz 0:109a7a5e3e6e 44
bracz 4:5a2af711d510 45 uint8_t getcolor(uint8_t from, uint8_t to)
bracz 4:5a2af711d510 46 {
bracz 0:109a7a5e3e6e 47 uint8_t result = 0x80;
bracz 0:109a7a5e3e6e 48 result |= getbit(from >> 0, to >> 0) << 0;
bracz 0:109a7a5e3e6e 49 result |= getbit(from >> 2, to >> 2) << 2;
bracz 0:109a7a5e3e6e 50 result |= getbit(from >> 4, to >> 4) << 4;
bracz 0:109a7a5e3e6e 51 return result;
bracz 0:109a7a5e3e6e 52 }
bracz 0:109a7a5e3e6e 53
bracz 0:109a7a5e3e6e 54
bracz 4:5a2af711d510 55 void write_strip(uint8_t* data, int len)
bracz 4:5a2af711d510 56 {
bracz 0:109a7a5e3e6e 57 latch = 0;
bracz 0:109a7a5e3e6e 58 for (int i = len - 1; i >= 0; i--) {
bracz 0:109a7a5e3e6e 59 spi.write(data[i]);
bracz 0:109a7a5e3e6e 60 }
bracz 14:2f2f9eb5532f 61 wait_us(1);
bracz 0:109a7a5e3e6e 62 latch = 1;
bracz 0:109a7a5e3e6e 63 wait_us(2);
bracz 0:109a7a5e3e6e 64 latch = 0;
bracz 0:109a7a5e3e6e 65 }
bracz 0:109a7a5e3e6e 66
bracz 4:5a2af711d510 67 class Schedulable
bracz 4:5a2af711d510 68 {
bracz 0:109a7a5e3e6e 69 public:
bracz 0:109a7a5e3e6e 70 int time_;
bracz 0:109a7a5e3e6e 71 virtual void Run() = 0;
bracz 4:5a2af711d510 72
bracz 0:109a7a5e3e6e 73 bool operator<(const Schedulable& o) const {
bracz 0:109a7a5e3e6e 74 return time_ < o.time_;
bracz 0:109a7a5e3e6e 75 }
bracz 0:109a7a5e3e6e 76 };
bracz 0:109a7a5e3e6e 77
bracz 0:109a7a5e3e6e 78
bracz 0:109a7a5e3e6e 79 struct comp {
bracz 0:109a7a5e3e6e 80 bool operator()(const Schedulable* a, const Schedulable* b) {
bracz 0:109a7a5e3e6e 81 return *b < *a;
bracz 0:109a7a5e3e6e 82 }
bracz 0:109a7a5e3e6e 83 };
bracz 0:109a7a5e3e6e 84
bracz 0:109a7a5e3e6e 85 priority_queue<Schedulable*, vector<Schedulable*>, comp> task_list;
bracz 0:109a7a5e3e6e 86
bracz 4:5a2af711d510 87 void Schedule(Schedulable* action)
bracz 4:5a2af711d510 88 {
bracz 0:109a7a5e3e6e 89 task_list.push(action);
bracz 0:109a7a5e3e6e 90 }
bracz 0:109a7a5e3e6e 91
bracz 0:109a7a5e3e6e 92 int global_tick = 0;
bracz 0:109a7a5e3e6e 93 bool strip_changed;
bracz 0:109a7a5e3e6e 94
bracz 4:5a2af711d510 95 void tick_cb()
bracz 4:5a2af711d510 96 {
bracz 0:109a7a5e3e6e 97 ++global_tick;
bracz 0:109a7a5e3e6e 98 strobe = !strobe;
bracz 0:109a7a5e3e6e 99 }
bracz 0:109a7a5e3e6e 100
bracz 4:5a2af711d510 101 class RepeatedFadeInOut : public Schedulable
bracz 4:5a2af711d510 102 {
bracz 0:109a7a5e3e6e 103 public:
bracz 0:109a7a5e3e6e 104 RepeatedFadeInOut(int start_time, int led, uint8_t a, uint8_t b, bool fast)
bracz 0:109a7a5e3e6e 105 : led_(led), a_(a), b_(b), fast_(fast) {
bracz 0:109a7a5e3e6e 106 time_ = start_time;
bracz 0:109a7a5e3e6e 107 Schedule(this);
bracz 4:5a2af711d510 108 }
bracz 0:109a7a5e3e6e 109
bracz 0:109a7a5e3e6e 110 virtual void Run() {
bracz 4:5a2af711d510 111 strip[led_] = getcolor(a_, b_);
bracz 0:109a7a5e3e6e 112 if (fast_) {
juliogerchman 2:590e99f4a313 113 strip[led_] |= FAST;
bracz 0:109a7a5e3e6e 114 time_ += 128;
bracz 0:109a7a5e3e6e 115 } else {
bracz 0:109a7a5e3e6e 116 time_ += 256;
bracz 0:109a7a5e3e6e 117 }
bracz 0:109a7a5e3e6e 118 strip_changed = true;
bracz 0:109a7a5e3e6e 119 swap(a_,b_);
bracz 0:109a7a5e3e6e 120 Schedule(this);
bracz 0:109a7a5e3e6e 121 }
bracz 4:5a2af711d510 122
bracz 0:109a7a5e3e6e 123 private:
bracz 0:109a7a5e3e6e 124 int led_;
bracz 0:109a7a5e3e6e 125 uint8_t a_,b_;
bracz 0:109a7a5e3e6e 126 bool fast_;
bracz 0:109a7a5e3e6e 127 };
bracz 0:109a7a5e3e6e 128
bracz 4:5a2af711d510 129 class WalkingFadeInOut : public Schedulable
bracz 4:5a2af711d510 130 {
bracz 1:1a0d5a780e57 131 public:
bracz 1:1a0d5a780e57 132 WalkingFadeInOut(int start_time, int led, int stride, uint8_t a, uint8_t b, bool fast)
bracz 1:1a0d5a780e57 133 : led_(led - stride), stride_(stride), a_(a), b_(b), fast_(fast), step_(true) {
bracz 1:1a0d5a780e57 134 time_ = start_time;
bracz 1:1a0d5a780e57 135 Schedule(this);
bracz 4:5a2af711d510 136 }
bracz 1:1a0d5a780e57 137
bracz 1:1a0d5a780e57 138 virtual void Run() {
bracz 1:1a0d5a780e57 139 if (step_) {
bracz 1:1a0d5a780e57 140 step_ = false;
bracz 1:1a0d5a780e57 141 if (led_ >= 0) strip[led_] = a_;
bracz 1:1a0d5a780e57 142 led_ += stride_;
bracz 1:1a0d5a780e57 143 led_ %= LENGTH;
bracz 1:1a0d5a780e57 144 } else {
bracz 1:1a0d5a780e57 145 step_ = true;
bracz 1:1a0d5a780e57 146 }
bracz 4:5a2af711d510 147 strip[led_] = getcolor(a_, b_);
bracz 1:1a0d5a780e57 148 if (fast_) {
juliogerchman 2:590e99f4a313 149 strip[led_] |= FAST;
bracz 1:1a0d5a780e57 150 time_ += 128;
bracz 1:1a0d5a780e57 151 } else {
bracz 1:1a0d5a780e57 152 time_ += 256;
bracz 1:1a0d5a780e57 153 }
bracz 1:1a0d5a780e57 154 strip_changed = true;
bracz 1:1a0d5a780e57 155 swap(a_,b_);
bracz 1:1a0d5a780e57 156 Schedule(this);
bracz 1:1a0d5a780e57 157 }
bracz 4:5a2af711d510 158
bracz 1:1a0d5a780e57 159 private:
bracz 1:1a0d5a780e57 160 int led_, stride_;
bracz 1:1a0d5a780e57 161 uint8_t a_,b_;
bracz 1:1a0d5a780e57 162 bool fast_, step_;
bracz 4:5a2af711d510 163
bracz 1:1a0d5a780e57 164 };
bracz 1:1a0d5a780e57 165
bracz 4:5a2af711d510 166 class RegionWalkingFadeInOut : public Schedulable
bracz 4:5a2af711d510 167 {
juliogerchman 2:590e99f4a313 168 public:
juliogerchman 2:590e99f4a313 169 RegionWalkingFadeInOut(int start_time, int led, int stride, int start_led, int length, uint8_t a, uint8_t b, bool fast, bool repeat, bool drop, Schedulable* next)
juliogerchman 2:590e99f4a313 170 : led_(led - stride), stride_(stride), start_led_(start_led), length_(length), a_(a), b_(b), fast_(fast), step_(true), repeat_(repeat), drop_(drop), next_(next) {
juliogerchman 2:590e99f4a313 171 time_ = start_time;
juliogerchman 2:590e99f4a313 172 Schedule(this);
bracz 4:5a2af711d510 173 }
bracz 1:1a0d5a780e57 174
juliogerchman 2:590e99f4a313 175 virtual void Run() {
juliogerchman 2:590e99f4a313 176 if (step_) {
juliogerchman 2:590e99f4a313 177 step_ = false;
juliogerchman 2:590e99f4a313 178 if (led_ >= 0) strip[led_ + start_led_] = a_;
juliogerchman 2:590e99f4a313 179 led_ += stride_;
juliogerchman 2:590e99f4a313 180 if (repeat_) {
juliogerchman 2:590e99f4a313 181 led_ %= length_;
juliogerchman 2:590e99f4a313 182 } else {
juliogerchman 3:42efa00ffef4 183 if (led_ >= length_) {
juliogerchman 3:42efa00ffef4 184 /*if (next_ && led_ == (length_ + stride_)) {
juliogerchman 2:590e99f4a313 185 next_->time_ = global_tick + 1;
juliogerchman 2:590e99f4a313 186 Schedule(next_);
juliogerchman 3:42efa00ffef4 187 }*/
juliogerchman 2:590e99f4a313 188 delete this;
juliogerchman 2:590e99f4a313 189 return;
juliogerchman 2:590e99f4a313 190 }
juliogerchman 2:590e99f4a313 191 }
juliogerchman 2:590e99f4a313 192 } else {
juliogerchman 3:42efa00ffef4 193 if (led_ == (length_ - 1) && drop_ && !repeat_) {
juliogerchman 2:590e99f4a313 194 if (next_) {
juliogerchman 3:42efa00ffef4 195 next_->time_ = global_tick + 257;
juliogerchman 2:590e99f4a313 196 Schedule(next_);
juliogerchman 2:590e99f4a313 197 }
juliogerchman 2:590e99f4a313 198 delete this;
juliogerchman 2:590e99f4a313 199 return;
juliogerchman 2:590e99f4a313 200 }
bracz 4:5a2af711d510 201 step_ = true;
juliogerchman 2:590e99f4a313 202 }
bracz 4:5a2af711d510 203 strip[led_ + start_led_] = getcolor(a_, b_);
juliogerchman 2:590e99f4a313 204 if (fast_) {
juliogerchman 2:590e99f4a313 205 strip[led_ + start_led_] |= FAST;
juliogerchman 2:590e99f4a313 206 time_ += 128;
juliogerchman 2:590e99f4a313 207 } else {
juliogerchman 2:590e99f4a313 208 time_ += 256;
juliogerchman 2:590e99f4a313 209 }
juliogerchman 2:590e99f4a313 210 strip_changed = true;
juliogerchman 2:590e99f4a313 211 swap(a_,b_);
juliogerchman 2:590e99f4a313 212 Schedule(this);
juliogerchman 2:590e99f4a313 213 }
bracz 4:5a2af711d510 214
juliogerchman 2:590e99f4a313 215 private:
juliogerchman 2:590e99f4a313 216 int led_, stride_;
juliogerchman 2:590e99f4a313 217 int start_led_, length_;
juliogerchman 2:590e99f4a313 218 uint8_t a_,b_;
juliogerchman 2:590e99f4a313 219 bool fast_, step_;
juliogerchman 2:590e99f4a313 220 bool repeat_, drop_;
juliogerchman 2:590e99f4a313 221 Schedulable* next_;
juliogerchman 2:590e99f4a313 222 };
juliogerchman 2:590e99f4a313 223
juliogerchman 8:77fd54b4864c 224 class WaitAndSetDone : public Schedulable {
juliogerchman 8:77fd54b4864c 225 public:
juliogerchman 8:77fd54b4864c 226 WaitAndSetDone(int start_time, bool* done)
juliogerchman 8:77fd54b4864c 227 : done_(done) {
juliogerchman 8:77fd54b4864c 228 time_ = start_time;
juliogerchman 8:77fd54b4864c 229 Schedule(this);
juliogerchman 8:77fd54b4864c 230 }
juliogerchman 8:77fd54b4864c 231
juliogerchman 8:77fd54b4864c 232 virtual void Run() {
juliogerchman 8:77fd54b4864c 233 strip_changed = true;
juliogerchman 8:77fd54b4864c 234 if (done_) *done_ = true;
juliogerchman 8:77fd54b4864c 235 delete this;
juliogerchman 8:77fd54b4864c 236 }
juliogerchman 8:77fd54b4864c 237
juliogerchman 8:77fd54b4864c 238 private:
juliogerchman 8:77fd54b4864c 239 bool* done_;
juliogerchman 8:77fd54b4864c 240 };
juliogerchman 8:77fd54b4864c 241
juliogerchman 7:e3b6f5741d9d 242 class FadeFillRegion : public Schedulable {
juliogerchman 7:e3b6f5741d9d 243 public:
juliogerchman 8:77fd54b4864c 244 FadeFillRegion(int start_time, int start_led, int length, uint8_t from_color, uint8_t to_color, bool fast, bool* done)
juliogerchman 8:77fd54b4864c 245 : start_led_(start_led), length_(length), from_color_(from_color), to_color_(to_color), fast_(fast), done_(done) {
juliogerchman 7:e3b6f5741d9d 246 time_ = start_time;
juliogerchman 7:e3b6f5741d9d 247 Schedule(this);
juliogerchman 7:e3b6f5741d9d 248 }
juliogerchman 7:e3b6f5741d9d 249
juliogerchman 7:e3b6f5741d9d 250 virtual void Run() {
juliogerchman 7:e3b6f5741d9d 251 for (int i = start_led_; i < start_led_ + length_; ++i) {
juliogerchman 7:e3b6f5741d9d 252 strip[i] = getcolor(from_color_, to_color_) | (fast_ ? FAST : 0);
juliogerchman 7:e3b6f5741d9d 253 }
juliogerchman 7:e3b6f5741d9d 254 strip_changed = true;
juliogerchman 8:77fd54b4864c 255 new WaitAndSetDone(global_tick + (fast_ ? 256 : 512), done_);
juliogerchman 7:e3b6f5741d9d 256 delete this;
juliogerchman 7:e3b6f5741d9d 257 }
juliogerchman 8:77fd54b4864c 258
juliogerchman 7:e3b6f5741d9d 259 private:
juliogerchman 7:e3b6f5741d9d 260 int start_led_, length_;
juliogerchman 7:e3b6f5741d9d 261 uint8_t from_color_, to_color_;
juliogerchman 7:e3b6f5741d9d 262 bool fast_;
juliogerchman 8:77fd54b4864c 263 bool* done_;
juliogerchman 7:e3b6f5741d9d 264 };
juliogerchman 7:e3b6f5741d9d 265
juliogerchman 2:590e99f4a313 266 /* Keep dropping water drops in a bucket, until it fills up. */
bracz 4:5a2af711d510 267 class DropBucketFill : public Schedulable
bracz 4:5a2af711d510 268 {
juliogerchman 2:590e99f4a313 269 public:
juliogerchman 8:77fd54b4864c 270 DropBucketFill(int start_time, int start_led, int length, int drop_size, uint8_t from_color, uint8_t to_color, int fade_out_pause, uint8_t fade_out_color, bool* done)
juliogerchman 8:77fd54b4864c 271 : start_led_(start_led), length_(length), original_length_(length), drop_size_(drop_size), from_color_(from_color), to_color_(to_color), fade_out_pause_(fade_out_pause), fade_out_color_(fade_out_color), done_(done) {
juliogerchman 2:590e99f4a313 272 time_ = start_time;
juliogerchman 2:590e99f4a313 273 Schedule(this);
juliogerchman 2:590e99f4a313 274 }
bracz 4:5a2af711d510 275
juliogerchman 2:590e99f4a313 276 virtual void Run() {
juliogerchman 2:590e99f4a313 277 // The bucket starts with a drop at its end.
juliogerchman 2:590e99f4a313 278 //strip[start_led_ + length_] = to_color_;
juliogerchman 2:590e99f4a313 279 //strip[start_led_ + length_] = RED;
juliogerchman 2:590e99f4a313 280 if (length_ > 0) {
juliogerchman 2:590e99f4a313 281 // There's still space in the bucket. Drop a new drop.
juliogerchman 3:42efa00ffef4 282 for (int i = 0; i < min(drop_size_, length_); ++i) {
juliogerchman 7:e3b6f5741d9d 283 Schedulable* next_drop = this;
juliogerchman 3:42efa00ffef4 284 new RegionWalkingFadeInOut(time_ + (256 * i / drop_size_), i, drop_size_, start_led_, length_, from_color_, to_color_, true, false, true, next_drop);
juliogerchman 2:590e99f4a313 285 }
juliogerchman 2:590e99f4a313 286 length_--;
bracz 4:5a2af711d510 287 } else if (length_ == 0) {
juliogerchman 2:590e99f4a313 288 // There's no more space in the bucket. Bail out.
juliogerchman 8:77fd54b4864c 289 new FadeFillRegion(global_tick + fade_out_pause_, start_led_, original_length_, to_color_, fade_out_color_, false, done_);
juliogerchman 2:590e99f4a313 290 delete this;
juliogerchman 2:590e99f4a313 291 return;
juliogerchman 2:590e99f4a313 292 }
juliogerchman 2:590e99f4a313 293 }
bracz 4:5a2af711d510 294
juliogerchman 2:590e99f4a313 295 private:
juliogerchman 7:e3b6f5741d9d 296 int start_led_, length_, original_length_;
juliogerchman 2:590e99f4a313 297 int drop_size_;
juliogerchman 2:590e99f4a313 298 uint8_t from_color_, to_color_;
juliogerchman 7:e3b6f5741d9d 299 int fade_out_pause_;
juliogerchman 7:e3b6f5741d9d 300 uint8_t fade_out_color_;
bracz 4:5a2af711d510 301 bool* done_;
juliogerchman 2:590e99f4a313 302 };
juliogerchman 2:590e99f4a313 303
bracz 4:5a2af711d510 304 Schedulable* g_watchdog;
bracz 4:5a2af711d510 305
bracz 4:5a2af711d510 306 class ProgramSupervisor
bracz 4:5a2af711d510 307 {
bracz 4:5a2af711d510 308 public:
juliogerchman 8:77fd54b4864c 309 ProgramSupervisor() {
juliogerchman 8:77fd54b4864c 310 next_program_ = 0;
juliogerchman 8:77fd54b4864c 311 }
bracz 4:5a2af711d510 312 // The program should be alive forever. Programs do not delete themselves upon completion. Every scheduling of a program happens with global time set to zero.
bracz 4:5a2af711d510 313 void RegisterProgram(Schedulable* program) {
bracz 4:5a2af711d510 314 programs_.push_back(program);
bracz 4:5a2af711d510 315 }
bracz 4:5a2af711d510 316
bracz 4:5a2af711d510 317 // This should be called by the program executor when it is completed.
bracz 4:5a2af711d510 318 // It is desired to leave all LEDs black after program completion.
bracz 4:5a2af711d510 319 void CurrentProgramDone() {
bracz 4:5a2af711d510 320 next_program_++;
bracz 4:5a2af711d510 321 next_program_ %= programs_.size();
bracz 4:5a2af711d510 322 ScheduleProgram();
bracz 4:5a2af711d510 323 }
bracz 4:5a2af711d510 324
bracz 4:5a2af711d510 325 void ScheduleProgram() {
bracz 4:5a2af711d510 326 global_tick = 0;
bracz 4:5a2af711d510 327 while (!task_list.empty()) task_list.pop();
bracz 4:5a2af711d510 328 Schedule(g_watchdog);
bracz 6:62c9a5483a84 329 memset(strip, 0x80, sizeof(strip));
bracz 6:62c9a5483a84 330 write_strip(strip, sizeof(strip));
bracz 4:5a2af711d510 331 if (programs_.empty()) return;
juliogerchman 8:77fd54b4864c 332 programs_[next_program_]->time_ = 0;
juliogerchman 8:77fd54b4864c 333 Schedule(programs_[next_program_]);
bracz 4:5a2af711d510 334 }
bracz 4:5a2af711d510 335
bracz 4:5a2af711d510 336
bracz 4:5a2af711d510 337 private:
bracz 4:5a2af711d510 338 vector<Schedulable*> programs_;
bracz 4:5a2af711d510 339 int next_program_; // indexes the programs_ array.
bracz 4:5a2af711d510 340 } supervisor;
bracz 4:5a2af711d510 341
bracz 4:5a2af711d510 342
bracz 4:5a2af711d510 343 class ProgramWatchdog : public Schedulable
bracz 4:5a2af711d510 344 {
bracz 4:5a2af711d510 345 public:
bracz 4:5a2af711d510 346 ProgramWatchdog() {
bracz 4:5a2af711d510 347 time_ = 5 * 60 * 1000; // 5 minutes deadline
bracz 4:5a2af711d510 348 }
bracz 4:5a2af711d510 349
bracz 4:5a2af711d510 350 virtual void Run() {
bracz 4:5a2af711d510 351 supervisor.CurrentProgramDone();
bracz 9:c3d4c7059979 352 if (this == g_watchdog) led2 = 1;
bracz 4:5a2af711d510 353 }
bracz 4:5a2af711d510 354
bracz 4:5a2af711d510 355 } g_watchdog_impl;
bracz 4:5a2af711d510 356
bracz 4:5a2af711d510 357
juliogerchman 10:01eb82c2a01b 358
juliogerchman 10:01eb82c2a01b 359 const int CycleColorsRegions[][2] = {
juliogerchman 10:01eb82c2a01b 360 {5, 10},
juliogerchman 10:01eb82c2a01b 361 {15, 10},
juliogerchman 10:01eb82c2a01b 362 {35, 5},
juliogerchman 10:01eb82c2a01b 363 {40, 50}
juliogerchman 10:01eb82c2a01b 364 };
juliogerchman 10:01eb82c2a01b 365
juliogerchman 10:01eb82c2a01b 366 class CycleColors : public Schedulable
juliogerchman 10:01eb82c2a01b 367 {
juliogerchman 10:01eb82c2a01b 368 public:
juliogerchman 10:01eb82c2a01b 369 CycleColors(bool fast, int cycle_count) : fast_(fast), cycle_count_(cycle_count), current_cycle_(0) {
juliogerchman 10:01eb82c2a01b 370 fade_out_time_ = fast_ ? 256 : 512;
juliogerchman 10:01eb82c2a01b 371 supervisor.RegisterProgram(this);
juliogerchman 10:01eb82c2a01b 372 }
juliogerchman 10:01eb82c2a01b 373
juliogerchman 10:01eb82c2a01b 374 virtual void Run() {
juliogerchman 10:01eb82c2a01b 375 strip[100] = RED;
juliogerchman 10:01eb82c2a01b 376 strip_changed = true;
juliogerchman 10:01eb82c2a01b 377
juliogerchman 10:01eb82c2a01b 378 int next_cycle_start_time = global_tick;
juliogerchman 10:01eb82c2a01b 379 for (int region = 0; region < sizeof(CycleColorsRegions) / sizeof(CycleColorsRegions[0]); ++region) {
juliogerchman 10:01eb82c2a01b 380 int region_start_led = CycleColorsRegions[region][0];
juliogerchman 10:01eb82c2a01b 381 int region_length = CycleColorsRegions[region][1];
juliogerchman 10:01eb82c2a01b 382 int region_from_color = google_colors[(current_cycle_ + region) % sizeof(google_colors)];
juliogerchman 10:01eb82c2a01b 383 int region_to_color = google_colors[(region_from_color + 1) % sizeof(google_colors)];
juliogerchman 10:01eb82c2a01b 384 new FadeFillRegion(next_cycle_start_time, region_start_led, region_length, region_from_color, region_to_color, fast_, NULL);
juliogerchman 10:01eb82c2a01b 385 }
juliogerchman 10:01eb82c2a01b 386
juliogerchman 10:01eb82c2a01b 387 ++current_cycle_;
juliogerchman 10:01eb82c2a01b 388 if (current_cycle_ < cycle_count_) {
juliogerchman 10:01eb82c2a01b 389 time_ += fade_out_time_;
juliogerchman 10:01eb82c2a01b 390 Schedule(this);
juliogerchman 10:01eb82c2a01b 391 } else {
juliogerchman 10:01eb82c2a01b 392 supervisor.CurrentProgramDone();
juliogerchman 10:01eb82c2a01b 393 }
juliogerchman 10:01eb82c2a01b 394 }
juliogerchman 10:01eb82c2a01b 395
juliogerchman 10:01eb82c2a01b 396 private:
juliogerchman 10:01eb82c2a01b 397 bool fast_;
juliogerchman 10:01eb82c2a01b 398 int fade_out_time_;
juliogerchman 10:01eb82c2a01b 399 int cycle_count_;
juliogerchman 10:01eb82c2a01b 400 int current_cycle_;
juliogerchman 10:01eb82c2a01b 401 };
juliogerchman 10:01eb82c2a01b 402
juliogerchman 10:01eb82c2a01b 403
bracz 4:5a2af711d510 404 class MultiDropBucketFillProgram : public Schedulable
bracz 4:5a2af711d510 405 {
bracz 4:5a2af711d510 406 public:
bracz 5:6f0f4e6c1e5f 407 MultiDropBucketFillProgram() {
bracz 5:6f0f4e6c1e5f 408 supervisor.RegisterProgram(this);
bracz 5:6f0f4e6c1e5f 409 }
bracz 5:6f0f4e6c1e5f 410
bracz 4:5a2af711d510 411 virtual void Run() {
bracz 4:5a2af711d510 412 int time = global_tick;
bracz 4:5a2af711d510 413 const int kLength = sizeof(google_colors);
bracz 4:5a2af711d510 414 memset(done_, 0, sizeof(done_));
bracz 4:5a2af711d510 415 for (int i = 0; i < kLength; i++) {
juliogerchman 8:77fd54b4864c 416 new DropBucketFill(time, 10 + i * 20, 20, 4, BLACK, google_colors[i], 2560, BLACK, done_ + i);
bracz 4:5a2af711d510 417 }
bracz 4:5a2af711d510 418 new EndWatcher(done_, kLength);
bracz 4:5a2af711d510 419 }
bracz 4:5a2af711d510 420
bracz 4:5a2af711d510 421 private:
bracz 4:5a2af711d510 422 class EndWatcher : public Schedulable {
bracz 4:5a2af711d510 423 public:
bracz 4:5a2af711d510 424 EndWatcher(bool* done_array, int len) : done_(done_array), len_(len) {
bracz 4:5a2af711d510 425 time_ = 0;
bracz 4:5a2af711d510 426 Schedule(this);
bracz 4:5a2af711d510 427 }
bracz 4:5a2af711d510 428
bracz 4:5a2af711d510 429 virtual void Run() {
bracz 4:5a2af711d510 430 int i;
bracz 4:5a2af711d510 431 for (i = 0; i < len_ && done_[i]; i++);
bracz 4:5a2af711d510 432 if (i < len_) {
bracz 4:5a2af711d510 433 // not done yet.
bracz 4:5a2af711d510 434 time_ = global_tick + 2;
bracz 4:5a2af711d510 435 Schedule(this);
bracz 4:5a2af711d510 436 } else {
bracz 4:5a2af711d510 437 supervisor.CurrentProgramDone();
bracz 4:5a2af711d510 438 delete this;
bracz 4:5a2af711d510 439 }
bracz 4:5a2af711d510 440 }
bracz 4:5a2af711d510 441
bracz 4:5a2af711d510 442 private:
bracz 4:5a2af711d510 443 bool* done_;
bracz 4:5a2af711d510 444 int len_;
bracz 4:5a2af711d510 445 };
bracz 4:5a2af711d510 446
bracz 4:5a2af711d510 447
bracz 4:5a2af711d510 448 bool done_[6];
bracz 4:5a2af711d510 449 };
bracz 4:5a2af711d510 450
bracz 9:c3d4c7059979 451 class WalkingFade : public Schedulable
bracz 9:c3d4c7059979 452 {
bracz 9:c3d4c7059979 453 public:
bracz 9:c3d4c7059979 454 WalkingFade(int start_time, int led, int stride, int end, uint8_t a, uint8_t b, bool fast)
bracz 9:c3d4c7059979 455 : led_(led), stride_(stride), end_(end), a_(a), b_(b), fast_(fast) {
bracz 9:c3d4c7059979 456 time_ = start_time;
bracz 9:c3d4c7059979 457 Schedule(this);
bracz 9:c3d4c7059979 458 }
bracz 9:c3d4c7059979 459
bracz 9:c3d4c7059979 460 virtual void Run() {
bracz 9:c3d4c7059979 461 if (led_ >= end_ || led_ < 0) {
bracz 9:c3d4c7059979 462 delete this;
bracz 9:c3d4c7059979 463 return;
bracz 9:c3d4c7059979 464 }
bracz 9:c3d4c7059979 465 strip[led_] = getcolor(a_, b_);
bracz 9:c3d4c7059979 466 if (fast_) {
bracz 9:c3d4c7059979 467 strip[led_] |= FAST;
bracz 9:c3d4c7059979 468 time_ += 128;
bracz 9:c3d4c7059979 469 } else {
bracz 12:cce8984e5569 470 time_ += 257;
bracz 9:c3d4c7059979 471 }
bracz 12:cce8984e5569 472 led_ += stride_;
bracz 9:c3d4c7059979 473 strip_changed = true;
bracz 9:c3d4c7059979 474 Schedule(this);
bracz 9:c3d4c7059979 475 }
bracz 9:c3d4c7059979 476
bracz 9:c3d4c7059979 477 private:
bracz 9:c3d4c7059979 478 int led_, stride_, end_;
bracz 9:c3d4c7059979 479 uint8_t a_,b_;
bracz 9:c3d4c7059979 480 bool fast_, step_;
bracz 9:c3d4c7059979 481 };
bracz 9:c3d4c7059979 482
bracz 9:c3d4c7059979 483
bracz 9:c3d4c7059979 484 class MorseGoogleProgram : public Schedulable {
bracz 9:c3d4c7059979 485 public:
bracz 12:cce8984e5569 486 MorseGoogleProgram() {
bracz 12:cce8984e5569 487 supervisor.RegisterProgram(this);
bracz 12:cce8984e5569 488 }
bracz 12:cce8984e5569 489
bracz 9:c3d4c7059979 490 virtual void Run() {
bracz 14:2f2f9eb5532f 491 const string code = "W.... .- .--. .--. -.-- / -... .. .-. - .... -.. .- -.-- --..-- / B--. R--- Y--- B--. G.-.. R. ";
bracz 14:2f2f9eb5532f 492 const int kSpaceTime = 512;
bracz 9:c3d4c7059979 493 const int kLedStart = 150;
bracz 9:c3d4c7059979 494 const int kStride = -2;
bracz 14:2f2f9eb5532f 495 const int kHalfStrideTime = 128;
bracz 14:2f2f9eb5532f 496 const int kDotSpaceTime = 256;
bracz 9:c3d4c7059979 497 int time = global_tick;
bracz 9:c3d4c7059979 498 uint8_t color = WHITE;
bracz 9:c3d4c7059979 499 for (int i = 0; i < code.size(); i++) {
bracz 9:c3d4c7059979 500 switch (code[i]) {
bracz 9:c3d4c7059979 501 case 'R': color = RED ; break;
bracz 9:c3d4c7059979 502 case 'G': color = GREEN ; break;
bracz 9:c3d4c7059979 503 case 'B': color = BLUE ; break;
bracz 9:c3d4c7059979 504 case 'Y': color = YELLOW ; break;
bracz 9:c3d4c7059979 505 case 'W': color = WHITE ; break;
bracz 9:c3d4c7059979 506 case 'C': color = CYAN ; break;
bracz 9:c3d4c7059979 507 case 'M': color = MAGENTA ; break;
bracz 9:c3d4c7059979 508 case '.': {
bracz 14:2f2f9eb5532f 509 new WalkingFade(time, kLedStart, kStride, 160, BLACK, color, false); time += kHalfStrideTime;
bracz 14:2f2f9eb5532f 510 new WalkingFade(time, kLedStart - 1, kStride, 160, BLACK, color, false); time += kHalfStrideTime;
bracz 14:2f2f9eb5532f 511 new WalkingFade(time, kLedStart, kStride / 2, 160, color, BLACK, true); time += kHalfStrideTime;
bracz 14:2f2f9eb5532f 512 //new WalkingFade(time, kLedStart - 1, kStride, 160, color, BLACK, true); time += kHalfStrideTime;
bracz 9:c3d4c7059979 513 time += kDotSpaceTime;
bracz 9:c3d4c7059979 514 break;
bracz 9:c3d4c7059979 515 }
bracz 9:c3d4c7059979 516 case '-': {
bracz 14:2f2f9eb5532f 517 new WalkingFade(time, kLedStart, kStride, 160, BLACK, color, false); time += kHalfStrideTime;
bracz 14:2f2f9eb5532f 518 new WalkingFade(time, kLedStart - 1, kStride, 160, BLACK, color, false); time += kHalfStrideTime;
bracz 9:c3d4c7059979 519 time += 3 * kHalfStrideTime; // should create three complete pixels
bracz 14:2f2f9eb5532f 520 new WalkingFade(time, kLedStart, kStride, 160, color, BLACK, false); time += kHalfStrideTime;
bracz 14:2f2f9eb5532f 521 new WalkingFade(time, kLedStart - 1, kStride, 160, color, BLACK, false); time += kHalfStrideTime;
bracz 9:c3d4c7059979 522 time += kDotSpaceTime;
bracz 9:c3d4c7059979 523 break;
bracz 9:c3d4c7059979 524 }
bracz 9:c3d4c7059979 525 case '/': // fall-through
bracz 9:c3d4c7059979 526 case ' ': time += kSpaceTime; break;
bracz 9:c3d4c7059979 527 }
bracz 9:c3d4c7059979 528 }
bracz 9:c3d4c7059979 529 finaliser_.time_ = time + kLedStart * kHalfStrideTime + 2000;
bracz 9:c3d4c7059979 530 Schedule(&finaliser_);
bracz 9:c3d4c7059979 531 }
bracz 9:c3d4c7059979 532
bracz 9:c3d4c7059979 533 private:
bracz 9:c3d4c7059979 534 ProgramWatchdog finaliser_;
bracz 9:c3d4c7059979 535 };
bracz 9:c3d4c7059979 536
bracz 12:cce8984e5569 537 class PrintFProgram : public Schedulable {
bracz 12:cce8984e5569 538 public:
bracz 12:cce8984e5569 539 PrintFProgram() {
bracz 12:cce8984e5569 540 supervisor.RegisterProgram(this);
bracz 12:cce8984e5569 541 }
bracz 12:cce8984e5569 542
bracz 12:cce8984e5569 543 virtual void Run() {
bracz 12:cce8984e5569 544 strip[20] = strip[50] = strip[100] = RED;
bracz 12:cce8984e5569 545 strip_changed = true;
bracz 12:cce8984e5569 546 new WalkingFade(global_tick, 155, -2, 160, BLACK, GREEN, true);
bracz 12:cce8984e5569 547 new WalkingFade(global_tick+64, 154, -2, 160, BLACK, GREEN, true);
bracz 12:cce8984e5569 548 }
bracz 12:cce8984e5569 549 };
bracz 4:5a2af711d510 550
bracz 4:5a2af711d510 551 void init_board()
bracz 4:5a2af711d510 552 {
bracz 0:109a7a5e3e6e 553 pc.baud(115200);
bracz 0:109a7a5e3e6e 554
bracz 0:109a7a5e3e6e 555 myled = 0;
bracz 0:109a7a5e3e6e 556 latch = 0;
bracz 4:5a2af711d510 557
bracz 0:109a7a5e3e6e 558 spi.format(8, 0);
bracz 0:109a7a5e3e6e 559 spi.frequency(300000);
bracz 0:109a7a5e3e6e 560 wait_ms(500);
bracz 0:109a7a5e3e6e 561 myled = 1;
juliogerchman 2:590e99f4a313 562 memset(strip, BLACK, sizeof(strip));
bracz 0:109a7a5e3e6e 563 write_strip(strip, sizeof(strip));
juliogerchman 2:590e99f4a313 564 g_ticker.attach(&tick_cb, 1.0/1000);
bracz 4:5a2af711d510 565
bracz 0:109a7a5e3e6e 566 memset(strip, 0x0, sizeof(strip));
juliogerchman 2:590e99f4a313 567 }
juliogerchman 2:590e99f4a313 568
bracz 4:5a2af711d510 569 void run_loop()
bracz 4:5a2af711d510 570 {
bracz 0:109a7a5e3e6e 571 while(1) {
bracz 0:109a7a5e3e6e 572 while (task_list.empty() || global_tick < task_list.top()->time_) {
bracz 0:109a7a5e3e6e 573 if (strip_changed) {
bracz 0:109a7a5e3e6e 574 write_strip(strip, sizeof(strip));
bracz 0:109a7a5e3e6e 575 strip_changed = false;
bracz 0:109a7a5e3e6e 576 memset(strip, 0x0, sizeof(strip));
bracz 0:109a7a5e3e6e 577 }
bracz 0:109a7a5e3e6e 578 }
bracz 0:109a7a5e3e6e 579 Schedulable* action = task_list.top();
bracz 0:109a7a5e3e6e 580 task_list.pop();
bracz 0:109a7a5e3e6e 581 action->Run();
bracz 0:109a7a5e3e6e 582 }
juliogerchman 2:590e99f4a313 583 }
bracz 0:109a7a5e3e6e 584
bracz 4:5a2af711d510 585 int main()
bracz 4:5a2af711d510 586 {
juliogerchman 2:590e99f4a313 587 init_board();
bracz 4:5a2af711d510 588 g_watchdog = &g_watchdog_impl;
bracz 5:6f0f4e6c1e5f 589
juliogerchman 10:01eb82c2a01b 590 // MultiDropBucketFillProgram multi_drop;
bracz 11:b12ce020d1ba 591 //CycleColors cycle_colors(false, 5);
bracz 9:c3d4c7059979 592 MorseGoogleProgram morse;
bracz 12:cce8984e5569 593 //PrintFProgram pr;
bracz 5:6f0f4e6c1e5f 594
bracz 4:5a2af711d510 595 supervisor.ScheduleProgram();
juliogerchman 3:42efa00ffef4 596
juliogerchman 2:590e99f4a313 597 run_loop();
juliogerchman 2:590e99f4a313 598 }