LED driver.

Committer:
Seb_Sok
Date:
Fri Mar 22 14:14:12 2019 +0000
Revision:
9:de0cfb4301d5
Parent:
8:edc0db715dda
rev. 1.6

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 #define NUM_LEDS_LIGHTING 3
lru 0:da2de84c3c04 114
lru 2:a83100cd9c9a 115 // Keeps indexes of LEDs that should be on in the next step.
Seb_Sok 3:b5cec57779aa 116 uint32_t led_index;
Seb_Sok 7:41cf0397d6ee 117 uint32_t dir_flag = 0; // Variable specifying the rotation direction of the leds
Seb_Sok 7:41cf0397d6ee 118 uint32_t button_was_pressed_counter = 0;
Seb_Sok 3:b5cec57779aa 119
lru 2:a83100cd9c9a 120 // Current color.
lru 0:da2de84c3c04 121 BGR24_color_t current_col[NUM_LEDS_LIGHTING];
lru 0:da2de84c3c04 122
Seb_Sok 3:b5cec57779aa 123 // User button initialization
Seb_Sok 3:b5cec57779aa 124 DigitalIn UserButton(P0_4, PullUp);
Seb_Sok 3:b5cec57779aa 125
lru 0:da2de84c3c04 126 // main() runs in its own thread in the OS
lru 0:da2de84c3c04 127 int main() {
Seb_Sok 3:b5cec57779aa 128 int color_step = 0, led_counter = 0;
lru 0:da2de84c3c04 129
lru 0:da2de84c3c04 130 leds.set_dma_usage(DMA_USAGE_ALWAYS);
lru 0:da2de84c3c04 131
Seb_Sok 3:b5cec57779aa 132 // Infinite loop
lru 0:da2de84c3c04 133 while (true) {
Seb_Sok 3:b5cec57779aa 134
Seb_Sok 3:b5cec57779aa 135 // Checks if the button is pressed.
Seb_Sok 3:b5cec57779aa 136 if(UserButton == 0 && button_was_pressed_counter == 0)
Seb_Sok 3:b5cec57779aa 137 {
Seb_Sok 3:b5cec57779aa 138 // Changing the direction of rotation of the leds.
Seb_Sok 3:b5cec57779aa 139 // If dir_flag is 1 then rotate right otherwise rotate left.
Seb_Sok 3:b5cec57779aa 140 if(dir_flag == 1) dir_flag = 0;
Seb_Sok 3:b5cec57779aa 141 else dir_flag = 1;
Seb_Sok 3:b5cec57779aa 142
Seb_Sok 3:b5cec57779aa 143 button_was_pressed_counter = 5;
Seb_Sok 3:b5cec57779aa 144 }
Seb_Sok 3:b5cec57779aa 145
Seb_Sok 3:b5cec57779aa 146 // If the button was pressed wait for 400 ms (5 * 80 ms) to eliminate vibrations contacts.
Seb_Sok 3:b5cec57779aa 147 if(button_was_pressed_counter){
Seb_Sok 3:b5cec57779aa 148 button_was_pressed_counter--;
Seb_Sok 3:b5cec57779aa 149 }
Seb_Sok 3:b5cec57779aa 150
lru 2:a83100cd9c9a 151 // This defines phase relationship between rotating pattern
lru 2:a83100cd9c9a 152 // and color change.
lru 2:a83100cd9c9a 153 // As there are 8 steps for the whole circle (8 LEDs)
lru 2:a83100cd9c9a 154 // value of 6 means the color changes every 3/4 of rotation.
Seb_Sok 3:b5cec57779aa 155 if (++color_step == 6) {
lru 2:a83100cd9c9a 156 color_step = 0;
lru 2:a83100cd9c9a 157 current_col[2] = gen_color();
Seb_Sok 3:b5cec57779aa 158 current_col[1] = dim(current_col[2], 25);
Seb_Sok 3:b5cec57779aa 159 current_col[0] = dim(current_col[2], 5);
lru 2:a83100cd9c9a 160 }
lru 2:a83100cd9c9a 161
lru 2:a83100cd9c9a 162 // Set up lighting pattern for current step.
Seb_Sok 3:b5cec57779aa 163 for (int i = 0; i < NUM_LEDS_LIGHTING; i++) {
Seb_Sok 3:b5cec57779aa 164
Seb_Sok 3:b5cec57779aa 165 if(led_counter + i > 7) led_index = led_counter + i - 8;
Seb_Sok 3:b5cec57779aa 166 else led_index = led_counter + i;
Seb_Sok 3:b5cec57779aa 167
Seb_Sok 4:59c5b7dee5bc 168 // The function is used to set the direction of the "tail".
Seb_Sok 5:b84ce6bea4ac 169 leds.set_color(led_index, current_col[i]);
Seb_Sok 4:59c5b7dee5bc 170
lru 0:da2de84c3c04 171 }
Seb_Sok 3:b5cec57779aa 172
Seb_Sok 3:b5cec57779aa 173 // Turn off / turn on all the buffer of leds prepared above.
lru 0:da2de84c3c04 174 leds.refresh();
lru 0:da2de84c3c04 175
Seb_Sok 3:b5cec57779aa 176 // Do nothing for 80 ms
Seb_Sok 3:b5cec57779aa 177 wait_ms(80);
Seb_Sok 3:b5cec57779aa 178
Seb_Sok 6:44851bff34a4 179 // This function is used to set the direction of rotation of the leds
Seb_Sok 3:b5cec57779aa 180 if(UserButton){
Seb_Sok 9:de0cfb4301d5 181 if(++led_counter > 7) led_counter = 0; // Right spin
Seb_Sok 7:41cf0397d6ee 182 }
Seb_Sok 4:59c5b7dee5bc 183
Seb_Sok 3:b5cec57779aa 184
Seb_Sok 3:b5cec57779aa 185 // Turn off all LEDs, so we have a dark frame buffer again.
lru 2:a83100cd9c9a 186 // Must be done after delay, as with DMA refresh() operation
lru 2:a83100cd9c9a 187 // only starts LEDs updating from the frame buffer.
Seb_Sok 3:b5cec57779aa 188 for (int i = 0; i < 8; i++) {
Seb_Sok 3:b5cec57779aa 189 leds.set_color(i, BGR24_color_t(0,0,0));
Seb_Sok 3:b5cec57779aa 190 }
Seb_Sok 3:b5cec57779aa 191
lru 0:da2de84c3c04 192
lru 0:da2de84c3c04 193 }
Seb_Sok 3:b5cec57779aa 194
lru 0:da2de84c3c04 195 }