split democode stuff
This commit is contained in:
parent
d2e2bb1695
commit
8d8a50a4f7
162
democode.c
Normal file
162
democode.c
Normal file
@ -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 <stdint.h>
|
||||
#include <string.h>
|
||||
#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;
|
||||
}
|
||||
}
|
124
demohelper.c
Normal file
124
demohelper.c
Normal file
@ -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 <stdint.h>
|
||||
#include <string.h>
|
||||
#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<<value) & mask) || value == old_value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
uint16_t color_ramp(uint16_t value, uint8_t *color)
|
||||
{
|
||||
uint8_t col1 = (value & 0xFF);
|
||||
uint8_t col2 = 0xFF - col1;
|
||||
|
||||
switch (value >> 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;
|
||||
}
|
||||
}
|
||||
}
|
4
eeprom.c
4
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();
|
||||
}
|
||||
|
141
main.c
141
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<<value) & mask) || value == old_value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
uint16_t color_ramp(uint16_t value, uint8_t *color)
|
||||
{
|
||||
uint8_t col1 = (value & 0xFF);
|
||||
uint8_t col2 = 0xFF - col1;
|
||||
|
||||
switch (value >> 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<<LED);
|
||||
PORTD = (1<<LED);
|
||||
|
||||
eeprom_read();
|
||||
/* timer1: FCPU/1024 */
|
||||
TCCR1B = (1<<CS12) | (1<<CS10);
|
||||
TCNT1 = 0x0000;
|
||||
|
||||
eeprom_read(1);
|
||||
rgb_init();
|
||||
mpm_init();
|
||||
|
||||
demomode_init(nvram_data.demomode);
|
||||
|
||||
sei();
|
||||
|
||||
uint8_t x = 0;
|
||||
uint8_t xdir = 1;
|
||||
uint16_t ramp = 0;
|
||||
|
||||
/* wait for complete update */
|
||||
rgb_update(COLOR_MASK, 1);
|
||||
|
||||
uint16_t wait = 0;
|
||||
while (1) {
|
||||
mpm_check_transfer();
|
||||
|
||||
/* wait for complete update */
|
||||
rgb_update(COLOR_MASK, 1);
|
||||
/* no delay or timeout reached */
|
||||
if (wait == 0 || (TIFR & (1<<TOV1))) {
|
||||
TIFR = (1<<TOV1);
|
||||
|
||||
_delay_ms(50);
|
||||
/* execute periodic democode */
|
||||
wait = demomode_run();
|
||||
rgb_update(COLOR_MASK, UPDATE_BLOCKING);
|
||||
|
||||
#if 1
|
||||
x = sequence_chase(x, &xdir, 0x1F1F);
|
||||
ramp = color_ramp(ramp +8, chan_value[x]);
|
||||
color_div(chan_value[x], 4, chan_decay[x]);
|
||||
|
||||
uint8_t i;
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (x != i) {
|
||||
color_sub(chan_value[i], chan_decay[i], chan_value[i]);
|
||||
if (wait > 0) {
|
||||
/* x * 8 / (8MHz/1024) */
|
||||
TCNT1 = 0xFFFF - (wait << 3);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
25
rgb16mpm.h
25
rgb16mpm.h
@ -2,7 +2,7 @@
|
||||
#define _RGB16MPM_H_
|
||||
|
||||
#define F_CPU 8000000
|
||||
#include <util/delay.h>
|
||||
//#include <util/delay.h>
|
||||
|
||||
#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_ */
|
||||
|
12
rgbctrl.c
12
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<<COLOR_RED)) && (nextColor == COLOR_BLUE)) {
|
||||
calculate_timer_values(COLOR_RED);
|
||||
chan_dirty &= ~(1<<COLOR_RED);
|
||||
@ -281,11 +281,10 @@ uint8_t rgb_update(uint8_t dirty_mask, uint8_t blocking)
|
||||
calculate_timer_values(COLOR_BLUE);
|
||||
chan_dirty &= ~(1<<COLOR_BLUE);
|
||||
|
||||
} else if (!blocking) {
|
||||
} else if (update_mode != UPDATE_BLOCKING) {
|
||||
break;
|
||||
}
|
||||
|
||||
} while (chan_dirty);
|
||||
};
|
||||
|
||||
return chan_dirty;
|
||||
}
|
||||
@ -306,8 +305,5 @@ void rgb_init(void)
|
||||
/* timer0, FCPU/64, overflow interrupt */
|
||||
TCCR0 = (1<<CS01) | (1<<CS00); /* FCPU/64 */
|
||||
TIMSK = (1<<TOIE0);
|
||||
|
||||
/* load initial values from eeprom */
|
||||
memcpy(chan_value, nvram_data.initialRGB, sizeof(chan_value));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user