Major refactor of RTC-related code
This commit is contained in:
@@ -11,21 +11,32 @@
|
||||
#include "nightm.h"
|
||||
#include "time.h"
|
||||
#include "led.h"
|
||||
#include "rtc.h"
|
||||
|
||||
#define PROJ_STR __PROJ_NAME " " __PROJ_REV " ::: " __PROJ_AUTHOR " " __PROJ_DATE
|
||||
|
||||
#define UNUSED(X) (void)(X)
|
||||
|
||||
int8_t cmd_at_handler(uint8_t mode, char* arg);
|
||||
int8_t cmd_ati_handler(uint8_t mode, char* arg);
|
||||
int8_t cmd_at_rst_handler(uint8_t mode, char* arg);
|
||||
int8_t cmd_at_tim_handler(uint8_t mode, char* arg);
|
||||
int8_t cmd_at_dat_handler(uint8_t mode, char* arg);
|
||||
int8_t cmd_at_bts_handler(uint8_t mode, char* arg);
|
||||
int8_t cmd_at_ngt_handler(uint8_t mode, char* arg);
|
||||
|
||||
#define AT_NUM 7
|
||||
const struct AT_CMD at_commands[AT_NUM] PROGMEM = {
|
||||
{ "AT", cmd_at_handler },
|
||||
{ "ATI", cmd_ati_handler },
|
||||
{ "AT+RST", cmd_at_rst_handler },
|
||||
{ "AT+TIM", cmd_at_tim_handler },
|
||||
{ "AT+DAT", cmd_at_dat_handler },
|
||||
{ "AT+BTS", cmd_at_bts_handler },
|
||||
{ "AT+NGT", cmd_at_ngt_handler }
|
||||
};
|
||||
|
||||
static struct RTC_DATA* rtc_data;
|
||||
|
||||
void parse_at(char* at_cmd, char* arg, uint8_t mode)
|
||||
{
|
||||
uint8_t ok = 0;
|
||||
@@ -73,6 +84,11 @@ void at_handler(char* cmd)
|
||||
}
|
||||
}
|
||||
|
||||
void at_update_rtc_data(struct RTC_DATA* rtc)
|
||||
{
|
||||
rtc_data = rtc;
|
||||
}
|
||||
|
||||
int8_t cmd_at_handler(uint8_t mode, char* arg)
|
||||
{
|
||||
UNUSED(arg);
|
||||
@@ -119,11 +135,7 @@ int8_t cmd_at_tim_handler(uint8_t mode, char* arg)
|
||||
switch(mode)
|
||||
{
|
||||
case M_GET:
|
||||
uart_puti(clock.hour, 10);
|
||||
uart_putc(':');
|
||||
uart_puti(clock.minute, 10);
|
||||
uart_putc(':');
|
||||
uart_puti(clock.second, 10);
|
||||
uart_puts(rtc_data->time_str);
|
||||
uart_puts("\n\r");
|
||||
break;
|
||||
|
||||
@@ -142,14 +154,14 @@ int8_t cmd_at_tim_handler(uint8_t mode, char* arg)
|
||||
time.second = atoi(val);
|
||||
if(time.second >= 60) return -1;
|
||||
|
||||
rtc_set_clock(&time);
|
||||
rtc_set_time(&time);
|
||||
|
||||
uart_puts_P(PSTR("+TIM="));
|
||||
uart_puti(clock.hour, 10);
|
||||
uart_puts(",");
|
||||
uart_puti(clock.minute, 10);
|
||||
uart_puts(",");
|
||||
uart_puti(clock.second, 10);
|
||||
uart_puti(time.hour, 10);
|
||||
uart_putc(',');
|
||||
uart_puti(time.minute, 10);
|
||||
uart_putc(',');
|
||||
uart_puti(time.second, 10);
|
||||
uart_puts("\n\r");
|
||||
break;
|
||||
|
||||
@@ -160,6 +172,52 @@ int8_t cmd_at_tim_handler(uint8_t mode, char* arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t cmd_at_dat_handler(uint8_t mode, char* arg)
|
||||
{
|
||||
struct DATE_YMD date;
|
||||
char* val;
|
||||
char* tail;
|
||||
|
||||
switch(mode)
|
||||
{
|
||||
case M_GET:
|
||||
uart_puts(rtc_data->date_str);
|
||||
uart_puts("\n\r");
|
||||
break;
|
||||
|
||||
case M_SET:
|
||||
if(!strlen(arg)) return -1;
|
||||
|
||||
val = strtok_r(arg, ",", &tail);
|
||||
date.day = atoi(val);
|
||||
if(date.day < 1 || 31 < date.day) return -1;
|
||||
|
||||
val = strtok_r(NULL, ",", &tail);
|
||||
date.month = atoi(val);
|
||||
if(date.month < 1 || 12 < date.month) return -1;
|
||||
|
||||
val = strtok_r(NULL, ",", &tail);
|
||||
date.year = atoi(val);
|
||||
|
||||
rtc_set_date(&date);
|
||||
|
||||
uart_puts_P(PSTR("+DAT="));
|
||||
uart_puti(date.day, 10);
|
||||
uart_putc(',');
|
||||
uart_puti(date.month, 10);
|
||||
uart_putc(',');
|
||||
uart_puti(date.year, 10);
|
||||
uart_puts("\n\r");
|
||||
break;
|
||||
|
||||
case M_NORM:
|
||||
uart_puts_P(PSTR("AT+DAT=(1-31),(1-12),(0-65535)\r\n"));
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t cmd_at_bts_handler(uint8_t mode, char* arg)
|
||||
{
|
||||
uint8_t btnes;
|
||||
@@ -176,8 +234,9 @@ int8_t cmd_at_bts_handler(uint8_t mode, char* arg)
|
||||
if(!strlen(arg)) return -1;
|
||||
|
||||
btnes = atoi(arg);
|
||||
if(btnes >= 8) return -1;
|
||||
led_set_btnes(btnes);
|
||||
if(btnes >= 8) return -1;
|
||||
led_set_btnes(ram_cfg.led_btnes = btnes);
|
||||
dump_ram2eem();
|
||||
|
||||
uart_puts_P(PSTR("+BTS="));
|
||||
uart_puts(arg);
|
||||
@@ -237,6 +296,7 @@ int8_t cmd_at_ngt_handler(uint8_t mode, char* arg)
|
||||
if(nightm_cfg.end.minute > 59) return -1;
|
||||
|
||||
nightm_config(&nightm_cfg);
|
||||
dump_ram2eem();
|
||||
|
||||
uart_puts_P(PSTR("+NGT="));
|
||||
uart_puti(nightm_cfg.led_btnes, 10);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define __AT_H__
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include "rtc.h"
|
||||
|
||||
#define M_SET 0
|
||||
#define M_GET 1
|
||||
@@ -14,15 +15,6 @@ struct AT_CMD
|
||||
};
|
||||
|
||||
void at_handler(char* cmd);
|
||||
|
||||
int8_t cmd_at_handler(uint8_t mode, char* arg);
|
||||
int8_t cmd_ati_handler(uint8_t mode, char* arg);
|
||||
int8_t cmd_at_rst_handler(uint8_t mode, char* arg);
|
||||
int8_t cmd_at_tim_handler(uint8_t mode, char* arg);
|
||||
int8_t cmd_at_bts_handler(uint8_t mode, char* arg);
|
||||
int8_t cmd_at_ngt_handler(uint8_t mode, char* arg);
|
||||
|
||||
#define AT_NUM 6
|
||||
extern const struct AT_CMD at_commands[AT_NUM] PROGMEM;
|
||||
void at_update_rtc_data(struct RTC_DATA* rtc);
|
||||
|
||||
#endif
|
||||
@@ -9,22 +9,24 @@ uint8_t k_inc_hour, k_inc_minute, k_inc_second, k_inc_brightness;
|
||||
|
||||
void inc_hour(void)
|
||||
{
|
||||
rtc_set_clock_part(HOUR, (clock.hour + 1) % 24);
|
||||
rtc_inc_time(HOUR);
|
||||
}
|
||||
|
||||
void inc_minute(void)
|
||||
{
|
||||
rtc_set_clock_part(MINUTE, (clock.minute + 1) % 60);
|
||||
rtc_inc_time(MINUTE);
|
||||
}
|
||||
|
||||
void inc_second(void)
|
||||
{
|
||||
rtc_set_clock_part(SECOND, (clock.second + 1) % 60);
|
||||
rtc_inc_time(SECOND);
|
||||
}
|
||||
|
||||
void inc_brightness(void)
|
||||
{
|
||||
led_inc_btnes();
|
||||
if(++ram_cfg.led_btnes > 7) ram_cfg.led_btnes = 0;
|
||||
led_set_btnes(ram_cfg.led_btnes);
|
||||
dump_ram2eem();
|
||||
}
|
||||
|
||||
void kbd_init(void)
|
||||
|
||||
@@ -2,40 +2,33 @@
|
||||
#include <avr/interrupt.h>
|
||||
#include "config.h"
|
||||
#include "led.h"
|
||||
#include "rtc.h"
|
||||
|
||||
volatile uint8_t led_btnes;
|
||||
static volatile uint8_t led_btnes;
|
||||
|
||||
static struct LED_DIGS display;
|
||||
|
||||
void led_init(void)
|
||||
{
|
||||
// Set brightness
|
||||
led_btnes = 1<<(ram_cfg.led_btnes);
|
||||
|
||||
// Set outputs
|
||||
ANODES_DIR |= HOUR_ANODE | MINUTE_ANODE | SECOND_ANODE;
|
||||
ANODES_DIR |= DIG0_ANODE | DIG1_ANODE | DIG2_ANODE;
|
||||
LED_DIR |= 0x3F; // 0b00111111
|
||||
|
||||
// Clear LEDs
|
||||
ANODES_PORT = HOUR_ANODE | MINUTE_ANODE | SECOND_ANODE;
|
||||
ANODES_PORT = DIG0_ANODE | DIG1_ANODE | DIG2_ANODE;
|
||||
LED_PORT |= 0x3F; // 0b00111111
|
||||
|
||||
TCCR0 |= (1<<CS00);
|
||||
TIMSK |= (1<<TOIE0);
|
||||
}
|
||||
|
||||
void led_set_btnes(uint8_t btnes)
|
||||
void led_display(struct LED_DIGS* digits)
|
||||
{
|
||||
if(btnes > 7) btnes = 0;
|
||||
led_btnes = 1<<btnes;
|
||||
ram_cfg.led_btnes = btnes;
|
||||
dump_ram2eem();
|
||||
display = *digits;
|
||||
}
|
||||
|
||||
void led_inc_btnes(void)
|
||||
void led_set_btnes(uint8_t btnes)
|
||||
{
|
||||
if(++(ram_cfg.led_btnes) > 7) ram_cfg.led_btnes = 0;
|
||||
led_btnes = 1<<(ram_cfg.led_btnes);
|
||||
dump_ram2eem();
|
||||
led_btnes = 1<<btnes;
|
||||
}
|
||||
|
||||
// 8 MHz / 256 = 31.25 kHz
|
||||
@@ -48,16 +41,16 @@ ISR(TIMER0_OVF_vect)
|
||||
switch(curr_anode)
|
||||
{
|
||||
case 1:
|
||||
LED_PORT = ~clock.hour;
|
||||
ANODES_PORT = led_btnes >= pwm_counter ? ~HOUR_ANODE : 0xFF;
|
||||
LED_PORT = ~display.dig0;
|
||||
ANODES_PORT = led_btnes >= pwm_counter ? ~DIG0_ANODE : 0xFF;
|
||||
break;
|
||||
case 2:
|
||||
LED_PORT = ~clock.minute;
|
||||
ANODES_PORT = led_btnes >= pwm_counter ? ~MINUTE_ANODE : 0xFF;
|
||||
LED_PORT = ~display.dig1;
|
||||
ANODES_PORT = led_btnes >= pwm_counter ? ~DIG1_ANODE : 0xFF;
|
||||
break;
|
||||
case 4:
|
||||
LED_PORT = ~clock.second;
|
||||
ANODES_PORT = led_btnes >= pwm_counter ? ~SECOND_ANODE : 0xFF;
|
||||
LED_PORT = ~display.dig2;
|
||||
ANODES_PORT = led_btnes >= pwm_counter ? ~DIG2_ANODE : 0xFF;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
#ifndef __LED_H__
|
||||
#define __LED_H__
|
||||
|
||||
#include "time.h"
|
||||
|
||||
#define LED_PORT PORTA
|
||||
#define LED_DIR DDRA
|
||||
|
||||
#define ANODES_PORT PORTD
|
||||
#define ANODES_DIR DDRD
|
||||
#define HOUR_ANODE (1<<PD5)
|
||||
#define MINUTE_ANODE (1<<PD6)
|
||||
#define SECOND_ANODE (1<<PD7)
|
||||
#define DIG0_ANODE (1<<PD5)
|
||||
#define DIG1_ANODE (1<<PD6)
|
||||
#define DIG2_ANODE (1<<PD7)
|
||||
|
||||
extern volatile uint8_t led_btnes;
|
||||
struct LED_DIGS
|
||||
{
|
||||
uint8_t dig0;
|
||||
uint8_t dig1;
|
||||
uint8_t dig2;
|
||||
};
|
||||
|
||||
void led_init(void);
|
||||
void led_display(struct LED_DIGS* digits);
|
||||
void led_set_btnes(uint8_t btnes);
|
||||
void led_inc_btnes(void);
|
||||
|
||||
#endif
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#define I2C_BITRATE 100000UL // 100kHz
|
||||
|
||||
void update_time(struct RTC_DATA* rtc);
|
||||
|
||||
int main()
|
||||
{
|
||||
@@ -23,17 +24,27 @@ int main()
|
||||
rtc_int0_init();
|
||||
led_init();
|
||||
uart_init();
|
||||
|
||||
uart_bind_handler(at_handler);
|
||||
rtc_bind_handler(update_time);
|
||||
|
||||
sei();
|
||||
led_set_btnes(ram_cfg.led_btnes);
|
||||
|
||||
char uart_buf[20];
|
||||
|
||||
sei();
|
||||
|
||||
while(1)
|
||||
{
|
||||
kbd_handle_event();
|
||||
uart_handle_event(uart_buf);
|
||||
|
||||
if(rtc_handle_clock()) nightm_handle();
|
||||
rtc_handle_event();
|
||||
}
|
||||
}
|
||||
|
||||
void update_time(struct RTC_DATA* rtc)
|
||||
{
|
||||
led_display((struct LED_DIGS*) &rtc->time);
|
||||
at_update_rtc_data(rtc);
|
||||
nightm_handle(rtc);
|
||||
}
|
||||
@@ -1,25 +1,23 @@
|
||||
#include "nightm.h"
|
||||
#include "ptimer.h"
|
||||
#include "led.h"
|
||||
#include "rtc.h"
|
||||
|
||||
#define TIME2INT(TIME) ((TIME).hour*60 + (TIME).minute)
|
||||
#define TIMER_FREQ 100 // ptimer works with 100Hz so it's going to reduce time to 1Hz = 1s
|
||||
|
||||
void nightm_config(struct NIGHTM_CFG* cfg)
|
||||
{
|
||||
ram_cfg.night_mode = *cfg;
|
||||
dump_ram2eem();
|
||||
ram_cfg.night_mode = *cfg;
|
||||
}
|
||||
|
||||
void nightm_handle(void)
|
||||
void nightm_handle(struct RTC_DATA* rtc)
|
||||
{
|
||||
if(ram_cfg.night_mode.led_btnes >= 0)
|
||||
{
|
||||
uint16_t current = TIME2INT(clock);
|
||||
uint16_t begin = TIME2INT(ram_cfg.night_mode.begin);
|
||||
uint16_t end = TIME2INT(ram_cfg.night_mode.end);
|
||||
uint16_t current = TIME_2_INT(rtc->time);
|
||||
uint16_t begin = TIME_2_INT(ram_cfg.night_mode.begin);
|
||||
uint16_t end = TIME_2_INT(ram_cfg.night_mode.end);
|
||||
|
||||
led_btnes = (begin <= current && current < end)
|
||||
? 1<<(ram_cfg.night_mode.led_btnes)
|
||||
: 1<<(ram_cfg.led_btnes);
|
||||
led_set_btnes((begin <= current && current < end) ? ram_cfg.night_mode.led_btnes : ram_cfg.led_btnes);
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
#define __NIGHTM_H__
|
||||
|
||||
#include "config.h"
|
||||
#include "time.h"
|
||||
#include "rtc.h"
|
||||
|
||||
void nightm_config(struct NIGHTM_CFG* cfg);
|
||||
void nightm_handle(void);
|
||||
void nightm_handle(struct RTC_DATA* rtc);
|
||||
|
||||
#endif
|
||||
@@ -17,5 +17,5 @@ void ptimer_init(void)
|
||||
// ~100 Hz
|
||||
ISR(TIMER2_COMP_vect)
|
||||
{
|
||||
if(tim_debounce) --tim_debounce;
|
||||
if(tim_debounce) --tim_debounce;
|
||||
}
|
||||
129
firmware/rtc.c
129
firmware/rtc.c
@@ -1,59 +1,126 @@
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/io.h>
|
||||
#include <stdlib.h>
|
||||
#include "rtc.h"
|
||||
#include "i2c.h"
|
||||
|
||||
volatile struct TIME_HMS clock;
|
||||
#define DEC_2_BCD(dec) ((((dec) / 10) << 4) | ((dec) % 10))
|
||||
#define BCD_2_DEC(bcd) (((((bcd) >> 4) & 0x0F) * 10) + ((bcd) & 0x0F))
|
||||
|
||||
static volatile struct RTC_DATA clock;
|
||||
static void (*rtc_handler)(struct RTC_DATA* clock);
|
||||
|
||||
void rtc_read_datetime(struct RTC_DATA* data);
|
||||
|
||||
void rtc_int0_init(void)
|
||||
{
|
||||
MCUCR |= (1<<ISC01);
|
||||
INT0_DIR &= ~(1<<INT0_PIN);
|
||||
INT0_PORT |= (1<<INT0_PIN);
|
||||
GICR |= (1<<INT0);
|
||||
INT0_PORT |= (1<<INT0_PIN);
|
||||
}
|
||||
|
||||
void rtc_int1_init(void)
|
||||
void rtc_bind_handler(void (*handler)(struct RTC_DATA* clock))
|
||||
{
|
||||
INT1_DIR &= ~(1<<INT1_PIN);
|
||||
INT1_PORT |= (1<<INT1_PIN);
|
||||
GICR |= (1<<INT1);
|
||||
rtc_handler = handler;
|
||||
}
|
||||
|
||||
void rtc_set_clock_part(uint8_t part, uint8_t value)
|
||||
void rtc_set_time(struct TIME_HMS* time)
|
||||
{
|
||||
uint8_t bcd = DEC_2_BCD(value);
|
||||
i2c_writebuf(RTC_I2C_ADDR, part, 1, &bcd);
|
||||
clock.buffer[0] = DEC_2_BCD(time->second);
|
||||
clock.buffer[1] = DEC_2_BCD(time->minute);
|
||||
clock.buffer[2] = DEC_2_BCD(time->hour);
|
||||
i2c_writebuf(RTC_I2C_ADDR, 0x02, 3, &clock.buffer);
|
||||
}
|
||||
|
||||
void rtc_set_clock(struct TIME_HMS* time)
|
||||
{
|
||||
uint8_t buf[] = { DEC_2_BCD(time->second), DEC_2_BCD(time->minute), DEC_2_BCD(time->hour) };
|
||||
i2c_writebuf(RTC_I2C_ADDR, SECOND, 3, buf); // SECOND is the first memory cell (0x02)
|
||||
}
|
||||
|
||||
void rtc_update_clock(void)
|
||||
void rtc_set_date(struct DATE_YMD* date)
|
||||
{
|
||||
uint8_t buffer[3];
|
||||
i2c_readbuf(RTC_I2C_ADDR, 0x02, 3, buffer);
|
||||
|
||||
clock.hour = BCD_2_DEC(buffer[2]);
|
||||
clock.minute = BCD_2_DEC(buffer[1]);
|
||||
clock.second = BCD_2_DEC(buffer[0]);
|
||||
clock.buffer[3] = ((date->year & 0x03) << 6) | DEC_2_BCD(date->day);
|
||||
clock.buffer[4] = DEC_2_BCD(date->month);
|
||||
i2c_writebuf(RTC_I2C_ADDR, 0x05, 2, &clock.buffer[3]);
|
||||
i2c_writebuf(RTC_I2C_ADDR, 0x10, 2, (uint8_t*) &date->year);
|
||||
}
|
||||
|
||||
uint8_t rtc_handle_clock(void)
|
||||
{
|
||||
if(!(GIFR & (1<<INTF0)))
|
||||
void rtc_inc_time(uint8_t part)
|
||||
{
|
||||
switch(part)
|
||||
{
|
||||
rtc_update_clock();
|
||||
GIFR |= 1<<INTF0;
|
||||
return 1;
|
||||
case SECOND:
|
||||
clock.buffer[0] = clock.time.second + 1;
|
||||
if(clock.buffer[0] >= 60) clock.buffer[0] = 0;
|
||||
break;
|
||||
case MINUTE:
|
||||
clock.buffer[0] = clock.time.minute + 1;
|
||||
if(clock.buffer[0] >= 60) clock.buffer[0] = 0;
|
||||
break;
|
||||
case HOUR:
|
||||
clock.buffer[0] = clock.time.hour + 1;
|
||||
if(clock.buffer[0] >= 24) clock.buffer[0] = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
clock.buffer[0] = DEC_2_BCD(clock.buffer[0]);
|
||||
|
||||
i2c_writebuf(RTC_I2C_ADDR, part, 1, &clock.buffer);
|
||||
rtc_invoke_handler();
|
||||
}
|
||||
|
||||
ISR(INT0_vect)
|
||||
void rtc_invoke_handler(void)
|
||||
{
|
||||
if(rtc_handler)
|
||||
{
|
||||
rtc_read_datetime(&clock);
|
||||
rtc_handler(&clock);
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_handle_event(void)
|
||||
{
|
||||
if(GIFR & (1<<INTF0))
|
||||
{
|
||||
rtc_invoke_handler();
|
||||
GIFR |= 1<<INTF0;
|
||||
}
|
||||
}
|
||||
|
||||
void rtc_read_datetime(struct RTC_DATA* data)
|
||||
{
|
||||
i2c_readbuf(RTC_I2C_ADDR, 0x02, 5, data->buffer);
|
||||
i2c_readbuf(RTC_I2C_ADDR, 0x10, 2, (uint8_t*) &(data->date.year));
|
||||
|
||||
char* curr_char = data->time_str;
|
||||
for(uint8_t i=0; i<3; ++i)
|
||||
{
|
||||
// data->time_str
|
||||
*(curr_char++) = ((data->buffer[2-i] & (!i ? 0x3F : 0x7F)) >> 4) + '0'; // Tens
|
||||
*(curr_char++) = (data->buffer[2-i] & 0x0F) + '0'; // Ones
|
||||
*(curr_char++) = i==2 ? 0 : ':'; // Separator
|
||||
|
||||
// data->time structure
|
||||
*((uint8_t*)(&data->time)+i) = BCD_2_DEC(data->buffer[2-i]);
|
||||
}
|
||||
|
||||
// data->date structure
|
||||
data->date.day = BCD_2_DEC(data->buffer[3] & 0x3F);
|
||||
|
||||
// data->date.year
|
||||
uint8_t year = data->buffer[3] >> 6;
|
||||
if((data->date.year & 0x03) != year)
|
||||
{
|
||||
while((data->date.year & 0x03) != year) ++(data->date.year);
|
||||
i2c_writebuf(RTC_I2C_ADDR, 0x10, 2, (uint8_t*) &(data->date.year));
|
||||
}
|
||||
|
||||
data->date.month = BCD_2_DEC(data->buffer[4] & 0x1F);
|
||||
data->date.weekday = data->buffer[4] >> 5;
|
||||
|
||||
// data->date_str
|
||||
curr_char = data->date_str;
|
||||
*(curr_char++) = ((data->buffer[3] & 0x3F) >> 4) + '0';
|
||||
*(curr_char++) = (data->buffer[3] & 0x0F) + '0';
|
||||
*(curr_char++) = DATE_SEPARATOR;
|
||||
*(curr_char++) = ((data->buffer[4] & 0x1F) >> 4) + '0';
|
||||
*(curr_char++) = (data->buffer[4] & 0x0F) + '0';
|
||||
*(curr_char++) = DATE_SEPARATOR;
|
||||
itoa(data->date.year, curr_char, 10);
|
||||
*(curr_char+4) = 0;
|
||||
}
|
||||
@@ -5,9 +5,7 @@
|
||||
|
||||
#define RTC_I2C_ADDR 0xA2
|
||||
|
||||
#define SECOND 0x02
|
||||
#define MINUTE 0x03
|
||||
#define HOUR 0x04
|
||||
#define DATE_SEPARATOR '.'
|
||||
|
||||
#define INT0_PORT PORTD
|
||||
#define INT0_DIR DDRD
|
||||
@@ -16,15 +14,24 @@
|
||||
#define INT1_DIR DDRD
|
||||
#define INT1_PIN PD3
|
||||
|
||||
#define DEC_2_BCD(dec) ((((dec) / 10) << 4) | ((dec) % 10))
|
||||
#define BCD_2_DEC(bcd) (((((bcd) >> 4) & 0x0F) * 10) + ((bcd) & 0x0F))
|
||||
#define SECOND 0x02
|
||||
#define MINUTE 0x03
|
||||
#define HOUR 0x04
|
||||
|
||||
extern volatile struct TIME_HMS clock;
|
||||
struct RTC_DATA
|
||||
{
|
||||
struct TIME_HMS time;
|
||||
struct DATE_YMDW date;
|
||||
char time_str[9];
|
||||
char date_str[11];
|
||||
uint8_t buffer[5];
|
||||
};
|
||||
|
||||
void rtc_int0_init(void);
|
||||
void rtc_int1_init(void);
|
||||
void rtc_set_clock(struct TIME_HMS* time);
|
||||
void rtc_set_clock_part(uint8_t part, uint8_t value);
|
||||
uint8_t rtc_handle_clock(void);
|
||||
void rtc_bind_handler(void (*handler)(struct RTC_DATA* clock));
|
||||
void rtc_set_time(struct TIME_HMS* time);
|
||||
void rtc_set_date(struct DATE_YMD* date);
|
||||
void rtc_inc_time(uint8_t part);
|
||||
void rtc_handle_event(void);
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,23 @@
|
||||
#ifndef __TIME_H__
|
||||
#define __TIME_H__
|
||||
|
||||
#define TIME_2_INT(TIME) ((TIME).hour*60 + (TIME).minute)
|
||||
|
||||
struct DATE_YMDW
|
||||
{
|
||||
uint16_t year;
|
||||
uint8_t month;
|
||||
uint8_t day;
|
||||
uint8_t weekday;
|
||||
};
|
||||
|
||||
struct DATE_YMD
|
||||
{
|
||||
uint16_t year;
|
||||
uint8_t month;
|
||||
uint8_t day;
|
||||
};
|
||||
|
||||
struct TIME_HMS
|
||||
{
|
||||
uint8_t hour;
|
||||
|
||||
Reference in New Issue
Block a user