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 Dec 19 20:22:13 2014 +0000
Revision:
1:0975d4a9b513
Parent:
0:30a7faf58768
Child:
2:a9a8027a7cb2
Added RTOS Mutex hooks to lockout i2c requests while accessing the DS3232

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 0:30a7faf58768 11 /** Class ds3232m implements the real time clock
loopsva 0:30a7faf58768 12 *
loopsva 1:0975d4a9b513 13 * The following definition is required if RTOS is used. It
loopsva 1:0975d4a9b513 14 * locks the I2C bus while I2C accesses are utilized
loopsva 1:0975d4a9b513 15 * for the DS3232.
loopsva 0:30a7faf58768 16 *
loopsva 1:0975d4a9b513 17 * contained in main.cpp:
loopsva 1:0975d4a9b513 18 * @code
loopsva 1:0975d4a9b513 19 *
loopsva 1:0975d4a9b513 20 * Mutex MutexI2C0; //lock/unlock I2C requests
loopsva 1:0975d4a9b513 21 *
loopsva 1:0975d4a9b513 22 * @endcode
loopsva 0:30a7faf58768 23 *
loopsva 0:30a7faf58768 24 */
loopsva 0:30a7faf58768 25
loopsva 0:30a7faf58768 26 class ds3232m {
loopsva 0:30a7faf58768 27
loopsva 0:30a7faf58768 28 public:
loopsva 0:30a7faf58768 29 /** Structure which is used to exchange the time and date
loopsva 0:30a7faf58768 30 */
loopsva 0:30a7faf58768 31 typedef struct {
loopsva 0:30a7faf58768 32 int sec; /*!< seconds [0..59] */
loopsva 0:30a7faf58768 33 int min; /*!< minutes {0..59] */
loopsva 0:30a7faf58768 34 int hour; /*!< hours [0..23] */
loopsva 0:30a7faf58768 35 int wday; /*!< weekday [1..7, where 1 = sunday, 2 = monday, ... */
loopsva 0:30a7faf58768 36 int date; /*!< day of month [0..31] */
loopsva 0:30a7faf58768 37 int mon; /*!< month of year [1..12] */
loopsva 0:30a7faf58768 38 int year; /*!< year [2000..2255] */
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 0:30a7faf58768 56 /**
loopsva 0:30a7faf58768 57 * Constructor with i2c clock setting option
loopsva 0:30a7faf58768 58 * - Fixed at I2C address 0x80
loopsva 0:30a7faf58768 59 * - I2C speed set by user
loopsva 0:30a7faf58768 60 *
loopsva 0:30a7faf58768 61 * @param sda - mbed I2C interface pin
loopsva 0:30a7faf58768 62 * @param scl - mbed I2C interface pin
loopsva 0:30a7faf58768 63 * @param set_I2C_frequency
loopsva 0:30a7faf58768 64 */
loopsva 0:30a7faf58768 65 ds3232m(PinName sda, PinName scl, int i2cFrequency);
loopsva 0:30a7faf58768 66 /**
loopsva 0:30a7faf58768 67 * Destructor
loopsva 0:30a7faf58768 68 *
loopsva 0:30a7faf58768 69 * @param --none--
loopsva 0:30a7faf58768 70 */
loopsva 0:30a7faf58768 71 ~ds3232m();
loopsva 0:30a7faf58768 72 /**
loopsva 0:30a7faf58768 73 * See if temperature conversion is busy or not
loopsva 0:30a7faf58768 74 *
loopsva 0:30a7faf58768 75 * @param --none--
loopsva 0:30a7faf58768 76 *
loopsva 0:30a7faf58768 77 * @return busy_flag - Temperature Conversion is busy
loopsva 0:30a7faf58768 78 * - true = busy
loopsva 0:30a7faf58768 79 * - false = ready
loopsva 0:30a7faf58768 80 */
loopsva 0:30a7faf58768 81 bool checkTempBusy();
loopsva 0:30a7faf58768 82 /**
loopsva 0:30a7faf58768 83 * Start a temperature conversion cycle
loopsva 0:30a7faf58768 84 * - Note: only 1 conversion per second allowed
loopsva 0:30a7faf58768 85 *
loopsva 0:30a7faf58768 86 * @param --none--
loopsva 0:30a7faf58768 87 *
loopsva 0:30a7faf58768 88 * @return busy_flag Temperature Conversion is Busy
loopsva 0:30a7faf58768 89 * - true = started new conversion
loopsva 0:30a7faf58768 90 * - false = already busy from previous converstion start
loopsva 0:30a7faf58768 91 */
loopsva 0:30a7faf58768 92 bool startTempCycle();
loopsva 0:30a7faf58768 93 /**
loopsva 0:30a7faf58768 94 * Get the chip temperature from the DS3232M
loopsva 0:30a7faf58768 95 *
loopsva 0:30a7faf58768 96 * @param --none--
loopsva 0:30a7faf58768 97 *
loopsva 0:30a7faf58768 98 * @return Temperature 0.25degC accuracy
loopsva 0:30a7faf58768 99 * @return 255.0 if temperature conversion not complete (still busy)
loopsva 0:30a7faf58768 100 */
loopsva 0:30a7faf58768 101 float getTemperature();
loopsva 0:30a7faf58768 102 /**
loopsva 0:30a7faf58768 103 * Get seconds register from DS3232M
loopsva 0:30a7faf58768 104 *
loopsva 0:30a7faf58768 105 * @param --none--
loopsva 0:30a7faf58768 106 *
loopsva 0:30a7faf58768 107 * @return BCD-to-decimal corrected seconds register
loopsva 0:30a7faf58768 108 */
loopsva 0:30a7faf58768 109 int getSeconds();
loopsva 0:30a7faf58768 110 /**
loopsva 0:30a7faf58768 111 * Clear out all 236 bytes of user RAM, from address 0x14 to 0xff
loopsva 0:30a7faf58768 112 * - 00h is put in all user RAM area
loopsva 0:30a7faf58768 113 *
loopsva 0:30a7faf58768 114 * @param --none--
loopsva 0:30a7faf58768 115 *
loopsva 0:30a7faf58768 116 * @return --none--
loopsva 0:30a7faf58768 117 */
loopsva 0:30a7faf58768 118 void clearRAM();
loopsva 0:30a7faf58768 119 /**
loopsva 0:30a7faf58768 120 * Retrieve data from DS3232M's user RAM area
loopsva 0:30a7faf58768 121 * - addresses range 0x14 - 0xfd
loopsva 0:30a7faf58768 122 * - CRC is checked of entire RAM contents
loopsva 0:30a7faf58768 123 *
loopsva 0:30a7faf58768 124 * @param buffer pointer
loopsva 0:30a7faf58768 125 * @param offset into DS3232M's RAM (range 0x14 = 0xfd)
loopsva 0:30a7faf58768 126 * @param length number of bytes to get
loopsva 0:30a7faf58768 127 *
loopsva 0:30a7faf58768 128 * @return 00 = no error
loopsva 0:30a7faf58768 129 * @return 01 = length + offset is over the highest user RAM location
loopsva 0:30a7faf58768 130 * @return 02 = offset < 0x14
loopsva 0:30a7faf58768 131 * @return 04 = length = 0
loopsva 0:30a7faf58768 132 * @return 08 = crc error occured from LoadRTCRam()
loopsva 0:30a7faf58768 133 */
loopsva 0:30a7faf58768 134 int getUserRAM(char *buffer, int offset, int length);
loopsva 0:30a7faf58768 135 /**
loopsva 0:30a7faf58768 136 * Store data DS3232M's user RAM area
loopsva 0:30a7faf58768 137 * - addresses range 0x14 - 0xfd
loopsva 0:30a7faf58768 138 * - CRC is added to the last 2 locations using addCRC16()
loopsva 0:30a7faf58768 139 *
loopsva 0:30a7faf58768 140 * @param buffer pointer
loopsva 0:30a7faf58768 141 * @param offset into DS3232M's RAM (range 0x14 = 0xfd)
loopsva 0:30a7faf58768 142 * @param length number of bytes to store
loopsva 0:30a7faf58768 143 *
loopsva 0:30a7faf58768 144 * @return 00 = no error
loopsva 0:30a7faf58768 145 * @return 01 = length + offset is over the highest user RAM location
loopsva 0:30a7faf58768 146 * @return 02 = offset < 0x14
loopsva 0:30a7faf58768 147 * @return 04 = length = 0
loopsva 0:30a7faf58768 148 */
loopsva 0:30a7faf58768 149 int putUserRAM(char *buffer, int offset, int length);
loopsva 0:30a7faf58768 150 /**
loopsva 0:30a7faf58768 151 * Calculate CRC16
loopsva 0:30a7faf58768 152 *
loopsva 0:30a7faf58768 153 * @param input buffer pointer
loopsva 0:30a7faf58768 154 * @param address offset into buffer
loopsva 0:30a7faf58768 155 * @param length number of bytes to calculate
loopsva 0:30a7faf58768 156 *
loopsva 0:30a7faf58768 157 * @return CRC16 value
loopsva 0:30a7faf58768 158 */
loopsva 0:30a7faf58768 159 uint16_t calculateCRC16(char input[], int offset, int length);
loopsva 0:30a7faf58768 160 /**
loopsva 0:30a7faf58768 161 * Turn on/off the 32KHz output pin
loopsva 0:30a7faf58768 162 * - with option to keep 32KHz output ON during battery backup
loopsva 0:30a7faf58768 163 * - This pin is push-pull, no pullup is required
loopsva 0:30a7faf58768 164 *
loopsva 0:30a7faf58768 165 * @param ena
loopsva 0:30a7faf58768 166 * - true = enable during normal operation
loopsva 0:30a7faf58768 167 * - false = disable 32KHz output pin during normal operation
loopsva 0:30a7faf58768 168 * @param batt
loopsva 0:30a7faf58768 169 * - true = enable 32KHz output pin during battery backup mode
loopsva 0:30a7faf58768 170 * - false = disable 32KHz output pin during battery backup mode
loopsva 0:30a7faf58768 171 * - Note: "ena" must be true or else batt is ignored
loopsva 0:30a7faf58768 172 *
loopsva 0:30a7faf58768 173 * @return --none--
loopsva 0:30a7faf58768 174 */
loopsva 0:30a7faf58768 175 void set32KhzOutput(bool ena, bool batt);
loopsva 0:30a7faf58768 176 /**
loopsva 0:30a7faf58768 177 * Turn on/off the 1Hz output pin
loopsva 0:30a7faf58768 178 * - with option to keep 1Hz output ON during battery backup
loopsva 0:30a7faf58768 179 * - This pin is open-drain
loopsva 0:30a7faf58768 180 * - Requires a pullup resistor to Vcc or the backup battery
loopsva 0:30a7faf58768 181 *
loopsva 0:30a7faf58768 182 * @param ena
loopsva 0:30a7faf58768 183 * - true = enable 1Hz output pin during normal operation
loopsva 0:30a7faf58768 184 * - false = disable 1Hz output pin during normal operation
loopsva 0:30a7faf58768 185 * @param batt
loopsva 0:30a7faf58768 186 * - true = enable 1Hz output pin during battery backup mode
loopsva 0:30a7faf58768 187 * - false = disable 1Hz output pin during battery backup mode
loopsva 0:30a7faf58768 188 * - Note: "ena" must be true or else batt is ignored
loopsva 0:30a7faf58768 189 *
loopsva 0:30a7faf58768 190 * @return --none--
loopsva 0:30a7faf58768 191 */
loopsva 0:30a7faf58768 192 void set1hzOutput(bool ena, bool batt);
loopsva 0:30a7faf58768 193 /**
loopsva 0:30a7faf58768 194 * Turn on/off the main oscillator during battery backup mode
loopsva 0:30a7faf58768 195 * - The oscillator always runs when Vcc is valid
loopsva 0:30a7faf58768 196 *
loopsva 0:30a7faf58768 197 * @param batt
loopsva 0:30a7faf58768 198 * - true = enable the oscillator during battery backup mode
loopsva 0:30a7faf58768 199 * - false = disable the oscillator during battery backup mode
loopsva 0:30a7faf58768 200 *
loopsva 0:30a7faf58768 201 * @return --none--
loopsva 0:30a7faf58768 202 */
loopsva 0:30a7faf58768 203 void enableBattClock(bool batt);
loopsva 0:30a7faf58768 204 /**
loopsva 0:30a7faf58768 205 * Read all of the current time registers from the DS3232M
loopsva 0:30a7faf58768 206 *
loopsva 0:30a7faf58768 207 * @param time_structure - will be filled with the time from DS3232M
loopsva 0:30a7faf58768 208 *
loopsva 0:30a7faf58768 209 * @returns --none--
loopsva 0:30a7faf58768 210 */
loopsva 0:30a7faf58768 211 void getTime(Time_rtc& time);
loopsva 0:30a7faf58768 212 /**
loopsva 0:30a7faf58768 213 * Write all of the current time registers into the DS3232M
loopsva 0:30a7faf58768 214 *
loopsva 0:30a7faf58768 215 * @param time_structure - will be filled with the time into the DS3232M
loopsva 0:30a7faf58768 216 *
loopsva 0:30a7faf58768 217 * @returns --none--
loopsva 0:30a7faf58768 218 */
loopsva 0:30a7faf58768 219 void setTime(Time_rtc& time);
loopsva 0:30a7faf58768 220 /**
loopsva 0:30a7faf58768 221 * Load the entire contents of the DS3232M into dedicated buffer RTCbuffer[]
loopsva 0:30a7faf58768 222 * - includes time registers, alarm registers and user RAM
loopsva 0:30a7faf58768 223 *
loopsva 0:30a7faf58768 224 * @param --none--
loopsva 0:30a7faf58768 225 *
loopsva 0:30a7faf58768 226 * @return CRC_Status - pass/fail of CRC readback of user RAM data
loopsva 0:30a7faf58768 227 * - true = CRC is ok
loopsva 0:30a7faf58768 228 * - false = CRC failed
loopsva 0:30a7faf58768 229 */
loopsva 0:30a7faf58768 230 bool LoadRTCRam();
loopsva 0:30a7faf58768 231 /**
loopsva 0:30a7faf58768 232 * Dedicated buffer that mirrors the RTC's entire contents
loopsva 0:30a7faf58768 233 * - loaded by LoadRTCRam()
loopsva 0:30a7faf58768 234 *
loopsva 0:30a7faf58768 235 * @param --none--
loopsva 0:30a7faf58768 236 *
loopsva 0:30a7faf58768 237 * @return --none--
loopsva 0:30a7faf58768 238 */
loopsva 0:30a7faf58768 239 char RTCbuffer[256];
loopsva 0:30a7faf58768 240
loopsva 0:30a7faf58768 241 private:
loopsva 0:30a7faf58768 242 void getControlStatusRegs();
loopsva 0:30a7faf58768 243 char RtcCtlReg;
loopsva 0:30a7faf58768 244 char RtcStatReg;
loopsva 0:30a7faf58768 245 void addCRC16();
loopsva 0:30a7faf58768 246
loopsva 0:30a7faf58768 247 // BCD-Decimal Conversions, hacked from Henry Leinen's RTC-DS1307 library
loopsva 0:30a7faf58768 248 static int BCDToDec(int dat) {
loopsva 0:30a7faf58768 249 return ((dat & 0xF0) >> 4) * 10 + (dat & 0x0F);
loopsva 0:30a7faf58768 250 }
loopsva 0:30a7faf58768 251
loopsva 0:30a7faf58768 252 static int DecToBCD(int dat) {
loopsva 0:30a7faf58768 253 return (dat % 10) + ((dat / 10) << 4);
loopsva 0:30a7faf58768 254 }
loopsva 0:30a7faf58768 255 };
loopsva 0:30a7faf58768 256
loopsva 0:30a7faf58768 257 #endif // DS3232M_H