rgbyteclock-code/ledcontroller.c

241 lines
4.7 KiB
C
Raw Permalink Normal View History

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
/*
* 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
}
/*
* 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);
}
/*
* 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-18 01:04:18 +01:00
led1642gw_flush();
}
/*
* 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-18 01:04:18 +01:00
led1642gw_clear();
}
/*
* Initialize the leddriver.
* Must be called before any other function in this module.
*/
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
}
/*
* 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-18 01:04:18 +01:00
led1642gw_turn_all_on();
}
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();
}