summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Baumann <derflob@derflob.de>2014-10-24 14:10:15 +0200
committerFlorian Baumann <derflob@derflob.de>2014-10-24 14:10:15 +0200
commitd97146bb20571909ee67c78895208e0dae30da96 (patch)
tree0a810de6abc63de195a5882b0137a6a50f40e49f
parent0b6bc53bf73bcf4c8c71471c348503453eaa46eb (diff)
downloadStripClock-d97146bb20571909ee67c78895208e0dae30da96.tar.gz
StripClock-d97146bb20571909ee67c78895208e0dae30da96.tar.bz2
final adjustments for attiny4313
-rw-r--r--StripClock.c91
-rw-r--r--ds1307.c78
-rw-r--r--i2cmaster.S16
3 files changed, 105 insertions, 80 deletions
diff --git a/StripClock.c b/StripClock.c
index 174ff47..d186832 100644
--- a/StripClock.c
+++ b/StripClock.c
@@ -6,7 +6,6 @@
#include "ds1307.h"
#include "light_ws2812.h"
-
#define BTN_MODE DDD3
#define BTN_MODE_PORT PORTD
#define BTN_MODE_PIN PIND
@@ -38,6 +37,7 @@ volatile struct datetime dt;
struct cRGB leds[LEDS];
uint8_t updateStrip(void);
+uint8_t updateStripSimple(void);
int main(void)
{
@@ -57,23 +57,11 @@ int main(void)
BTN_MODE_DDR &= ~(1 << BTN_MODE);
BTN_MODE_PORT |= (1 << BTN_MODE);
-
i2c_init();
ds1307_start();
ds1307_SQWRate(SQW_4kHz);
ds1307_SQW(1);
-
- ds1307_getDateTime(&dt);
-
- dt.hour = 15;
- dt.minute = 45;
- dt.second = 0;
- dt.year = 2014;
- dt.month = 10;
- dt.day = 23;
-
- ds1307_setDateTime(&dt);
ds1307_getDateTime(&dt);
sei();
@@ -84,14 +72,14 @@ int main(void)
updateStrip();
updated = 0;
} else {
+ memset(leds, 0, sizeof(struct cRGB) * LEDS);
switch (mode) {
- memset(leds, 0, sizeof(struct cRGB) * LEDS);
case DM_HOUR:
for (uint8_t i = 0; i < dt.hour; i++) {
leds[i].r = 255;
- if (i % 5 == 0) {
- leds[i].g = 50;
- leds[i].b = 50;
+ if (i % 5 == 4) {
+ leds[i].g = 75;
+ leds[i].b = 75;
}
}
ws2812_setleds(leds, LEDS);
@@ -99,19 +87,19 @@ int main(void)
case DM_MINUTE:
for (uint8_t i = 0; i < dt.minute; i++) {
leds[i].g = 255;
- if (i % 5 == 0) {
- leds[i].r = 50;
- leds[i].b = 50;
+ 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.hour; i++) {
+ for (uint8_t i = 0; i < dt.second; i++) {
leds[i].b = 255;
- if (i % 5 == 0) {
- leds[i].r = 50;
- leds[i].g = 50;
+ if (i % 5 == 4) {
+ leds[i].r = 75;
+ leds[i].g = 75;
}
}
ws2812_setleds(leds, LEDS);
@@ -119,6 +107,7 @@ int main(void)
case DM_END:
ds1307_setDateTime(&dt);
mode = DM_NONE;
+ TIMSK &= ~(1 << TOIE0);
updateStrip();
break;
default:
@@ -140,25 +129,16 @@ ISR(INT0_vect)
ISR(INT1_vect)
{
- //debounce button, by temp disabling this interrupt
+ //debounce BTN_MODE, by temp disabling this interrupt
GIMSK &= ~(1 << INT1);
- if (mode == DM_NONE) {
- //enable TIMER0 in normal mode, prescale 1024
- TCCR0A = 0;
- TCCR0B = ((1 << CS02) | (1 << CS00));
- //enable overflow intr
- TIMSK |= (1 << TOIE0);
- }
-
- mode++;
-
+ //TIMER1 in ctc mode
//ctc mode
TCCR1A = 0;
//ctc && precale 1024
TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10);
//should be about 50ms
- OCR1A = 1024;
+ OCR1A = 390;
//enable ctc intrrupt
TIMSK |= (1 << OCIE1A);
@@ -168,28 +148,41 @@ ISR(TIMER1_COMPA_vect)
{
//debounce of BTN_MODE
- //disable timer
+ //disable TIMER1
TCCR1B = 0;
//disable this interrupt
TIMSK &= ~(1 << OCIE1A);
//enable INT1
GIMSK |= (1 << INT1);
+
+ if (!(BTN_MODE_PIN & (1 << BTN_MODE))) {
+
+ 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);
+ }
+
+ mode++;
+ }
}
ISR(TIMER0_OVF_vect)
{
- //after 30 overflows, ~ 360ms elapsed
- if (++btn_debounce == 30) {
+ //after 5 overflows, ~ 160ms elapsed
+ if (++btn_debounce == 5) {
btn_debounce = 0;
- if (BTN_INC_PIN & (1 << BTN_INC)) {
+ if (!(BTN_INC_PIN & (1 << BTN_INC))) {
switch (mode) {
case DM_HOUR:
dt.hour = (++dt.hour) % 24;
break;
case DM_MINUTE:
- dt.minute = (++dt.second) % 60;
+ dt.minute = (++dt.minute) % 60;
break;
case DM_SECOND:
dt.second = (++dt.second) % 60;
@@ -198,10 +191,23 @@ ISR(TIMER0_OVF_vect)
break;
}
}
-
}
}
+uint8_t updateStripSimple(void)
+{
+
+ memset(leds, 0, LEDS * sizeof(struct cRGB));
+
+ leds[dt.hour].r = 255;
+ leds[dt.minute].g = 255;
+ leds[dt.second].b = 255;
+
+ ws2812_setleds(leds, LEDS);
+
+ return 0;
+}
+
uint8_t updateStrip(void)
{
uint8_t hour_led = ((dt.hour % 12) * (LEDS/12)) - 1;
@@ -245,6 +251,7 @@ uint8_t updateStrip(void)
} else {
r = g = b = 0;
}
+
if (i % 15 == 14) {
r *= 5;
g *= 10;
diff --git a/ds1307.c b/ds1307.c
index 0a87efe..e78f24a 100644
--- a/ds1307.c
+++ b/ds1307.c
@@ -1,30 +1,26 @@
#include "i2cmaster.h"
#include "ds1307.h"
+static uint8_t bcd_dec(uint8_t bcd);
+static uint8_t dec_bcd(uint8_t dec);
static uint8_t ds1307_init_rw(unsigned char reg);
static uint8_t ds1307_init_write(unsigned char reg);
static uint8_t ds1307_init_read(unsigned char reg);
-
-#define BCD2DEC(x) ((0x0F & (x)) + 10 * ((x) >> 4))
-#define DEC2BCD(x) ((((x) / 10) << 4) | ((x) % 10))
-
-uint8_t ds1307_start(void)
+static uint8_t bcd_dec(uint8_t bcd)
{
- //set 24 hour mode
- ds1307_init_read(0x02);
- unsigned char hour = i2c_readNak();
- hour &= ~(1 << DS1307_BIT_AMPM);
- ds1307_init_write(0x02);
- i2c_write(hour);
- i2c_stop();
+ return ((10 * ((bcd & 0xF0) >> 4)) + (bcd & 0x0F));
+}
- //unhalt clock
- ds1307_halt(0);
- return 0;
+static uint8_t dec_bcd(uint8_t dec)
+{
+ return (((dec / 10) << 4) | dec % 10);
}
+#define BCD2DEC(x) (10 * (((x) & 0xF0) >> 4) + ((x) & 0x0F))
+#define DEC2BCD(x) ((((x) / 10) << 4) | ((x) % 10))
+
static uint8_t ds1307_init_rw(unsigned char reg)
{
i2c_start_wait(DS1307_ADDR + I2C_WRITE);
@@ -45,10 +41,27 @@ static uint8_t ds1307_init_read(unsigned char reg)
return 0;
}
+uint8_t ds1307_start(void)
+{
+ //set 24 hour mode
+ ds1307_init_read(0x02);
+ unsigned char hour = i2c_readNak();
+ hour &= ~(1 << DS1307_BIT_AMPM);
+ ds1307_init_write(0x02);
+ i2c_write(hour);
+ i2c_stop();
+
+ //unhalt clock
+ ds1307_halt(0);
+
+ return 0;
+}
+
uint8_t ds1307_halt(uint8_t halted)
{
ds1307_init_read(0x00);
- unsigned char sec = i2c_readAck();
+ unsigned char sec = i2c_readNak();
+ i2c_stop();
if (halted)
sec |= (1 << DS1307_BIT_CH);
@@ -67,14 +80,15 @@ uint8_t ds1307_getDateTime(struct datetime* dt)
{
ds1307_init_read(0x00);
//omit CH bit
- dt->second = BCD2DEC(i2c_readAck() & ~(1 << DS1307_BIT_CH));
- dt->minute = BCD2DEC(i2c_readAck());
+ dt->second = bcd_dec(i2c_readAck() & ~(1 << DS1307_BIT_CH));
+ dt->minute = bcd_dec(i2c_readAck());
//omit AMPM bit (which should be 0 because we only have 24 hour mode)
- dt->hour = BCD2DEC(i2c_readAck() & ~(1 << DS1307_BIT_AMPM));
- dt->dow = BCD2DEC(i2c_readAck());
- dt->day = BCD2DEC(i2c_readAck());
- dt->month = BCD2DEC(i2c_readAck());
- dt->year = 2000 + BCD2DEC(i2c_readNak());
+ dt->hour = bcd_dec(i2c_readAck() & ~(1 << DS1307_BIT_AMPM));
+ dt->dow = bcd_dec(i2c_readAck());
+ dt->day = bcd_dec(i2c_readAck());
+ dt->month = bcd_dec(i2c_readAck());
+ dt->year = 2000 + bcd_dec(i2c_readNak());
+ i2c_stop();
return 0;
}
@@ -86,18 +100,20 @@ uint8_t ds1307_setDateTime(struct datetime* dt)
ds1307_init_read(0x00);
ch = i2c_readAck() & (1 << DS1307_BIT_CH);
+ //discard minute register
i2c_readAck();
ampm = i2c_readNak() & (1 << DS1307_BIT_AMPM);
+ i2c_stop();
ds1307_init_write(0x00);
- i2c_write(DEC2BCD(dt->second) | (ch << DS1307_BIT_CH));
- i2c_write(DEC2BCD(dt->minute));
- i2c_write(DEC2BCD(dt->hour) | (ampm << DS1307_BIT_AMPM));
- i2c_write(DEC2BCD(dt->dow));
- i2c_write(DEC2BCD(dt->day));
- i2c_write(DEC2BCD(dt->month));
- i2c_write(DEC2BCD(dt->year - 2000));
+ i2c_write(dec_bcd(dt->second) | (ch << DS1307_BIT_CH));
+ i2c_write(dec_bcd(dt->minute));
+ i2c_write(dec_bcd(dt->hour) | (ampm << DS1307_BIT_AMPM));
+ i2c_write(dec_bcd(dt->dow));
+ i2c_write(dec_bcd(dt->day));
+ i2c_write(dec_bcd(dt->month));
+ i2c_write(dec_bcd(dt->year - 2000));
i2c_stop();
return 0;
@@ -108,6 +124,7 @@ uint8_t ds1307_SQW(uint8_t enabled)
unsigned char sqw;
ds1307_init_read(0x07);
sqw = i2c_readNak();
+ i2c_stop();
if (enabled)
sqw |= (1 << DS1307_BIT_SQWE);
@@ -126,6 +143,7 @@ uint8_t ds1307_SQWRate(enum SQWRate rate)
unsigned char sqw;
ds1307_init_read(0x07);
sqw = i2c_readNak();
+ i2c_stop();
sqw = (sqw & ~(0x3)) | (rate & 0x3);
diff --git a/i2cmaster.S b/i2cmaster.S
index bd6c3f6..7264011 100644
--- a/i2cmaster.S
+++ b/i2cmaster.S
@@ -68,10 +68,10 @@
; For I2C in normal mode (100kHz), use T/2 > 5us
; For I2C in fast mode (400kHz), use T/2 > 1.3us
;*************************************************************************
- .stabs "",100,0,0,i2c_delay_T2
- .stabs "i2cmaster.S",100,0,0,i2c_delay_T2
- .func i2c_delay_T2 ; delay 5.0 microsec with 4 Mhz crystal
-i2c_delay_T2: ; 4 cycles
+ .stabs "",100,0,0,i2c_delay_T2_
+ .stabs "i2cmaster.S",100,0,0,i2c_delay_T2_
+ .func i2c_delay_T2_ ; delay 5.0 microsec with 4 Mhz crystal
+i2c_delay_T2_: ; 4 cycles
rjmp 1f ; 2 "
1: rjmp 2f ; 2 "
2: rjmp 3f ; 2 "
@@ -82,11 +82,11 @@ i2c_delay_T2: ; 4 cycles
ret ; 3 "
.endfunc ; total 20 cyles = 5.0 microsec with 4 Mhz crystal
- .func i2c_delay_T2a ; calling i2c_delay_T2_ two times gives about
+ .func i2c_delay_T2 ; calling i2c_delay_T2_ two times gives about
; the right timing for 8Mhz crystals +- a bit.
-i2c_delay_T2a:
- rcall i2c_delay_T2
- rcall i2c_delay_T2
+i2c_delay_T2:
+ rcall i2c_delay_T2_
+ rcall i2c_delay_T2_
ret
.endfunc