summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--moodlamp.c5
-rw-r--r--pwm.c19
-rw-r--r--pwm.h2
-rw-r--r--shiftbrite.c133
-rw-r--r--shiftbrite.h7
5 files changed, 93 insertions, 73 deletions
diff --git a/moodlamp.c b/moodlamp.c
index 6392a4e..47e7bdd 100644
--- a/moodlamp.c
+++ b/moodlamp.c
@@ -30,5 +30,8 @@ int main(void)
sb_init();
sei();
- pwm_worker_loop();
+ for (;;) {
+ pwm_tick();
+ sb_tick();
+ }
}
diff --git a/pwm.c b/pwm.c
index cf7b854..3436e9f 100644
--- a/pwm.c
+++ b/pwm.c
@@ -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)
diff --git a/pwm.h b/pwm.h
index fd479e8..45d7532 100644
--- a/pwm.h
+++ b/pwm.h
@@ -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