Example program to blink RGB LEDs on Sequana board in a rotating pattern.

Committer:
lru
Date:
Mon Mar 04 14:15:06 2019 +0000
Revision:
2:a83100cd9c9a
Parent:
0:da2de84c3c04
Updated color selection algorithm

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lru 0:da2de84c3c04 1 /*
lru 0:da2de84c3c04 2 * Mbed OS example program for Future Electronics Sequana board.
lru 0:da2de84c3c04 3 *
lru 0:da2de84c3c04 4 * Copyright (c) 2018 Future Electronics
lru 0:da2de84c3c04 5 *
lru 0:da2de84c3c04 6 * Licensed under the Apache License, Version 2.0 (the "License");
lru 0:da2de84c3c04 7 * you may not use this file except in compliance with the License.
lru 0:da2de84c3c04 8 * You may obtain a copy of the License at
lru 0:da2de84c3c04 9 *
lru 0:da2de84c3c04 10 * http://www.apache.org/licenses/LICENSE-2.0
lru 0:da2de84c3c04 11 *
lru 0:da2de84c3c04 12 * Unless required by applicable law or agreed to in writing, software
lru 0:da2de84c3c04 13 * distributed under the License is distributed on an "AS IS" BASIS,
lru 0:da2de84c3c04 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
lru 0:da2de84c3c04 15 * See the License for the specific language governing permissions and
lru 0:da2de84c3c04 16 * limitations under the License.
lru 0:da2de84c3c04 17 */
lru 0:da2de84c3c04 18
lru 0:da2de84c3c04 19 // This example demonstrates used of ROHM BD2808 24-channel LED Controller
lru 0:da2de84c3c04 20 // and its driver library on Sequana board.
lru 0:da2de84c3c04 21
lru 0:da2de84c3c04 22 #include "mbed.h"
lru 0:da2de84c3c04 23 #include "BD2808.h"
lru 0:da2de84c3c04 24
lru 0:da2de84c3c04 25 BD2808 leds;
lru 0:da2de84c3c04 26
lru 2:a83100cd9c9a 27 // Return new color value by dimming the current color to x%
lru 0:da2de84c3c04 28 BGR24_color_t dim(BGR24_color_t color, uint8_t percent)
lru 0:da2de84c3c04 29 {
lru 0:da2de84c3c04 30 BGR24_color_t new_color;
lru 0:da2de84c3c04 31
lru 0:da2de84c3c04 32 new_color.r = color.r * percent / 100;
lru 0:da2de84c3c04 33 new_color.g = color.g * percent / 100;
lru 0:da2de84c3c04 34 new_color.b = color.b * percent / 100;
lru 0:da2de84c3c04 35
lru 0:da2de84c3c04 36 return new_color;
lru 0:da2de84c3c04 37 }
lru 0:da2de84c3c04 38
lru 0:da2de84c3c04 39 #define sat(x) (uint8_t)((x) > 255? 255 : (x) < 0? 0 : (x))
lru 0:da2de84c3c04 40
lru 2:a83100cd9c9a 41 // This function generates color sequence. Each call to this function
lru 2:a83100cd9c9a 42 // returns the next color in a sequence.
lru 2:a83100cd9c9a 43 // Color sequence generation algorithm is such, that it provides
lru 2:a83100cd9c9a 44 // smooth color swipe, keeping intensity roughly the same.
lru 0:da2de84c3c04 45 BGR24_color_t gen_color()
lru 0:da2de84c3c04 46 {
lru 2:a83100cd9c9a 47 const uint8_t step = 40;
lru 0:da2de84c3c04 48 const uint8_t max = 200;
lru 2:a83100cd9c9a 49 static uint32_t phase = 0;
lru 0:da2de84c3c04 50 static int32_t r = max;
lru 0:da2de84c3c04 51 static int32_t g = max;
lru 0:da2de84c3c04 52 static int32_t b = 0;
lru 2:a83100cd9c9a 53 static int32_t base_level = 6;
lru 0:da2de84c3c04 54
lru 2:a83100cd9c9a 55 #define step_up(x) do { if ((x += step) > max) x = max; } while(0)
lru 2:a83100cd9c9a 56 #define step_down(x, v) do { x -= step; if (x < v) x = v;} while (0)
lru 0:da2de84c3c04 57
lru 2:a83100cd9c9a 58 switch (phase) {
lru 2:a83100cd9c9a 59 case 0:
lru 2:a83100cd9c9a 60 // swiping from reddish into blueish
lru 2:a83100cd9c9a 61 step_down(r, 0);
lru 2:a83100cd9c9a 62 g = base_level;
lru 2:a83100cd9c9a 63 step_up(b);
lru 2:a83100cd9c9a 64 if (r == 0) phase++;
lru 2:a83100cd9c9a 65 break;
lru 2:a83100cd9c9a 66 case 1:
lru 2:a83100cd9c9a 67 // swiping from blueish into greenish to level off blue
lru 2:a83100cd9c9a 68 r = 0;
lru 2:a83100cd9c9a 69 step_up(g);
lru 2:a83100cd9c9a 70 step_down(b, base_level);
lru 2:a83100cd9c9a 71 if (b == base_level) phase++;
lru 2:a83100cd9c9a 72 break;
lru 2:a83100cd9c9a 73 case 2:
lru 2:a83100cd9c9a 74 // swiping from greenish into reddish
lru 2:a83100cd9c9a 75 step_up(r);
lru 2:a83100cd9c9a 76 step_down(g, 0);
lru 2:a83100cd9c9a 77 b = base_level;
lru 2:a83100cd9c9a 78 if (g == 0) phase++;
lru 2:a83100cd9c9a 79 break;
lru 2:a83100cd9c9a 80 case 3:
lru 2:a83100cd9c9a 81 // swiping from reddish into blueish to level off red
lru 2:a83100cd9c9a 82 step_down(r, base_level);
lru 2:a83100cd9c9a 83 g = 0;
lru 2:a83100cd9c9a 84 step_up(b);
lru 2:a83100cd9c9a 85 if (r == base_level) phase++;
lru 2:a83100cd9c9a 86 break;
lru 2:a83100cd9c9a 87 case 4:
lru 2:a83100cd9c9a 88 // swiping from blueish into greenish
lru 2:a83100cd9c9a 89 r = base_level;
lru 2:a83100cd9c9a 90 step_up(g);
lru 2:a83100cd9c9a 91 step_down(b, 0);
lru 2:a83100cd9c9a 92 if (b == 0) phase++;
lru 2:a83100cd9c9a 93 break;
lru 2:a83100cd9c9a 94 case 5:
lru 2:a83100cd9c9a 95 // swiping from greenish into reddish to level off green
lru 2:a83100cd9c9a 96 step_up(r);
lru 2:a83100cd9c9a 97 step_down(g, base_level);
lru 2:a83100cd9c9a 98 b = 0;
lru 2:a83100cd9c9a 99 if (g == base_level) {
lru 2:a83100cd9c9a 100 phase = 0;
lru 2:a83100cd9c9a 101 base_level *= 2;
lru 2:a83100cd9c9a 102 if (base_level > 200) {
lru 2:a83100cd9c9a 103 base_level = 6;
lru 2:a83100cd9c9a 104 }
lru 2:a83100cd9c9a 105 g = base_level;
lru 0:da2de84c3c04 106 }
lru 2:a83100cd9c9a 107 break;
lru 0:da2de84c3c04 108 }
lru 0:da2de84c3c04 109
lru 0:da2de84c3c04 110 return BGR24_color_t(sat(b), sat(g), sat(r));
lru 0:da2de84c3c04 111 }
lru 0:da2de84c3c04 112
lru 0:da2de84c3c04 113
lru 0:da2de84c3c04 114 #define NUM_LEDS_LIGHTING 3
lru 0:da2de84c3c04 115
lru 2:a83100cd9c9a 116 // Keeps indexes of LEDs that should be on in the next step.
lru 0:da2de84c3c04 117 uint32_t led_index[NUM_LEDS_LIGHTING] = {0, 1, 2};
lru 2:a83100cd9c9a 118 // Current color.
lru 0:da2de84c3c04 119 BGR24_color_t current_col[NUM_LEDS_LIGHTING];
lru 0:da2de84c3c04 120
lru 0:da2de84c3c04 121 // main() runs in its own thread in the OS
lru 0:da2de84c3c04 122 int main() {
lru 2:a83100cd9c9a 123 int color_step = 0;
lru 0:da2de84c3c04 124
lru 0:da2de84c3c04 125 leds.set_dma_usage(DMA_USAGE_ALWAYS);
lru 0:da2de84c3c04 126
lru 0:da2de84c3c04 127 while (true) {
lru 2:a83100cd9c9a 128 // This defines phase relationship between rotating pattern
lru 2:a83100cd9c9a 129 // and color change.
lru 2:a83100cd9c9a 130 // As there are 8 steps for the whole circle (8 LEDs)
lru 2:a83100cd9c9a 131 // value of 6 means the color changes every 3/4 of rotation.
lru 2:a83100cd9c9a 132 if (++color_step == 6) {
lru 2:a83100cd9c9a 133 color_step = 0;
lru 2:a83100cd9c9a 134 current_col[2] = gen_color();
lru 2:a83100cd9c9a 135 current_col[1] = dim(current_col[2], 50);
lru 2:a83100cd9c9a 136 current_col[0] = dim(current_col[2], 10);
lru 2:a83100cd9c9a 137 }
lru 2:a83100cd9c9a 138
lru 2:a83100cd9c9a 139 // Set up lighting pattern for current step.
lru 0:da2de84c3c04 140 for (int i = 0; i < NUM_LEDS_LIGHTING; ++i) {
lru 0:da2de84c3c04 141 leds.set_color(led_index[i], current_col[i]);
lru 0:da2de84c3c04 142 }
lru 0:da2de84c3c04 143 leds.refresh();
lru 0:da2de84c3c04 144
lru 0:da2de84c3c04 145 wait_ms(50);
lru 2:a83100cd9c9a 146 // Turn off set LEDs, so we have a dark frame buffer again.
lru 2:a83100cd9c9a 147 // Must be done after delay, as with DMA refresh() operation
lru 2:a83100cd9c9a 148 // only starts LEDs updating from the frame buffer.
lru 0:da2de84c3c04 149 leds.set_color(led_index[0], BGR24_color_t(0,0,0));
lru 0:da2de84c3c04 150
lru 2:a83100cd9c9a 151 // Update lighting LED indexes for the next step.
lru 0:da2de84c3c04 152 for (int i = 0; i < NUM_LEDS_LIGHTING; ++i) {
lru 0:da2de84c3c04 153 if (++led_index[i] == 8) led_index[i] = 0;
lru 0:da2de84c3c04 154 }
lru 0:da2de84c3c04 155 }
lru 0:da2de84c3c04 156 }