87 lines
2.2 KiB
C
87 lines
2.2 KiB
C
// https://tronixstuff.com/2013/08/13/tutorial-arduino-and-pcf8563-real-time-clock-ic/
|
|
// https://www.nxp.com/docs/en/data-sheet/PCF8563.pdf
|
|
|
|
#include "lib/pcf8563.h"
|
|
#include "lib/i2c.h"
|
|
#include "lib/uart.h"
|
|
#include "lib/utils.h"
|
|
|
|
t_error pcf8563_read_date(pcf8563_date* out) {
|
|
uint8_t bytes[7] = {0};
|
|
pcf8563_date ret;
|
|
ERR_RET(i2c_start());
|
|
ERR_RET(i2c_write(I2C_ADDR(PCF8563address, TW_WRITE)));
|
|
ERR_RET(i2c_write(0x2));
|
|
ERR_RET(i2c_stop());
|
|
|
|
ERR_RET(i2c_start());
|
|
ERR_RET(i2c_write(I2C_ADDR(PCF8563address, TW_READ)));
|
|
|
|
for (uint8_t i = 0; i < 6; i++)
|
|
ERR_RET(i2c_read_ack(&bytes[i]));
|
|
ERR_RET(i2c_read_nack(&bytes[6]));
|
|
|
|
ret.second = bcdToDec(bytes[0] & 0b01111111);
|
|
ret.minute = bcdToDec(bytes[1] & 0b01111111);
|
|
ret.hour = bcdToDec(bytes[2] & 0b00111111);
|
|
ret.dayOfMonth = bcdToDec(bytes[3] & 0b00111111);
|
|
ret.dayOfWeek = bcdToDec(bytes[4] & 0b00000111);
|
|
ret.month = bcdToDec(bytes[5] & 0b00011111);
|
|
ret.year = bcdToDec(bytes[6]) + ((bytes[5] & 0b10000000) ? 1900 : 2000);
|
|
|
|
*out = ret;
|
|
return NO_ERROR;
|
|
}
|
|
|
|
t_error pcf8563_set_date(pcf8563_date date) {
|
|
ERR_RET(i2c_start());
|
|
ERR_RET(i2c_write(I2C_ADDR(PCF8563address, TW_WRITE)));
|
|
ERR_RET(i2c_write(0x2));
|
|
ERR_RET(i2c_write(decToBcd(date.second)));
|
|
ERR_RET(i2c_write(decToBcd(date.minute)));
|
|
ERR_RET(i2c_write(decToBcd(date.hour)));
|
|
ERR_RET(i2c_write(decToBcd(date.dayOfMonth)));
|
|
ERR_RET(i2c_write(decToBcd(date.dayOfWeek)));
|
|
uint8_t month = decToBcd(date.month);
|
|
|
|
if (date.year < 2000)
|
|
month |= 0b10000000; // set century bit for 1900s
|
|
else
|
|
month &= 0b01111111; // clear for 2000s
|
|
|
|
ERR_RET(i2c_write(month));
|
|
ERR_RET(i2c_write(decToBcd(date.year % 100)) /*- ((date.year > 1999) ? 2000 : 1900)))*/);
|
|
ERR_RET(i2c_stop());
|
|
return NO_ERROR;
|
|
}
|
|
|
|
void pcf8563_print_date(pcf8563_date* date) {
|
|
if (date->dayOfMonth < 10)
|
|
uart_tx('0');
|
|
uart_send_u8(date->dayOfMonth);
|
|
|
|
uart_tx('/');
|
|
|
|
if (date->month < 10)
|
|
uart_tx('0');
|
|
uart_send_u8(date->month);
|
|
|
|
uart_tx('/');
|
|
uart_send_u16(date->year);
|
|
|
|
uart_tx(' ');
|
|
if (date->hour < 10)
|
|
uart_tx('0');
|
|
uart_send_u8(date->hour);
|
|
uart_tx(':');
|
|
|
|
if (date->minute < 10)
|
|
uart_tx('0');
|
|
uart_send_u8(date->minute);
|
|
uart_tx(':');
|
|
if (date->second < 10)
|
|
uart_tx('0');
|
|
uart_send_u8(date->second);
|
|
|
|
uart_sendstring("\r\n");
|
|
}
|