Browse Source

split democode stuff

master
Olaf Rempel 8 years ago
parent
commit
8d8a50a4f7
7 changed files with 332 additions and 138 deletions
  1. +162
    -0
      democode.c
  2. +124
    -0
      demohelper.c
  3. +2
    -2
      eeprom.c
  4. +17
    -124
      main.c
  5. +1
    -1
      mpmctrl.c
  6. +22
    -3
      rgb16mpm.h
  7. +4
    -8
      rgbctrl.c

+ 162
- 0
democode.c View 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
- 0
demohelper.c View 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;
}
}
}

+ 2
- 2
eeprom.c View File

@@ -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();
}


+ 17
- 124
main.c View File

@@ -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();

sei();

uint8_t x = 0;
uint8_t xdir = 1;
uint16_t ramp = 0;
demomode_init(nvram_data.demomode);

/* wait for complete update */
rgb_update(COLOR_MASK, 1);
sei();

uint16_t wait = 0;
while (1) {
mpm_check_transfer();

/* wait for complete update */
rgb_update(COLOR_MASK, 1);

_delay_ms(50);
/* no delay or timeout reached */
if (wait == 0 || (TIFR & (1<<TOV1))) {
TIFR = (1<<TOV1);

#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]);
/* execute periodic democode */
wait = demomode_run();
rgb_update(COLOR_MASK, UPDATE_BLOCKING);

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
}
}

+ 1
- 1
mpmctrl.c View File

@@ -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();


+ 22
- 3
rgb16mpm.h View File

@@ -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_ */

+ 4
- 8
rgbctrl.c View File

@@ -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…
Cancel
Save