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

Dependents:   ISL1208_HelloWorld

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ISL1208.h Source File

ISL1208.h

00001 /* ISL1208 Driver Library
00002  * Copyright (c) 2013 Neil Thiessen
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #ifndef ISL1208_H
00018 #define ISL1208_H
00019 
00020 #include "mbed.h"
00021 
00022 /** ISL1208 class.
00023  *  Used for controlling an ISL1208 real time clock connected via I2C.
00024  *
00025  * Example:
00026  * @code
00027  * #include "mbed.h"
00028  * #include "ISL1208.h"
00029  *
00030  * ISL1208 rtc(p28, p27);
00031  *
00032  * int main()
00033  * {
00034  *     //Try to open the ISL1208
00035  *     if (rtc.open()) {
00036  *         printf("Device detected!\n");
00037  *
00038  *         //Configure the oscillator for a 32.768kHz crystal
00039  *         rtc.oscillatorMode(ISL1208::OSCILLATOR_CRYSTAL);
00040  *
00041  *         //Check if we need to reset the time
00042  *         if (rtc.powerFailed()) {
00043  *             //The time has been lost due to a power complete power failure
00044  *             printf("Device has lost power! Resetting time...\n");
00045  *
00046  *             //Set RTC time to Wed, 28 Oct 2009 11:35:37
00047  *             rtc.time(1256729737);
00048  *         }
00049  *
00050  *         while(1) {
00051  *             //Get the current time
00052  *             time_t seconds = rtc.time();
00053  *
00054  *             //Print the time in various formats
00055  *             printf("\nTime as seconds since January 1, 1970 = %d\n", seconds);
00056  *             printf("Time as a basic string = %s", ctime(&seconds));
00057  *             char buffer[32];
00058  *             strftime(buffer, 32, "%I:%M %p\n", localtime(&seconds));
00059  *             printf("Time as a custom formatted string = %s", buffer);
00060  *
00061  *             //Delay for 1.0 seconds
00062  *             wait(1.0);
00063  *         }
00064  *     } else {
00065  *         error("Device not detected!\n");
00066  *     }
00067  * }
00068  * @endcode
00069  */
00070 class ISL1208
00071 {
00072 public:
00073     /** Represents the different oscillator modes for the ISL1208
00074      */
00075     enum OscillatorMode {
00076         OSCILLATOR_CRYSTAL,  /**< The internal crystal oscillator is enabled */
00077         OSCILLATOR_EXTERNAL  /**< The internal crystal oscillator is disabled, an external 32kHz oscillator is connected to X1 */
00078     };
00079 
00080     /** Represents the different output frequencies for the IRQ/fOUT pin on the ISL1208
00081      */
00082     enum OutputFrequency {
00083         FOUT_DISABLED = 0,  /**< Disable frequency generation on the IRQ/fOUT pin */
00084         FOUT_32768_HZ,      /**< Generate 32.768kHz on the IRQ/fOUT pin */
00085         FOUT_4096_HZ,       /**< Generate 4.096kHz on the IRQ/fOUT pin */
00086         FOUT_1024_HZ,       /**< Generate 1.024kHz on the IRQ/fOUT pin */
00087         FOUT_64_HZ,         /**< Generate 64Hz on the IRQ/fOUT pin */
00088         FOUT_32_HZ,         /**< Generate 32Hz on the IRQ/fOUT pin */
00089         FOUT_16_HZ,         /**< Generate 16Hz on the IRQ/fOUT pin */
00090         FOUT_8_HZ,          /**< Generate 8Hz on the IRQ/fOUT pin */
00091         FOUT_4_HZ,          /**< Generate 4Hz on the IRQ/fOUT pin */
00092         FOUT_2_HZ,          /**< Generate 2Hz on the IRQ/fOUT pin */
00093         FOUT_1_HZ,          /**< Generate 1Hz on the IRQ/fOUT pin */
00094         FOUT_1_2_HZ,        /**< Generate 1/2Hz on the IRQ/fOUT pin */
00095         FOUT_1_4_HZ,        /**< Generate 1/4Hz on the IRQ/fOUT pin */
00096         FOUT_1_8_HZ,        /**< Generate 1/8Hz on the IRQ/fOUT pin */
00097         FOUT_1_16_HZ,       /**< Generate 1/16Hz on the IRQ/fOUT pin */
00098         FOUT_1_32_HZ        /**< Generate 1/32Hz on the IRQ/fOUT pin */
00099     };
00100 
00101     /** Represents the power mode of the ISL1208
00102      */
00103     enum PowerMode {
00104         POWER_NORMAL,   /**< VBAT supply will be used when VDD < VBAT - VBATHYS and VDD < VTRIP */
00105         POWER_LPMODE    /**< VBAT supply will be used when VDD < VBAT - VBATHYS */
00106     };
00107 
00108     /** Represents the alarm mode of the ISL1208
00109      */
00110     enum AlarmMode {
00111         ALARM_DISABLED, /**< The alarm function is disabled */
00112         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 */
00113         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 */
00114     };
00115 
00116     /** Represents the different battery mode ATR selections of the ISL1208
00117      */
00118     enum BatteryModeATR {
00119         BMATR_ZERO = 0,     /**< Delta capacitance = 0pF */
00120         BMATR_MINUS_0_5,    /**< Delta capacitance = -0.5pF (≈ +2ppm) */
00121         BMATR_PLUS_0_5,     /**< Delta capacitance = +0.5pF (≈ -2ppm) */
00122         BMATR_PLUS_1_0      /**< Delta capacitance = +1pF (≈ -4ppm) */
00123     };
00124 
00125     /** Represents the different digital trim selections of the ISL1208
00126      */
00127     enum DigitalTrim {
00128         DTR_ZERO = 0,       /**< Digital trim = 0ppm */
00129         DTR_PLUS_20,        /**< Digital trim = ≈ +20ppm */
00130         DTR_PLUS_40,        /**< Digital trim = ≈ +40ppm */
00131         DTR_PLUS_60,        /**< Digital trim = ≈ +60ppm */
00132         DTR_MINUS_20 = 5,   /**< Digital trim = ≈ -20ppm */
00133         DTR_MINUS_40,       /**< Digital trim = ≈ -40ppm */
00134         DTR_MINUS_60        /**< Digital trim = ≈ -60ppm */
00135     };
00136 
00137     /** Create a ISL1208 object connected to the specified I2C pins
00138      *
00139      * @param sda The I2C data pin.
00140      * @param scl The I2C clock pin.
00141      * @param hz The I2C bus frequency (defaults to 400kHz).
00142      */
00143     ISL1208(PinName sda, PinName scl, int hz = 400000);
00144 
00145     /** Probe for the ISL1208 and configure auto reset if present
00146      *
00147      * @returns
00148      *   'true' if the device exists on the bus,
00149      *   'false' if the device doesn't exist on the bus.
00150      */
00151     bool open();
00152 
00153     /** Get the current time from the ISL1208
00154      *
00155      * @returns The current time as a Unix timestamp.
00156      */
00157     time_t time();
00158 
00159     /** Set the current time on the ISL1208 from a Unix timestamp
00160      *
00161      * @param t The current time as a Unix timestamp.
00162      */
00163     void time(time_t t);
00164 
00165     /** Determine whether the RTC has completely lost power (and hence the time and SRAM)
00166      *
00167      * @returns Whether or not the RTC has completely lost power.
00168      */
00169     bool powerFailed();
00170 
00171     /** Determine whether the RTC has been on battery backup
00172      *
00173      * @returns Whether or not the RTC has been on battery backup.
00174      */
00175     bool batteryFlag();
00176 
00177     /** Clear the battery backup flag
00178      */
00179     void clearBatteryFlag();
00180 
00181     /** Determine whether the alarm has matched the RTC
00182      *
00183      * @returns Whether or not the alarm has matched the RTC.
00184      */
00185     bool alarmFlag();
00186 
00187     /** Clear the alarm flag
00188      */
00189     void clearAlarmFlag();
00190 
00191     /** Get the current oscillator mode of the ISL1208
00192      *
00193      * @returns The current oscillator mode as a OscillatorMode enum.
00194      */
00195     ISL1208::OscillatorMode oscillatorMode();
00196 
00197     /** Set the oscillator mode of the ISL1208
00198      *
00199      * @param mode The new oscillator mode as a OscillatorMode enum.
00200      */
00201     void oscillatorMode(OscillatorMode mode);
00202 
00203     /** Get the current output frequency on the IRQ/fOUT pin
00204      *
00205      * @returns The current output frequency.
00206      */
00207     ISL1208::OutputFrequency foutFrequency();
00208 
00209     /** Set the output frequency on the IRQ/fOUT pin
00210      *
00211      * @param freq The new output frequency.
00212      */
00213     void foutFrequency(OutputFrequency freq);
00214 
00215     /** Determine whether or not the IRQ/fOUT pin will continue to output on battery power
00216      *
00217      * @returns Whether or not the IRQ/fOUT pin will continue to output on battery power.
00218      */
00219     bool outputOnBattery();
00220 
00221     /** Set whether or not the IRQ/fOUT pin should continue to output on battery power
00222      *
00223      * @param output Whether or not the IRQ/fOUT pin should continue to output on battery power.
00224      */
00225     void outputOnBattery(bool output);
00226 
00227     /** Get the current power mode of the ISL1208
00228      *
00229      * @returns The current power mode as a PowerMode enum.
00230      */
00231     ISL1208::PowerMode powerMode();
00232 
00233     /** Set the power mode of the ISL1208
00234      *
00235      * @param mode The new power mode as a PowerMode enum.
00236      */
00237     void powerMode(PowerMode mode);
00238 
00239     /** Get the current alarm mode of the ISL1208
00240      *
00241      * @returns The current alarm mode as an AlarmMode enum.
00242      */
00243     ISL1208::AlarmMode alarmMode();
00244 
00245     /** Set the alarm mode of the ISL1208
00246      *
00247      * @param mode The new alarm mode as an AlarmMode enum.
00248      */
00249     void alarmMode(AlarmMode mode);
00250 
00251     /** Get the current analog trim of the ISL1208
00252      *
00253      * @returns The current analog trim in pF.
00254      */
00255     float analogTrim();
00256 
00257     /** Set the analog trim of the ISL1208
00258      *
00259      * @param trim The new analog trim in pF (valid range 4.5pF to 20.25pF in 0.25pF steps).
00260      */
00261     void analogTrim(float trim);
00262 
00263     /** Get the current battery mode analog trim of the ISL1208
00264      *
00265      * @returns The current battery mode analog trim as a BatteryModeATR enum.
00266      */
00267     ISL1208::BatteryModeATR batteryModeATR();
00268 
00269     /** Set the battery mode analog trim of the ISL1208
00270      *
00271      * @param mode The new battery mode analog trim as a BatteryModeATR enum.
00272      */
00273     void batteryModeATR(BatteryModeATR atr);
00274 
00275     /** Get the current digital trim of the ISL1208
00276      *
00277      * @returns The current digital trim as a DigitalTrim enum.
00278      */
00279     ISL1208::DigitalTrim digitalTrim();
00280 
00281     /** Set the digital trim of the ISL1208
00282      *
00283      * @param mode The new digital trim as a DigitalTrim enum.
00284      */
00285     void digitalTrim(DigitalTrim dtr);
00286 
00287     /** Get the alarm time from the ISL1208
00288      *
00289      * @returns The current alarm time as a Unix timestamp (with the current year)
00290      */
00291     time_t alarmTime();
00292 
00293     /** Set the alarm time on the ISL1208 from a Unix timestamp
00294      *
00295      * @param t The alarm time as a Unix timestamp.
00296      * @param sc Enable or disable seconds matching.
00297      * @param mn Enable or disable minutes matching.
00298      * @param hr Enable or disable hours matching.
00299      * @param dt Enable or disable date matching.
00300      * @param mo Enable or disable month matching.
00301      * @param dw Enable or disable day of week matching.
00302      */
00303     void alarmTime(time_t t, bool sc = true, bool mn = true, bool hr = true, bool dt = true, bool mo = true, bool dw = true);
00304 
00305     /** Read the contents of the battery-backed SRAM
00306      *
00307      * @returns The current contents of the SRAM.
00308      */
00309     unsigned short sram();
00310 
00311     /** Write new data to the battery-backed SRAM
00312      *
00313      * @param data The new data for the SRAM.
00314      */
00315     void sram(unsigned short data);
00316 
00317 private:
00318     //I2C register addresses
00319     enum Register {
00320         REG_RTC_SC  = 0x00,
00321         REG_RTC_MN,
00322         REG_RTC_HR,
00323         REG_RTC_DT,
00324         REG_RTC_MO,
00325         REG_RTC_YR,
00326         REG_RTC_DW,
00327         REG_CTL_SR,
00328         REG_CTL_INT,
00329         REG_CTL_ATR = 0x0A,
00330         REG_CTL_DTR,
00331         REG_ALM_SCA,
00332         REG_ALM_MNA,
00333         REG_ALM_HRA,
00334         REG_ALM_DTA,
00335         REG_ALM_MOA,
00336         REG_ALM_DWA,
00337         REG_USR_USR1,
00338         REG_USR_USR2
00339     };
00340 
00341     //Member constants
00342     static const int m_ADDR;
00343 
00344     //Member variables
00345     I2C m_I2C;
00346 
00347     //Internal functions
00348     char read8(char reg);
00349     void write8(char reg, char data);
00350     unsigned short read16(char reg);
00351     void write16(char reg, unsigned short data);
00352     unsigned int bcd2bin(unsigned char val);
00353     char bin2bcd(unsigned int val);
00354 };
00355 
00356 #endif