A feature complete driver for the ISL1208 real time clock from Intersil.

Dependents:   ISL1208_HelloWorld

Committer:
neilt6
Date:
Thu Nov 07 17:58:43 2013 +0000
Revision:
2:f33dbb2535a3
Parent:
1:c951ff6da740
Child:
4:42dc07f9ffb3
Minor improvements

Who changed what in which revision?

UserRevisionLine numberNew contents of line
neilt6 0:697ca602e934 1 /* ISL1208 Driver Library
neilt6 0:697ca602e934 2 * Copyright (c) 2013 Neil Thiessen
neilt6 0:697ca602e934 3 *
neilt6 0:697ca602e934 4 * Licensed under the Apache License, Version 2.0 (the "License");
neilt6 0:697ca602e934 5 * you may not use this file except in compliance with the License.
neilt6 0:697ca602e934 6 * You may obtain a copy of the License at
neilt6 0:697ca602e934 7 *
neilt6 0:697ca602e934 8 * http://www.apache.org/licenses/LICENSE-2.0
neilt6 0:697ca602e934 9 *
neilt6 0:697ca602e934 10 * Unless required by applicable law or agreed to in writing, software
neilt6 0:697ca602e934 11 * distributed under the License is distributed on an "AS IS" BASIS,
neilt6 0:697ca602e934 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
neilt6 0:697ca602e934 13 * See the License for the specific language governing permissions and
neilt6 0:697ca602e934 14 * limitations under the License.
neilt6 0:697ca602e934 15 */
neilt6 0:697ca602e934 16
neilt6 0:697ca602e934 17 #ifndef ISL1208_H
neilt6 0:697ca602e934 18 #define ISL1208_H
neilt6 0:697ca602e934 19
neilt6 0:697ca602e934 20 #include "mbed.h"
neilt6 0:697ca602e934 21
neilt6 0:697ca602e934 22 /** ISL1208 class.
neilt6 0:697ca602e934 23 * Used for controlling an ISL1208 real time clock connected via I2C.
neilt6 0:697ca602e934 24 *
neilt6 0:697ca602e934 25 * Example:
neilt6 0:697ca602e934 26 * @code
neilt6 0:697ca602e934 27 * #include "mbed.h"
neilt6 0:697ca602e934 28 * #include "ISL1208.h"
neilt6 0:697ca602e934 29 *
neilt6 0:697ca602e934 30 * ISL1208 rtc(p28, p27);
neilt6 0:697ca602e934 31 *
neilt6 0:697ca602e934 32 * int main()
neilt6 0:697ca602e934 33 * {
neilt6 0:697ca602e934 34 * //Try to open the ISL1208
neilt6 0:697ca602e934 35 * if (rtc.open(ISL1208::OSCILLATOR_CRYSTAL)) {
neilt6 0:697ca602e934 36 * printf("Device detected!\n");
neilt6 0:697ca602e934 37 *
neilt6 0:697ca602e934 38 * //Check if we need to reset the time
neilt6 0:697ca602e934 39 * if (rtc.powerFailed()) {
neilt6 0:697ca602e934 40 * //The time has been lost due to a power complete power failure
neilt6 0:697ca602e934 41 * printf("Device has lost power! Resetting time...\n");
neilt6 0:697ca602e934 42 *
neilt6 0:697ca602e934 43 * //Set RTC time to Wed, 28 Oct 2009 11:35:37
neilt6 0:697ca602e934 44 * rtc.time(1256729737);
neilt6 0:697ca602e934 45 * }
neilt6 0:697ca602e934 46 *
neilt6 0:697ca602e934 47 * while(1) {
neilt6 0:697ca602e934 48 * //Get the current time
neilt6 0:697ca602e934 49 * time_t seconds = rtc.time();
neilt6 0:697ca602e934 50 *
neilt6 0:697ca602e934 51 * //Print the time in various formats
neilt6 0:697ca602e934 52 * printf("\nTime as seconds since January 1, 1970 = %d\n", seconds);
neilt6 0:697ca602e934 53 * printf("Time as a basic string = %s", ctime(&seconds));
neilt6 0:697ca602e934 54 * char buffer[32];
neilt6 0:697ca602e934 55 * strftime(buffer, 32, "%I:%M %p\n", localtime(&seconds));
neilt6 0:697ca602e934 56 * printf("Time as a custom formatted string = %s", buffer);
neilt6 0:697ca602e934 57 *
neilt6 0:697ca602e934 58 * //Delay for 1.0 seconds
neilt6 0:697ca602e934 59 * wait(1.0);
neilt6 0:697ca602e934 60 * }
neilt6 0:697ca602e934 61 * } else {
neilt6 1:c951ff6da740 62 * error("Device not detected!\n");
neilt6 0:697ca602e934 63 * }
neilt6 0:697ca602e934 64 * }
neilt6 0:697ca602e934 65 * @endcode
neilt6 0:697ca602e934 66 */
neilt6 0:697ca602e934 67 class ISL1208
neilt6 0:697ca602e934 68 {
neilt6 0:697ca602e934 69 public:
neilt6 0:697ca602e934 70 /** Represents the different oscillator modes for the ISL1208
neilt6 0:697ca602e934 71 */
neilt6 0:697ca602e934 72 enum OscillatorMode {
neilt6 0:697ca602e934 73 OSCILLATOR_CRYSTAL, /**< The internal crystal oscillator is enabled */
neilt6 0:697ca602e934 74 OSCILLATOR_EXTERNAL /**< The internal crystal oscillator is disabled, an external 32kHz oscillator is connected to X1 */
neilt6 0:697ca602e934 75 };
neilt6 0:697ca602e934 76
neilt6 0:697ca602e934 77 /** Represents the different output frequencies for the IRQ/fOUT pin on the ISL1208
neilt6 0:697ca602e934 78 */
neilt6 0:697ca602e934 79 enum OutputFrequency {
neilt6 0:697ca602e934 80 FOUT_DISABLED = 0, /**< Disable frequency generation on the IRQ/fOUT pin */
neilt6 0:697ca602e934 81 FOUT_32768_HZ, /**< Generate 32.768kHz on the IRQ/fOUT pin */
neilt6 0:697ca602e934 82 FOUT_4096_HZ, /**< Generate 4.096kHz on the IRQ/fOUT pin */
neilt6 0:697ca602e934 83 FOUT_1024_HZ, /**< Generate 1.024kHz on the IRQ/fOUT pin */
neilt6 0:697ca602e934 84 FOUT_64_HZ, /**< Generate 64Hz on the IRQ/fOUT pin */
neilt6 0:697ca602e934 85 FOUT_32_HZ, /**< Generate 32Hz on the IRQ/fOUT pin */
neilt6 0:697ca602e934 86 FOUT_16_HZ, /**< Generate 16Hz on the IRQ/fOUT pin */
neilt6 0:697ca602e934 87 FOUT_8_HZ, /**< Generate 8Hz on the IRQ/fOUT pin */
neilt6 0:697ca602e934 88 FOUT_4_HZ, /**< Generate 4Hz on the IRQ/fOUT pin */
neilt6 0:697ca602e934 89 FOUT_2_HZ, /**< Generate 2Hz on the IRQ/fOUT pin */
neilt6 0:697ca602e934 90 FOUT_1_HZ, /**< Generate 1Hz on the IRQ/fOUT pin */
neilt6 0:697ca602e934 91 FOUT_1_2_HZ, /**< Generate 1/2Hz on the IRQ/fOUT pin */
neilt6 0:697ca602e934 92 FOUT_1_4_HZ, /**< Generate 1/4Hz on the IRQ/fOUT pin */
neilt6 0:697ca602e934 93 FOUT_1_8_HZ, /**< Generate 1/8Hz on the IRQ/fOUT pin */
neilt6 0:697ca602e934 94 FOUT_1_16_HZ, /**< Generate 1/16Hz on the IRQ/fOUT pin */
neilt6 0:697ca602e934 95 FOUT_1_32_HZ /**< Generate 1/32Hz on the IRQ/fOUT pin */
neilt6 0:697ca602e934 96 };
neilt6 0:697ca602e934 97
neilt6 0:697ca602e934 98 /** Represents the power mode of the ISL1208
neilt6 0:697ca602e934 99 */
neilt6 0:697ca602e934 100 enum PowerMode {
neilt6 0:697ca602e934 101 POWER_NORMAL, /**< VBAT supply will be used when VDD < VBAT - VBATHYS and VDD < VTRIP */
neilt6 0:697ca602e934 102 POWER_LPMODE /**< VBAT supply will be used when VDD < VBAT - VBATHYS */
neilt6 0:697ca602e934 103 };
neilt6 0:697ca602e934 104
neilt6 0:697ca602e934 105 /** Represents the alarm mode of the ISL1208
neilt6 0:697ca602e934 106 */
neilt6 0:697ca602e934 107 enum AlarmMode {
neilt6 0:697ca602e934 108 ALARM_DISABLED, /**< The alarm function is disabled */
neilt6 0:697ca602e934 109 ALARM_SINGLE, /**< Only a one-time match will be made between the RTC and alarm registers, and the IRQ/fOUT pin will pull low until the alarm flag is cleared */
neilt6 0:697ca602e934 110 ALARM_INTERRUPT /**< Every time an alarm match is made the IRQ/fOUT pin will pull low for 250ms, the alarm flag does not have to be cleared */
neilt6 0:697ca602e934 111 };
neilt6 0:697ca602e934 112
neilt6 0:697ca602e934 113 /** Represents the different battery mode ATR selections of the ISL1208
neilt6 0:697ca602e934 114 */
neilt6 0:697ca602e934 115 enum BatteryModeATR {
neilt6 0:697ca602e934 116 BMATR_ZERO = 0, /**< Delta capacitance = 0pF */
neilt6 0:697ca602e934 117 BMATR_MINUS_0_5, /**< Delta capacitance = -0.5pF (≈ +2ppm) */
neilt6 0:697ca602e934 118 BMATR_PLUS_0_5, /**< Delta capacitance = +0.5pF (≈ -2ppm) */
neilt6 0:697ca602e934 119 BMATR_PLUS_1_0 /**< Delta capacitance = +1pF (≈ -4ppm) */
neilt6 0:697ca602e934 120 };
neilt6 0:697ca602e934 121
neilt6 0:697ca602e934 122 /** Represents the different digital trim selections of the ISL1208
neilt6 0:697ca602e934 123 */
neilt6 0:697ca602e934 124 enum DigitalTrim {
neilt6 0:697ca602e934 125 DTR_ZERO = 0, /**< Digital trim = 0ppm */
neilt6 0:697ca602e934 126 DTR_PLUS_20, /**< Digital trim = ≈ +20ppm */
neilt6 0:697ca602e934 127 DTR_PLUS_40, /**< Digital trim = ≈ +40ppm */
neilt6 0:697ca602e934 128 DTR_PLUS_60, /**< Digital trim = ≈ +60ppm */
neilt6 0:697ca602e934 129 DTR_MINUS_20 = 5, /**< Digital trim = ≈ -20ppm */
neilt6 0:697ca602e934 130 DTR_MINUS_40, /**< Digital trim = ≈ -40ppm */
neilt6 0:697ca602e934 131 DTR_MINUS_60 /**< Digital trim = ≈ -60ppm */
neilt6 0:697ca602e934 132 };
neilt6 0:697ca602e934 133
neilt6 0:697ca602e934 134 /** Create a ISL1208 object connected to the specified I2C pins
neilt6 0:697ca602e934 135 *
neilt6 0:697ca602e934 136 * @param sda The I2C data pin.
neilt6 0:697ca602e934 137 * @param scl The I2C clock pin.
neilt6 0:697ca602e934 138 */
neilt6 0:697ca602e934 139 ISL1208(PinName sda, PinName scl);
neilt6 0:697ca602e934 140
neilt6 0:697ca602e934 141 /** Probe for the ISL1208 and configures the oscillator mode if present
neilt6 0:697ca602e934 142 *
neilt6 0:697ca602e934 143 * @param mode The oscillator mode.
neilt6 0:697ca602e934 144 * @returns
neilt6 0:697ca602e934 145 * 'true' if the device exists on the bus,
neilt6 0:697ca602e934 146 * 'false' if the device doesn't exist on the bus.
neilt6 0:697ca602e934 147 */
neilt6 0:697ca602e934 148 bool open(OscillatorMode mode);
neilt6 0:697ca602e934 149
neilt6 0:697ca602e934 150 /** Get the current time from the ISL1208
neilt6 0:697ca602e934 151 *
neilt6 0:697ca602e934 152 * @returns The current time as a Unix timestamp.
neilt6 0:697ca602e934 153 */
neilt6 2:f33dbb2535a3 154 time_t time();
neilt6 0:697ca602e934 155
neilt6 0:697ca602e934 156 /** Set the current time on the ISL1208 from a Unix timestamp
neilt6 0:697ca602e934 157 *
neilt6 0:697ca602e934 158 * @param t The current time as a Unix timestamp.
neilt6 0:697ca602e934 159 */
neilt6 0:697ca602e934 160 void time(time_t t);
neilt6 0:697ca602e934 161
neilt6 0:697ca602e934 162 /** Determine whether the RTC has completely lost power (and hence the time and SRAM)
neilt6 0:697ca602e934 163 *
neilt6 0:697ca602e934 164 * @returns Whether or not the RTC has completely lost power.
neilt6 0:697ca602e934 165 */
neilt6 2:f33dbb2535a3 166 bool powerFailed();
neilt6 0:697ca602e934 167
neilt6 0:697ca602e934 168 /** Determine whether the RTC has been on battery backup
neilt6 0:697ca602e934 169 *
neilt6 0:697ca602e934 170 * @returns Whether or not the RTC has been on battery backup.
neilt6 0:697ca602e934 171 */
neilt6 2:f33dbb2535a3 172 bool batteryFlag();
neilt6 0:697ca602e934 173
neilt6 0:697ca602e934 174 /** Clear the battery backup flag
neilt6 0:697ca602e934 175 */
neilt6 2:f33dbb2535a3 176 void clearBatteryFlag();
neilt6 0:697ca602e934 177
neilt6 0:697ca602e934 178 /** Determine whether the alarm has matched the RTC
neilt6 0:697ca602e934 179 *
neilt6 0:697ca602e934 180 * @returns Whether or not the alarm has matched the RTC.
neilt6 0:697ca602e934 181 */
neilt6 2:f33dbb2535a3 182 bool alarmFlag();
neilt6 0:697ca602e934 183
neilt6 0:697ca602e934 184 /** Clear the alarm flag
neilt6 0:697ca602e934 185 */
neilt6 2:f33dbb2535a3 186 void clearAlarmFlag();
neilt6 0:697ca602e934 187
neilt6 0:697ca602e934 188 /** Get the current output frequency on the IRQ/fOUT pin
neilt6 0:697ca602e934 189 *
neilt6 0:697ca602e934 190 * @returns The current output frequency.
neilt6 0:697ca602e934 191 */
neilt6 2:f33dbb2535a3 192 ISL1208::OutputFrequency foutFrequency();
neilt6 0:697ca602e934 193
neilt6 0:697ca602e934 194 /** Set the output frequency on the IRQ/fOUT pin
neilt6 0:697ca602e934 195 *
neilt6 0:697ca602e934 196 * @param freq The new output frequency.
neilt6 0:697ca602e934 197 */
neilt6 0:697ca602e934 198 void foutFrequency(OutputFrequency freq);
neilt6 0:697ca602e934 199
neilt6 0:697ca602e934 200 /** Determine whether or not the IRQ/fOUT pin will continue to output on battery power
neilt6 0:697ca602e934 201 *
neilt6 0:697ca602e934 202 * @returns Whether or not the IRQ/fOUT pin will continue to output on battery power.
neilt6 0:697ca602e934 203 */
neilt6 2:f33dbb2535a3 204 bool outputOnBattery();
neilt6 0:697ca602e934 205
neilt6 0:697ca602e934 206 /** Set whether or not the IRQ/fOUT pin should continue to output on battery power
neilt6 0:697ca602e934 207 *
neilt6 0:697ca602e934 208 * @param output Whether or not the IRQ/fOUT pin should continue to output on battery power.
neilt6 0:697ca602e934 209 */
neilt6 0:697ca602e934 210 void outputOnBattery(bool output);
neilt6 0:697ca602e934 211
neilt6 0:697ca602e934 212 /** Get the current power mode of the ISL1208
neilt6 0:697ca602e934 213 *
neilt6 0:697ca602e934 214 * @returns The current power mode as a PowerMode enum.
neilt6 0:697ca602e934 215 */
neilt6 2:f33dbb2535a3 216 ISL1208::PowerMode powerMode();
neilt6 0:697ca602e934 217
neilt6 0:697ca602e934 218 /** Set the power mode of the ISL1208
neilt6 0:697ca602e934 219 *
neilt6 0:697ca602e934 220 * @param mode The new power mode as a PowerMode enum.
neilt6 0:697ca602e934 221 */
neilt6 0:697ca602e934 222 void powerMode(PowerMode mode);
neilt6 0:697ca602e934 223
neilt6 0:697ca602e934 224 /** Get the current alarm mode of the ISL1208
neilt6 0:697ca602e934 225 *
neilt6 0:697ca602e934 226 * @returns The current alarm mode as an AlarmMode enum.
neilt6 0:697ca602e934 227 */
neilt6 2:f33dbb2535a3 228 ISL1208::AlarmMode alarmMode();
neilt6 0:697ca602e934 229
neilt6 0:697ca602e934 230 /** Set the alarm mode of the ISL1208
neilt6 0:697ca602e934 231 *
neilt6 0:697ca602e934 232 * @param mode The new alarm mode as an AlarmMode enum.
neilt6 0:697ca602e934 233 */
neilt6 0:697ca602e934 234 void alarmMode(AlarmMode mode);
neilt6 0:697ca602e934 235
neilt6 0:697ca602e934 236 /** Get the current analog trim of the ISL1208
neilt6 0:697ca602e934 237 *
neilt6 0:697ca602e934 238 * @returns The current analog trim in pF.
neilt6 0:697ca602e934 239 */
neilt6 2:f33dbb2535a3 240 float analogTrim();
neilt6 0:697ca602e934 241
neilt6 0:697ca602e934 242 /** Set the analog trim of the ISL1208
neilt6 0:697ca602e934 243 *
neilt6 0:697ca602e934 244 * @param trim The new analog trim in pF (valid range 4.5pF to 20.25pF in 0.25pF steps).
neilt6 0:697ca602e934 245 */
neilt6 0:697ca602e934 246 void analogTrim(float trim);
neilt6 0:697ca602e934 247
neilt6 0:697ca602e934 248 /** Get the current battery mode analog trim of the ISL1208
neilt6 0:697ca602e934 249 *
neilt6 0:697ca602e934 250 * @returns The current battery mode analog trim as a BatteryModeATR enum.
neilt6 0:697ca602e934 251 */
neilt6 2:f33dbb2535a3 252 ISL1208::BatteryModeATR batteryModeATR();
neilt6 0:697ca602e934 253
neilt6 0:697ca602e934 254 /** Set the battery mode analog trim of the ISL1208
neilt6 0:697ca602e934 255 *
neilt6 0:697ca602e934 256 * @param mode The new battery mode analog trim as a BatteryModeATR enum.
neilt6 0:697ca602e934 257 */
neilt6 0:697ca602e934 258 void batteryModeATR(BatteryModeATR atr);
neilt6 0:697ca602e934 259
neilt6 0:697ca602e934 260 /** Get the current digital trim of the ISL1208
neilt6 0:697ca602e934 261 *
neilt6 0:697ca602e934 262 * @returns The current digital trim as a DigitalTrim enum.
neilt6 0:697ca602e934 263 */
neilt6 2:f33dbb2535a3 264 ISL1208::DigitalTrim digitalTrim();
neilt6 0:697ca602e934 265
neilt6 0:697ca602e934 266 /** Set the digital trim of the ISL1208
neilt6 0:697ca602e934 267 *
neilt6 0:697ca602e934 268 * @param mode The new digital trim as a DigitalTrim enum.
neilt6 0:697ca602e934 269 */
neilt6 0:697ca602e934 270 void digitalTrim(DigitalTrim dtr);
neilt6 0:697ca602e934 271
neilt6 0:697ca602e934 272 /** Get the alarm time from the ISL1208
neilt6 0:697ca602e934 273 *
neilt6 0:697ca602e934 274 * @returns The current alarm time as a Unix timestamp (with the current year)
neilt6 0:697ca602e934 275 */
neilt6 2:f33dbb2535a3 276 time_t alarmTime();
neilt6 0:697ca602e934 277
neilt6 0:697ca602e934 278 /** Set the alarm time on the ISL1208 from a Unix timestamp
neilt6 0:697ca602e934 279 *
neilt6 0:697ca602e934 280 * @param t The alarm time as a Unix timestamp.
neilt6 0:697ca602e934 281 * @param sc Enable or disable seconds matching.
neilt6 0:697ca602e934 282 * @param mn Enable or disable minutes matching.
neilt6 0:697ca602e934 283 * @param hr Enable or disable hours matching.
neilt6 0:697ca602e934 284 * @param dt Enable or disable date matching.
neilt6 0:697ca602e934 285 * @param mo Enable or disable month matching.
neilt6 0:697ca602e934 286 * @param dw Enable or disable day of week matching.
neilt6 0:697ca602e934 287 */
neilt6 0:697ca602e934 288 void alarmTime(time_t t, bool sc = true, bool mn = true, bool hr = true, bool dt = true, bool mo = true, bool dw = true);
neilt6 0:697ca602e934 289
neilt6 0:697ca602e934 290 /** Read the contents of the battery-backed SRAM
neilt6 0:697ca602e934 291 *
neilt6 0:697ca602e934 292 * @returns The current contents of the SRAM.
neilt6 0:697ca602e934 293 */
neilt6 2:f33dbb2535a3 294 unsigned short sram();
neilt6 0:697ca602e934 295
neilt6 0:697ca602e934 296 /** Write new data to the battery-backed SRAM
neilt6 0:697ca602e934 297 *
neilt6 0:697ca602e934 298 * @param data The new data for the SRAM.
neilt6 0:697ca602e934 299 */
neilt6 0:697ca602e934 300 void sram(unsigned short data);
neilt6 0:697ca602e934 301
neilt6 0:697ca602e934 302 private:
neilt6 0:697ca602e934 303 //I2C register addresses
neilt6 0:697ca602e934 304 enum Register {
neilt6 0:697ca602e934 305 REG_RTC_SC = 0x00,
neilt6 0:697ca602e934 306 REG_RTC_MN,
neilt6 0:697ca602e934 307 REG_RTC_HR,
neilt6 0:697ca602e934 308 REG_RTC_DT,
neilt6 0:697ca602e934 309 REG_RTC_MO,
neilt6 0:697ca602e934 310 REG_RTC_YR,
neilt6 0:697ca602e934 311 REG_RTC_DW,
neilt6 0:697ca602e934 312 REG_CTL_SR,
neilt6 0:697ca602e934 313 REG_CTL_INT,
neilt6 0:697ca602e934 314 REG_CTL_ATR = 0x0A,
neilt6 0:697ca602e934 315 REG_CTL_DTR,
neilt6 0:697ca602e934 316 REG_ALM_SCA,
neilt6 0:697ca602e934 317 REG_ALM_MNA,
neilt6 0:697ca602e934 318 REG_ALM_HRA,
neilt6 0:697ca602e934 319 REG_ALM_DTA,
neilt6 0:697ca602e934 320 REG_ALM_MOA,
neilt6 0:697ca602e934 321 REG_ALM_DWA,
neilt6 0:697ca602e934 322 REG_USR_USR1,
neilt6 0:697ca602e934 323 REG_USR_USR2
neilt6 0:697ca602e934 324 };
neilt6 0:697ca602e934 325
neilt6 0:697ca602e934 326 //Member constants
neilt6 0:697ca602e934 327 static const int m_ADDR = (0x6F << 1);
neilt6 0:697ca602e934 328
neilt6 0:697ca602e934 329 //Member variables
neilt6 0:697ca602e934 330 I2C m_I2C;
neilt6 0:697ca602e934 331
neilt6 0:697ca602e934 332 //Internal functions
neilt6 0:697ca602e934 333 char read8(char reg);
neilt6 0:697ca602e934 334 void write8(char reg, char data);
neilt6 0:697ca602e934 335 unsigned short read16(char reg);
neilt6 0:697ca602e934 336 void write16(char reg, unsigned short data);
neilt6 0:697ca602e934 337 unsigned int bcd2bin(unsigned char val);
neilt6 0:697ca602e934 338 char bin2bcd(unsigned int val);
neilt6 0:697ca602e934 339 };
neilt6 0:697ca602e934 340
neilt6 0:697ca602e934 341 #endif