summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Baumann <derflob@derflob.de>2014-11-02 15:58:45 +0100
committerFlorian Baumann <derflob@derflob.de>2014-11-04 18:59:47 +0100
commitf82152da8f4edf47c16ace8f769d6c1bd19e4a11 (patch)
tree3231a9c0ae24c7f789163be837c6eb2416428ac2
parentd97146bb20571909ee67c78895208e0dae30da96 (diff)
downloadStripClock-f82152da8f4edf47c16ace8f769d6c1bd19e4a11.tar.gz
StripClock-f82152da8f4edf47c16ace8f769d6c1bd19e4a11.tar.bz2
update for hw rev 2.0
changed i2c ports rotary encoder with brightness adjustment
-rw-r--r--StripClock.c302
-rw-r--r--i2cmaster.S2
2 files changed, 172 insertions, 132 deletions
diff --git a/StripClock.c b/StripClock.c
index d186832..060f01b 100644
--- a/StripClock.c
+++ b/StripClock.c
@@ -6,15 +6,11 @@
#include "ds1307.h"
#include "light_ws2812.h"
-#define BTN_MODE DDD3
-#define BTN_MODE_PORT PORTD
-#define BTN_MODE_PIN PIND
-#define BTN_MODE_DDR DDRD
-
-#define BTN_INC DDB0
-#define BTN_INC_PORT PORTB
-#define BTN_INC_PIN PINB
-#define BTN_INC_DDR DDRB
+#define ENC_RESOLUTION 4
+const int8_t rotary_states[][4] = { { 0, -1, +1, 0 },
+ { +1, 0, 0, -1 },
+ { -1, 0, 0, +1 },
+ { 0, +1, -1, 0 } };
enum display_mode {
DM_NONE,
@@ -23,39 +19,65 @@ enum display_mode {
DM_SECOND,
DM_END
};
+enum display_mode mode = DM_NONE;
-volatile uint8_t updated = 0;
-volatile uint16_t ticks = 4095;
+enum btn_state {
+ BTN_UP,
+ BTN_UP_PROCESSED,
+ BTN_DOWN,
+ BTN_DOWN_PROCESSED
+};
+volatile enum btn_state rotary_btn = BTN_UP;
-volatile uint8_t btn_debounce = 0;
+volatile uint8_t updated = 0;
+volatile uint16_t ticks = 4096;
-volatile enum display_mode mode = DM_NONE;
+volatile int8_t rotary_updated = 0;
volatile struct datetime dt;
#define LEDS 60
struct cRGB leds[LEDS];
+#define MAX_BRIGHTNESS 10
+int8_t brightness;
+
uint8_t updateStrip(void);
uint8_t updateStripSimple(void);
+uint8_t updateStripEncoder(void);
int main(void)
{
cli();
//set INT0 from sqw as input
- PORTD &= ~(1 << DDD2);
+ DDRD &= ~(1 << DDD2);
+
+ //set rotary enc pins as input
+ //ENC_A
+ DDRB &= ~(1 << DDB3);
+ //ENC_B
+ DDRB &= ~(1 << DDB2);
+ //ENC_BTN
+ DDRB &= ~(1 << DDB4);
+
+ //enable internal pull-ups
+ //ENC_A
+ PORTB |= (1 << PORTB3);
+ //ENC_B
+ PORTB |= (1 << PORTB2);
+ //ENC_BTN
+ PORTB |= (1 << PORTB4);
+
+ //enable pcint for rotary enc
+ PCMSK = (1 << PCINT3) | (1 << PCINT2) | (1 << PCINT4);
+ GIMSK |= (1 << PCIE0);
//enable INT0 on falling edges
MCUCR |= (1 << ISC01);
+ GIMSK |= (1 << INT0);
//enable INT1 on falling edges
- MCUCR |= (1 << ISC11);
- GIMSK |= ((1 << INT0) | (1 << INT1));
-
- //set BTN_* as input and pull-ups high
- BTN_INC_DDR &= ~(1 << BTN_INC);
- BTN_INC_PORT |= (1 << BTN_INC);
- BTN_MODE_DDR &= ~(1 << BTN_MODE);
- BTN_MODE_PORT |= (1 << BTN_MODE);
+ //MCUCR |= (1 << ISC11);
+ //GIMSK |= (1 << INT1);
i2c_init();
@@ -64,6 +86,8 @@ int main(void)
ds1307_SQW(1);
ds1307_getDateTime(&dt);
+ brightness = 0;
+
sei();
for (;;) {
@@ -71,50 +95,26 @@ int main(void)
ds1307_getDateTime(&dt);
updateStrip();
updated = 0;
- } else {
- memset(leds, 0, sizeof(struct cRGB) * LEDS);
- switch (mode) {
- case DM_HOUR:
- for (uint8_t i = 0; i < dt.hour; i++) {
- leds[i].r = 255;
- if (i % 5 == 4) {
- leds[i].g = 75;
- leds[i].b = 75;
- }
- }
- ws2812_setleds(leds, LEDS);
- break;
- case DM_MINUTE:
- for (uint8_t i = 0; i < dt.minute; i++) {
- leds[i].g = 255;
- if (i % 5 == 4) {
- leds[i].r = 75;
- leds[i].b = 75;
- }
- }
- ws2812_setleds(leds, LEDS);
- break;
- case DM_SECOND:
- for (uint8_t i = 0; i < dt.second; i++) {
- leds[i].b = 255;
- if (i % 5 == 4) {
- leds[i].r = 75;
- leds[i].g = 75;
- }
- }
- ws2812_setleds(leds, LEDS);
- break;
- case DM_END:
- ds1307_setDateTime(&dt);
- mode = DM_NONE;
- TIMSK &= ~(1 << TOIE0);
- updateStrip();
- break;
- default:
- break;
- }
}
+ if (rotary_updated != 0) {
+ updateStripEncoder();
+ rotary_updated = 0;
+ }
+
+ if (rotary_btn == BTN_DOWN) {
+ mode++;
+ rotary_btn = BTN_DOWN_PROCESSED;
+
+ if (mode == DM_END) {
+ ds1307_setDateTime(&dt);
+ mode = DM_NONE;
+ TIMSK &= ~(1 << TOIE0);
+ updateStrip();
+ } else {
+ updateStripEncoder();
+ }
+ }
}
}
@@ -123,75 +123,113 @@ ISR(INT0_vect)
//after 4096 ticks 1 sec is elapsed
if (--ticks == 0) {
updated = 1;
- ticks = 4095;
+ ticks = 4096;
}
}
-ISR(INT1_vect)
+/*
+ISR(PCINT0_vect)
{
- //debounce BTN_MODE, by temp disabling this interrupt
- GIMSK &= ~(1 << INT1);
-
- //TIMER1 in ctc mode
- //ctc mode
+ //debounce rotary encoder
+ GIMSK &= ~(1 << PCIE0);
+ //ctc mode, prescale 1024, 1.25ms, @8MHz
TCCR1A = 0;
- //ctc && precale 1024
TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10);
- //should be about 50ms
- OCR1A = 390;
-
- //enable ctc intrrupt
+ OCR1A = 10;
TIMSK |= (1 << OCIE1A);
}
+*/
-ISR(TIMER1_COMPA_vect)
+ISR(PCINT0_vect)
{
- //debounce of BTN_MODE
+ //disable this interrupt aa
+ //TIMSK &= ~(1 << OCIE1A);
+ //enable pcint for rotary encoder
+ //GIMSK |= (1 << PCIE0);
- //disable TIMER1
- TCCR1B = 0;
- //disable this interrupt
- TIMSK &= ~(1 << OCIE1A);
+ static uint8_t state = 0;
+ static int8_t delta = 0;
- //enable INT1
- GIMSK |= (1 << INT1);
+ uint8_t new_state = (!(PINB & (1 << PINB3)) << 1) + !(PINB & (1 << PINB2));
- if (!(BTN_MODE_PIN & (1 << BTN_MODE))) {
+ delta += rotary_states[state][new_state];
+ state = new_state;
- if (mode == DM_NONE) {
- //enable TIMER0 in normal mode, prescale 1024
- TCCR0A = 0;
- TCCR0B = ((1 << CS02) | (1 << CS00));
- //enable TIMER0 overflow intr
- TIMSK |= (1 << TOIE0);
- }
+ if (delta == ENC_RESOLUTION || delta == -ENC_RESOLUTION) {
+ delta > 0 ? rotary_updated-- : rotary_updated++;
+ delta = 0;
+ }
- mode++;
+ if (!(PINB & (1 << PINB4)) && rotary_btn != BTN_DOWN_PROCESSED) {
+ rotary_btn = BTN_DOWN;
+ } else if (PINB & (1 << PINB4) && rotary_btn != BTN_UP_PROCESSED) {
+ rotary_btn = BTN_UP;
}
}
-ISR(TIMER0_OVF_vect)
+uint8_t updateStripEncoder(void)
{
- //after 5 overflows, ~ 160ms elapsed
- if (++btn_debounce == 5) {
- btn_debounce = 0;
-
- if (!(BTN_INC_PIN & (1 << BTN_INC))) {
- switch (mode) {
- case DM_HOUR:
- dt.hour = (++dt.hour) % 24;
- break;
- case DM_MINUTE:
- dt.minute = (++dt.minute) % 60;
- break;
- case DM_SECOND:
- dt.second = (++dt.second) % 60;
- break;
- default:
- break;
+
+ switch (mode) {
+ case DM_HOUR:
+ memset(leds, 0, sizeof(struct cRGB) * LEDS);
+ dt.hour = (dt.hour + rotary_updated) % 24;
+ for (uint8_t i = 0; i < dt.hour; i++) {
+ leds[i].r = 127;
+ if (i % 5 == 4) {
+ leds[i].g = 50;
+ leds[i].b = 50;
+ }
}
- }
+ break;
+ case DM_MINUTE:
+ memset(leds, 0, sizeof(struct cRGB) * LEDS);
+ dt.minute = (dt.minute + rotary_updated) % 60;
+ for (uint8_t i = 0; i < dt.minute; i++) {
+ leds[i].g = 127;
+ if (i % 5 == 4) {
+ leds[i].r = 50;
+ leds[i].b = 50;
+ }
+ }
+ break;
+ case DM_SECOND:
+ memset(leds, 0, sizeof(struct cRGB) * LEDS);
+ dt.second = (dt.second + rotary_updated) % 60;
+ for (uint8_t i = 0; i < dt.second; i++) {
+ leds[i].b = 127;
+ if (i % 5 == 4) {
+ leds[i].r = 50;
+ leds[i].g = 50;
+ }
+ }
+ break;
+ case DM_NONE:
+ if (rotary_updated > 0 && brightness < MAX_BRIGHTNESS) {
+ if (brightness + rotary_updated > MAX_BRIGHTNESS) {
+ brightness = MAX_BRIGHTNESS;
+ } else {
+ brightness += rotary_updated;
+ }
+ updated = 1;
+ }
+
+ if (rotary_updated < 0 && brightness >= 0) {
+ if (brightness < -rotary_updated) {
+ brightness = -1;
+ } else {
+ brightness += rotary_updated;
+ }
+ updated = 1;
+ }
+ break;
+ default:
+ break;
}
+
+ ws2812_setleds(leds, LEDS);
+
+ return 0;
}
uint8_t updateStripSimple(void)
@@ -210,6 +248,12 @@ uint8_t updateStripSimple(void)
uint8_t updateStrip(void)
{
+ if (brightness < 0) {
+ memset(leds, 0, sizeof(struct cRGB) * LEDS);
+ ws2812_setleds(leds, LEDS);
+ return 0;
+ }
+
uint8_t hour_led = ((dt.hour % 12) * (LEDS/12)) - 1;
if (hour_led == -1)
hour_led = 59;
@@ -217,34 +261,30 @@ uint8_t updateStrip(void)
for (uint8_t i = 0; i < LEDS; i++) {
int16_t r, g, b = 0;
- const int16_t cur_min_r = 4;
- const int16_t cur_min_g = 16;
- const int16_t cur_min_b = 1;
- const int16_t past_min_r = 2;
- const int16_t past_min_g = 2;
- const int16_t past_min_b = 1;
+ const int16_t cur_min_r = 4 + brightness;
+ const int16_t cur_min_g = 16 + brightness;
+ const int16_t cur_min_b = 1 + brightness;
+ const int16_t past_min_r = 2 + brightness;
+ const int16_t past_min_g = 2 + brightness;
+ const int16_t past_min_b = 1 + brightness;
if (i < dt.minute - 1) {
- r = g = 2;
- b = 1;
+ //past minute
+ r = past_min_r;
+ g = past_min_g;
+ b = past_min_b;
} else if (i == dt.minute - 1 || (i == 59 && dt.minute == 0)) {
+ //running minute
r = cur_min_r + (past_min_r - cur_min_r) * (int16_t)dt.second / 60;
g = cur_min_g + (past_min_g - cur_min_g) * (int16_t)dt.second / 60;
b = cur_min_b + (past_min_b - cur_min_b) * (int16_t)dt.second / 60;
-
-
- //r = scalePing((uint8_t)r);
- //g = scalePing((uint8_t)g);
- //b = scalePing((uint8_t)b);
} else if (i == dt.minute) {
+ //next minute
r = past_min_r + (cur_min_r - past_min_r) * (int16_t)dt.second / 60;
g = past_min_g + (cur_min_g - past_min_g) * (int16_t)dt.second / 60;
b = past_min_b + (cur_min_b - past_min_b) * (int16_t)dt.second / 60;
-
- //r = scalePing((uint8_t)r);
- //g = scalePing((uint8_t)g);
- //b = scalePing((uint8_t)b);
} else if (i % 5 == 4) {
+ //future hour leds
r = past_min_r;
g = past_min_g;
b = past_min_b;
@@ -263,8 +303,8 @@ uint8_t updateStrip(void)
}
if (i == hour_led) {
- g += 50;
- r += 40;
+ g += 50 + brightness * 2;
+ r += 40 + brightness * 2;
}
leds[i].r = r;
diff --git a/i2cmaster.S b/i2cmaster.S
index 7264011..35ff729 100644
--- a/i2cmaster.S
+++ b/i2cmaster.S
@@ -41,7 +41,7 @@
;***** Adapt these SCA and SCL port and pin definition to your target !!
;
#define SDA 1 // SDA Port D, Pin 4
-#define SCL 2 // SCL Port D, Pin 5
+#define SCL 0 // SCL Port D, Pin 5
#define SDA_PORT PORTB // SDA Port B
#define SCL_PORT PORTB // SCL Port 2