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.
Fork of LedStrip_test by
main.cpp@6:6f0f4e6c1e5f, 2013-09-21 (annotated)
- Committer:
- bracz
- Date:
- Sat Sep 21 20:21:24 2013 +0000
- Revision:
- 6:6f0f4e6c1e5f
- Parent:
- 5:5a2af711d510
- Child:
- 7:62c9a5483a84
registers an actual program.
Who changed what in which revision?
User | Revision | Line number | New 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 | 2:590e99f4a313 | 222 | /* Keep dropping water drops in a bucket, until it fills up. */ |
bracz | 5:5a2af711d510 | 223 | class DropBucketFill : public Schedulable |
bracz | 5:5a2af711d510 | 224 | { |
juliogerchman | 2:590e99f4a313 | 225 | public: |
bracz | 5:5a2af711d510 | 226 | DropBucketFill(int start_time, int start_led, int length, int drop_size, uint8_t from_color, uint8_t to_color, bool* done) |
bracz | 5:5a2af711d510 | 227 | : start_led_(start_led), length_(length), drop_size_(drop_size), from_color_(from_color), to_color_(to_color), done_(done) { |
juliogerchman | 2:590e99f4a313 | 228 | time_ = start_time; |
juliogerchman | 2:590e99f4a313 | 229 | Schedule(this); |
juliogerchman | 2:590e99f4a313 | 230 | } |
bracz | 5:5a2af711d510 | 231 | |
juliogerchman | 2:590e99f4a313 | 232 | virtual void Run() { |
juliogerchman | 2:590e99f4a313 | 233 | // The bucket starts with a drop at its end. |
juliogerchman | 2:590e99f4a313 | 234 | //strip[start_led_ + length_] = to_color_; |
juliogerchman | 2:590e99f4a313 | 235 | //strip[start_led_ + length_] = RED; |
juliogerchman | 2:590e99f4a313 | 236 | if (length_ > 0) { |
juliogerchman | 2:590e99f4a313 | 237 | // There's still space in the bucket. Drop a new drop. |
juliogerchman | 3:42efa00ffef4 | 238 | for (int i = 0; i < min(drop_size_, length_); ++i) { |
juliogerchman | 2:590e99f4a313 | 239 | Schedulable* next_drop = NULL; |
juliogerchman | 2:590e99f4a313 | 240 | next_drop = this; |
juliogerchman | 3:42efa00ffef4 | 241 | 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 | 242 | } |
juliogerchman | 2:590e99f4a313 | 243 | length_--; |
bracz | 5:5a2af711d510 | 244 | } else if (length_ == 0) { |
juliogerchman | 2:590e99f4a313 | 245 | // There's no more space in the bucket. Bail out. |
bracz | 5:5a2af711d510 | 246 | if (done_) *done_ = true; |
juliogerchman | 2:590e99f4a313 | 247 | delete this; |
juliogerchman | 2:590e99f4a313 | 248 | return; |
juliogerchman | 2:590e99f4a313 | 249 | } |
juliogerchman | 2:590e99f4a313 | 250 | } |
bracz | 5:5a2af711d510 | 251 | |
juliogerchman | 2:590e99f4a313 | 252 | private: |
juliogerchman | 2:590e99f4a313 | 253 | int start_led_, length_; |
juliogerchman | 2:590e99f4a313 | 254 | int drop_size_; |
juliogerchman | 2:590e99f4a313 | 255 | uint8_t from_color_, to_color_; |
bracz | 5:5a2af711d510 | 256 | bool* done_; |
juliogerchman | 2:590e99f4a313 | 257 | }; |
juliogerchman | 2:590e99f4a313 | 258 | |
bracz | 5:5a2af711d510 | 259 | Schedulable* g_watchdog; |
bracz | 5:5a2af711d510 | 260 | |
bracz | 5:5a2af711d510 | 261 | class ProgramSupervisor |
bracz | 5:5a2af711d510 | 262 | { |
bracz | 5:5a2af711d510 | 263 | public: |
bracz | 5:5a2af711d510 | 264 | |
bracz | 5:5a2af711d510 | 265 | // 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 | 266 | void RegisterProgram(Schedulable* program) { |
bracz | 5:5a2af711d510 | 267 | programs_.push_back(program); |
bracz | 5:5a2af711d510 | 268 | } |
bracz | 5:5a2af711d510 | 269 | |
bracz | 5:5a2af711d510 | 270 | // This should be called by the program executor when it is completed. |
bracz | 5:5a2af711d510 | 271 | // It is desired to leave all LEDs black after program completion. |
bracz | 5:5a2af711d510 | 272 | void CurrentProgramDone() { |
bracz | 5:5a2af711d510 | 273 | next_program_++; |
bracz | 5:5a2af711d510 | 274 | next_program_ %= programs_.size(); |
bracz | 5:5a2af711d510 | 275 | ScheduleProgram(); |
bracz | 5:5a2af711d510 | 276 | } |
bracz | 5:5a2af711d510 | 277 | |
bracz | 5:5a2af711d510 | 278 | void ScheduleProgram() { |
bracz | 5:5a2af711d510 | 279 | global_tick = 0; |
bracz | 5:5a2af711d510 | 280 | while (!task_list.empty()) task_list.pop(); |
bracz | 5:5a2af711d510 | 281 | Schedule(g_watchdog); |
bracz | 5:5a2af711d510 | 282 | if (programs_.empty()) return; |
bracz | 5:5a2af711d510 | 283 | } |
bracz | 5:5a2af711d510 | 284 | |
bracz | 5:5a2af711d510 | 285 | |
bracz | 5:5a2af711d510 | 286 | private: |
bracz | 5:5a2af711d510 | 287 | vector<Schedulable*> programs_; |
bracz | 5:5a2af711d510 | 288 | int next_program_; // indexes the programs_ array. |
bracz | 5:5a2af711d510 | 289 | } supervisor; |
bracz | 5:5a2af711d510 | 290 | |
bracz | 5:5a2af711d510 | 291 | |
bracz | 5:5a2af711d510 | 292 | class ProgramWatchdog : public Schedulable |
bracz | 5:5a2af711d510 | 293 | { |
bracz | 5:5a2af711d510 | 294 | public: |
bracz | 5:5a2af711d510 | 295 | ProgramWatchdog() { |
bracz | 5:5a2af711d510 | 296 | time_ = 5 * 60 * 1000; // 5 minutes deadline |
bracz | 5:5a2af711d510 | 297 | } |
bracz | 5:5a2af711d510 | 298 | |
bracz | 5:5a2af711d510 | 299 | virtual void Run() { |
bracz | 5:5a2af711d510 | 300 | supervisor.CurrentProgramDone(); |
bracz | 5:5a2af711d510 | 301 | led2 = 1; |
bracz | 5:5a2af711d510 | 302 | } |
bracz | 5:5a2af711d510 | 303 | |
bracz | 5:5a2af711d510 | 304 | } g_watchdog_impl; |
bracz | 5:5a2af711d510 | 305 | |
bracz | 5:5a2af711d510 | 306 | |
bracz | 5:5a2af711d510 | 307 | class MultiDropBucketFillProgram : public Schedulable |
bracz | 5:5a2af711d510 | 308 | { |
bracz | 5:5a2af711d510 | 309 | public: |
bracz | 6:6f0f4e6c1e5f | 310 | MultiDropBucketFillProgram() { |
bracz | 6:6f0f4e6c1e5f | 311 | supervisor.RegisterProgram(this); |
bracz | 6:6f0f4e6c1e5f | 312 | } |
bracz | 6:6f0f4e6c1e5f | 313 | |
bracz | 5:5a2af711d510 | 314 | virtual void Run() { |
bracz | 5:5a2af711d510 | 315 | int time = global_tick; |
bracz | 5:5a2af711d510 | 316 | const int kLength = sizeof(google_colors); |
bracz | 5:5a2af711d510 | 317 | memset(done_, 0, sizeof(done_)); |
bracz | 5:5a2af711d510 | 318 | for (int i = 0; i < kLength; i++) { |
bracz | 5:5a2af711d510 | 319 | new DropBucketFill(time, 10 + i * 20, 20, 4, BLACK, google_colors[i], done_ + i); |
bracz | 5:5a2af711d510 | 320 | } |
bracz | 5:5a2af711d510 | 321 | new EndWatcher(done_, kLength); |
bracz | 5:5a2af711d510 | 322 | } |
bracz | 5:5a2af711d510 | 323 | |
bracz | 5:5a2af711d510 | 324 | private: |
bracz | 5:5a2af711d510 | 325 | class EndWatcher : public Schedulable { |
bracz | 5:5a2af711d510 | 326 | public: |
bracz | 5:5a2af711d510 | 327 | EndWatcher(bool* done_array, int len) : done_(done_array), len_(len) { |
bracz | 5:5a2af711d510 | 328 | time_ = 0; |
bracz | 5:5a2af711d510 | 329 | Schedule(this); |
bracz | 5:5a2af711d510 | 330 | } |
bracz | 5:5a2af711d510 | 331 | |
bracz | 5:5a2af711d510 | 332 | virtual void Run() { |
bracz | 5:5a2af711d510 | 333 | int i; |
bracz | 5:5a2af711d510 | 334 | for (i = 0; i < len_ && done_[i]; i++); |
bracz | 5:5a2af711d510 | 335 | if (i < len_) { |
bracz | 5:5a2af711d510 | 336 | // not done yet. |
bracz | 5:5a2af711d510 | 337 | time_ = global_tick + 2; |
bracz | 5:5a2af711d510 | 338 | Schedule(this); |
bracz | 5:5a2af711d510 | 339 | } else { |
bracz | 5:5a2af711d510 | 340 | supervisor.CurrentProgramDone(); |
bracz | 5:5a2af711d510 | 341 | delete this; |
bracz | 5:5a2af711d510 | 342 | } |
bracz | 5:5a2af711d510 | 343 | } |
bracz | 5:5a2af711d510 | 344 | |
bracz | 5:5a2af711d510 | 345 | private: |
bracz | 5:5a2af711d510 | 346 | bool* done_; |
bracz | 5:5a2af711d510 | 347 | int len_; |
bracz | 5:5a2af711d510 | 348 | }; |
bracz | 5:5a2af711d510 | 349 | |
bracz | 5:5a2af711d510 | 350 | |
bracz | 5:5a2af711d510 | 351 | bool done_[6]; |
bracz | 5:5a2af711d510 | 352 | }; |
bracz | 5:5a2af711d510 | 353 | |
bracz | 5:5a2af711d510 | 354 | |
bracz | 5:5a2af711d510 | 355 | void init_board() |
bracz | 5:5a2af711d510 | 356 | { |
bracz | 0:109a7a5e3e6e | 357 | pc.baud(115200); |
bracz | 0:109a7a5e3e6e | 358 | |
bracz | 0:109a7a5e3e6e | 359 | myled = 0; |
bracz | 0:109a7a5e3e6e | 360 | latch = 0; |
bracz | 5:5a2af711d510 | 361 | |
bracz | 0:109a7a5e3e6e | 362 | spi.format(8, 0); |
bracz | 0:109a7a5e3e6e | 363 | spi.frequency(300000); |
bracz | 0:109a7a5e3e6e | 364 | wait_ms(500); |
bracz | 0:109a7a5e3e6e | 365 | myled = 1; |
juliogerchman | 2:590e99f4a313 | 366 | memset(strip, BLACK, sizeof(strip)); |
bracz | 0:109a7a5e3e6e | 367 | write_strip(strip, sizeof(strip)); |
juliogerchman | 2:590e99f4a313 | 368 | g_ticker.attach(&tick_cb, 1.0/1000); |
bracz | 5:5a2af711d510 | 369 | |
bracz | 0:109a7a5e3e6e | 370 | memset(strip, 0x0, sizeof(strip)); |
juliogerchman | 2:590e99f4a313 | 371 | } |
juliogerchman | 2:590e99f4a313 | 372 | |
bracz | 5:5a2af711d510 | 373 | void run_loop() |
bracz | 5:5a2af711d510 | 374 | { |
bracz | 0:109a7a5e3e6e | 375 | while(1) { |
bracz | 0:109a7a5e3e6e | 376 | while (task_list.empty() || global_tick < task_list.top()->time_) { |
bracz | 0:109a7a5e3e6e | 377 | if (strip_changed) { |
bracz | 0:109a7a5e3e6e | 378 | write_strip(strip, sizeof(strip)); |
bracz | 0:109a7a5e3e6e | 379 | strip_changed = false; |
bracz | 0:109a7a5e3e6e | 380 | memset(strip, 0x0, sizeof(strip)); |
bracz | 0:109a7a5e3e6e | 381 | } |
bracz | 0:109a7a5e3e6e | 382 | } |
bracz | 0:109a7a5e3e6e | 383 | Schedulable* action = task_list.top(); |
bracz | 0:109a7a5e3e6e | 384 | task_list.pop(); |
bracz | 0:109a7a5e3e6e | 385 | action->Run(); |
bracz | 0:109a7a5e3e6e | 386 | } |
juliogerchman | 2:590e99f4a313 | 387 | } |
bracz | 0:109a7a5e3e6e | 388 | |
bracz | 5:5a2af711d510 | 389 | int main() |
bracz | 5:5a2af711d510 | 390 | { |
juliogerchman | 2:590e99f4a313 | 391 | init_board(); |
bracz | 5:5a2af711d510 | 392 | g_watchdog = &g_watchdog_impl; |
bracz | 6:6f0f4e6c1e5f | 393 | |
bracz | 6:6f0f4e6c1e5f | 394 | MultiDropBucketFillProgram multi_drop; |
bracz | 6:6f0f4e6c1e5f | 395 | |
bracz | 5:5a2af711d510 | 396 | supervisor.ScheduleProgram(); |
juliogerchman | 2:590e99f4a313 | 397 | run_loop(); |
juliogerchman | 2:590e99f4a313 | 398 | } |