From 8d8a50a4f7800333d1afe4c750809ed69b4c091f Mon Sep 17 00:00:00 2001 From: Olaf Rempel Date: Sun, 11 Mar 2012 15:49:41 +0100 Subject: [PATCH] split democode stuff --- democode.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++ demohelper.c | 124 +++++++++++++++++++++++++++++++++++++++ eeprom.c | 4 +- main.c | 141 ++++++-------------------------------------- mpmctrl.c | 2 +- rgb16mpm.h | 25 +++++++- rgbctrl.c | 12 ++-- 7 files changed, 332 insertions(+), 138 deletions(-) create mode 100644 democode.c create mode 100644 demohelper.c diff --git a/democode.c b/democode.c new file mode 100644 index 0000000..e79b16c --- /dev/null +++ b/democode.c @@ -0,0 +1,162 @@ +/*************************************************************************** + * some RGB demo modes * + * * + * Copyright (C) 2011 - 2012 by Olaf Rempel * + * razzor AT kopf MINUS tisch DOT de * + * * + * 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; version 2 of the License, * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include +#include +#include "rgb16mpm.h" + +struct dm001data { + uint8_t pos; + uint8_t dir; + uint16_t ramp; + uint8_t decay[16][3]; +}; + +struct dm002data { + uint16_t ramp; +}; + +struct dm003data { + uint8_t step; + uint8_t pos[3]; + uint8_t dir[3]; +}; + +union demodata { + struct dm001data dm001; + struct dm002data dm002; + struct dm003data dm003; +}; + +static union demodata demo; + +static uint16_t demomode000(void) +{ + return 0; +} + +static uint16_t demomode001(void) +{ + struct dm001data *dm = &demo.dm001; + + dm->pos = sequence_chase(dm->pos, &dm->dir, nvram_data.channels); + dm->ramp = color_ramp(dm->ramp +8, chan_value[dm->pos]); + color_div(chan_value[dm->pos], 4, dm->decay[dm->pos]); + + uint8_t chan; + for (chan = 0; chan < 16; chan++) { + if (chan != dm->pos) { + color_sub(chan_value[chan], dm->decay[chan], chan_value[chan]); + } + } + + return 50; +} + +static uint16_t demomode002(void) +{ + struct dm002data *dm = &demo.dm002; + + uint8_t color[3]; + dm->ramp = color_ramp(dm->ramp +1, color); + + uint8_t chan; + for (chan = 0; chan < 16; chan++) { + chan_value[chan][COLOR_RED] = color[COLOR_RED]; + chan_value[chan][COLOR_GREEN] = color[COLOR_GREEN]; + chan_value[chan][COLOR_BLUE] = color[COLOR_BLUE]; + } + + return 0; +} + +static uint16_t demomode003(void) +{ + struct dm003data *dm = &demo.dm003; + + uint8_t color; + + dm->step++; + if (dm->step == 2) { + dm->step = 0; + } + + for (color = 0; color < 3; color++) { + if (dm->step == 0) { + dm->pos[color] = sequence_chase(dm->pos[color], &dm->dir[color], nvram_data.channels); + } + + uint8_t chan; + for (chan = 0; chan < 16; chan++) { + if (chan == dm->pos[color]) { + chan_value[chan][color] = 0xFF; + } else if (chan_value[chan][color] > 16) { + chan_value[chan][color] -= 16; + } else { + chan_value[chan][color] = 0; + } + } + } + + return 50; +} + +uint16_t (* demomode_run)(void) = demomode000; + +void demomode_init(uint8_t mode) +{ + memset(&demo, 0x00, sizeof(union demodata)); + memset(chan_value, 0x00, sizeof(chan_value)); + + switch (mode) { + case 0x00: + /* load initial values from eeprom */ + memcpy(chan_value, nvram_data.initialRGB, sizeof(chan_value)); + demomode_run = demomode000; + break; + + case 0x01: + /* rgb chase */ + demo.dm001.dir = 1; + demomode_run = demomode001; + break; + + case 0x02: + /* one color, all channes, rgb fader */ + demomode_run = demomode002; + break; + + case 0x03: + /* three color chaser */ + demo.dm003.pos[COLOR_RED] = 0; + demo.dm003.pos[COLOR_GREEN] = 9; + demo.dm003.pos[COLOR_BLUE] = 9; + demo.dm003.dir[COLOR_RED] = 1; + demo.dm003.dir[COLOR_GREEN] = 1; + demo.dm003.dir[COLOR_BLUE] = 0; + demomode_run = demomode003; + break; + + default: + /* stay black */ + demomode_run = demomode000; + break; + } +} diff --git a/demohelper.c b/demohelper.c new file mode 100644 index 0000000..0e98918 --- /dev/null +++ b/demohelper.c @@ -0,0 +1,124 @@ +/*************************************************************************** + * helper functions for demo modes * + * * + * Copyright (C) 2011 - 2012 by Olaf Rempel * + * razzor AT kopf MINUS tisch DOT de * + * * + * 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; version 2 of the License, * + * * + * 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, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include +#include +#include "rgb16mpm.h" + +uint8_t sequence_chase(uint8_t old_value, uint8_t *dir, uint16_t mask) +{ + uint8_t value = old_value; + + do { + value = (*dir) ? value +1 : value -1; + value &= 0x0F; + + if (value == 0x00 || value == 0x0F) { + *dir = (value == 0x00); + } + + } while (!((1<> 8) { + default: + value = 0x0000; + /* no break */ + + case 0: /* red: on, green: ramp up, blue: off */ + color[0] = 0xFF; + color[1] = col1; + color[2] = 0x00; + break; + + case 1: /* red: ramp down, green: on, blue:off */ + color[0] = col2; + color[1] = 0xFF; + color[2] = 0x00; + break; + + case 2: /* red: off, green: on, blue: ramp up */ + color[0] = 0x00; + color[1] = 0xFF; + color[2] = col1; + break; + + case 3: /* red: off, green: ramp down: blue: on */ + color[0] = 0x00; + color[1] = col2; + color[2] = 0xFF; + break; + + case 4: /* red: ramp up, green: off, blue: on */ + color[0] = col1; + color[1] = 0x00; + color[2] = 0xFF; + break; + + case 5: /* red: on, green: off, blue: ramp down */ + color[0] = 0xFF; + color[1] = 0x00; + color[2] = col2; + break; + } + + return value; +} + +void color_add(uint8_t *color1, uint8_t *color2, uint8_t *output) +{ + uint8_t i; + for (i = 0; i < 3; i++) { + uint16_t tmp = color1[i] + color2[i]; + output[i] = (tmp & 0xFF00) ? 0xFF : tmp; + } +} + +void color_sub(uint8_t *color1, uint8_t *color2, uint8_t *output) +{ + uint8_t i; + for (i = 0; i < 3; i++) { + uint16_t tmp = color1[i] - color2[i]; + output[i] = (tmp & 0xFF00) ? 0x00 : tmp; + } +} + +void color_div(uint8_t *color, uint8_t div, uint8_t *output) +{ + uint8_t i; + for (i = 0; i < 3; i++) { + if (color[i] != 0) { + output[i] = color[i] / div; + if (output[i] == 0) { + output[i] = 0x01; + } + + } else { + output[i] = 0x00; + } + } +} diff --git a/eeprom.c b/eeprom.c index 87dc6c8..c3e2d6d 100644 --- a/eeprom.c +++ b/eeprom.c @@ -77,7 +77,7 @@ void eeprom_write(void) } /* read nvram from eeprom and check crc */ -void eeprom_read(void) +void eeprom_read(uint8_t defaults) { uint8_t i; uint16_t crc = 0x0000; @@ -90,7 +90,7 @@ void eeprom_read(void) } /* if nvram content is invalid, overwrite with defaults */ - if ((nvram_data.nvram_size != sizeof(struct _nvdata)) || (crc != 0x0000)) { + if ((nvram_data.nvram_size != sizeof(struct _nvdata)) || (crc != 0x0000) || defaults) { memcpy_P(&nvram_data, &nvram_defaults, sizeof(struct _nvdata)); eeprom_write(); } diff --git a/main.c b/main.c index d963b6c..34ee291 100644 --- a/main.c +++ b/main.c @@ -41,147 +41,40 @@ * PD3 -> /LED */ -uint8_t sequence_chase(uint8_t old_value, uint8_t *dir, uint16_t mask) -{ - uint8_t value = old_value; - - do { - value = (*dir) ? value +1 : value -1; - value &= 0x0F; - - if (value == 0x00 || value == 0x0F) { - *dir = (value == 0x00); - } - - } while (!((1<> 8) { - default: - value = 0x0000; - /* no break */ - - case 0: /* red: on, green: ramp up, blue: off */ - color[0] = 0xFF; - color[1] = col1; - color[2] = 0x00; - break; - - case 1: /* red: ramp down, green: on, blue:off */ - color[0] = col2; - color[1] = 0xFF; - color[2] = 0x00; - break; - - case 2: /* red: off, green: on, blue: ramp up */ - color[0] = 0x00; - color[1] = 0xFF; - color[2] = col1; - break; - - case 3: /* red: off, green: ramp down: blue: on */ - color[0] = 0x00; - color[1] = col2; - color[2] = 0xFF; - break; - - case 4: /* red: ramp up, green: off, blue: on */ - color[0] = col1; - color[1] = 0x00; - color[2] = 0xFF; - break; - - case 5: /* red: on, green: off, blue: ramp down */ - color[0] = 0xFF; - color[1] = 0x00; - color[2] = col2; - break; - } - - return value; -} - -void color_add(uint8_t *color1, uint8_t *color2, uint8_t *output) -{ - uint8_t i; - for (i = 0; i < 3; i++) { - uint16_t tmp = color1[i] + color2[i]; - output[i] = (tmp & 0xFF00) ? 0xFF : tmp; - } -} - -void color_sub(uint8_t *color1, uint8_t *color2, uint8_t *output) -{ - uint8_t i; - for (i = 0; i < 3; i++) { - uint16_t tmp = color1[i] - color2[i]; - output[i] = (tmp & 0xFF00) ? 0x00 : tmp; - } -} - -void color_div(uint8_t *color, uint8_t div, uint8_t *output) -{ - uint8_t i; - for (i = 0; i < 3; i++) { - if (color[i] != 0) { - output[i] = color[i] / div; - if (output[i] == 0) { - output[i] = 0x01; - } - - } else { - output[i] = 0x00; - } - } -} - -static uint8_t chan_decay[16][3]; - int main(void) __attribute__ ((noreturn)); int main(void) { DDRD = (1< 0) { + /* x * 8 / (8MHz/1024) */ + TCNT1 = 0xFFFF - (wait << 3); } } -#endif } } diff --git a/mpmctrl.c b/mpmctrl.c index b5ad055..af17be8 100644 --- a/mpmctrl.c +++ b/mpmctrl.c @@ -234,7 +234,7 @@ void mpm_check_transfer(void) mpm_reply(rx_cmd, cause, 0, NULL); if (rx_cmd == CMD_WRITE_RAW_COLOR) { - rgb_update(COLOR_MASK, 1); + rgb_update(COLOR_MASK, UPDATE_BLOCKING); } else { eeprom_write(); diff --git a/rgb16mpm.h b/rgb16mpm.h index a4214cc..dd47ac6 100644 --- a/rgb16mpm.h +++ b/rgb16mpm.h @@ -2,7 +2,7 @@ #define _RGB16MPM_H_ #define F_CPU 8000000 -#include +//#include #define ROW1 PORTB1 /* RED */ #define ROW2 PORTB0 /* GREEN */ @@ -30,16 +30,20 @@ struct _nvdata { uint16_t nvram_size; /* first */ + uint16_t channels; /* connected channels */ uint8_t initialRGB[16][3]; /* initial color values */ + uint8_t demomode; /* initial demo mode */ uint16_t nvram_crc; /* last */ }; #define NVRAM_DEFAULTS {\ + .channels = 0x1F1F, \ .initialRGB = { { 0xFF, 0x00, 0x00 }, { 0xFF, 0x80, 0x00 }, { 0xFF, 0xFF, 0x00 }, { 0x80, 0xFF, 0x00 }, \ { 0x00, 0xFF, 0x00 }, { 0x00, 0xFF, 0x80 }, { 0x00, 0xFF, 0xFF }, { 0x00, 0x80, 0xFF }, \ { 0x00, 0x00, 0xFF }, { 0x80, 0x00, 0xFF }, { 0xFF, 0x00, 0xFF }, { 0xFF, 0x00, 0x80 }, \ { 0x20, 0x20, 0x20 }, { 0x40, 0x40, 0x40 }, { 0x80, 0x80, 0x80 }, { 0xFF, 0xFF, 0xFF } \ }, \ + .demomode = 0x03, \ }; /* eeprom.c vars */ @@ -47,7 +51,18 @@ extern struct _nvdata nvram_data; /* eeprom.c funcs */ void eeprom_write(void); -void eeprom_read(void); +void eeprom_read(uint8_t defaults); + +/* democode.c funcs */ +void demomode_init(uint8_t mode); +extern uint16_t (*demomode_run)(void); + +/* demohelper.c funcs */ +uint8_t sequence_chase(uint8_t old_value, uint8_t *dir, uint16_t mask); +uint16_t color_ramp(uint16_t value, uint8_t *color); +void color_add(uint8_t *color1, uint8_t *color2, uint8_t *output); +void color_sub(uint8_t *color1, uint8_t *color2, uint8_t *output); +void color_div(uint8_t *color, uint8_t div, uint8_t *output); /* mpmctrl.c funcs */ void mpm_init(void); @@ -58,6 +73,10 @@ extern uint8_t chan_value[16][3]; /* rgbctrl.c funcs */ void rgb_init(void); -uint8_t rgb_update(uint8_t dirty_mask, uint8_t blocking); +uint8_t rgb_update(uint8_t dirty_mask, uint8_t update_mode); + +#define UPDATE_NONE 0x00 +#define UPDATE_PARTIAL 0x01 +#define UPDATE_BLOCKING 0x02 #endif /* _RGB16MPM_H_ */ diff --git a/rgbctrl.c b/rgbctrl.c index a64bcf6..ac5f963 100644 --- a/rgbctrl.c +++ b/rgbctrl.c @@ -262,13 +262,13 @@ static void calculate_timer_values(uint8_t color) *pData++ = ((chan_init >> 8) & 0xFF); /* PORTC */ } -uint8_t rgb_update(uint8_t dirty_mask, uint8_t blocking) +uint8_t rgb_update(uint8_t dirty_mask, uint8_t update_mode) { static uint8_t chan_dirty; chan_dirty |= (dirty_mask & COLOR_MASK); - do { + while ((chan_dirty != 0) && (update_mode != UPDATE_NONE)) { if ((chan_dirty & (1<