You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
230 lines
4.5 KiB
230 lines
4.5 KiB
/* |
|
RV8523 RTC Lib for Arduino |
|
by Watterott electronic (www.watterott.com) |
|
*/ |
|
|
|
#include <inttypes.h> |
|
#if defined(__AVR__) |
|
# include <avr/io.h> |
|
#endif |
|
#if ARDUINO >= 100 |
|
# include "Arduino.h" |
|
#else |
|
# include "WProgram.h" |
|
#endif |
|
#include "Wire.h" |
|
#include "RV8523.h" |
|
|
|
|
|
#define I2C_ADDR (0xD0>>1) |
|
|
|
|
|
//-------------------- Constructor -------------------- |
|
|
|
|
|
RV8523::RV8523(void) |
|
{ |
|
Wire.begin(); |
|
|
|
return; |
|
} |
|
|
|
|
|
//-------------------- Public -------------------- |
|
|
|
|
|
void RV8523::start(void) |
|
{ |
|
uint8_t val; |
|
|
|
Wire.beginTransmission(I2C_ADDR); |
|
Wire.write(byte(0x00)); //control 1 |
|
Wire.endTransmission(); |
|
Wire.requestFrom(I2C_ADDR, 1); |
|
val = Wire.read(); |
|
|
|
if(val & (1<<5)) |
|
{ |
|
Wire.beginTransmission(I2C_ADDR); |
|
Wire.write(byte(0x00)); //control 1 |
|
Wire.write(val & ~(1<<5)); //clear STOP (bit 5) |
|
Wire.endTransmission(); |
|
} |
|
|
|
return; |
|
} |
|
|
|
|
|
void RV8523::stop(void) |
|
{ |
|
uint8_t val; |
|
|
|
Wire.beginTransmission(I2C_ADDR); |
|
Wire.write(byte(0x00)); //control 1 |
|
Wire.endTransmission(); |
|
Wire.requestFrom(I2C_ADDR, 1); |
|
val = Wire.read(); |
|
|
|
if(!(val & (1<<5))) |
|
{ |
|
Wire.beginTransmission(I2C_ADDR); |
|
Wire.write(byte(0x00)); //control 1 |
|
Wire.write(val | (1<<5)); //set STOP (bit 5) |
|
Wire.endTransmission(); |
|
} |
|
|
|
return; |
|
} |
|
|
|
|
|
void RV8523::set12HourMode(void) //set 12 hour mode |
|
{ |
|
uint8_t val; |
|
|
|
Wire.beginTransmission(I2C_ADDR); |
|
Wire.write(byte(0x00)); //control 1 |
|
Wire.endTransmission(); |
|
Wire.requestFrom(I2C_ADDR, 1); |
|
val = Wire.read(); |
|
|
|
if(!(val & (1<<3))) |
|
{ |
|
Wire.beginTransmission(I2C_ADDR); |
|
Wire.write(byte(0x00)); //control 1 |
|
Wire.write(val | (1<<3)); //set 12 hour mode (bit 3) |
|
Wire.endTransmission(); |
|
} |
|
|
|
return; |
|
} |
|
|
|
|
|
void RV8523::set24HourMode(void) //set 24 hour mode |
|
{ |
|
uint8_t val; |
|
|
|
Wire.beginTransmission(I2C_ADDR); |
|
Wire.write(byte(0x00)); //control 1 |
|
Wire.endTransmission(); |
|
Wire.requestFrom(I2C_ADDR, 1); |
|
val = Wire.read(); |
|
|
|
if(val & (1<<3)) |
|
{ |
|
Wire.beginTransmission(I2C_ADDR); |
|
Wire.write(byte(0x00)); //control 1 |
|
Wire.write(val & ~(1<<3)); //set 12 hour mode (bit 3) |
|
Wire.endTransmission(); |
|
} |
|
|
|
return; |
|
} |
|
|
|
|
|
void RV8523::batterySwitchOver(int on) //activate/deactivate battery switch over mode |
|
{ |
|
uint8_t val; |
|
|
|
Wire.beginTransmission(I2C_ADDR); |
|
Wire.write(byte(0x02)); //control 3 |
|
Wire.endTransmission(); |
|
Wire.requestFrom(I2C_ADDR, 1); |
|
val = Wire.read(); |
|
if(val & 0xE0) |
|
{ |
|
Wire.beginTransmission(I2C_ADDR); |
|
Wire.write(byte(0x02)); //control 3 |
|
if(on) |
|
{ |
|
Wire.write(val & ~0xE0); //battery switchover in standard mode |
|
} |
|
else |
|
{ |
|
Wire.write(val | 0xE0); //battery switchover disabled |
|
} |
|
Wire.endTransmission(); |
|
} |
|
|
|
return; |
|
} |
|
|
|
|
|
void RV8523::get(uint8_t *sec, uint8_t *min, uint8_t *hour, uint8_t *day, uint8_t *month, uint16_t *year) |
|
{ |
|
Wire.beginTransmission(I2C_ADDR); |
|
Wire.write(byte(0x03)); |
|
Wire.endTransmission(); |
|
|
|
Wire.requestFrom(I2C_ADDR, 7); |
|
*sec = bcd2bin(Wire.read() & 0x7F); |
|
*min = bcd2bin(Wire.read() & 0x7F); |
|
*hour = bcd2bin(Wire.read() & 0x3F); //24 hour mode |
|
*day = bcd2bin(Wire.read() & 0x3F); |
|
bcd2bin(Wire.read() & 0x07); //day of week |
|
*month = bcd2bin(Wire.read() & 0x1F); |
|
*year = bcd2bin(Wire.read()) + 2000; |
|
|
|
return; |
|
} |
|
|
|
|
|
void RV8523::get(int *sec, int *min, int *hour, int *day, int *month, int *year) |
|
{ |
|
Wire.beginTransmission(I2C_ADDR); |
|
Wire.write(byte(0x03)); |
|
Wire.endTransmission(); |
|
|
|
Wire.requestFrom(I2C_ADDR, 7); |
|
*sec = bcd2bin(Wire.read() & 0x7F); |
|
*min = bcd2bin(Wire.read() & 0x7F); |
|
*hour = bcd2bin(Wire.read() & 0x3F); //24 hour mode |
|
*day = bcd2bin(Wire.read() & 0x3F); |
|
bcd2bin(Wire.read() & 0x07); //day of week |
|
*month = bcd2bin(Wire.read() & 0x1F); |
|
*year = bcd2bin(Wire.read()) + 2000; |
|
|
|
return; |
|
} |
|
|
|
|
|
void RV8523::set(uint8_t sec, uint8_t min, uint8_t hour, uint8_t day, uint8_t month, uint16_t year) |
|
{ |
|
if(year > 2000) |
|
{ |
|
year -= 2000; |
|
} |
|
|
|
Wire.beginTransmission(I2C_ADDR); |
|
Wire.write(byte(0x03)); |
|
Wire.write(bin2bcd(sec)); |
|
Wire.write(bin2bcd(min)); |
|
Wire.write(bin2bcd(hour)); |
|
Wire.write(bin2bcd(day)); |
|
Wire.write(bin2bcd(0)); |
|
Wire.write(bin2bcd(month)); |
|
Wire.write(bin2bcd(year)); |
|
Wire.endTransmission(); |
|
|
|
return; |
|
} |
|
|
|
|
|
void RV8523::set(int sec, int min, int hour, int day, int month, int year) |
|
{ |
|
return set((uint8_t)sec, (uint8_t)min, (uint8_t)hour, (uint8_t)day, (uint8_t)month, (uint16_t)year); |
|
} |
|
|
|
|
|
//-------------------- Private -------------------- |
|
|
|
|
|
uint8_t RV8523::bin2bcd(uint8_t val) |
|
{ |
|
return val + 6 * (val / 10); |
|
} |
|
|
|
|
|
uint8_t RV8523::bcd2bin(uint8_t val) |
|
{ |
|
return val - 6 * (val >> 4); |
|
}
|
|
|