Add pattern ioctl for RGBLED

This commit is contained in:
Julian Oes
2013-08-16 18:04:24 +02:00
parent 1d7b8bb565
commit af3e0d459a
2 changed files with 54 additions and 13 deletions
+13 -2
View File
@@ -72,9 +72,12 @@
/** set color */ /** set color */
#define RGBLED_SET_COLOR _RGBLEDIOC(5) #define RGBLED_SET_COLOR _RGBLEDIOC(5)
/** set blink pattern and speed */ /** set blink speed */
#define RGBLED_SET_MODE _RGBLEDIOC(6) #define RGBLED_SET_MODE _RGBLEDIOC(6)
/** set pattern */
#define RGBLED_SET_PATTERN _RGBLEDIOC(7)
/* /*
structure passed to RGBLED_SET_RGB ioctl() structure passed to RGBLED_SET_RGB ioctl()
Note that the driver scales the brightness to 0 to 255, regardless Note that the driver scales the brightness to 0 to 255, regardless
@@ -104,5 +107,13 @@ typedef enum {
RGBLED_MODE_ON, RGBLED_MODE_ON,
RGBLED_MODE_BLINK_SLOW, RGBLED_MODE_BLINK_SLOW,
RGBLED_MODE_BLINK_NORMAL, RGBLED_MODE_BLINK_NORMAL,
RGBLED_MODE_BLINK_FAST RGBLED_MODE_BLINK_FAST,
RGBLED_MODE_PATTERN
} rgbled_mode_t; } rgbled_mode_t;
#define RGBLED_PATTERN_LENGTH 20
typedef struct {
rgbled_color_t color[RGBLED_PATTERN_LENGTH];
unsigned duration[RGBLED_PATTERN_LENGTH];
} rgbled_pattern_t;
+41 -11
View File
@@ -92,8 +92,9 @@ public:
private: private:
work_s _work; work_s _work;
rgbled_color_t _colors[8]; rgbled_color_t _color;
rgbled_mode_t _mode; rgbled_mode_t _mode;
rgbled_pattern_t _pattern;
bool _should_run; bool _should_run;
bool _running; bool _running;
@@ -102,6 +103,7 @@ private:
void set_color(rgbled_color_t ledcolor); void set_color(rgbled_color_t ledcolor);
void set_mode(rgbled_mode_t mode); void set_mode(rgbled_mode_t mode);
void set_pattern(rgbled_pattern_t *pattern);
static void led_trampoline(void *arg); static void led_trampoline(void *arg);
void led(); void led();
@@ -123,13 +125,14 @@ extern "C" __EXPORT int rgbled_main(int argc, char *argv[]);
RGBLED::RGBLED(int bus, int rgbled) : RGBLED::RGBLED(int bus, int rgbled) :
I2C("rgbled", RGBLED_DEVICE_PATH, bus, rgbled, 100000), I2C("rgbled", RGBLED_DEVICE_PATH, bus, rgbled, 100000),
_colors({RGBLED_COLOR_OFF,RGBLED_COLOR_OFF,RGBLED_COLOR_OFF,RGBLED_COLOR_OFF,RGBLED_COLOR_OFF,RGBLED_COLOR_OFF,RGBLED_COLOR_OFF,RGBLED_COLOR_OFF}), _color(RGBLED_COLOR_OFF),
_mode(RGBLED_MODE_OFF), _mode(RGBLED_MODE_OFF),
_running(false), _running(false),
_led_interval(0), _led_interval(0),
_counter(0) _counter(0)
{ {
memset(&_work, 0, sizeof(_work)); memset(&_work, 0, sizeof(_work));
memset(&_pattern, 0, sizeof(_pattern));
} }
RGBLED::~RGBLED() RGBLED::~RGBLED()
@@ -204,10 +207,14 @@ RGBLED::ioctl(struct file *filp, int cmd, unsigned long arg)
return OK; return OK;
case RGBLED_SET_MODE: case RGBLED_SET_MODE:
/* set the specified blink pattern/speed */ /* set the specified blink speed */
set_mode((rgbled_mode_t)arg); set_mode((rgbled_mode_t)arg);
return OK; return OK;
case RGBLED_SET_PATTERN:
/* set a special pattern */
set_pattern((rgbled_pattern_t*)arg);
return OK;
default: default:
break; break;
@@ -239,6 +246,14 @@ RGBLED::led()
else else
set_on(false); set_on(false);
break; break;
case RGBLED_MODE_PATTERN:
/* don't run out of the pattern array and stop if the next frame is 0 */
if (_counter >= RGBLED_PATTERN_LENGTH || _pattern.duration[_counter] <= 0)
_counter = 0;
set_color(_pattern.color[_counter]);
_led_interval = _pattern.duration[_counter];
break;
default: default:
break; break;
} }
@@ -251,6 +266,9 @@ RGBLED::led()
void void
RGBLED::set_color(rgbled_color_t color) { RGBLED::set_color(rgbled_color_t color) {
_color = color;
switch (color) { switch (color) {
case RGBLED_COLOR_OFF: // off case RGBLED_COLOR_OFF: // off
set_rgb(0,0,0); set_rgb(0,0,0);
@@ -302,11 +320,16 @@ RGBLED::set_mode(rgbled_mode_t mode)
break; break;
case RGBLED_MODE_BLINK_NORMAL: case RGBLED_MODE_BLINK_NORMAL:
_should_run = true; _should_run = true;
_led_interval = 1000; _led_interval = 500;
break; break;
case RGBLED_MODE_BLINK_FAST: case RGBLED_MODE_BLINK_FAST:
_should_run = true; _should_run = true;
_led_interval = 500; _led_interval = 100;
break;
case RGBLED_MODE_PATTERN:
_should_run = true;
set_on(true);
_counter = 0;
break; break;
default: default:
warnx("mode unknown"); warnx("mode unknown");
@@ -325,6 +348,14 @@ RGBLED::set_mode(rgbled_mode_t mode)
} }
} }
void
RGBLED::set_pattern(rgbled_pattern_t *pattern)
{
memcpy(&_pattern, pattern, sizeof(rgbled_pattern_t));
set_mode(RGBLED_MODE_PATTERN);
}
int int
RGBLED::set(bool on, uint8_t r, uint8_t g, uint8_t b) RGBLED::set(bool on, uint8_t r, uint8_t g, uint8_t b)
{ {
@@ -467,13 +498,12 @@ rgbled_main(int argc, char *argv[])
if (fd == -1) { if (fd == -1) {
errx(1, "Unable to open " RGBLED_DEVICE_PATH); errx(1, "Unable to open " RGBLED_DEVICE_PATH);
} }
ret = ioctl(fd, RGBLED_SET_COLOR, (unsigned long)RGBLED_COLOR_WHITE);
if(ret != OK) { rgbled_pattern_t pattern = { {RGBLED_COLOR_RED, RGBLED_COLOR_GREEN, RGBLED_COLOR_BLUE, RGBLED_COLOR_OFF},
close(fd); {200, 200, 200, 400 } };
exit(ret);
} ret = ioctl(fd, RGBLED_SET_PATTERN, (unsigned long)&pattern);
ret = ioctl(fd, RGBLED_SET_MODE, (unsigned long)RGBLED_MODE_BLINK_NORMAL);
close(fd); close(fd);
exit(ret); exit(ret);
} }