Julio G / Mbed 2 deprecated LedStrip

Dependencies:   mbed

Fork of LedStrip_test by Balazs Racz

Committer:
juliogerchman
Date:
Sat Sep 21 22:14:57 2013 +0000
Revision:
9:01eb82c2a01b
Parent:
8:77fd54b4864c
cyclecolors not working yet

Who changed what in which revision?

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