extras: ds3231: Add support for DS3231 real-time clock (RTC)
Add support for DS3231 extremely accurate I2C real-time clock (RTC). Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@gmail.com>
This commit is contained in:
		
							parent
							
								
									083aa0451a
								
							
						
					
					
						commit
						782cdfd11d
					
				
					 4 changed files with 514 additions and 0 deletions
				
			
		
							
								
								
									
										22
									
								
								extras/ds3231/LICENSE
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								extras/ds3231/LICENSE
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
The MIT License (MIT)
 | 
			
		||||
 | 
			
		||||
Copyright (c) 2015 Richard A Burton <richardaburton@gmail.com>
 | 
			
		||||
Copyright (c) 2016 Bhuvanchandra DV <bhuvanchandra.dv@gmail.com>
 | 
			
		||||
 | 
			
		||||
Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
in the Software without restriction, including without limitation the rights
 | 
			
		||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
furnished to do so, subject to the following conditions:
 | 
			
		||||
 | 
			
		||||
The above copyright notice and this permission notice shall be included in
 | 
			
		||||
all copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
			
		||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
THE SOFTWARE.
 | 
			
		||||
							
								
								
									
										9
									
								
								extras/ds3231/component.mk
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								extras/ds3231/component.mk
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
# Component makefile for extras/ds3231
 | 
			
		||||
 | 
			
		||||
# expected anyone using bmp driver includes it as 'ds3231/ds3231.h'
 | 
			
		||||
INC_DIRS += $(ds3231_ROOT)..
 | 
			
		||||
 | 
			
		||||
# args for passing into compile rule generation
 | 
			
		||||
ds3231_SRC_DIR =  $(ds3231_ROOT)
 | 
			
		||||
 | 
			
		||||
$(eval $(call component_compile_rules,ds3231))
 | 
			
		||||
							
								
								
									
										296
									
								
								extras/ds3231/ds3231.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										296
									
								
								extras/ds3231/ds3231.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,296 @@
 | 
			
		|||
/* Driver for DS3231 high precision RTC module
 | 
			
		||||
 *
 | 
			
		||||
 * Part of esp-open-rtos
 | 
			
		||||
 * Copyright (C) 2015 Richard A Burton <richardaburton@gmail.com>
 | 
			
		||||
 * Copyright (C) 2016 Bhuvanchandra DV <bhuvanchandra.dv@gmail.com>
 | 
			
		||||
 * MIT Licensed as described in the file LICENSE
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "ds3231.h"
 | 
			
		||||
#include "espressif/esp_common.h"
 | 
			
		||||
#include "espressif/sdk_private.h"
 | 
			
		||||
#include "esp8266.h"
 | 
			
		||||
 | 
			
		||||
#include "i2c/i2c.h"
 | 
			
		||||
 | 
			
		||||
/* Convert normal decimal to binary coded decimal */
 | 
			
		||||
