Library for Maxim DS3232M super-accurate, I2C based Real Time Clock chip with 234 bytes of user RAM. Library includes user RAM read/write operations along with CRC routines for accessing the user RAM area.

Dependents:   ds3232m_HelloWorld

Committer:
loopsva
Date:
Fri Mar 11 18:09:54 2016 +0000
Revision:
6:968b8efe3ca0
Parent:
2:a9a8027a7cb2
Changed things around.  Moved RTCbuffer to data structure. Added CRC saved & calculated data to data structure.  Put more requirements on the calling program.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
loopsva 0:30a7faf58768 1 #ifndef DS3232M_H
loopsva 0:30a7faf58768 2 #define DS3232M_H
loopsva 0:30a7faf58768 3
loopsva 0:30a7faf58768 4 /*
loopsva 0:30a7faf58768 5 Maxim Integrated DS3232M, fully integrated Real Time Clock chip. The
loopsva 0:30a7faf58768 6 chip contains an I2C interface, compatable time-base registers to
loopsva 0:30a7faf58768 7 the DS1307 and M11T41, a super-accurate internal oscillator, 2 alarms
loopsva 0:30a7faf58768 8 and 236 bytes of user defined battery-backed RAM.
loopsva 0:30a7faf58768 9 */
loopsva 0:30a7faf58768 10
loopsva 6:968b8efe3ca0 11 //possible error returns from getUserRAM()
loopsva 6:968b8efe3ca0 12 #define DS3232_NOERROR 0x00 //ok, no error
loopsva 6:968b8efe3ca0 13 #define DS3232_OVERFLOWERROR 0x01 //length + offset is over the highest user RAM location
loopsva 6:968b8efe3ca0 14 #define DS3232_OFFSETERROR 0x02 //offset < 0x14, those registers are not in the user RAM area
loopsva 6:968b8efe3ca0 15 #define DS3232_LENZEROERROR 0x04 //length = 0
loopsva 6:968b8efe3ca0 16 #define DS3232_CRCERROR 0x08 //crc error
loopsva 6:968b8efe3ca0 17
loopsva 0:30a7faf58768 18 /** Class ds3232m implements the real time clock
loopsva 0:30a7faf58768 19 *
loopsva 0:30a7faf58768 20 *
loopsva 0:30a7faf58768 21 */
loopsva 0:30a7faf58768 22
loopsva 0:30a7faf58768 23 class ds3232m {
loopsva 0:30a7faf58768 24
loopsva 0:30a7faf58768 25 public:
loopsva 0:30a7faf58768 26 /** Structure which is used to exchange the time and date
loopsva 0:30a7faf58768 27 */
loopsva 0:30a7faf58768 28 typedef struct {
loopsva 0:30a7faf58768 29 int sec; /*!< seconds [0..59] */
loopsva 0:30a7faf58768 30 int min; /*!< minutes {0..59] */
loopsva 0:30a7faf58768 31 int hour; /*!< hours [0..23] */
loopsva 0:30a7faf58768 32 int wday; /*!< weekday [1..7, where 1 = sunday, 2 = monday, ... */
loopsva 0:30a7faf58768 33 int date; /*!< day of month [0..31] */
loopsva 0:30a7faf58768 34 int mon; /*!< month of year [1..12] */
loopsva 0:30a7faf58768 35 int year; /*!< year [2000..2255] */
loopsva 6:968b8efe3ca0 36 uint16_t s_crc; /*!< stored crc value in RTC RAM */
loopsva 6:968b8efe3ca0 37 uint16_t c_crc; /*!< calculated crc value */
loopsva 6:968b8efe3ca0 38 char RTCbuffer[256]; /*!< ds3232 ram buffer */
loopsva 0:30a7faf58768 39 } Time_rtc;
loopsva 0:30a7faf58768 40
loopsva 0:30a7faf58768 41 protected:
loopsva 0:30a7faf58768 42 I2C* _i2c_;
loopsva 0:30a7faf58768 43
loopsva 0:30a7faf58768 44 // static const char *m_weekDays[];
loopsva 0:30a7faf58768 45
loopsva 0:30a7faf58768 46 public:
loopsva 0:30a7faf58768 47 /**
loopsva 0:30a7faf58768 48 * Constructor with default i2c clock speed
loopsva 0:30a7faf58768 49 * - Fixed at I2C address 0x80
loopsva 0:30a7faf58768 50 * - I2C speed set to 400KHz
loopsva 0:30a7faf58768 51 *
loopsva 0:30a7faf58768 52 * @param sda - mbed I2C interface pin
loopsva 0:30a7faf58768 53 * @param scl - mbed I2C interface pin
loopsva 0:30a7faf58768 54 */
loopsva 0:30a7faf58768 55 ds3232m(PinName sda, PinName scl);
loopsva 6:968b8efe3ca0 56
loopsva 0:30a7faf58768 57 /**
loopsva 0:30a7faf58768 58 * Constructor with i2c clock setting option
loopsva 0:30a7faf58768 59 * - Fixed at I2C address 0x80
loopsva 0:30a7faf58768 60 * - I2C speed set by user
loopsva 0:30a7faf58768 61 *
loopsva 0:30a7faf58768 62 * @param sda - mbed I2C interface pin
loopsva 0:30a7faf58768 63 * @param scl - mbed I2C interface pin
loopsva 0:30a7faf58768 64 * @param set_I2C_frequency
loopsva 0:30a7faf58768 65 */
loopsva 0:30a7faf58768 66 ds3232m(PinName sda, PinName scl, int i2cFrequency);
loopsva 6:968b8efe3ca0 67
loopsva 0:30a7faf58768 68 /**
loopsva 0:30a7faf58768 69 * Destructor
loopsva 0:30a7faf58768 70 *
loopsva 0:30a7faf58768 71 * @param --none--
loopsva 0:30a7faf58768 72 */
loopsva 0:30a7faf58768 73 ~ds3232m();
loopsva 6:968b8efe3ca0 74
loopsva 0:30a7faf58768 75 /**
loopsva 0:30a7faf58768 76 * See if temperature conversion is busy or not
loopsva 0:30a7faf58768 77 *
loopsva 6:968b8efe3ca0 78 * @param pointer to Time_rtc DS3232 data structure
loopsva 0:30a7faf58768 79 *
loopsva 0:30a7faf58768 80 * @return busy_flag - Temperature Conversion is busy
loopsva 0:30a7faf58768 81 * - true = busy
loopsva 0:30a7faf58768 82 * - false = ready
loopsva 0:30a7faf58768 83 */
loopsva 6:968b8efe3ca0 84 bool checkTempBusy(Time_rtc& dsSTR);
loopsva 6:968b8efe3ca0 85
loopsva 0:30a7faf58768 86 /**
loopsva 0:30a7faf58768 87 * Start a temperature conversion cycle
loopsva 0:30a7faf58768 88 * - Note: only 1 conversion per second allowed
loopsva 0:30a7faf58768 89 *
loopsva 6:968b8efe3ca0 90 * @param pointer to Time_rtc DS3232 data structure
loopsva 0:30a7faf58768 91 *
loopsva 0:30a7faf58768 92 * @return busy_flag Temperature Conversion is Busy
loopsva 0:30a7faf58768 93 * - true = started new conversion
loopsva 0:30a7faf58768 94 * - false = already busy from previous converstion start
loopsva 0:30a7faf58768 95 */
loopsva 6:968b8efe3ca0 96 bool startTempCycle(Time_rtc& dsSTR);
loopsva 6:968b8efe3ca0 97
loopsva 0:30a7faf58768 98 /**
loopsva 0:30a7faf58768 99 * Get the chip temperature from the DS3232M
loopsva 0:30a7faf58768 100 *
loopsva 6:968b8efe3ca0 101 * @param pointer to Time_rtc DS3232 data structure
loopsva 0:30a7faf58768 102 *
loopsva 0:30a7faf58768 103 * @return Temperature 0.25degC accuracy
loopsva 0:30a7faf58768 104 * @return 255.0 if temperature conversion not complete (still busy)
loopsva 0:30a7faf58768 105 */
loopsva 6:968b8efe3ca0 106 float getTemperature(Time_rtc& dsSTR);
loopsva 6:968b8efe3ca0 107
loopsva 0:30a7faf58768 108 /**
loopsva 0:30a7faf58768 109 * Get seconds register from DS3232M
loopsva 0:30a7faf58768 110 *
loopsva 6:968b8efe3ca0 111 * @param pointer to Time_rtc DS3232 data structure
loopsva 0:30a7faf58768 112 *
loopsva 0:30a7faf58768 113 * @return BCD-to-decimal corrected seconds register
loopsva 0:30a7faf58768 114 */
loopsva 6:968b8efe3ca0 115 uint8_t getSeconds(Time_rtc& dsSTR);
loopsva 6:968b8efe3ca0 116
loopsva 6:968b8efe3ca0 117 /**
loopsva 6:968b8efe3ca0 118 * Get day-of-the-week register from DS3232M
loopsva 6:968b8efe3ca0 119 *
loopsva 6:968b8efe3ca0 120 * @param pointer to Time_rtc DS3232 data structure
loopsva 6:968b8efe3ca0 121 *
loopsva 6:968b8efe3ca0 122 * @return BCD-to-decimal corrected day of week register (1-7)
loopsva 6:968b8efe3ca0 123 */
loopsva 6:968b8efe3ca0 124 uint8_t getDayOfWeek(Time_rtc& dsSTR);
loopsva 6:968b8efe3ca0 125
loopsva 6:968b8efe3ca0 126 /**
loopsva 6:968b8efe3ca0 127 * Set the day-of-the-week register in the DS3232M
loopsva 6:968b8efe3ca0 128 *
loopsva 6:968b8efe3ca0 129 * @param pointer to Time_rtc DS3232 data structure
loopsva 6:968b8efe3ca0 130 * @param uint8_t dow3232 day_of_the_week (1=Mon....7=Sun)
loopsva 6:968b8efe3ca0 131 *
loopsva 6:968b8efe3ca0 132 * @return --none--
loopsva 6:968b8efe3ca0 133 */
loopsva 6:968b8efe3ca0 134 void putDayOfWeek(Time_rtc& dsSTR, uint8_t dow3232);
loopsva 6:968b8efe3ca0 135
loopsva 0:30a7faf58768 136 /**
loopsva 0:30a7faf58768 137 * Clear out all 236 bytes of user RAM, from address 0x14 to 0xff
loopsva 0:30a7faf58768 138 * - 00h is put in all user RAM area
loopsva 0:30a7faf58768 139 *
loopsva 6:968b8efe3ca0 140 * @param pointer to Time_rtc DS3232 data structure
loopsva 0:30a7faf58768 141 *
loopsva 0:30a7faf58768 142 * @return --none--
loopsva 0:30a7faf58768 143 */
loopsva 6:968b8efe3ca0 144 void clearRAM(Time_rtc& dsSTR);
loopsva 6:968b8efe3ca0 145
loopsva 0:30a7faf58768 146 /**
loopsva 0:30a7faf58768 147 * Retrieve data from DS3232M's user RAM area
loopsva 6:968b8efe3ca0 148 * - addresses range 0x14 - 0xfa
loopsva 0:30a7faf58768 149 * - CRC is checked of entire RAM contents
loopsva 0:30a7faf58768 150 *
loopsva 6:968b8efe3ca0 151 * @param pointer to I2C data buffer
loopsva 6:968b8efe3ca0 152 * @param pointer to Time_rtc DS3232 data structure
loopsva 6:968b8efe3ca0 153 * @param int offset into DS3232M's RAM (range 0x14 = 0xfa)
loopsva 6:968b8efe3ca0 154 * @param int length number of bytes to get
loopsva 0:30a7faf58768 155 *
loopsva 0:30a7faf58768 156 * @return 00 = no error
loopsva 0:30a7faf58768 157 * @return 01 = length + offset is over the highest user RAM location
loopsva 0:30a7faf58768 158 * @return 02 = offset < 0x14
loopsva 0:30a7faf58768 159 * @return 04 = length = 0
loopsva 0:30a7faf58768 160 * @return 08 = crc error occured from LoadRTCRam()
loopsva 0:30a7faf58768 161 */
loopsva 6:968b8efe3ca0 162 uint8_t getUserRAM(char *buffer, Time_rtc& dsSTR, int offset, int length);
loopsva 6:968b8efe3ca0 163
loopsva 0:30a7faf58768 164 /**
loopsva 0:30a7faf58768 165 * Store data DS3232M's user RAM area
loopsva 6:968b8efe3ca0 166 * - addresses range 0x14 - 0xfa
loopsva 0:30a7faf58768 167 * - CRC is added to the last 2 locations using addCRC16()
loopsva 0:30a7faf58768 168 *
loopsva 6:968b8efe3ca0 169 * @param pointer to I2C data buffer
loopsva 6:968b8efe3ca0 170 * @param pointer to Time_rtc DS3232 data structure
loopsva 6:968b8efe3ca0 171 * @param int offset into DS3232M's RAM (range 0x14 = 0xfa)
loopsva 6:968b8efe3ca0 172 * @param int length number of bytes to store
loopsva 0:30a7faf58768 173 *
loopsva 0:30a7faf58768 174 * @return 00 = no error
loopsva 0:30a7faf58768 175 * @return 01 = length + offset is over the highest user RAM location
loopsva 0:30a7faf58768 176 * @return 02 = offset < 0x14
loopsva 0:30a7faf58768 177 * @return 04 = length = 0
loopsva 0:30a7faf58768 178 */
loopsva 6:968b8efe3ca0 179 uint8_t putUserRAM(char *buffer, Time_rtc& dsSTR, int offset, int length);
loopsva 6:968b8efe3ca0 180
loopsva 0:30a7faf58768 181 /**
loopsva 0:30a7faf58768 182 * Calculate CRC16
loopsva 0:30a7faf58768 183 *
loopsva 6:968b8efe3ca0 184 * @param pointer to I2C data buffer
loopsva 6:968b8efe3ca0 185 * @param pointer to Time_rtc DS3232 data structure
loopsva 6:968b8efe3ca0 186 * @param int offset into buffer
loopsva 6:968b8efe3ca0 187 * @param int length number of bytes to calculate
loopsva 0:30a7faf58768 188 *
loopsva 6:968b8efe3ca0 189 * @return uint16_t CRC16 value
loopsva 0:30a7faf58768 190 */
loopsva 6:968b8efe3ca0 191 uint16_t calculateCRC16(char input[], Time_rtc& dsSTR, int offset, int length);
loopsva 6:968b8efe3ca0 192
loopsva 0:30a7faf58768 193 /**
loopsva 0:30a7faf58768 194 * Turn on/off the 32KHz output pin
loopsva 0:30a7faf58768 195 * - with option to keep 32KHz output ON during battery backup
loopsva 0:30a7faf58768 196 * - This pin is push-pull, no pullup is required
loopsva 0:30a7faf58768 197 *
loopsva 6:968b8efe3ca0 198 * @param pointer to Time_rtc DS3232 data structure
loopsva 6:968b8efe3ca0 199 * @param bool ena
loopsva 0:30a7faf58768 200 * - true = enable during normal operation
loopsva 0:30a7faf58768 201 * - false = disable 32KHz output pin during normal operation
loopsva 6:968b8efe3ca0 202 * @param bool batt
loopsva 0:30a7faf58768 203 * - true = enable 32KHz output pin during battery backup mode
loopsva 0:30a7faf58768 204 * - false = disable 32KHz output pin during battery backup mode
loopsva 0:30a7faf58768 205 * - Note: "ena" must be true or else batt is ignored
loopsva 0:30a7faf58768 206 *
loopsva 0:30a7faf58768 207 * @return --none--
loopsva 0:30a7faf58768 208 */
loopsva 6:968b8efe3ca0 209 void set32KhzOutput(Time_rtc& dsSTR, bool ena, bool batt);
loopsva 6:968b8efe3ca0 210
loopsva 0:30a7faf58768 211 /**
loopsva 0:30a7faf58768 212 * Turn on/off the 1Hz output pin
loopsva 0:30a7faf58768 213 * - with option to keep 1Hz output ON during battery backup
loopsva 0:30a7faf58768 214 * - This pin is open-drain
loopsva 0:30a7faf58768 215 * - Requires a pullup resistor to Vcc or the backup battery
loopsva 0:30a7faf58768 216 *
loopsva 6:968b8efe3ca0 217 * @param pointer to Time_rtc DS3232 data structure
loopsva 0:30a7faf58768 218 * @param ena
loopsva 0:30a7faf58768 219 * - true = enable 1Hz output pin during normal operation
loopsva 0:30a7faf58768 220 * - false = disable 1Hz output pin during normal operation
loopsva 0:30a7faf58768 221 * @param batt
loopsva 0:30a7faf58768 222 * - true = enable 1Hz output pin during battery backup mode
loopsva 0:30a7faf58768 223 * - false = disable 1Hz output pin during battery backup mode
loopsva 0:30a7faf58768 224 * - Note: "ena" must be true or else batt is ignored
loopsva 0:30a7faf58768 225 *
loopsva 0:30a7faf58768 226 * @return --none--
loopsva 0:30a7faf58768 227 */
loopsva 6:968b8efe3ca0 228 void set1hzOutput(Time_rtc& dsSTR, bool ena, bool batt);
loopsva 6:968b8efe3ca0 229
loopsva 0:30a7faf58768 230 /**
loopsva 0:30a7faf58768 231 * Turn on/off the main oscillator during battery backup mode
loopsva 0:30a7faf58768 232 * - The oscillator always runs when Vcc is valid
loopsva 0:30a7faf58768 233 *
loopsva 6:968b8efe3ca0 234 * @param pointer to Time_rtc DS3232 data structure
loopsva 0:30a7faf58768 235 * @param batt
loopsva 0:30a7faf58768 236 * - true = enable the oscillator during battery backup mode
loopsva 0:30a7faf58768 237 * - false = disable the oscillator during battery backup mode
loopsva 0:30a7faf58768 238 *
loopsva 0:30a7faf58768 239 * @return --none--
loopsva 0:30a7faf58768 240 */
loopsva 6:968b8efe3ca0 241 void enableBattClock(Time_rtc& dsSTR, bool batt);
loopsva 6:968b8efe3ca0 242
loopsva 0:30a7faf58768 243 /**
loopsva 0:30a7faf58768 244 * Read all of the current time registers from the DS3232M
loopsva 0:30a7faf58768 245 *
loopsva 6:968b8efe3ca0 246 * @param pointer to Time_rtc DS3232 data structure
loopsva 0:30a7faf58768 247 *
loopsva 0:30a7faf58768 248 * @returns --none--
loopsva 0:30a7faf58768 249 */
loopsva 6:968b8efe3ca0 250 void getTime(Time_rtc& dsSTR);
loopsva 6:968b8efe3ca0 251
loopsva 0:30a7faf58768 252 /**
loopsva 0:30a7faf58768 253 * Write all of the current time registers into the DS3232M
loopsva 0:30a7faf58768 254 *
loopsva 6:968b8efe3ca0 255 * @param pointer to Time_rtc DS3232 data structure
loopsva 0:30a7faf58768 256 *
loopsva 0:30a7faf58768 257 * @returns --none--
loopsva 0:30a7faf58768 258 */
loopsva 6:968b8efe3ca0 259 void setTime(Time_rtc& dsSTR);
loopsva 6:968b8efe3ca0 260
loopsva 0:30a7faf58768 261 /**
loopsva 0:30a7faf58768 262 * Load the entire contents of the DS3232M into dedicated buffer RTCbuffer[]
loopsva 0:30a7faf58768 263 * - includes time registers, alarm registers and user RAM
loopsva 0:30a7faf58768 264 *
loopsva 6:968b8efe3ca0 265 * @param pointer to Time_rtc DS3232 data structure
loopsva 0:30a7faf58768 266 *
loopsva 0:30a7faf58768 267 * @return CRC_Status - pass/fail of CRC readback of user RAM data
loopsva 0:30a7faf58768 268 * - true = CRC is ok
loopsva 0:30a7faf58768 269 * - false = CRC failed
loopsva 0:30a7faf58768 270 */
loopsva 6:968b8efe3ca0 271 bool LoadRTCRam(Time_rtc& dsSTR);
loopsva 0:30a7faf58768 272
loopsva 0:30a7faf58768 273 private:
loopsva 6:968b8efe3ca0 274 void getControlStatusRegs(Time_rtc& dsSTR);
loopsva 0:30a7faf58768 275 char RtcCtlReg;
loopsva 0:30a7faf58768 276 char RtcStatReg;
loopsva 6:968b8efe3ca0 277 void addCRC16(Time_rtc& dsSTR);
loopsva 0:30a7faf58768 278
loopsva 0:30a7faf58768 279 // BCD-Decimal Conversions, hacked from Henry Leinen's RTC-DS1307 library
loopsva 0:30a7faf58768 280 static int BCDToDec(int dat) {
loopsva 0:30a7faf58768 281 return ((dat & 0xF0) >> 4) * 10 + (dat & 0x0F);
loopsva 0:30a7faf58768 282 }
loopsva 0:30a7faf58768 283
loopsva 0:30a7faf58768 284 static int DecToBCD(int dat) {
loopsva 0:30a7faf58768 285 return (dat % 10) + ((dat / 10) << 4);
loopsva 0:30a7faf58768 286 }
loopsva 0:30a7faf58768 287 };
loopsva 0:30a7faf58768 288
loopsva 0:30a7faf58768 289 #endif // DS3232M_H