Lightness correction for RGB LED driver

This commit is contained in:
Jeff 2017-07-28 06:54:06 -06:00 committed by Gregory Nutt
parent b458934ac4
commit 7f8f833714
1 changed files with 69 additions and 2 deletions

View File

@ -1,7 +1,7 @@
/****************************************************************************
* drivers/rgbled.c
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Copyright (C) 2016-2017 Gregory Nutt. All rights reserved.
* Author: Alan Carvalho de Assis <acassis@gmail.com>
*
* Redistribution and use in source and binary forms, with or without
@ -107,6 +107,9 @@ static const struct file_operations g_rgbledops =
#ifndef CONFIG_DISABLE_POLL
, 0 /* poll */
#endif
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
, 0 /* unlink */
#endif
};
/****************************************************************************
@ -222,11 +225,65 @@ static ssize_t rgbled_read(FAR struct file *filep, FAR char *buffer,
return 0;
}
/****************************************************************************
* Name: rgbled_lightness
*
* Description:
* Convert an 8-bit color level to a 16-bit PWM command, using a
* piecewise linear approximation of the CIE 1931 lightness formula.
*
****************************************************************************/
#ifdef CONFIG_RGBLED_LIGHTNESS_CORRECTION
static unsigned short rgbled_lightness(unsigned char color_level)
{
unsigned int lut_index;
unsigned short pwm_cmd = 0;
static const unsigned char lut_color_in[9] =
{
0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xc0, 0xe0, 0xff
};
static const unsigned short lut_pwm_out[9] =
{
0x0000, 0x03d1, 0x0b62, 0x1952, 0x2f93,
0x5015, 0x7ccb, 0xb7a7, 0xffff
};
for (lut_index = 0; lut_index < sizeof(lut_color_in); ++lut_index)
{
if (lut_color_in[lut_index] >= color_level)
{
break;
}
}
if (lut_index < sizeof(lut_color_in))
{
if (lut_color_in[lut_index] == color_level)
{
pwm_cmd = lut_pwm_out[lut_index];
}
else
{
pwm_cmd = (unsigned short)(lut_pwm_out[lut_index - 1] +
(int)(lut_pwm_out[lut_index] - lut_pwm_out[lut_index - 1]) *
(int)(color_level - lut_color_in[lut_index - 1]) /
(int)(lut_color_in[lut_index] - lut_color_in[lut_index - 1]));
}
}
return pwm_cmd;
}
#endif /* CONFIG_RGBLED_LIGHTNESS_CORRECTION */
/****************************************************************************
* Name: rgbled_write
*
* Description:
* A dummy write method. This is provided only to satisfy the VFS layer.
* A write method which parses an HTML-style RGB string like "#FF8833"
* into color values, and sends them to the lower-half PWM drivers.
*
****************************************************************************/
@ -304,10 +361,20 @@ static ssize_t rgbled_write(FAR struct file *filep, FAR const char *buffer,
/* Convert 8bit to 16bits */
#ifdef CONFIG_RGBLED_LIGHTNESS_CORRECTION
red = rgbled_lightness((unsigned char)red);
green = rgbled_lightness((unsigned char)green);
blue = rgbled_lightness((unsigned char)blue);
#else
red = (red << 8) | red;
green = (green << 8) | green;
blue = (blue << 8) | blue;
#endif
#ifdef CONFIG_RGBLED_INVERT
red ^= 0xffff;
green ^= 0xffff;