static inline uint8_t  decToBcd(uint8_t dec)
 | 
			
		||||
{
 | 
			
		||||
    return(((dec / 10) * 16) + (dec % 10));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Convert binary coded decimal to normal decimal */
 | 
			
		||||
static inline uint8_t  bcdToDec(uint8_t bcd)
 | 
			
		||||
{
 | 
			
		||||
    return(((bcd / 16) * 10) + (bcd % 16));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Send a number of bytes to the rtc over i2c
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
static inline bool ds3231_send(uint8_t *data, uint8_t len)
 | 
			
		||||
{
 | 
			
		||||
    return i2c_slave_write(DS3231_ADDR, data, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Read a number of bytes from the rtc over i2c
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
static inline bool ds3231_recv(uint8_t *data, uint8_t len)
 | 
			
		||||
{
 | 
			
		||||
    return i2c_slave_read(DS3231_ADDR, data[0], data, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ds3231_setTime(struct tm *time)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t data[8];
 | 
			
		||||
 | 
			
		||||
    /* start register */
 | 
			
		||||
    data[0] = DS3231_ADDR_TIME;
 | 
			
		||||
    /* time/date data */
 | 
			
		||||
    data[1] = decToBcd(time->tm_sec);
 | 
			
		||||
    data[2] = decToBcd(time->tm_min);
 | 
			
		||||
    data[3] = decToBcd(time->tm_hour);
 | 
			
		||||
    data[4] = decToBcd(time->tm_wday + 1);
 | 
			
		||||
    data[5] = decToBcd(time->tm_mday);
 | 
			
		||||
    data[6] = decToBcd(time->tm_mon + 1);
 | 
			
		||||
    data[7] = decToBcd(time->tm_year - 100);
 | 
			
		||||
 | 
			
		||||
    return ds3231_send(data, 8);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ds3231_setAlarm(uint8_t alarms, struct tm *time1, uint8_t option1, struct tm *time2, uint8_t option2)
 | 
			
		||||
{
 | 
			
		||||
    int i = 0;
 | 
			
		||||
    uint8_t data[8];
 | 
			
		||||
 | 
			
		||||
    /* start register */
 | 
			
		||||
    data[i++] = (alarms == DS3231_ALARM_2 ? DS3231_ADDR_ALARM2 : DS3231_ADDR_ALARM1);
 | 
			
		||||
 | 
			
		||||
    /* alarm 1 data */
 | 
			
		||||
    if (alarms != DS3231_ALARM_2) {
 | 
			
		||||
        data[i++] = (option1 >= DS3231_ALARM1_MATCH_SEC ? decToBcd(time1->tm_sec) : DS3231_ALARM_NOTSET);
 | 
			
		||||
        data[i++] = (option1 >= DS3231_ALARM1_MATCH_SECMIN ? decToBcd(time1->tm_min) : DS3231_ALARM_NOTSET);
 | 
			
		||||
        data[i++] = (option1 >= DS3231_ALARM1_MATCH_SECMINHOUR ? decToBcd(time1->tm_hour) : DS3231_ALARM_NOTSET);
 | 
			
		||||
        data[i++] = (option1 == DS3231_ALARM1_MATCH_SECMINHOURDAY ? (decToBcd(time1->tm_wday + 1) & DS3231_ALARM_WDAY) :
 | 
			
		||||
            (option1 == DS3231_ALARM1_MATCH_SECMINHOURDATE ? decToBcd(time1->tm_mday) : DS3231_ALARM_NOTSET));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* alarm 2 data */
 | 
			
		||||
    if (alarms != DS3231_ALARM_1) {
 | 
			
		||||
        data[i++] = (option2 >= DS3231_ALARM2_MATCH_MIN ? decToBcd(time2->tm_min) : DS3231_ALARM_NOTSET);
 | 
			
		||||
        data[i++] = (option2 >= DS3231_ALARM2_MATCH_MINHOUR ? decToBcd(time2->tm_hour) : DS3231_ALARM_NOTSET);
 | 
			
		||||
        data[i++] = (option2 == DS3231_ALARM2_MATCH_MINHOURDAY ? (decToBcd(time2->tm_wday + 1) & DS3231_ALARM_WDAY) :
 | 
			
		||||
            (option2 == DS3231_ALARM2_MATCH_MINHOURDATE ? decToBcd(time2->tm_mday) : DS3231_ALARM_NOTSET));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return ds3231_send(data, i);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Get a byte containing just the requested bits
 | 
			
		||||
 * pass the register address to read, a mask to apply to the register and
 | 
			
		||||
 * an uint* for the output
 | 
			
		||||
 * you can test this value directly as true/false for specific bit mask
 | 
			
		||||
 * of use a mask of 0xff to just return the whole register byte
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
bool ds3231_getFlag(uint8_t addr, uint8_t mask, uint8_t *flag)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t data[1];
 | 
			
		||||
 | 
			
		||||
    /* get register */
 | 
			
		||||
    data[0] = addr;
 | 
			
		||||
    if (ds3231_send(data, 1) && ds3231_recv(data, 1)) {
 | 
			
		||||
        /* return only requested flag */
 | 
			
		||||
        *flag = (data[0] & mask);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Set/clear bits in a byte register, or replace the byte altogether
 | 
			
		||||
 * pass the register address to modify, a byte to replace the existing
 | 
			
		||||
 * value with or containing the bits to set/clear and one of
 | 
			
		||||
 * DS3231_SET/DS3231_CLEAR/DS3231_REPLACE
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
bool ds3231_setFlag(uint8_t addr, uint8_t bits, uint8_t mode)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t data[2];
 | 
			
		||||
 | 
			
		||||
    data[0] = addr;
 | 
			
		||||
    /* get status register */
 | 
			
		||||
    if (ds3231_send(data, 1) && ds3231_recv(data+1, 1)) {
 | 
			
		||||
        /* clear the flag */
 | 
			
		||||
        if (mode == DS3231_REPLACE)
 | 
			
		||||
            data[1] = bits;
 | 
			
		||||
        else if (mode == DS3231_SET)
 | 
			
		||||
            data[1] |= bits;
 | 
			
		||||
        else
 | 
			
		||||
            data[1] &= ~bits;
 | 
			
		||||
 | 
			
		||||
        if (ds3231_send(data, 2)) {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ds3231_getOscillatorStopFlag(bool *flag)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t f;
 | 
			
		||||
 | 
			
		||||
    if (ds3231_getFlag(DS3231_ADDR_STATUS, DS3231_STAT_OSCILLATOR, &f)) {
 | 
			
		||||
        *flag = (f ? true : false);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool ds3231_clearOscillatorStopFlag()
 | 
			
		||||
{
 | 
			
		||||
    return ds3231_setFlag(DS3231_ADDR_STATUS, DS3231_STAT_OSCILLATOR, DS3231_CLEAR);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool ds3231_getAlarmFlags(uint8_t *alarms)
 | 
			
		||||
{
 | 
			
		||||
    return ds3231_getFlag(DS3231_ADDR_STATUS, DS3231_ALARM_BOTH, alarms);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool ds3231_clearAlarmFlags(uint8_t alarms)
 | 
			
		||||
{
 | 
			
		||||
    return ds3231_setFlag(DS3231_ADDR_STATUS, alarms, DS3231_CLEAR);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool ds3231_enableAlarmInts(uint8_t alarms)
 | 
			
		||||
{
 | 
			
		||||
    return ds3231_setFlag(DS3231_ADDR_CONTROL, DS3231_CTRL_ALARM_INTS | alarms, DS3231_SET);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool ds3231_disableAlarmInts(uint8_t alarms)
 | 
			
		||||
{
 | 
			
		||||
    /* Just disable specific alarm(s) requested
 | 
			
		||||
     * does not disable alarm interrupts generally (which would enable the squarewave)
 | 
			
		||||
     */
 | 
			
		||||
    return ds3231_setFlag(DS3231_ADDR_CONTROL, alarms, DS3231_CLEAR);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool ds3231_enable32khz()
 | 
			
		||||
{
 | 
			
		||||
    return ds3231_setFlag(DS3231_ADDR_STATUS, DS3231_STAT_32KHZ, DS3231_SET);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool ds3231_disable32khz()
 | 
			
		||||
{
 | 
			
		||||
    return ds3231_setFlag(DS3231_ADDR_STATUS, DS3231_STAT_32KHZ, DS3231_CLEAR);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool ds3231_enableSquarewave()
 | 
			
		||||
{
 | 
			
		||||
    return ds3231_setFlag(DS3231_ADDR_CONTROL, DS3231_CTRL_ALARM_INTS, DS3231_CLEAR);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline bool ds3231_disableSquarewave()
 | 
			
		||||
{
 | 
			
		||||
    return ds3231_setFlag(DS3231_ADDR_CONTROL, DS3231_CTRL_ALARM_INTS, DS3231_SET);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ds3231_setSquarewaveFreq(uint8_t freq)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t flag = 0;
 | 
			
		||||
 | 
			
		||||
    if (ds3231_getFlag(DS3231_ADDR_CONTROL, 0xff, &flag)) {
 | 
			
		||||
        /* clear current rate */
 | 
			
		||||
        flag &= ~DS3231_CTRL_SQWAVE_8192HZ;
 | 
			
		||||
        /* set new rate */
 | 
			
		||||
        flag |= freq;
 | 
			
		||||
 | 
			
		||||
        return ds3231_setFlag(DS3231_ADDR_CONTROL, flag, DS3231_REPLACE);
 | 
			
		||||
    }
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ds3231_getRawTemp(int16_t *temp)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t data[2];
 | 
			
		||||
 | 
			
		||||
    data[0] = DS3231_ADDR_TEMP;
 | 
			
		||||
    if (ds3231_send(data, 1) && ds3231_recv(data, 2)) {
 | 
			
		||||
        *temp = (int16_t)(int8_t)data[0] << 2 | data[1] >> 6;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ds3231_getTempInteger(int8_t *temp)
 | 
			
		||||
{
 | 
			
		||||
    int16_t tInt;
 | 
			
		||||
 | 
			
		||||
    if (ds3231_getRawTemp(&tInt)) {
 | 
			
		||||
        *temp = tInt >> 2;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ds3231_getTempFloat(float *temp)
 | 
			
		||||
{
 | 
			
		||||
    int16_t tInt;
 | 
			
		||||
 | 
			
		||||
    if (ds3231_getRawTemp(&tInt)) {
 | 
			
		||||
        *temp = tInt * 0.25;
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ds3231_getTime(struct tm *time)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t data[7];
 | 
			
		||||
 | 
			
		||||
    /* start register address */
 | 
			
		||||
    data[0] = DS3231_ADDR_TIME;
 | 
			
		||||
    if (!ds3231_send(data, 1)) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* read time */
 | 
			
		||||
    if (!ds3231_recv(data, 7)) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* convert to unix time structure */
 | 
			
		||||
    time->tm_sec = bcdToDec(data[0]);
 | 
			
		||||
    time->tm_min = bcdToDec(data[1]);
 | 
			
		||||
    if (data[2] & DS3231_12HOUR_FLAG) {
 | 
			
		||||
        /* 12H */
 | 
			
		||||
        time->tm_hour = bcdToDec(data[2] & DS3231_12HOUR_MASK);
 | 
			
		||||
        /* AM/PM? */
 | 
			
		||||
        if (data[2] & DS3231_PM_FLAG) time->tm_hour += 12;
 | 
			
		||||
    } else {
 | 
			
		||||
        /* 24H */
 | 
			
		||||
        time->tm_hour = bcdToDec(data[2]);
 | 
			
		||||
    }
 | 
			
		||||
    time->tm_wday = bcdToDec(data[3]) - 1;
 | 
			
		||||
    time->tm_mday = bcdToDec(data[4]);
 | 
			
		||||
    time->tm_mon  = bcdToDec(data[5] & DS3231_MONTH_MASK) - 1;
 | 
			
		||||
    time->tm_year = bcdToDec(data[6]) + 100;
 | 
			
		||||
    time->tm_isdst = 0;
 | 
			
		||||
 | 
			
		||||
    // apply a time zone (if you are not using localtime on the rtc or you want to check/apply DST)
 | 
			
		||||
    //applyTZ(time);
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ds3231_Init(uint8_t scl, uint8_t sda)
 | 
			
		||||
{
 | 
			
		||||
    i2c_init(scl, sda);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										187
									
								
								extras/ds3231/ds3231.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								extras/ds3231/ds3231.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,187 @@
 | 
			
		|||
/* Driver for DS3231 high precision RTC module
 | 
			
		||||
 *
 | 
			
		||||
 * Part of esp-open-rtos
 | 
			
		||||
 * Copyright (C) 2015 Richard A Burton <richardaburton@gmail.com>
 | 
			
		||||
 * Copyright (C) 2016 Bhuvanchandra DV <bhuvanchandra.dv@gmail.com>
 | 
			
		||||
 * MIT Licensed as described in the file LICENSE
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef __DS3231_H__
 | 
			
		||||
#define __DS3231_H__
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
 | 
			
		||||
#define DS3231_ADDR            0x68
 | 
			
		||||
 | 
			
		||||
#define DS3231_STAT_OSCILLATOR        0x80
 | 
			
		||||
#define DS3231_STAT_32KHZ        0x08
 | 
			
		||||
#define DS3231_STAT_BUSY        0x04
 | 
			
		||||
#define DS3231_STAT_ALARM_2        0x02
 | 
			
		||||
#define DS3231_STAT_ALARM_1        0x01
 | 
			
		||||
 | 
			
		||||
#define DS3231_CTRL_OSCILLATOR        0x80
 | 
			
		||||
#define DS3231_CTRL_SQUAREWAVE_BB    0x40
 | 
			
		||||
#define DS3231_CTRL_TEMPCONV        0x20
 | 
			
		||||
#define DS3231_CTRL_SQWAVE_4096HZ    0x10
 | 
			
		||||
#define DS3231_CTRL_SQWAVE_1024HZ    0x08
 | 
			
		||||
#define DS3231_CTRL_SQWAVE_8192HZ    0x18
 | 
			
		||||
#define DS3231_CTRL_SQWAVE_1HZ        0x00
 | 
			
		||||
#define DS3231_CTRL_ALARM_INTS        0x04
 | 
			
		||||
#define DS3231_CTRL_ALARM2_INT        0x02
 | 
			
		||||
#define DS3231_CTRL_ALARM1_INT        0x01
 | 
			
		||||
 | 
			
		||||
#define DS3231_ALARM_WDAY        0x40
 | 
			
		||||
#define DS3231_ALARM_NOTSET        0x80
 | 
			
		||||
 | 
			
		||||
#define DS3231_ADDR_TIME        0x00
 | 
			
		||||
#define DS3231_ADDR_ALARM1        0x07
 | 
			
		||||
#define DS3231_ADDR_ALARM2        0x0b
 | 
			
		||||
#define DS3231_ADDR_CONTROL        0x0e
 | 
			
		||||
#define DS3231_ADDR_STATUS        0x0f
 | 
			
		||||
#define DS3231_ADDR_AGING        0x10
 | 
			
		||||
#define DS3231_ADDR_TEMP        0x11
 | 
			
		||||
 | 
			
		||||
#define DS3231_12HOUR_FLAG        0x40
 | 
			
		||||
#define DS3231_12HOUR_MASK        0x1f
 | 
			
		||||
#define DS3231_PM_FLAG            0x20
 | 
			
		||||
#define DS3231_MONTH_MASK        0x1f
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    DS3231_SET = 0,
 | 
			
		||||
    DS3231_CLEAR,
 | 
			
		||||
    DS3231_REPLACE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    DS3231_ALARM_NONE = 0,
 | 
			
		||||
    DS3231_ALARM_1,
 | 
			
		||||
    DS3231_ALARM_2,
 | 
			
		||||
    DS3231_ALARM_BOTH
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    DS3231_ALARM1_EVERY_SECOND = 0,
 | 
			
		||||
    DS3231_ALARM1_MATCH_SEC,
 | 
			
		||||
    DS3231_ALARM1_MATCH_SECMIN,
 | 
			
		||||
    DS3231_ALARM1_MATCH_SECMINHOUR,
 | 
			
		||||
    DS3231_ALARM1_MATCH_SECMINHOURDAY,
 | 
			
		||||
    DS3231_ALARM1_MATCH_SECMINHOURDATE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    DS3231_ALARM2_EVERY_MIN = 0,
 | 
			
		||||
    DS3231_ALARM2_MATCH_MIN,
 | 
			
		||||
    DS3231_ALARM2_MATCH_MINHOUR,
 | 
			
		||||
    DS3231_ALARM2_MATCH_MINHOURDAY,
 | 
			
		||||
    DS3231_ALARM2_MATCH_MINHOURDATE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Set the time on the rtc
 | 
			
		||||
 * timezone agnostic, pass whatever you like
 | 
			
		||||
 * I suggest using GMT and applying timezone and DST when read back
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
bool ds3231_setTime(struct tm *time);
 | 
			
		||||
 | 
			
		||||
/* Set alarms
 | 
			
		||||
 * alarm1 works with seconds, minutes, hours and day of week/month, or fires every second
 | 
			
		||||
 * alarm2 works with minutes, hours and day of week/month, or fires every minute
 | 
			
		||||
 * not all combinations are supported, see DS3231_ALARM1_* and DS3231_ALARM2_* defines
 | 
			
		||||
 * for valid options you only need to populate the fields you are using in the tm struct,
 | 
			
		||||
 * and you can set both alarms at the same time (pass DS3231_ALARM_1/DS3231_ALARM_2/DS3231_ALARM_BOTH)
 | 
			
		||||
 * if only setting one alarm just pass 0 for tm struct and option field for the other alarm
 | 
			
		||||
 * if using DS3231_ALARM1_EVERY_SECOND/DS3231_ALARM2_EVERY_MIN you can pass 0 for tm stuct
 | 
			
		||||
 * if you want to enable interrupts for the alarms you need to do that separately
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
bool ds3231_setAlarm(uint8_t alarms, struct tm *time1, uint8_t option1, struct tm *time2, uint8_t option2);
 | 
			
		||||
 | 
			
		||||
/* Check if oscillator has previously stopped, e.g. no power/battery or disabled
 | 
			
		||||
 * sets flag to true if there has been a stop
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
bool ds3231_getOscillatorStopFlag(bool *flag);
 | 
			
		||||
 | 
			
		||||
/* Clear the oscillator stopped flag
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
bool ds3231_clearOscillatorStopFlag();
 | 
			
		||||
 | 
			
		||||
/* Check which alarm(s) have past
 | 
			
		||||
 * sets alarms to DS3231_ALARM_NONE/DS3231_ALARM_1/DS3231_ALARM_2/DS3231_ALARM_BOTH
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
bool ds3231_getAlarmFlags(uint8_t *alarms);
 | 
			
		||||
 | 
			
		||||
/* Clear alarm past flag(s)
 | 
			
		||||
 * pass DS3231_ALARM_1/DS3231_ALARM_2/DS3231_ALARM_BOTH
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
bool ds3231_clearAlarmFlags(uint8_t alarm);
 | 
			
		||||
 | 
			
		||||
/* enable alarm interrupts (and disables squarewave)
 | 
			
		||||
 * pass DS3231_ALARM_1/DS3231_ALARM_2/DS3231_ALARM_BOTH
 | 
			
		||||
 * if you set only one alarm the status of the other is not changed
 | 
			
		||||
 * you must also clear any alarm past flag(s) for alarms with
 | 
			
		||||
 * interrupt enabled, else it will trigger immediately
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
bool ds3231_enableAlarmInts(uint8_t alarms);
 | 
			
		||||
 | 
			
		||||
/* Disable alarm interrupts (does not (re-)enable squarewave)
 | 
			
		||||
 * pass DS3231_ALARM_1/DS3231_ALARM_2/DS3231_ALARM_BOTH
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
bool ds3231_disableAlarmInts(uint8_t alarms);
 | 
			
		||||
 | 
			
		||||
/* Enable the output of 32khz signal
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
bool ds3231_enable32khz();
 | 
			
		||||
 | 
			
		||||
/* Disable the output of 32khz signal
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
bool ds3231_disable32khz();
 | 
			
		||||
 | 
			
		||||
/* Enable the squarewave output (disables alarm interrupt functionality)
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
bool ds3231_enableSquarewave();
 | 
			
		||||
 | 
			
		||||
/* Disable the squarewave output (which re-enables alarm interrupts, but individual
 | 
			
		||||
 * alarm interrupts also need to be enabled, if not already, before they will trigger)
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
bool ds3231_disableSquarewave();
 | 
			
		||||
 | 
			
		||||
/* Set the frequency of the squarewave output (but does not enable it)
 | 
			
		||||
 * pass DS3231_SQUAREWAVE_RATE_1HZ/DS3231_SQUAREWAVE_RATE_1024HZ/DS3231_SQUAREWAVE_RATE_4096HZ/DS3231_SQUAREWAVE_RATE_8192HZ
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
bool ds3231_setSquarewaveFreq(uint8_t freq);
 | 
			
		||||
 | 
			
		||||
/* Get the raw value
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
bool ds3231_getRawTemp(int16_t *temp);
 | 
			
		||||
 | 
			
		||||
/* Get the temperature as an integer
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
bool ds3231_getTempInteger(int8_t *temp);
 | 
			
		||||
 | 
			
		||||
/* Get the temerapture as a float (in quarter degree increments)
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
bool ds3231_getTempFloat(float *temp);
 | 
			
		||||
 | 
			
		||||
/* Get the time from the rtc, populates a supplied tm struct
 | 
			
		||||
 * returns true to indicate success
 | 
			
		||||
 */
 | 
			
		||||
bool ds3231_getTime(struct tm *time);
 | 
			
		||||
void ds3231_Init(uint8_t scl, uint8_t sda);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue