diff options
-rw-r--r-- | moodlamp.c | 5 | ||||
-rw-r--r-- | pwm.c | 19 | ||||
-rw-r--r-- | pwm.h | 2 | ||||
-rw-r--r-- | shiftbrite.c | 133 | ||||
-rw-r--r-- | shiftbrite.h | 7 |
5 files changed, 93 insertions, 73 deletions
@@ -30,5 +30,8 @@ int main(void) sb_init(); sei(); - pwm_worker_loop(); + for (;;) { + pwm_tick(); + sb_tick(); + } } @@ -20,6 +20,7 @@ #include <avr/io.h> #include <stdint.h> #include <string.h> +#include "shiftbrite.h" volatile uint16_t value_red = 3072; volatile uint16_t value_green = 2048; @@ -32,17 +33,15 @@ void pwm_set_rgb(uint8_t r, uint8_t g, uint8_t b) value_blue = b << 4; } -void pwm_worker_loop(void) +void pwm_tick(void) { - for (;;) { - for (uint16_t i = 0; i < 4096; i++) { - // this should take about the same time for each iteration, regardless of pulse width - PORTA= (PORTA & ~((1<<PA0)|(1<<PA1)|(1<<PA2))) | - (value_red > i? (1<<PA0): 0) | - (value_green > i? (1<<PA1): 0) | - (value_blue > i? (1<<PA2): 0); - } - } + for (uint16_t i = 0; i < 4096; i++) { + // this should take about the same time for each iteration, regardless of pulse width + PORTA= (PORTA & ~((1<<PA0)|(1<<PA1)|(1<<PA2))) | + (value_red > i? (1<<PA0): 0) | + (value_green > i? (1<<PA1): 0) | + (value_blue > i? (1<<PA2): 0); + } } void pwm_init(void) @@ -20,7 +20,7 @@ #define PWM_H void pwm_set_rgb(uint8_t r, uint8_t g, uint8_t b); -void pwm_worker_loop(void); +void pwm_tick(void); void pwm_init(void); #endif diff --git a/shiftbrite.c b/shiftbrite.c index 5cc5b82..a5f319b 100644 --- a/shiftbrite.c +++ b/shiftbrite.c @@ -22,96 +22,101 @@ #include <stdint.h> #include <string.h> #include <util/delay.h> +#include <stdio.h> +#include <inttypes.h> +#include "serial.h" -// shiftbrites connected to header labeled as 'aux', setup: -// PC0 -> CI (clock) -// PC1 -> LI (latch) -// PC2 -> DI (data) +/* 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 SBCI (1<<PC0) +#define SBLI (1<<PC1) +#define SBDI (1<<PC2) #define MAXSHIFTBRITES 16 typedef struct rgb { - uint16_t r, g, b; // 10-bit values + 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 +/* number of connected shiftbrites + (automatically updated in sb_setcolor) */ static volatile uint8_t sb_num_shiftbrites= 3; -// toggle the latch so the shiftbrites accept new values +/* index of next shiftbrite register to be shifted out + used by sb_pwmtick */ +static uint8_t sb_shiftidx; + +/* toggle the latch so the shiftbrites accept new values */ static void sb_toggle_latch(void) { + PORTC |= SBLI; _delay_us(15); - PORTC|= (1<<PC1); + PORTC &= ~SBLI; _delay_us(15); - PORTC&= ~(1<<PC1); } -// shift out one 32-bit shiftbrite register. +/* 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 + const unsigned clkdelay = 0; + for(int8_t i = 31; i>=0; i--) { + _delay_us(clkdelay); + PORTC&= ~SBCI; /* clock lo */ if((val>>i)&1) - PORTC|= (1<<PC2); // data bit + PORTC|= SBDI; /* data bit */ else - PORTC&= ~(1<<PC2); - //_delay_us(clkdelay); - PORTC|= (1<<PC0); // clock hi + PORTC&= ~SBDI; + _delay_us(clkdelay); + PORTC|= SBCI; /* clock hi */ } } -// shift out all color values to connected shiftbrites +#if 0 +/* 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--) + 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(); } +#endif - -// set the color of a shiftbrite. +/* 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; + if(lamp_index >= MAXSHIFTBRITES) return; + if(lamp_index+1 > sb_num_shiftbrites) sb_num_shiftbrites= lamp_index+1; + + sb_colors[lamp_index].r= r*r>>6; + sb_colors[lamp_index].g= g*g>>6; + sb_colors[lamp_index].b= b*b>>6; + + + char ch[256]; + sprintf(ch, "%" PRIx16 " %" PRIx16 " %" PRIx16 "\n", sb_colors[lamp_index].r, sb_colors[lamp_index].g, sb_colors[lamp_index].b); + serial_send(ch, strlen(ch), 1); + + /* works */ +/* + sb_colors[lamp_index].r= ((uint16_t)r*r>>6); + sb_colors[lamp_index].g= ((uint16_t)g*g>>6); + sb_colors[lamp_index].b= ((uint16_t)b*b>>6); +*/ +/* + updates are now done in sb_tick() 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 +/* 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++) @@ -119,20 +124,26 @@ static void sb_set_default_config_values(void) sb_toggle_latch(); } -// setup port for shiftbrites +/* shift out a shiftbrite register, or toggle latch once finished + to be called from pwm worker loop */ +void sb_tick(void) +{ + sb_shiftidx= (sb_shiftidx+1)%(sb_num_shiftbrites+1); + if(sb_shiftidx==sb_num_shiftbrites) + sb_toggle_latch(); + else + { + int i= sb_num_shiftbrites-sb_shiftidx-1; + sb_shiftout( (uint32_t)(sb_colors[i].g&0x3FF) | ((uint32_t)(sb_colors[i].r&0x3FF)<<10) | ((uint32_t)(sb_colors[i].b&0x3FF)<<20) ); + } +} + +/* setup port for shiftbrites */ void sb_init(void) { PORTC= 0; - DDRC= (1<<PC0) | (1<<PC1) | (1<<PC2); + DDRC= SBCI | SBLI | SBDI; 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 index d2f5ebd..09edffb 100644 --- a/shiftbrite.h +++ b/shiftbrite.h @@ -1,5 +1,12 @@ +#ifndef SHIFTBRITE_H +#define SHIFTBRITE_H + // 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); + +void sb_tick(void); + +#endif //SHIFTBRITE_H |