2016-08-14 18:37:58 +02:00
|
|
|
/* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
/** library to communicate with the Maxim DS1307 I2C RTC IC (code)
|
|
|
|
* @file rtc_ds1307.c
|
|
|
|
* @author King Kévin <kingkevin@cuvoodoo.info>
|
2017-04-03 13:05:30 +02:00
|
|
|
* @date 2016-2017
|
|
|
|
* @note peripherals used: I2C @ref i2c_master_i2c
|
2016-08-14 18:37:58 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* standard libraries */
|
|
|
|
#include <stdint.h> // standard integer types
|
|
|
|
#include <stdio.h> // standard I/O facilities
|
|
|
|
#include <stdlib.h> // general utilities
|
|
|
|
|
|
|
|
/* STM32 (including CM3) libraries */
|
|
|
|
#include <libopencm3/stm32/rcc.h> // real-time control clock library
|
|
|
|
#include <libopencm3/stm32/gpio.h> // general purpose input output library
|
|
|
|
#include <libopencm3/stm32/i2c.h> // I2C library
|
|
|
|
|
|
|
|
#include "global.h" // global utilities
|
|
|
|
#include "rtc_ds1307.h" // RTC header and definitions
|
2017-04-03 13:05:30 +02:00
|
|
|
#include "i2c_master.h" // i2c utilities
|
2016-08-14 18:37:58 +02:00
|
|
|
|
2017-04-03 13:05:30 +02:00
|
|
|
#define RTC_DS1307_I2C_ADDR 0x68 /**< DS1307 I2C address (fixed to 0b1101000) */
|
2016-08-14 18:37:58 +02:00
|
|
|
|
|
|
|
void rtc_ds1307_setup(void)
|
|
|
|
{
|
2017-04-03 13:05:30 +02:00
|
|
|
// configure I2C peripheral
|
|
|
|
i2c_master_setup(false); // DS1307 only supports normal mode (up to 100 kHz)
|
2016-08-14 18:37:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool rtc_ds1307_oscillator_disabled(void)
|
|
|
|
{
|
|
|
|
uint8_t data[1] = {0}; // to read data over I2C
|
2017-04-03 13:05:30 +02:00
|
|
|
const uint8_t address[] = {0x00}; // memory address for data
|
|
|
|
if (!i2c_master_read(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data))) { // read a single byte containing CH value
|
|
|
|
return false;
|
|
|
|
}
|
2016-08-14 18:37:58 +02:00
|
|
|
return data[0]&0x80; // return CH bit value to indicate if oscillator is disabled
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t rtc_ds1307_read_square_wave(void)
|
|
|
|
{
|
|
|
|
uint16_t to_return = 0; // square wave frequency to return (in Hz)
|
|
|
|
uint8_t data[1] = {0}; // to read data over I2C
|
|
|
|
const uint16_t rtc_ds1307_rs[] = {1, 4096, 8192, 32768}; // RS1/RS0 values
|
2017-04-03 13:05:30 +02:00
|
|
|
const uint8_t address[] = {0x07}; // memory address for data
|
|
|
|
if (!i2c_master_read(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data))) { // read a single byte containing control register
|
|
|
|
return 0xffff; // error occurred
|
|
|
|
}
|
2016-08-14 18:37:58 +02:00
|
|
|
if (data[0]&0x10) { // verify if the square wave is enabled (SQWE)
|
|
|
|
to_return = rtc_ds1307_rs[data[0]&0x03]; // read RS1/RS0 and get value
|
|
|
|
} else {
|
|
|
|
to_return = 0; // square wave output is disabled
|
|
|
|
}
|
|
|
|
return to_return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t rtc_ds1307_read_seconds(void)
|
|
|
|
{
|
|
|
|
uint8_t to_return = 0; // seconds to return
|
|
|
|
uint8_t data[1] = {0}; // to read data over I2C
|
2017-04-03 13:05:30 +02:00
|
|
|
const uint8_t address[] = {0x00}; // memory address for data
|
|
|
|
if (!i2c_master_read(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data))) { // read a single byte containing value
|
|
|
|
return 0xff;
|
|
|
|
}
|
2016-08-14 18:37:58 +02:00
|
|
|
to_return = ((data[0]&0x70)>>4)*10+(data[0]&0x0f); // convert BCD coding into seconds
|
|
|
|
return to_return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t rtc_ds1307_read_minutes(void)
|
|
|
|
{
|
|
|
|
uint8_t to_return = 0; // minutes to return
|
|
|
|
uint8_t data[1] = {0}; // to read data over I2C
|
2017-04-03 13:05:30 +02:00
|
|
|
const uint8_t address[] = {0x01}; // memory address for data
|
|
|
|
if (!i2c_master_read(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data))) { // read a single byte containing value
|
|
|
|
return 0xff;
|
|
|
|
}
|
2016-08-14 18:37:58 +02:00
|
|
|
to_return = (data[0]>>4)*10+(data[0]&0x0f); // convert BCD coding into minutes
|
|
|
|
return to_return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t rtc_ds1307_read_hours(void)
|
|
|
|
{
|
|
|
|
uint8_t to_return = 0; // hours to return
|
|
|
|
uint8_t data[1] = {0}; // to read data over I2C
|
2017-04-03 13:05:30 +02:00
|
|
|
const uint8_t address[] = {0x02}; // memory address for data
|
|
|
|
if (!i2c_master_read(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data))) { // read a single byte containing value
|
|
|
|
return 0xff;
|
|
|
|
}
|
2016-08-14 18:37:58 +02:00
|
|
|
if (data[0]&0x40) { // 12 hour mode
|
|
|
|
if (data[0]&0x02) { // PM
|
|
|
|
to_return += 12; // add the 12 hours
|
|
|
|
}
|
|
|
|
to_return += ((data[0]&0x10)>>4)*10; // convert BCD coding into hours (first digit)
|
|
|
|
} else {
|
|
|
|
to_return = ((data[0]&0x30)>>4)*10; // convert BCD coding into hours (first digit)
|
|
|
|
}
|
|
|
|
to_return += (data[0]&0x0f); // convert BCD coding into hours (second digit)
|
|
|
|
return to_return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t rtc_ds1307_read_day(void)
|
|
|
|
{
|
|
|
|
uint8_t to_return = 0; // day to return
|
|
|
|
uint8_t data[1] = {0}; // to read data over I2C
|
2017-04-03 13:05:30 +02:00
|
|
|
const uint8_t address[] = {0x03}; // memory address for data
|
|
|
|
if (!i2c_master_read(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data))) { // read a single byte containing value
|
|
|
|
return 0xff;
|
|
|
|
}
|
2016-08-14 18:37:58 +02:00
|
|
|
to_return = (data[0]&0x07); // convert BCD coding into days
|
|
|
|
return to_return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t rtc_ds1307_read_date(void)
|
|
|
|
{
|
|
|
|
uint8_t to_return = 0; // date to return
|
|
|
|
uint8_t data[1] = {0}; // to read data over I2C
|
2017-04-03 13:05:30 +02:00
|
|
|
const uint8_t address[] = {0x04}; // memory address for data
|
|
|
|
if (!i2c_master_read(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data))) { // read a single byte containing value
|
|
|
|
return 0xff;
|
|
|
|
}
|
2016-08-14 18:37:58 +02:00
|
|
|
to_return = ((data[0]&0x30)>>4)*10+(data[0]&0x0f); // convert BCD coding into date
|
|
|
|
return to_return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t rtc_ds1307_read_month(void)
|
|
|
|
{
|
|
|
|
uint8_t to_return = 0; // month to return
|
|
|
|
uint8_t data[1] = {0}; // to read data over I2C
|
2017-04-03 13:05:30 +02:00
|
|
|
const uint8_t address[] = {0x05}; // memory address for data
|
|
|
|
if (!i2c_master_read(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data))) { // read a single byte containing value
|
|
|
|
return 0xff;
|
|
|
|
}
|
2016-08-14 18:37:58 +02:00
|
|
|
to_return = ((data[0]&0x10)>>4)*10+(data[0]&0x0f); // convert BCD coding into month
|
|
|
|
return to_return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t rtc_ds1307_read_year(void)
|
|
|
|
{
|
|
|
|
uint8_t data[1] = {0}; // to read data over I2C
|
2017-04-03 13:05:30 +02:00
|
|
|
const uint8_t address[] = {0x06}; // memory address for data
|
|
|
|
if (!i2c_master_read(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data))) { // read a single byte containing value
|
|
|
|
return 0xff;
|
|
|
|
}
|
2016-08-14 18:37:58 +02:00
|
|
|
uint8_t to_return = ((data[0]&0xf0)>>4)*10+(data[0]&0x0f); // convert BCD coding into year
|
|
|
|
return to_return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t* rtc_ds1307_read_time(void)
|
|
|
|
{
|
|
|
|
static uint8_t time[7] = {0}; // store time {seconds, minutes, hours, day, date, month, year}
|
|
|
|
uint8_t data[7] = {0}; // to read data over I2C
|
2017-04-03 13:05:30 +02:00
|
|
|
const uint8_t address[] = {0x00}; // memory address for data
|
|
|
|
if (!i2c_master_read(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data))) { // read all time bytes
|
|
|
|
return NULL; // error occurred
|
|
|
|
}
|
2016-08-14 18:37:58 +02:00
|
|
|
time[0] = ((data[0]&0x70)>>4)*10+(data[0]&0x0f); // convert seconds from BCD
|
|
|
|
time[1] = (data[1]>>4)*10+(data[1]&0x0f); // convert minutes from BCD
|
|
|
|
time[2] = 0; // re-initialize hours
|
|
|
|
if (data[2]&0x40) { // 12 hour mode
|
|
|
|
if (data[2]&0x02) { // PM
|
|
|
|
time[2] += 12; // add the 12 hours
|
|
|
|
}
|
|
|
|
time[2] += ((data[2]&0x10)>>4)*10; // convert BCD coding into hours (first digit)
|
|
|
|
} else {
|
|
|
|
time[2] = ((data[2]&0x30)>>4)*10; // convert BCD coding into hours (first digit)
|
|
|
|
}
|
|
|
|
time[2] += (data[2]&0x0f); // convert BCD coding into hours (second digit)
|
|
|
|
time[3] = (data[3]&0x07); // convert BCD coding into days
|
|
|
|
time[4] = ((data[4]&0x30)>>4)*10+(data[4]&0x0f); // convert BCD coding into date
|
|
|
|
time[5] = ((data[5]&0x10)>>4)*10+(data[5]&0x0f); // convert BCD coding into month
|
|
|
|
time[6] = ((data[6]&0xf0)>>4)*10+(data[6]&0x0f); // convert BCD coding into year
|
|
|
|
return time;
|
|
|
|
}
|
|
|
|
|
2017-04-03 13:05:30 +02:00
|
|
|
bool rtc_ds1307_read_ram(uint8_t* data, uint8_t start, uint8_t length)
|
2016-08-14 18:37:58 +02:00
|
|
|
{
|
2017-04-03 13:05:30 +02:00
|
|
|
// sanity checks
|
|
|
|
if (data==NULL || length==0) { // nothing to read
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (start>55 || start+length>56) { // out of bounds RAM
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
const uint8_t address[] = {0x08+start}; // memory address for data
|
|
|
|
return i2c_master_read(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data)); // read RAM (starting at 0x08)
|
2016-08-14 18:37:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool rtc_ds1307_oscillator_disable(void)
|
|
|
|
{
|
|
|
|
uint8_t data[1] = {0}; // to write CH value data over I2C
|
2017-04-03 13:05:30 +02:00
|
|
|
const uint8_t address[] = {0x00}; // memory address for data
|
|
|
|
if (!i2c_master_read(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data))) { // read seconds with CH value
|
|
|
|
return false;
|
|
|
|
}
|
2016-08-14 18:37:58 +02:00
|
|
|
data[0] |= 0x80; // set CH to disable oscillator
|
2017-04-03 13:05:30 +02:00
|
|
|
return i2c_master_write(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data)); // write current seconds with CH value
|
2016-08-14 18:37:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool rtc_ds1307_oscillator_enable(void)
|
|
|
|
{
|
|
|
|
uint8_t data[1] = {0}; // to write CH value data over I2C
|
2017-04-03 13:05:30 +02:00
|
|
|
const uint8_t address[] = {0x00}; // memory address for data
|
|
|
|
if (!i2c_master_read(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data))) { // read seconds with CH value
|
|
|
|
return false;
|
|
|
|
}
|
2016-08-14 18:37:58 +02:00
|
|
|
data[0] &= 0x7f; // clear CH to enable oscillator
|
2017-04-03 13:05:30 +02:00
|
|
|
return i2c_master_write(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data)); // write current seconds with CH value
|
2016-08-14 18:37:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool rtc_ds1307_write_square_wave(uint16_t frequency)
|
|
|
|
{
|
|
|
|
uint8_t data[1] = {0}; // to write control register value data over I2C
|
|
|
|
switch (frequency) { // set RS1/RS0 based on frequency
|
|
|
|
case 0:
|
|
|
|
data[0] = 0;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
data[0] = 0|(1<<4);
|
|
|
|
break;
|
|
|
|
case 4096:
|
|
|
|
data[0] = 1|(1<<4);
|
|
|
|
break;
|
|
|
|
case 8192:
|
|
|
|
data[0] = 2|(1<<4);
|
|
|
|
break;
|
|
|
|
case 32768:
|
|
|
|
data[0] = 3|(1<<4);
|
|
|
|
break;
|
|
|
|
default: // unspecified frequency
|
|
|
|
return false;
|
|
|
|
}
|
2017-04-03 13:05:30 +02:00
|
|
|
const uint8_t address[] = {0x07}; // memory address for data
|
|
|
|
return i2c_master_write(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data)); // write current seconds with CH value
|
2016-08-14 18:37:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool rtc_ds1307_write_seconds(uint8_t seconds)
|
|
|
|
{
|
|
|
|
if (seconds>59) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
uint8_t data[1] = {0}; // to read CH value data and write seconds value over I2C
|
2017-04-03 13:05:30 +02:00
|
|
|
const uint8_t address[] = {0x00}; // memory address for data
|
|
|
|
if (!i2c_master_read(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data))) { // read seconds with CH value
|
2016-08-14 18:37:58 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
data[0] &= 0x80; // only keep CH flag
|
|
|
|
data[0] |= (((seconds/10)%6)<<4)+(seconds%10); // encode seconds in BCD format
|
2017-04-03 13:05:30 +02:00
|
|
|
|
|
|
|
return i2c_master_write(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data)); // write current seconds with previous CH value
|
2016-08-14 18:37:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool rtc_ds1307_write_minutes(uint8_t minutes)
|
|
|
|
{
|
|
|
|
if (minutes>59) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
uint8_t data[1] = {0}; // to write time value
|
|
|
|
data[0] = (((minutes/10)%6)<<4)+(minutes%10); // encode minutes in BCD format
|
2017-04-03 13:05:30 +02:00
|
|
|
|
|
|
|
const uint8_t address[] = {0x01}; // memory address for data
|
|
|
|
return i2c_master_write(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data)); // write time value on RTC
|
2016-08-14 18:37:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool rtc_ds1307_write_hours(uint8_t hours)
|
|
|
|
{
|
|
|
|
if (hours>24) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
uint8_t data[1] = {0}; // to write time value
|
|
|
|
data[0] = (((hours/10)%3)<<4)+(hours%10); // encode hours in BCD 24h format
|
2017-04-03 13:05:30 +02:00
|
|
|
|
|
|
|
const uint8_t address[] = {0x02}; // memory address for data
|
|
|
|
return i2c_master_write(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data)); // write time value on RTC
|
2016-08-14 18:37:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool rtc_ds1307_write_day(uint8_t day)
|
|
|
|
{
|
|
|
|
if (day<1 || day>7) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
uint8_t data[1] = {0}; // to write time value
|
|
|
|
data[0] = (day%8); // encode day in BCD format
|
2017-04-03 13:05:30 +02:00
|
|
|
|
|
|
|
const uint8_t address[] = {0x03}; // memory address for data
|
|
|
|
return i2c_master_write(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data)); // write time value on RTC
|
2016-08-14 18:37:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool rtc_ds1307_write_date(uint8_t date)
|
|
|
|
{
|
|
|
|
if (date<1 || date>31) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
uint8_t data[1] = {0}; // to write time value
|
|
|
|
data[0] = (((date/10)%4)<<4)+(date%10); // encode date in BCD format
|
2017-04-03 13:05:30 +02:00
|
|
|
|
|
|
|
const uint8_t address[] = {0x04}; // memory address for data
|
|
|
|
return i2c_master_write(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data)); // write time value on RTC
|
2016-08-14 18:37:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool rtc_ds1307_write_month(uint8_t month)
|
|
|
|
{
|
|
|
|
if (month<1 || month>12) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
uint8_t data[1] = {0}; // to write time value
|
|
|
|
data[0] = (((month/10)%2)<<4)+(month%10); // encode month in BCD format
|
2017-04-03 13:05:30 +02:00
|
|
|
|
|
|
|
const uint8_t address[] = {0x05}; // memory address for data
|
|
|
|
return i2c_master_write(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data)); // write time value on RTC
|
2016-08-14 18:37:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool rtc_ds1307_write_year(uint8_t year)
|
|
|
|
{
|
|
|
|
if (year>99) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
uint8_t data[1] = {0}; // to write time value
|
|
|
|
data[0] = (((year/10)%10)<<4)+(year%10); // encode year in BCD format
|
2017-04-03 13:05:30 +02:00
|
|
|
|
|
|
|
const uint8_t address[] = {0x06}; // memory address for data
|
|
|
|
return i2c_master_write(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data)); // write time value on RTC
|
2016-08-14 18:37:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool rtc_ds1307_write_time(uint8_t seconds, uint8_t minutes, uint8_t hours, uint8_t day, uint8_t date, uint8_t month, uint8_t year)
|
|
|
|
{
|
|
|
|
uint8_t data[7] = {0}; // to write all time values
|
2017-04-03 13:05:30 +02:00
|
|
|
const uint8_t address[] = {0x00}; // memory address for data
|
2016-08-14 18:37:58 +02:00
|
|
|
// seconds
|
|
|
|
if (seconds>59) {
|
|
|
|
return false;
|
|
|
|
}
|
2017-04-03 13:05:30 +02:00
|
|
|
if (!i2c_master_read(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, 1)) { // read seconds with CH value
|
2016-08-14 18:37:58 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
data[0] &= 0x80; // only keep CH flag
|
|
|
|
data[0] |= (((seconds/10)%6)<<4)+(seconds%10); // encode seconds in BCD format
|
|
|
|
// minutes
|
|
|
|
if (minutes>59) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
data[1] = (((minutes/10)%6)<<4)+(minutes%10); // encode minutes in BCD format
|
|
|
|
// hours
|
|
|
|
if (hours>24) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
data[2] = (((hours/10)%3)<<4)+(hours%10); // encode hours in BCD 24h format
|
|
|
|
// day
|
|
|
|
if (day<1 || day>7) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
data[3] = (day%8); // encode day in BCD format
|
|
|
|
// date
|
|
|
|
if (date<1 || date>31) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
data[4] = (((date/10)%4)<<4)+(date%10); // encode date in BCD format
|
|
|
|
// month
|
|
|
|
if (month<1 || month>12) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
data[5] = (((month/10)%2)<<4)+(month%10); // encode month in BCD format
|
|
|
|
// year
|
|
|
|
if (year>99) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
data[6] = (((year/10)%10)<<4)+(year%10); // encode year in BCD format
|
|
|
|
|
2017-04-03 13:05:30 +02:00
|
|
|
return i2c_master_write(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data)); // write time value on RTC
|
2016-08-14 18:37:58 +02:00
|
|
|
}
|
|
|
|
|
2017-04-03 13:05:30 +02:00
|
|
|
bool rtc_ds1307_write_ram(uint8_t* data, uint8_t start, uint8_t length)
|
2016-08-14 18:37:58 +02:00
|
|
|
{
|
2017-04-03 13:05:30 +02:00
|
|
|
// sanity checks
|
|
|
|
if (data==NULL || length==0) { // nothing to read
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (start>55 || start+length>56) { // out of bounds RAM
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
const uint8_t address[] = {0x08+start}; // memory address for data
|
|
|
|
return i2c_master_write(RTC_DS1307_I2C_ADDR, address, LENGTH(address), data, LENGTH(data)); // write RAM (starting at 0x08)
|
2016-08-14 18:37:58 +02:00
|
|
|
}
|