LED driver.

main.cpp

Committer:
Seb_Sok
Date:
2019-03-19
Revision:
4:59c5b7dee5bc
Parent:
3:b5cec57779aa
Child:
5:b84ce6bea4ac

File content as of revision 4:59c5b7dee5bc:

/*
 * Mbed OS example program for Future Electronics Sequana board.
 *
 * Copyright (c) 2018 Future Electronics
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// This example demonstrates used of ROHM BD2808 24-channel LED Controller
// and its driver library on Sequana board.

#include "mbed.h"
#include "BD2808.h"

BD2808 leds;

// Return new color value by dimming the current color to x%
BGR24_color_t dim(BGR24_color_t color, uint8_t percent)
{
    BGR24_color_t new_color;

    new_color.r = color.r * percent / 100;
    new_color.g = color.g * percent / 100;
    new_color.b = color.b * percent / 100;

    return new_color;
}

#define sat(x)  (uint8_t)((x) > 255? 255 : (x) < 0? 0 : (x))

// This function generates color sequence. Each call to this function
// returns the next color in a sequence.
// Color sequence generation algorithm is such, that it provides
// smooth color swipe, keeping intensity roughly the same.
BGR24_color_t gen_color()
{
    const uint8_t step = 40;
    const uint8_t max = 200;
    static uint32_t phase = 0;
    static int32_t r = max;
    static int32_t g = max;
    static int32_t b = 0;
    static int32_t base_level = 6;

#define step_up(x)      do { if ((x += step) > max) x = max; } while(0)
#define step_down(x, v) do { x -= step; if (x < v) x = v;} while (0)

    switch (phase) {
        case 0:
            // swiping from reddish into blueish
            step_down(r, 0);
            g = base_level;
            step_up(b);
            if (r == 0) phase++;
            break;
        case 1:
            // swiping from blueish into greenish to level off blue
            r = 0;
            step_up(g);
            step_down(b, base_level);
            if (b == base_level) phase++;
            break;
        case 2:
            // swiping from greenish into reddish
            step_up(r);
            step_down(g, 0);
            b = base_level;
            if (g == 0) phase++;
            break;
        case 3:
            // swiping from reddish into blueish to level off red
            step_down(r, base_level);
            g = 0;
            step_up(b);
            if (r == base_level) phase++;
            break;
        case 4:
            // swiping from blueish into greenish
            r = base_level;
            step_up(g);
            step_down(b, 0);
            if (b == 0) phase++;
            break;
        case 5:
            // swiping from greenish into reddish to level off green
            step_up(r);
            step_down(g, base_level);
            b = 0;
            if (g == base_level) {
                phase = 0;
                base_level *= 2;
                if (base_level > 200) {
                    base_level = 6;
                }
                g = base_level;
            }
            break;
    }

    return BGR24_color_t(sat(b), sat(g), sat(r));
}

#define NUM_LEDS_LIGHTING   3

// Keeps indexes of LEDs that should be on in the next step.
uint32_t led_index;
uint32_t dir_flag = 0, button_was_pressed_counter = 0;

// Current color.
BGR24_color_t current_col[NUM_LEDS_LIGHTING];

// User button initialization
DigitalIn  UserButton(P0_4, PullUp);   

// main() runs in its own thread in the OS
int main() {
    int color_step = 0, led_counter = 0;

    leds.set_dma_usage(DMA_USAGE_ALWAYS);

    // Infinite loop
    while (true) {
        
        // Checks if the button is pressed.
        if(UserButton == 0 && button_was_pressed_counter == 0) 
        {
            // Changing the direction of rotation of the leds.
            // If dir_flag is 1 then rotate right otherwise rotate left.
            if(dir_flag == 1) dir_flag = 0;
            else dir_flag = 1;
            
            button_was_pressed_counter = 5;
        }

        // If the button was pressed wait for 400 ms (5 * 80 ms) to eliminate vibrations contacts.
        if(button_was_pressed_counter){
            button_was_pressed_counter--;
        }

        // This defines phase relationship between rotating pattern
        // and color change.
        // As there are 8 steps for the whole circle (8 LEDs)
        // value of 6 means the color changes every 3/4 of rotation.
       if (++color_step == 6) {
            color_step = 0;
            current_col[2] = gen_color();
            current_col[1] = dim(current_col[2], 25);
            current_col[0] = dim(current_col[2], 5);
        }

        // Set up lighting pattern for current step.
        for (int i = 0; i < NUM_LEDS_LIGHTING; i++) {
            
            
            if(led_counter + i > 7) led_index = led_counter + i - 8;
            else led_index = led_counter + i;
            
            // The function is used to set the direction of the "tail".
                leds.set_color(led_index, current_col[i]);
  
        }
        
        // Turn off / turn on all the buffer of leds prepared above.
        leds.refresh();

        // Do nothing for 80 ms
        wait_ms(80);             
        
        // The function is used to change the direction of rotation of the leds depending on "dir_flag".
        if(UserButton){
            if(++led_counter > 7) led_counter = 0; // Right turn
        }

            
        // Turn off all LEDs, so we have a dark frame buffer again.
        // Must be done after delay, as with DMA refresh() operation
        // only starts LEDs updating from the frame buffer.
        for (int i = 0; i < 8; i++) {
            leds.set_color(i, BGR24_color_t(0,0,0));
        }
        

    }
    
}