diff options
-rw-r--r-- | shiftbrite.c | 141 | ||||
-rw-r--r-- | shiftbrite.h | 5 |
2 files changed, 146 insertions, 0 deletions
diff --git a/shiftbrite.c b/shiftbrite.c new file mode 100644 index 0000000..5cc5b82 --- /dev/null +++ b/shiftbrite.c @@ -0,0 +1,141 @@ +/* + * Simple ShiftBrite interface code for remoodlamp firmware + * Copyright 2012 (C) Johannes Kroll <jkroll at lavabit com> + * + * 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 <http://www.gnu.org/licenses/>. + * + */ + +#include <avr/interrupt.h> +#include <avr/io.h> +#include <stdint.h> +#include <string.h> +#include <util/delay.h> + +// shiftbrites connected to header labeled as 'aux', setup: +// PC0 -> CI (clock) +// PC1 -> LI (latch) +// PC2 -> DI (data) + +#define SBCI PC0 +#define SBLI PC1 +#define SBDI PC2 + +#define MAXSHIFTBRITES 16 + + +typedef struct rgb +{ + uint16_t r, g, b; // 10-bit values +} rgb_t; + +static volatile rgb_t sb_colors[MAXSHIFTBRITES]; + +// number of connected shiftbrites +// todo: create a command to make this value configurable +static volatile uint8_t sb_num_shiftbrites= 3; + +// toggle the latch so the shiftbrites accept new values +static void sb_toggle_latch(void) +{ + _delay_us(15); + PORTC|= (1<<PC1); + _delay_us(15); + PORTC&= ~(1<<PC1); +} + +// shift out one 32-bit shiftbrite register. +static void sb_shiftout(uint32_t val) +{ + //const unsigned clkdelay= 2; + for(int8_t i= 31; i>=0; i--) { + //_delay_us(clkdelay); + PORTC&= ~(1<<PC0); // clock lo + if((val>>i)&1) + PORTC|= (1<<PC2); // data bit + else + PORTC&= ~(1<<PC2); + //_delay_us(clkdelay); + PORTC|= (1<<PC0); // clock hi + } +} + +// shift out all color values to connected shiftbrites +static void sb_update_all_colors(void) +{ + for(int i= sb_num_shiftbrites-1; i>=0; i--) + sb_shiftout( (uint32_t)sb_colors[i].g | ((uint32_t)sb_colors[i].r<<10) | ((uint32_t)sb_colors[i].b<<20) ); + sb_toggle_latch(); +} + + +// set the color of a shiftbrite. +void sb_setcolor(uint8_t lamp_index, uint8_t r, uint8_t g, uint8_t b) +{ + if(lamp_index>=MAXSHIFTBRITES) return; + sb_colors[lamp_index].r= r<<2; + sb_colors[lamp_index].g= g<<2; + sb_colors[lamp_index].b= b<<2; + sb_update_all_colors(); +} + + +#if 0 +static void tmp_shiftbritetest(void) +{ + sb_shiftout( (uint32_t)(100) | ((uint32_t)(120)<<10) | ((uint32_t)(100)<<20) | ((uint32_t)1<<30) ); + sb_shiftout( (uint32_t)(100) | ((uint32_t)(120)<<10) | ((uint32_t)(100)<<20) | ((uint32_t)1<<30) ); + sb_shiftout( (uint32_t)(100) | ((uint32_t)(120)<<10) | ((uint32_t)(100)<<20) | ((uint32_t)1<<30) ); + _delay_us(15); + PORTC|= (1<<PC1); + _delay_us(15); + PORTC&= ~(1<<PC1); + sb_shiftout( (uint32_t)(1023) | ((uint32_t)(0)<<10) | ((uint32_t)(0)<<20) ); + sb_shiftout( (uint32_t)(0) | ((uint32_t)(1023)<<10) | ((uint32_t)(0)<<20) ); + sb_shiftout( (uint32_t)(0) | ((uint32_t)(0)<<10) | ((uint32_t)(1023)<<20) ); + _delay_us(15); + PORTC|= (1<<PC1); + _delay_us(15); + PORTC&= ~(1<<PC1); +} +#endif + +// write default values to config registers of all shiftbrites +static void sb_set_default_config_values(void) +{ + for(int i= 0; i<sb_num_shiftbrites; i++) + sb_shiftout( (uint32_t)(100) | ((uint32_t)(120)<<10) | ((uint32_t)(100)<<20) | ((uint32_t)1<<30) ); + sb_toggle_latch(); +} + +// setup port for shiftbrites +void sb_init(void) +{ + PORTC= 0; + DDRC= (1<<PC0) | (1<<PC1) | (1<<PC2); + sb_set_default_config_values(); +#if 0 + for(int k= 0; k<1000; k++) + { + memset((void*)sb_colors, 0, sizeof(sb_colors)); + sb_setcolor(k%sb_num_shiftbrites, 0xff, 0x00, 0xff); + _delay_ms(100); + } +#endif +} + + + + + diff --git a/shiftbrite.h b/shiftbrite.h new file mode 100644 index 0000000..d2f5ebd --- /dev/null +++ b/shiftbrite.h @@ -0,0 +1,5 @@ +// setup port for shiftbrites +void sb_init(void); + +// set the color of a shiftbrite. +void sb_setcolor(uint8_t lamp_index, uint8_t r, uint8_t g, uint8_t b); |