Diff: DS3231.h
- Revision:
- 1:8ac54576db6d
- Parent:
- 0:38f84a23a08a
- Child:
- 2:3710775b1864
--- a/DS3231.h Wed Dec 20 12:17:53 2017 +0000
+++ b/DS3231.h Wed Dec 20 12:24:11 2017 +0000
@@ -0,0 +1,483 @@
+/**
+ * @brief DS3231.h
+ * @details Extremely Accurate I2C-Integrated RTC/TCXO/Crystal.
+ * Header file.
+ *
+ *
+ * @return NA
+ *
+ * @author Manuel Caballero
+ * @date 20/December/2017
+ * @version 20/December/2017 The ORIGIN
+ * @pre NaN.
+ * @warning NaN
+ * @pre This code belongs to AqueronteBlog ( http://unbarquero.blogspot.com ).
+ */
+#ifndef DS3231_H
+#define DS3231_H
+
+#include "mbed.h"
+
+
+/**
+ Example:
+
+[todo]
+
+*/
+
+
+/*!
+ Library for the DS3231 Extremely Accurate I2C-Integrated RTC/TCXO/Crystal.
+*/
+class DS3231
+{
+public:
+ /**
+ * @brief DEFAULT ADDRESSES
+ */
+ typedef enum {
+ DS3231_ADDRESS = ( 0x68 << 1 ) /*!< DS3231 I2C Address */
+ } DS3231_address_t;
+
+
+// REGISTERS
+ /**
+ * @brief TIMEKEEPING REGISTERS
+ */
+ typedef enum {
+ DS3231_SECONDS = 0x00, /*!< Seconds. RANGE 00-59 */
+ DS3231_MINUTES = 0x01, /*!< Minutes. RANGE 00-59 */
+ DS3231_HOURS = 0x02, /*!< Hours. 1-12 + AM/PM 00-23 */
+ DS3231_DAY = 0x03, /*!< Day. 1-7 */
+ DS3231_DATE = 0x04, /*!< Date. 01-31 */
+ DS3231_MONTH_CENTURY = 0x05, /*!< Month/Century. 01-12 + Century */
+ DS3231_YEAR = 0x06, /*!< Year. 00-99 */
+ DS3231_ALARM_1_SECONDS = 0x07, /*!< Alarm 1 seconds. 00-59 */
+ DS3231_ALARM_1_MINUTES = 0x08, /*!< Alarm 1 minutes. 00-59 */
+ DS3231_ALARM_1_HOURS = 0x09, /*!< Alarm 1 hours. 1-12 + AM/PM 00-23 */
+ DS3231_ALARM_1_DAY_DATE = 0x0A, /*!< Alarm 1 day/date. 1-7/1-31 */
+ DS3231_ALARM_2_MINUTES = 0x0B, /*!< Alarm 2 minutes. 00-59 */
+ DS3231_ALARM_2_HOURS = 0x0C, /*!< Alarm 2 hours. 1-12 + AM/PM 00-23 */
+ DS3231_ALARM_2_DAY_DATE = 0x0D, /*!< Alarm 2 day/date. 1-7/1-31 */
+ DS3231_CONTROL = 0x0E, /*!< Control */
+ DS3231_CONTROL_STATUS = 0x0F, /*!< Control/Status */
+ DS3231_AGING_OFFSET = 0x10, /*!< Aging offset */
+ DS3231_MSB_TEMPERATURE = 0x11, /*!< MSB of Temp */
+ DS3231_LSB_TEMPERATURE = 0x12 /*!< LSB of Temp */
+ } DS3231_registers_t;
+
+
+
+// CONTROL REGISTER
+ /**
+ * @brief Enable Oscillator ( #EOSC )
+ */
+ typedef enum {
+ CONTROL_STATUS_ENABLE_OSCILLATOR_MASK = ( 1 << 7 ), /*!< #EOSC Mask */
+ CONTROL_STATUS_ENABLE_OSCILLATOR_ENABLED = ( 1 << 7 ), /*!< Enable oscillator */
+ CONTROL_STATUS_ENABLE_OSCILLATOR_DISABLED = ( 0 << 7 ) /*!< Disable oscillator */
+ } DS3231_control_status_enable_oscillator_t;
+
+
+ /**
+ * @brief Battery-Backed Square-Wave Enable ( BBSQW )
+ */
+ typedef enum {
+ CONTROL_STATUS_BBSQW_MASK = ( 1 << 6 ), /*!< BBSQW Mask */
+ CONTROL_STATUS_BBSQW_ENABLED = ( 1 << 6 ), /*!< Enable BBSQW */
+ CONTROL_STATUS_BBSQW_DISABLED = ( 0 << 6 ) /*!< Disable BBSQW */
+ } DS3231_control_status_bbsqw_t;
+
+
+ /**
+ * @brief Convert Temperature ( CONV )
+ */
+ typedef enum {
+ CONTROL_STATUS_CONVERT_TEMPERATURE_MASK = ( 1 << 5 ), /*!< CONVERT TEMPERATURE Mask */
+ CONTROL_STATUS_CONVERT_TEMPERATURE_ENABLED = ( 1 << 5 ), /*!< Enable CONVERT_TEMPERATURE */
+ CONTROL_STATUS_CONVERT_TEMPERATURE_DISABLED = ( 0 << 5 ) /*!< Disable CONVERT_TEMPERATURE */
+ } DS3231_control_status_convert_temperature_t;
+
+
+ /**
+ * @brief Rate Select ( RS2 and RS1 )
+ */
+ typedef enum {
+ CONTROL_STATUS_RATE_SELECT_MASK = ( 3 << 3 ), /*!< Rate select Mask */
+ CONTROL_STATUS_RATE_SELECT_1_HZ = ( 0 << 3 ), /*!< Rate select 1 Hz */
+ CONTROL_STATUS_RATE_SELECT_1_024_KHZ = ( 1 << 3 ), /*!< Rate select 1.024 kHz */
+ CONTROL_STATUS_RATE_SELECT_4_096_KHZ = ( 2 << 3 ), /*!< Rate select 4.096 kHz */
+ CONTROL_STATUS_RATE_SELECT_8_192_KHZ = ( 3 << 3 ) /*!< Rate select 8.192 kHz */
+ } DS3231_control_status_rate_select_t;
+
+
+ /**
+ * @brief Interrupt Control ( INTCN )
+ */
+ typedef enum {
+ CONTROL_STATUS_INTERRUPT_CONTROL_MASK = ( 1 << 2 ), /*!< Interrupt control Mask */
+ CONTROL_STATUS_INTERRUPT_CONTROL_SQW = ( 0 << 2 ), /*!< Square wave is output */
+ CONTROL_STATUS_INTERRUPT_CONTROL_INT = ( 1 << 2 ) /*!< Alarm activates the output */
+ } DS3231_control_status_interrupt_control_t;
+
+
+ /**
+ * @brief Alarm 2 Interrupt Enable ( A2IE )
+ */
+ typedef enum {
+ CONTROL_STATUS_ALARM2_MASK = ( 1 << 1 ), /*!< Alarm 2 Mask */
+ CONTROL_STATUS_ALARM2_ENABLED = ( 1 << 1 ), /*!< Alarm 2 enabled */
+ CONTROL_STATUS_ALARM2_DISABLED = ( 0 << 1 ) /*!< Alarm 2 disabled */
+ } DS3231_control_status_alarm2_t;
+
+
+ /**
+ * @brief Alarm 1 Interrupt Enable ( A1IE )
+ */
+ typedef enum {
+ CONTROL_STATUS_ALARM1_MASK = ( 1 << 0 ), /*!< Alarm 1 Mask */
+ CONTROL_STATUS_ALARM1_ENABLED = ( 1 << 0 ), /*!< Alarm 1 enabled */
+ CONTROL_STATUS_ALARM1_DISABLED = ( 0 << 0 ) /*!< Alarm 1 disabled */
+ } DS3231_control_status_alarm1_t;
+
+
+
+// STATUS REGISTER
+ /**
+ * @brief Oscillator Stop Flag ( OSF )
+ */
+ typedef enum {
+ STATUS_OSCILLATOR_STOP_FLAG_MASK = ( 1 << 7 ), /*!< OSF Mask */
+ STATUS_OSCILLATOR_STOP_FLAG_ENABLED = ( 1 << 7 ), /*!< Flag ON */
+ STATUS_OSCILLATOR_STOP_FLAG_DISABLED = ( 0 << 7 ), /*!< Flag OFF */
+ STATUS_OSCILLATOR_STOP_FLAG_RESET = ( 0 << 7 ) /*!< Reset flag */
+ } DS3231_status_oscillator_stop_flag_t;
+
+
+ /**
+ * @brief Enable 32kHz Output ( EN32kHz )
+ */
+ typedef enum {
+ STATUS_ENABLE_32KHZ_OUTPUT_MASK = ( 1 << 3 ), /*!< 32kHz output mask */
+ STATUS_ENABLE_32KHZ_OUTPUT_ENABLED = ( 1 << 3 ), /*!< 32kHz output on 32kHz pin */
+ STATUS_ENABLE_32KHZ_OUTPUT_DISABLED = ( 0 << 3 ) /*!< 32kHz output disabled */
+ } DS3231_status_enable_32khz_output_t;
+
+
+ /**
+ * @brief Busy ( BSY )
+ */
+ typedef enum {
+ STATUS_BUSY_MASK = ( 1 << 2 ), /*!< BSY mask */
+ STATUS_BUSY_BUSY = ( 1 << 2 ), /*!< device busy executing TCXO functions */
+ STATUS_BUSY_NOBUSY = ( 0 << 2 ) /*!< device IS NOT busy */
+ } DS3231_status_busy_t;
+
+
+ /**
+ * @brief Alarm 2 Flag ( A2F )
+ */
+ typedef enum {
+ STATUS_ALARM2_FLAG_MASK = ( 1 << 1 ), /*!< Alarm 2 flag mask */
+ STATUS_ALARM2_FLAG_ENABLED = ( 1 << 1 ), /*!< Alarm 2 flag enabled */
+ STATUS_ALARM2_FLAG_DISABLED = ( 0 << 1 ), /*!< Alarm 2 flag disabled */
+ STATUS_ALARM2_FLAG_RESET = ( 0 << 1 ), /*!< Alarm 2 flag reset flag */
+ } DS3231_status_alarm2_flag_t;
+
+
+
+ /**
+ * @brief Alarm 1 Flag ( A1F )
+ */
+ typedef enum {
+ STATUS_ALARM1_FLAG_MASK = ( 1 << 0 ), /*!< Alarm 1 flag mask */
+ STATUS_ALARM1_FLAG_ENABLED = ( 1 << 0 ), /*!< Alarm 1 flag enabled */
+ STATUS_ALARM1_FLAG_DISABLED = ( 0 << 0 ), /*!< Alarm 1 flag disabled */
+ STATUS_ALARM1_FLAG_RESET = ( 0 << 0 ), /*!< Alarm 1 flag reset flag */
+ } DS3231_status_alarm1_flag_t;
+
+
+
+// ALARMS
+ /**
+ * @brief Alarm 1 Mask Bits
+ */
+ typedef enum {
+ ALARM1_ALARM_ONCE_PER_SECOND = 1, /*!< Alarm 1 once per second */
+ ALARM1_WHEN_SECONDS_MATCH = 2, /*!< Alarm 1 when seconds match */
+ ALARM1_WHEN_MINUTES_AND_SECONDS_MATCH = 3, /*!< Alarm 1 when minutes and seconds match */
+ ALARM1_WHEN_HOURS_MINUTES_AND_SECONDS_MATCH = 4, /*!< Alarm 1 when hours, minutes, and seconds match */
+ ALARM1_WHEN_DATE_HOURS_MINUTES_AND_SECONDS_MATCH = 5, /*!< Alarm 1 when date, hours, minutes, and seconds match */
+ ALARM1_WHEN_DAY_HOURS_MINUTES_AND_SECONDS_MATCH = 6 /*!< Alarm 1 when day, hours, minutes, and seconds match */
+ } DS3231_alarm1_register_t;
+
+
+ /**
+ * @brief Alarm 2 Mask Bits
+ */
+ typedef enum {
+ ALARM2_ALARM_ONCE_PER_MINUTE = 1, /*!< Alarm 2 once per minute */
+ ALARM2_WHEN_MINUTES_MATCH = 2, /*!< Alarm 2 when minutes match */
+ ALARM2_WHEN_HOURS_MINUTES_MATCH = 3, /*!< Alarm 2 when hours and minutes match */
+ ALARM2_WHEN_DATE_HOURS_AND_MINUTES_MATCH = 4, /*!< Alarm 2 when date, hours and minutes match */
+ ALARM2_WHEN_DAY_HOURS_AND_MINUTES_MATCH = 5 /*!< Alarm 2 when day, hours and minutes match */
+ } DS3231_alarm2_register_t;
+
+
+// TIMEKEEPING REGISTERS
+// SECONDS
+ typedef enum {
+ SECONDS_SECONDS_MASK = 0x0F, /*!< Seconds Seconds mask */
+ SECONDS_10SECONDS_MASK = 0x70 /*!< Seconds 10Seconds mask */
+ } DS3231_seconds_t;
+
+
+// MINUTES
+ typedef enum {
+ MINUTES_MINUTES_MASK = 0x0F, /*!< Minutes Minutes mask */
+ MINUTES_10MINUTES_MASK = 0x70 /*!< Minutes 10Minutes mask */
+ } DS3231_minutes_t;
+
+
+// HOURS
+ typedef enum {
+ HOURS_HOUR_MASK = 0x0F, /*!< Hour Hour mask */
+ HOURS_10HOUR_MASK = 0x10, /*!< Hour 10Hour mask */
+
+ HOURS_nAM_PM_MASK = 0x20, /*!< Hour #AM/PM mask */
+ HOURS_AM_ENABLED = ( 0 << 5 ), /*!< Hour AM ENABLED */
+ HOURS_PM_ENABLED = ( 1 << 5 ), /*!< Hour PM ENABLED */
+
+ HOURS_12_n24_MASK = 0x40, /*!< Hour 12/#24 mask */
+ HOURS_12_ENABLED = ( 1 << 6 ), /*!< Hour 12 ENABLED */
+ HOURS_24_ENABLED = ( 0 << 6 ), /*!< Hour 24 ENABLED */
+ } DS3231_hours_t;
+
+
+// DAY
+ typedef enum {
+ DAY_DAY_MASK = 0x07 /*!< Day Day mask */
+ } DS3231_day_t;
+
+
+// DATE
+ typedef enum {
+ DATE_DATE_MASK = 0x0F, /*!< Date Date mask */
+ DATE_10DATE_MASK = 0x30 /*!< Date 10Date mask */
+ } DS3231_date_t;
+
+
+// MONTH/CENTURY
+ typedef enum {
+ MONTH_MONTH_MASK = 0x0F, /*!< Month Month mask */
+ MONTH_10MONTH_MASK = 0x10, /*!< Month 10Month mask */
+ MONTH_CENTURY_MASK = 0x80 /*!< Month Century mask */
+ } DS3231_month_t;
+
+
+// YEAR
+ typedef enum {
+ YEAR_YEAR_MASK = 0x0F, /*!< Year Year mask */
+ YEAR_10YEAR_MASK = 0xF0 /*!< Year 10Year mask */
+ } DS3231_year_t;
+
+
+// ALARM 1 SECONDS
+ typedef enum {
+ ALARM1_A1M1_MASK = 0x80, /*!< Alarm1 A1M1 mask */
+ ALARM1_10SECONDS_MASK = 0x70, /*!< Alarm1 10Seconds mask */
+ ALARM1_SECONDS_MASK = 0x0F /*!< Alarm1 Seconds mask */
+ } DS3231_alarm1_seconds_t;
+
+
+// ALARM 1 MINUTES
+ typedef enum {
+ ALARM1_A1M2_MASK = 0x80, /*!< Alarm1 A1M2 mask */
+ ALARM1_10MINUTES_MASK = 0x70, /*!< Alarm1 10Minutes mask */
+ ALARM1_MINUTES_MASK = 0x0F /*!< Alarm1 Minutes mask */
+ } DS3231_alarm1_minutes_t;
+
+
+// ALARM 1 HOURS
+ typedef enum {
+ ALARM1_A1M3_MASK = 0x80, /*!< Alarm1 A1M3 mask */
+ ALARM1_10HOUR_MASK = 0x10, /*!< Alarm1 10Hour mask */
+ ALARM1_HOUR_MASK = 0x0F /*!< Alarm1 Hour mask */
+ } DS3231_alarm1_hours_t;
+
+
+// ALARM 1 DAY/DATE
+ typedef enum {
+ ALARM1_A1M4_MASK = 0x80, /*!< Alarm1 A1M4 mask */
+ ALARM1_DYDT_MASK = 0x40, /*!< Alarm1 DY/DT mask */
+ ALARM1_10DATE_MASK = 0x30, /*!< Alarm1 10Date mask */
+ ALARM1_DATE_DAY_MASK = 0x0F /*!< Alarm1 Day/Date mask */
+ } DS3231_alarm1_day_date_t;
+
+
+// ALARM 2 MINUTES
+ typedef enum {
+ ALARM2_A2M2_MASK = 0x80, /*!< Alarm2 A2M2 mask */
+ ALARM2_10MINUTES_MASK = 0x70, /*!< Alarm2 10Minutes mask */
+ ALARM2_MINUTES_MASK = 0x0F /*!< Alarm2 Minutes mask */
+ } DS3231_alarm2_minutes_t;
+
+
+// ALARM 2 HOURS
+ typedef enum {
+ ALARM2_A2M3_MASK = 0x80, /*!< Alarm2 A1M3 mask */
+ ALARM2_10HOUR_MASK = 0x10, /*!< Alarm2 10Hour mask */
+ ALARM2_HOUR_MASK = 0x0F /*!< Alarm2 Hour mask */
+ } DS3231_alarm2_hours_t;
+
+
+// ALARM 2 DAY/DATE
+ typedef enum {
+ ALARM2_A2M4_MASK = 0x80, /*!< Alarm2 A2M4 mask */
+ ALARM2_DYDT_MASK = 0x40, /*!< Alarm2 DY/DT mask */
+ ALARM2_10DATE_MASK = 0x30, /*!< Alarm2 10Date mask */
+ ALARM2_DATE_DAY_MASK = 0x0F /*!< Alarm2 Day/Date mask */
+ } DS3231_alarm2_day_date_t;
+
+
+
+// MACRO: It turns BCD into decimal
+#define _MYBCD_TO_DECIMAL( x ) ({ \
+ ( ( x & 0x0F ) + ( ( ( x & 0xF0 ) >> 4) * 10) ); \
+ })
+
+// MACRO: It turns decimal into BCD
+#define _MYDECIMAL_TO_BCD( x ) ({ \
+ ( ( ( x / 10) << 4 ) & 0xF0 ) | ( ( x % 10 ) & 0x0F ); \
+ })
+
+
+
+
+
+
+#ifndef DS3231_VECTOR_STRUCT_H
+#define DS3231_VECTOR_STRUCT_H
+ typedef struct {
+ uint8_t MSBTemperature;
+ uint8_t LSBTemperature;
+ uint8_t RawAging;
+ uint8_t Control_Status_Register;
+
+ float Temperature;
+ } DS3231_vector_data_t;
+
+ typedef struct {
+ uint8_t Date;
+ uint8_t Month;
+ uint8_t Year;
+ uint8_t DayOfWeek;
+ uint8_t Century;
+
+ uint8_t Hours;
+ uint8_t Minutes;
+ uint8_t Seconds;
+ uint8_t Mode_nAM_PM; /*!< Mode_nAM_PM = 0 -> AM | Mode_nAM_PM = 0x20 -> PM */
+ uint8_t Mode_12_n24; /*!< Mode_12_n24 = 0x40 -> 12 | Mode_12_n24 = 0 -> 24 */
+ } DS3231_vector_date_time_t;
+#endif
+
+
+
+ /**
+ * @brief INTERNAL CONSTANTS
+ */
+ typedef enum {
+ DS3231_SUCCESS = 0,
+ DS3231_FAILURE = 1,
+ DS3231_TIMEOUT = 1000,
+
+ I2C_SUCCESS = 0 /*!< I2C communication was fine */
+ } DS3231_status_t;
+
+
+
+
+ /** Create an DS3231 object connected to the specified I2C pins.
+ *
+ * @param sda I2C data pin
+ * @param scl I2C clock pin
+ * @param addr I2C slave address
+ * @param freq I2C frequency in Hz.
+ */
+ DS3231 ( PinName sda, PinName scl, uint32_t addr, uint32_t freq );
+
+ /** Delete DS3231 object.
+ */
+ ~DS3231();
+
+ /** It reads the temperature data.
+ */
+ DS3231_status_t DS3231_ReadTemperature ( DS3231_vector_data_t* myTemperature );
+
+ /** It reads the raw temperature data.
+ */
+ DS3231_status_t DS3231_ReadRawTemperature ( DS3231_vector_data_t* myRawTemperature );
+
+ /** It triggers a new temperature measurement.
+ */
+ DS3231_status_t DS3231_StartNewConvertTemperature ( void );
+
+ /** It reads the raw aging data.
+ */
+ DS3231_status_t DS3231_ReadRawAging ( DS3231_vector_data_t* myRawAging );
+
+ /** It sets the 32kHz pin output: Enabled/Disabled.
+ */
+ DS3231_status_t DS3231_Status32kHzPin ( DS3231_status_enable_32khz_output_t my32kHzPin );
+
+ /** It clears alarm flags.
+ */
+ DS3231_status_t DS3231_ClearAlarmFlag ( DS3231_status_alarm1_flag_t myA1F, DS3231_status_alarm2_flag_t myA2F );
+
+ /** It sets the alarm1.
+ */
+ DS3231_status_t DS3231_SetAlarm1 ( DS3231_alarm1_register_t myAlarm1 );
+
+ /** It sets the alarm2.
+ */
+ DS3231_status_t DS3231_SetAlarm2 ( DS3231_alarm2_register_t myAlarm2 );
+
+ /** It enables/disables Alarm ( 1 and 2 ) interrupts.
+ */
+ DS3231_status_t DS3231_SetAlarmsInterrupt ( DS3231_control_status_alarm1_t myAlarm1, DS3231_control_status_alarm2_t myAlarm2 );
+
+ /** It sets square-wave output frequency.
+ */
+ DS3231_status_t DS3231_SetSquareWaveOutput ( DS3231_control_status_rate_select_t myRate );
+
+ /** It gets the date.
+ */
+ DS3231_status_t DS3231_GetDate ( DS3231_vector_date_time_t* myDate );
+
+ /** It sets the date.
+ */
+ DS3231_status_t DS3231_SetDate ( DS3231_vector_date_time_t myDate );
+
+ /** It gets the time.
+ */
+ DS3231_status_t DS3231_GetTime ( DS3231_vector_date_time_t* myTime );
+
+ /** It sets the time.
+ */
+ DS3231_status_t DS3231_SetTime ( DS3231_vector_date_time_t myTime );
+
+ /** It gets the CONTROL/STATUS register.
+ */
+ DS3231_status_t DS3231_GetControlStatusRegister ( DS3231_vector_data_t* myControlStatusReg );
+
+
+
+
+private:
+ I2C _i2c;
+ uint32_t _DS3231_Addr;
+};
+
+#endif