Add support for weekdays

This commit is contained in:
2020-11-21 22:49:27 +01:00
parent 20663bbc13
commit ec58f9f660
3 changed files with 34 additions and 6 deletions

View File

@@ -12,7 +12,7 @@
#include "time.h"
#include "led.h"
#define PROJ_STR __PROJ_NAME " " __PROJ_REV " ::: " __PROJ_AUTHOR " " __PROJ_DATE
#define PROJ_STR __PROJ_NAME __PROJ_REV " ::: " __PROJ_AUTHOR __PROJ_DATE
#define UNUSED(X) (void)(X)
@@ -107,8 +107,8 @@ int8_t cmd_ati_handler(uint8_t mode, char* arg)
if(mode != M_NORM) return -1;
uart_puts_P(PSTR(PROJ_STR "\r\n"));
uart_puts_P(PSTR("compilation " __DATE__ " " __TIME__ "\n\r"));
uart_puts_P(PSTR("avr-libc v" __AVR_LIBC_VERSION_STRING__ " " __AVR_LIBC_DATE_STRING__ "\n\r"));
uart_puts_P(PSTR("compilation " __DATE__ __TIME__ "\n\r"));
uart_puts_P(PSTR("avr-libc v" __AVR_LIBC_VERSION_STRING__ __AVR_LIBC_DATE_STRING__ "\n\r"));
return 0;
}
@@ -182,6 +182,8 @@ int8_t cmd_at_dat_handler(uint8_t mode, char* arg)
{
case M_GET:
uart_puts(rtc_data->date_str);
uart_putc(' ');
uart_puts(rtc_data->weekday_str);
uart_puts("\n\r");
break;

View File

@@ -1,16 +1,20 @@
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/io.h>
#include <stdlib.h>
#include "rtc.h"
#include "i2c.h"
#define DEC_2_BCD(dec) ((((dec) / 10) << 4) | ((dec) % 10))
#define BCD_2_DEC(bcd) (((((bcd) >> 4) & 0x0F) * 10) + ((bcd) & 0x0F))
static const uint16_t days_of_month[] PROGMEM = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
static const char weekday_strings[] PROGMEM = { "mon" "\x00" "tue" "\x00" "wed" "\x00" "thu" "\x00" "fri" "\x00" "sat" "\x00" "sun" };
static volatile struct RTC_DATA clock;
static void (*rtc_handler)(struct RTC_DATA* clock);
void rtc_read_datetime(struct RTC_DATA* data);
uint8_t eval_weekday(struct DATE_YMD* date);
void rtc_int0_init(void)
{
@@ -35,7 +39,7 @@ void rtc_set_time(struct TIME_HMS* time)
void rtc_set_date(struct DATE_YMD* date)
{
clock.buffer[3] = ((date->year & 0x03) << 6) | DEC_2_BCD(date->day);
clock.buffer[4] = DEC_2_BCD(date->month);
clock.buffer[4] = (eval_weekday(date) << 5) | 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);
}
@@ -122,5 +126,26 @@ void rtc_read_datetime(struct RTC_DATA* data)
*(curr_char++) = (data->buffer[4] & 0x0F) + '0';
*(curr_char++) = DATE_SEPARATOR;
itoa(data->date.year, curr_char, 10);
*(curr_char+4) = 0;
*(curr_char+4) = 0;
// data->weekday_str
strcpy_P(&data->weekday_str, weekday_strings + data->date.weekday * 4);
}
uint8_t eval_weekday(struct DATE_YMD* date)
{
uint16_t yy = (date->year-1) % 100;
uint16_t c = (date->year-1) - yy;
uint16_t g = yy + yy/4;
uint16_t jan1 = c / 10;
jan1 %= 4;
jan1 *= 5;
jan1 += g;
jan1 %= 7;
uint16_t day_of_year = pgm_read_word(&days_of_month[date->month-1]) + date->day;
if(!(date->year & 0x03) && date->month > 3) ++day_of_year;
return (jan1 + day_of_year - 1) % 7;
}

View File

@@ -24,6 +24,7 @@ struct RTC_DATA
struct DATE_YMDW date;
char time_str[9];
char date_str[11];
char weekday_str[4];
uint8_t buffer[5];
};