From e7d05bc6b2ad3c4d3d12536089bb3d1259b03344 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Sat, 8 Sep 2012 22:58:54 +0200 Subject: add sequencer mode --- command.c | 42 ++++++++++++++++++++++++++--- moodlamp.c | 10 ++++--- sequencer.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ sequencer.h | 28 ++++++++++++++++++++ 4 files changed, 159 insertions(+), 8 deletions(-) create mode 100644 sequencer.c create mode 100644 sequencer.h diff --git a/command.c b/command.c index 0212ce9..8e0cc15 100644 --- a/command.c +++ b/command.c @@ -22,6 +22,7 @@ #include "pwm.h" #include "serial.h" +#include "sequencer.h" #include "util.h" #include "shiftbrite.h" @@ -50,20 +51,49 @@ static void handle_immediate(char *buffer, uint16_t len) command_error(); return; } - + + sequencer_disable(); uint8_t sb_no; if ((len > sizeof("irrggbb\r") - 1) && parse_hex_number(&buffer[7], &sb_no)==0 && sb_no) { sb_setcolor(sb_no-1, new_red, new_green, new_blue); command_success(); - } - else { + } else { pwm_set_rgb(new_red, new_green, new_blue); command_success(); - } + } } +static void handle_sequence(char *buffer, uint16_t len) +{ + uint8_t steps = 0; + + buffer += 1; + len -= 1; + + while (len >= 10) { + uint8_t tout, lamp, new_red, new_blue, new_green; + + if (parse_hex_number(&buffer[0], &tout) + || parse_hex_number(&buffer[2], &lamp) + || parse_hex_number(&buffer[4], &new_red) + || parse_hex_number(&buffer[6], &new_blue) + || parse_hex_number(&buffer[8], &new_green)) { + command_error(); + return; + } + + sequencer_set(steps, tout, lamp, new_red, new_blue, new_green); + steps += 1; + buffer += 10; + len -= 10; + } + sequencer_len(steps); + sequencer_enable(); +} + + uint16_t serial_rx_cb(char *buffer, uint16_t len) { switch (buffer[len - 1]) { @@ -86,6 +116,10 @@ uint16_t serial_rx_cb(char *buffer, uint16_t len) serial_toggle_verbose(); command_success(); break; + case 's': + case 'S': + handle_sequence(buffer, len); + break; default: command_error(); } diff --git a/moodlamp.c b/moodlamp.c index 47e7bdd..a6fa77a 100644 --- a/moodlamp.c +++ b/moodlamp.c @@ -22,6 +22,7 @@ #include "serial.h" #include "pwm.h" #include "shiftbrite.h" +#include "sequencer.h" int main(void) { @@ -30,8 +31,9 @@ int main(void) sb_init(); sei(); - for (;;) { - pwm_tick(); - sb_tick(); - } + for (;;) { + pwm_tick(); + sb_tick(); + sequencer_tick(); + } } diff --git a/sequencer.c b/sequencer.c new file mode 100644 index 0000000..f3b9d85 --- /dev/null +++ b/sequencer.c @@ -0,0 +1,87 @@ +/* + * Copyright 2012 (C) Christian Franke + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with This program. If not, see . + * + */ +#include + +#include "sequencer.h" +#include "pwm.h" +#include "shiftbrite.h" + +struct sequencer_entry { + uint8_t len; + uint8_t lamp; + uint8_t red; + uint8_t blue; + uint8_t green; +}; + +volatile static uint8_t seq_enabled = 0; /* whether to process sequencer or not */ +volatile static uint8_t seq_pos; /* pending slot to execute */ +volatile static uint8_t seq_timeout; /* timeout for progress to next slot */ + +volatile static struct sequencer_entry seq_slots[64]; /* the actual slots */ +volatile static uint8_t seq_len; /* the number of slots */ + +static void sequencer_progress(uint8_t pos) +{ + if (seq_slots[pos].lamp) { + sb_setcolor(seq_slots[pos].lamp - 1, seq_slots[pos].red, + seq_slots[pos].green, seq_slots[pos].blue); + } else { + pwm_set_rgb(seq_slots[pos].red, seq_slots[pos].green, + seq_slots[pos].blue); + } + seq_timeout = seq_slots[pos].len; + seq_pos = pos + 1; + if (seq_pos >= seq_len) + seq_pos = 0; +} + +void sequencer_set(uint8_t step, uint8_t len, uint8_t lamp, + uint8_t r, uint8_t g, uint8_t b) +{ + if (step >= 64) + return; + seq_slots[step].len = len; + seq_slots[step].lamp = lamp; + seq_slots[step].red = r; + seq_slots[step].green = g; + seq_slots[step].blue = b; +} + +void sequencer_len(uint8_t len) +{ + seq_len = len; +} + +void sequencer_enable(void) +{ + sequencer_progress(0); + seq_enabled = 1; +} + +void sequencer_disable(void) +{ + seq_enabled = 0; +} + +void sequencer_tick(void) +{ + while (seq_enabled && !(--seq_timeout)) { + sequencer_progress(seq_pos); + } +} diff --git a/sequencer.h b/sequencer.h new file mode 100644 index 0000000..c6c5612 --- /dev/null +++ b/sequencer.h @@ -0,0 +1,28 @@ +/* + * Copyright 2012 (C) Christian Franke + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with This program. If not, see . + * + */ +#ifndef SEQUENCER_H +#define SEQUENCER_H + +void sequencer_set(uint8_t step, uint8_t len, uint8_t lamp, + uint8_t r, uint8_t g, uint8_t b); +void sequencer_len(uint8_t len); +void sequencer_enable(void); +void sequencer_disable(void); +void sequencer_tick(void); + +#endif -- cgit v1.2.1