2014-03-02 07:18:48 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
* "THE BEER-WARE LICENSE" (Revision 42):
|
|
|
|
* <struppi@struppi.name> wrote this file. As long as you retain this notice you
|
|
|
|
* can do whatever you want with this stuff. If we meet some day, and you think
|
|
|
|
* this stuff is worth it, you can buy me a beer in return.
|
|
|
|
* (c) 2014 Stefan Rupp
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2014-03-03 05:01:36 +01:00
|
|
|
/*
|
|
|
|
* This module tries to control 15 RGB-LEDs
|
|
|
|
* connected to three daisy-chained
|
|
|
|
* LED1642GW-ICs from STM.
|
|
|
|
*/
|
|
|
|
|
2014-03-02 07:18:48 +01:00
|
|
|
#include "ledcontroller.h"
|
2014-03-18 01:04:18 +01:00
|
|
|
#include "led1642gw.h"
|
2014-03-02 07:18:48 +01:00
|
|
|
|
2014-03-18 02:09:21 +01:00
|
|
|
/*
|
|
|
|
* Application specific mapping of LEDs and there respective color channels
|
|
|
|
* to the respective channels of the three LED1642GW ICs.
|
|
|
|
*/
|
2014-03-03 05:01:36 +01:00
|
|
|
static int8_t map_lednum_to_channels(uint8_t lednum, uint8_t *channel_r, uint8_t *channel_g, uint8_t *channel_b)
|
2014-03-02 07:18:48 +01:00
|
|
|
{
|
2014-03-13 03:03:08 +01:00
|
|
|
uint8_t ret=0;
|
|
|
|
|
|
|
|
if (lednum < 14) {
|
2014-03-02 07:18:48 +01:00
|
|
|
ret = 1;
|
2014-03-13 03:03:08 +01:00
|
|
|
switch (lednum) {
|
|
|
|
case 0:
|
|
|
|
*channel_r = 13;
|
|
|
|
*channel_g = 14;
|
|
|
|
*channel_b = 15;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
*channel_r = 33;
|
|
|
|
*channel_g = 34;
|
|
|
|
*channel_b = 35;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
*channel_r = 36;
|
|
|
|
*channel_g = 37;
|
|
|
|
*channel_b = 38;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
*channel_r = 45;
|
|
|
|
*channel_g = 46;
|
|
|
|
*channel_b = 47;
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
*channel_r = 42;
|
|
|
|
*channel_g = 43;
|
|
|
|
*channel_b = 44;
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
*channel_r = 39;
|
|
|
|
*channel_g = 40;
|
|
|
|
*channel_b = 41;
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
*channel_r = 29;
|
|
|
|
*channel_g = 30;
|
|
|
|
*channel_b = 31;
|
|
|
|
break;
|
|
|
|
case 7:
|
|
|
|
*channel_r = 26;
|
|
|
|
*channel_g = 27;
|
|
|
|
*channel_b = 28;
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
*channel_r = 23;
|
|
|
|
*channel_g = 24;
|
|
|
|
*channel_b = 25;
|
|
|
|
break;
|
|
|
|
case 9:
|
|
|
|
*channel_r = 20;
|
|
|
|
*channel_g = 21;
|
|
|
|
*channel_b = 22;
|
|
|
|
break;
|
|
|
|
case 10:
|
|
|
|
*channel_r = 17;
|
|
|
|
*channel_g = 18;
|
|
|
|
*channel_b = 19;
|
|
|
|
break;
|
|
|
|
case 11:
|
|
|
|
*channel_r = 10;
|
|
|
|
*channel_g = 11;
|
|
|
|
*channel_b = 12;
|
|
|
|
break;
|
|
|
|
case 12:
|
|
|
|
*channel_r = 4;
|
|
|
|
*channel_g = 5;
|
|
|
|
*channel_b = 6;
|
|
|
|
break;
|
|
|
|
case 13:
|
|
|
|
*channel_r = 7;
|
|
|
|
*channel_g = 8;
|
|
|
|
*channel_b = 9;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ret = 0;
|
|
|
|
break;
|
|
|
|
}
|
2014-03-02 07:18:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
2014-03-13 03:03:08 +01:00
|
|
|
|
2014-03-02 07:18:48 +01:00
|
|
|
}
|
|
|
|
|
2014-03-18 02:09:21 +01:00
|
|
|
/*
|
|
|
|
* set one RGB LED to a RGB value.
|
|
|
|
* This only changes the Red, Green and Blue values in the
|
|
|
|
* internal LED buffer, the physical LED will still remain in its previous
|
|
|
|
* state, until you call led_flush().
|
|
|
|
*/
|
2014-03-18 01:04:18 +01:00
|
|
|
void led_set(uint8_t lednum, uint16_t red, uint16_t green, uint16_t blue)
|
2014-03-12 23:46:14 +01:00
|
|
|
{
|
2014-03-18 01:04:18 +01:00
|
|
|
uint8_t c_r, c_g, c_b;
|
2014-03-12 23:46:14 +01:00
|
|
|
|
2014-03-18 01:04:18 +01:00
|
|
|
if ( map_lednum_to_channels(lednum, &c_r, &c_g, &c_b) > 0 ) {
|
|
|
|
led1642gw_set_channel(c_r, red);
|
|
|
|
led1642gw_set_channel(c_g, green);
|
|
|
|
led1642gw_set_channel(c_b, blue);
|
|
|
|
}
|
2014-03-12 23:46:14 +01:00
|
|
|
|
2014-03-02 07:18:48 +01:00
|
|
|
}
|
|
|
|
|
2014-08-07 17:38:08 +02:00
|
|
|
void led_set_hsv(uint8_t lednum, uint16_t hue, uint8_t saturation, uint8_t value)
|
|
|
|
{
|
|
|
|
uint16_t red, green, blue;
|
|
|
|
|
|
|
|
//Calculate hue
|
|
|
|
if ( hue < 61 ) {
|
|
|
|
red = 255;
|
|
|
|
green = ( 425UL * hue ) / 100;
|
|
|
|
blue = 0;
|
|
|
|
} else if ( hue < 121 ) {
|
|
|
|
red = 255 - ( ( 425UL * ( hue - 60 ) ) / 100 );
|
|
|
|
green = 255;
|
|
|
|
blue = 0;
|
|
|
|
} else if ( hue < 181 ) {
|
|
|
|
red = 0;
|
|
|
|
green = 255;
|
|
|
|
blue = ( 425UL * ( hue - 120 ) ) / 100;
|
|
|
|
} else if ( hue < 241 ) {
|
|
|
|
red = 0;
|
|
|
|
green = 255 - ( ( 425UL * ( hue - 180 ) ) / 100 );
|
|
|
|
blue = 255;
|
|
|
|
} else if ( hue < 301 ) {
|
|
|
|
red = ( 425UL * ( hue - 240 ) ) / 100;
|
|
|
|
green = 0;
|
|
|
|
blue = 255;
|
|
|
|
} else if ( hue < 360) {
|
|
|
|
red = 255;
|
|
|
|
green = 0;
|
|
|
|
blue = 255 - ( ( 425UL * ( hue - 300 ) ) / 100);
|
|
|
|
}
|
|
|
|
|
|
|
|
//Calculate saturation
|
|
|
|
uint8_t diff;
|
|
|
|
saturation = 100 - saturation;
|
|
|
|
diff = ( ( 255 - red ) * saturation ) / 100;
|
|
|
|
red += diff;
|
|
|
|
|
|
|
|
diff = ( ( 255 - green ) * saturation ) / 100;
|
|
|
|
green += diff;
|
|
|
|
|
|
|
|
diff = ( ( 255 - blue ) * saturation ) / 100;
|
|
|
|
blue += diff;
|
|
|
|
|
|
|
|
//Calculate value
|
|
|
|
red = ( red * value ) / 100;
|
|
|
|
green = ( green * value ) / 100;
|
|
|
|
blue = ( blue * value ) / 100;
|
|
|
|
|
|
|
|
led_set(lednum, red<<8, green<<8, blue<<8);
|
|
|
|
}
|
|
|
|
|
2014-03-18 02:09:21 +01:00
|
|
|
/*
|
|
|
|
* Write the data stored in the LED buffers via led_set().
|
|
|
|
*/
|
2014-03-18 01:04:18 +01:00
|
|
|
void led_flush(void)
|
2014-03-12 21:12:16 +01:00
|
|
|
{
|
2014-03-18 01:04:18 +01:00
|
|
|
led1642gw_flush();
|
2014-03-12 21:12:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-03-18 02:09:21 +01:00
|
|
|
/*
|
|
|
|
* Clear the LED buffer.
|
|
|
|
* This function only affects the LED buffer, but not the LEDs, until
|
|
|
|
* you call led_flush().
|
|
|
|
*/
|
2014-03-18 01:04:18 +01:00
|
|
|
void led_clear(void)
|
2014-03-12 21:12:16 +01:00
|
|
|
{
|
2014-03-18 01:04:18 +01:00
|
|
|
led1642gw_clear();
|
2014-03-12 21:12:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-03-18 02:09:21 +01:00
|
|
|
/*
|
|
|
|
* Initialize the leddriver.
|
|
|
|
* Must be called before any other function in this module.
|
|
|
|
*/
|
2014-03-15 00:18:40 +01:00
|
|
|
void led_init(void)
|
2014-03-02 07:18:48 +01:00
|
|
|
{
|
2014-03-18 01:04:18 +01:00
|
|
|
led1642gw_init();
|
2014-03-02 07:18:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-03-18 02:09:21 +01:00
|
|
|
/*
|
|
|
|
* Turn all channels on on every LED1642GW IC.
|
|
|
|
* If you don't turn the channels on, led_set
|
|
|
|
* won't have any effect, and the LEDs will remain dark.
|
|
|
|
*/
|
2014-03-18 01:04:18 +01:00
|
|
|
void led_turn_all_on(void)
|
2014-03-13 01:33:13 +01:00
|
|
|
{
|
2014-03-18 01:04:18 +01:00
|
|
|
led1642gw_turn_all_on();
|
2014-03-13 01:33:13 +01:00
|
|
|
}
|
|
|
|
|
2014-04-17 04:15:15 +02:00
|
|
|
|
|
|
|
void led_set_gain(uint8_t gain)
|
|
|
|
{
|
|
|
|
if (gain > 0x3f) {
|
|
|
|
gain = 0x3f;
|
|
|
|
}
|
|
|
|
|
|
|
|
led1642gw_set_gain(gain);
|
|
|
|
led1642gw_flush_config();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void led_set_current_mode(uint8_t mode)
|
|
|
|
{
|
|
|
|
led1642gw_set_current_mode(mode);
|
|
|
|
led1642gw_flush_config();
|
|
|
|
}
|
|
|
|
|
|
|
|
|