From 753680192ced57c1183588aa4b6383f06ccba4ec Mon Sep 17 00:00:00 2001
From: Johannes Kroll <jkroll@lavabit.com>
Date: Tue, 6 Mar 2012 23:07:28 +0100
Subject: wip mult stuff

---
 moodlamp.c   |   5 ++-
 pwm.c        |  19 ++++-----
 pwm.h        |   2 +-
 shiftbrite.c | 133 ++++++++++++++++++++++++++++++++---------------------------
 shiftbrite.h |   7 ++++
 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
-- 
cgit v1.2.1