A feature complete driver for the ISL1208 real time clock from Intersil.
Dependents: ISL1208_HelloWorld
Revision 0:697ca602e934, committed 2013-09-09
- Comitter:
- neilt6
- Date:
- Mon Sep 09 19:32:41 2013 +0000
- Child:
- 1:c951ff6da740
- Commit message:
- Initial commit
Changed in this revision
ISL1208.cpp | Show annotated file Show diff for this revision Revisions of this file |
ISL1208.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ISL1208.cpp Mon Sep 09 19:32:41 2013 +0000 @@ -0,0 +1,513 @@ +/* ISL1208 Driver Library + * Copyright (c) 2013 Neil Thiessen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ISL1208.h" + +ISL1208::ISL1208(PinName sda, PinName scl) : m_I2C(sda, scl) +{ + //Nothing else to initialize +} + +bool ISL1208::open(OscillatorMode mode) +{ + //Probe for the ISL1208 using a Zero Length Transfer + if (!m_I2C.write(m_ADDR, NULL, 0)) { + //Read the current status register + char sr = read8(REG_CTL_SR); + + //Configure the oscillator mode + if (mode == OSCILLATOR_CRYSTAL) + sr &= ~(1 << 6); + else + sr |= (1 << 6); + + //Disable auto reset for BAT and ALM bits + sr &= ~(1 << 7); + + //Write the new status register + write8(REG_CTL_SR, sr); + + //Return success + return true; + } else { + //Return failure + return false; + } +} + +time_t ISL1208::time(void) +{ + //Setup a tm structure based on the RTC + struct tm timeinfo; + timeinfo.tm_sec = bcd2bin(read8(REG_RTC_SC)); + timeinfo.tm_min = bcd2bin(read8(REG_RTC_MN)); + + //Make sure we get the proper hour regardless of the mode + char hours = read8(REG_RTC_HR); + if (hours & (1 << 7)) { + //RTC is in 24-hour mode + timeinfo.tm_hour = bcd2bin(hours & 0x3F); + } else { + //RTC is in 12-hour mode + timeinfo.tm_hour = bcd2bin(hours & 0x1F); + + //Check for the PM flag + if (hours & (1 << 5)) + timeinfo.tm_hour += 12; + } + + //Continue reading the registers + timeinfo.tm_mday = bcd2bin(read8(REG_RTC_DT)); + timeinfo.tm_mon = bcd2bin(read8(REG_RTC_MO)) - 1; + timeinfo.tm_year = bcd2bin(read8(REG_RTC_YR)) + 100; + timeinfo.tm_wday = bcd2bin(read8(REG_RTC_DW)); + + //Return as a timestamp + return mktime(&timeinfo); +} + +void ISL1208::time(time_t t) +{ + //Convert the time to a tm + struct tm *timeinfo = localtime(&t); + + /* The clock has an 8 bit wide bcd-coded register (they never learn) + * for the year. tm_year is an offset from 1900 and we are interested + * in the 2000-2099 range, so any value less than 100 is invalid. + */ + if (timeinfo->tm_year < 100) + return; + + //Read the old SR register value + char sr = read8(REG_CTL_SR); + + //Enable RTC writing + write8(REG_CTL_SR, sr | (1 << 4)); + + //Write the current time + write8(REG_RTC_SC, bin2bcd(timeinfo->tm_sec)); + write8(REG_RTC_MN, bin2bcd(timeinfo->tm_min)); + write8(REG_RTC_HR, bin2bcd(timeinfo->tm_hour) | (1 << 7)); //24-hour mode + write8(REG_RTC_DT, bin2bcd(timeinfo->tm_mday)); + write8(REG_RTC_MO, bin2bcd(timeinfo->tm_mon + 1)); + write8(REG_RTC_YR, bin2bcd(timeinfo->tm_year - 100)); + write8(REG_RTC_DW, bin2bcd(timeinfo->tm_wday & 7)); + + //Disable RTC writing + write8(REG_CTL_SR, sr); +} + +bool ISL1208::powerFailed(void) +{ + //Read the 8-bit register value + char value = read8(REG_CTL_SR); + + //Return the status of the RTCF bit + if (value & (1 << 0)) + return true; + else + return false; +} + +bool ISL1208::batteryFlag(void) +{ + //Read the 8-bit register value + char value = read8(REG_CTL_SR); + + //Return the status of the BAT bit + if (value & (1 << 1)) + return true; + else + return false; +} + +void ISL1208::clearBatteryFlag(void) +{ + //Read the current 8-bit register value + char value = read8(REG_CTL_SR); + + //Clear the BAT bit + value &= ~(1 << 1); + + //Write the value back out + write8(REG_CTL_SR, value); +} + +bool ISL1208::alarmFlag(void) +{ + //Read the 8-bit register value + char value = read8(REG_CTL_SR); + + //Return the status of the ALM bit + if (value & (1 << 2)) + return true; + else + return false; +} + +void ISL1208::clearAlarmFlag(void) +{ + //Read the current 8-bit register value + char value = read8(REG_CTL_SR); + + //Clear the ALM bit + value &= ~(1 << 2); + + //Write the value back out + write8(REG_CTL_SR, value); +} + +ISL1208::OutputFrequency ISL1208::foutFrequency(void) +{ + //Read the 8-bit register value + char value = read8(REG_CTL_INT); + + //Return the lower nibble + return (OutputFrequency)(value & 0x0F); +} + +void ISL1208::foutFrequency(OutputFrequency freq) +{ + //Read the current 8-bit register value + char value = read8(REG_CTL_INT); + + //Clear the old frequency bits + value &= 0xF0; + + //Set the new frequency bits + value |= freq; + + //Write the value back out + write8(REG_CTL_INT, value); +} + +bool ISL1208::outputOnBattery(void) +{ + //Read the 8-bit register value + char value = read8(REG_CTL_INT); + + //Return the status of the FOBATB bit + if (value & (1 << 4)) + return false; + else + return true; +} + +void ISL1208::outputOnBattery(bool output) +{ + //Read the current 8-bit register value + char value = read8(REG_CTL_INT); + + //Set or clear the FOBATB bit + if (output) + value &= ~(1 << 4); + else + value |= (1 << 4); + + //Write the value back out + write8(REG_CTL_INT, value); +} + +ISL1208::PowerMode ISL1208::powerMode(void) +{ + //Read the 8-bit register value + char value = read8(REG_CTL_INT); + + //Return the status of the LPMODE bit + if (value & (1 << 5)) + return POWER_LPMODE; + else + return POWER_NORMAL; +} + +void ISL1208::powerMode(PowerMode mode) +{ + //Read the current 8-bit register value + char value = read8(REG_CTL_INT); + + //Set or clear the LPMODE bit + if (mode == POWER_LPMODE) + value |= (1 << 5); + else + value &= ~(1 << 5); + + //Write the value back out + write8(REG_CTL_INT, value); +} + +ISL1208::AlarmMode ISL1208::alarmMode(void) +{ + //Read the 8-bit register value + char value = read8(REG_CTL_INT); + + //Return the status of the ALME and IM bits + if (value & (1 << 6)) { + if (value & (1 << 7)) + return ALARM_INTERRUPT; + else + return ALARM_SINGLE; + } else + return ALARM_DISABLED; +} + +void ISL1208::alarmMode(AlarmMode mode) +{ + //Read the current 8-bit register value + char value = read8(REG_CTL_INT); + + //Set or clear the ALME and IM bit + if (mode != ALARM_DISABLED) { + value |= (1 << 6); + if (mode == ALARM_INTERRUPT) + value |= (1 << 7); + else + value &= ~(1 << 7); + } else + value &= ~(1 << 6); + + //Write the value back out + write8(REG_CTL_INT, value); +} + +float ISL1208::analogTrim(void) +{ + //Read the 8-bit register value + char value = read8(REG_CTL_ATR); + + //Mask off the top 2 bits + value &= 0x3F; + + //Invert bit 5 + value ^= 1 << 5; + + //Add an offset of 4.5pF (unit[atr] = 0.25pF) + value += 2 * 9; + + //Return the analog trim in pF + return value * 0.25; +} + +void ISL1208::analogTrim(float trim) +{ + //Range limit trim + if (trim < 4.5) + trim = 4.5; + else if (trim > 20.25) + trim = 20.25; + + //Convert the analog trim value to a 6-bit integer + char value = (char)(trim / 0.25); + + //Remove the offset of 4.5pF (unit[atr] = 0.25pF) + value -= 2 * 9; + + //Invert bit 5 + value ^= 1 << 5; + + //Read the current 8-bit register value + char reg = read8(REG_CTL_ATR); + + //Clear the old ATR bits + reg &= 0xC0; + + //Add the new ATR bits + reg |= value; + + //Write the value back out + write8(REG_CTL_ATR, reg); +} + +ISL1208::BatteryModeATR ISL1208::batteryModeATR(void) +{ + //Read the 8-bit register value + char value = read8(REG_CTL_ATR); + + //Shift out the ATR bits + value >>= 6; + + //Return the value as a BatteryModeATR enum + return (BatteryModeATR)value; +} + +void ISL1208::batteryModeATR(BatteryModeATR atr) +{ + //Read the current 8-bit register value + char value = read8(REG_CTL_ATR); + + //Clear the old battery mode ATR bits + value &= 0x3F; + + //Add the new battery mode ATR bits + value |= (atr << 6); + + //Write the value back out + write8(REG_CTL_ATR, value); +} + +ISL1208::DigitalTrim ISL1208::digitalTrim(void) +{ + //Read the 8-bit register value + char value = read8(REG_CTL_DTR); + + //Mask off the reserved bit + value &= ~(1 << 7); + + //Return the value as a DigitalTrim enum + return (DigitalTrim)value; +} + +void ISL1208::digitalTrim(DigitalTrim dtr) +{ + //Read the current 8-bit register value (to preserve the reserved bit) + char value = read8(REG_CTL_DTR); + + //Clear the old DTR bits + value &= 0xF8; + + //Add the new DTR bits + value |= dtr; + + //Write the value back out + write8(REG_CTL_DTR, value); +} + +time_t ISL1208::alarmTime(void) +{ + //Setup a tm structure based on the RTC + struct tm timeinfo; + + //MSB of each alarm register is an enable bit + timeinfo.tm_sec = bcd2bin(read8(REG_ALM_SCA) & 0x7F); + timeinfo.tm_min = bcd2bin(read8(REG_ALM_MNA) & 0x7F); + timeinfo.tm_hour = bcd2bin(read8(REG_ALM_HRA) & 0x3F); + timeinfo.tm_mday = bcd2bin(read8(REG_ALM_DTA) & 0x3F); + timeinfo.tm_mon = bcd2bin(read8(REG_ALM_MOA) & 0x1F) - 1; + timeinfo.tm_wday = bcd2bin(read8(REG_ALM_DWA) & 0x03); + + //The alarm doesn't store the year, so get it from the RTC section + timeinfo.tm_year = bcd2bin(read8(REG_RTC_YR)) + 100; + + //Return as a timestamp + return mktime(&timeinfo); +} + +void ISL1208::alarmTime(time_t t, bool sc, bool mn, bool hr, bool dt, bool mo, bool dw) +{ + //Convert the time to a tm + struct tm *timeinfo = localtime(&t); + + //Write the new alarm time components (if enabled) + if (sc) + write8(REG_ALM_SCA, bin2bcd(timeinfo->tm_sec) | 0x80); + else + write8(REG_ALM_SCA, 0x0); + if (mn) + write8(REG_ALM_MNA, bin2bcd(timeinfo->tm_min) | 0x80); + else + write8(REG_ALM_MNA, 0x0); + if (hr) + write8(REG_ALM_HRA, bin2bcd(timeinfo->tm_hour) | 0x80); + else + write8(REG_ALM_HRA, 0x0); + if (hr) + write8(REG_ALM_DTA, bin2bcd(timeinfo->tm_mday) | 0x80); + else + write8(REG_ALM_DTA, 0x0); + if (mo) + write8(REG_ALM_MOA, bin2bcd(timeinfo->tm_mon + 1) | 0x80); + else + write8(REG_ALM_MOA, 0x0); + if (dw) + write8(REG_ALM_DWA, bin2bcd(timeinfo->tm_wday & 7) | 0x80); + else + write8(REG_ALM_DWA, 0x0); +} + +unsigned short ISL1208::sram(void) +{ + //Return the complete contents of the SRAM + return read16(REG_USR_USR1); +} + +void ISL1208::sram(unsigned short data) +{ + //Write the complete contents of the SRAM + write16(REG_USR_USR1, data); +} + +char ISL1208::read8(char reg) +{ + //Select the register + m_I2C.write(m_ADDR, ®, 1); + + //Read the 8-bit register + m_I2C.read(m_ADDR, ®, 1); + + //Return the byte + return reg; +} + +void ISL1208::write8(char reg, char data) +{ + //Create a temporary buffer + char buff[2]; + + //Load the register address and 8-bit data + buff[0] = reg; + buff[1] = data; + + //Write the data + m_I2C.write(m_ADDR, buff, 2); +} + +unsigned short ISL1208::read16(char reg) +{ + //Create a temporary buffer + char buff[2]; + + //Select the register + m_I2C.write(m_ADDR, ®, 1); + + //Read the 16-bit register + m_I2C.read(m_ADDR, buff, 2); + + //Return the combined 16-bit value + return (buff[0] << 8) | buff[1]; +} + +void ISL1208::write16(char reg, unsigned short data) +{ + //Create a temporary buffer + char buff[3]; + + //Load the register address and 16-bit data + buff[0] = reg; + buff[1] = data >> 8; + buff[2] = data; + + //Write the data + m_I2C.write(m_ADDR, buff, 3); +} + +unsigned int ISL1208::bcd2bin(unsigned char val) +{ + return (val & 0x0F) + (val >> 4) * 10; +} + +char ISL1208::bin2bcd(unsigned int val) +{ + return ((val / 10) << 4) + val % 10; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ISL1208.h Mon Sep 09 19:32:41 2013 +0000 @@ -0,0 +1,341 @@ +/* ISL1208 Driver Library + * Copyright (c) 2013 Neil Thiessen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ISL1208_H +#define ISL1208_H + +#include "mbed.h" + +/** ISL1208 class. + * Used for controlling an ISL1208 real time clock connected via I2C. + * + * Example: + * @code + * #include "mbed.h" + * #include "ISL1208.h" + * + * ISL1208 rtc(p28, p27); + * + * int main() + * { + * //Try to open the ISL1208 + * if (rtc.open(ISL1208::OSCILLATOR_CRYSTAL)) { + * printf("Device detected!\n"); + * + * //Check if we need to reset the time + * if (rtc.powerFailed()) { + * //The time has been lost due to a power complete power failure + * printf("Device has lost power! Resetting time...\n"); + * + * //Set RTC time to Wed, 28 Oct 2009 11:35:37 + * rtc.time(1256729737); + * } + * + * while(1) { + * //Get the current time + * time_t seconds = rtc.time(); + * + * //Print the time in various formats + * printf("\nTime as seconds since January 1, 1970 = %d\n", seconds); + * printf("Time as a basic string = %s", ctime(&seconds)); + * char buffer[32]; + * strftime(buffer, 32, "%I:%M %p\n", localtime(&seconds)); + * printf("Time as a custom formatted string = %s", buffer); + * + * //Delay for 1.0 seconds + * wait(1.0); + * } + * } else { + * printf("Device not detected!\n"); + * } + * } + * @endcode + */ +class ISL1208 +{ +public: + /** Represents the different oscillator modes for the ISL1208 + */ + enum OscillatorMode { + OSCILLATOR_CRYSTAL, /**< The internal crystal oscillator is enabled */ + OSCILLATOR_EXTERNAL /**< The internal crystal oscillator is disabled, an external 32kHz oscillator is connected to X1 */ + }; + + /** Represents the different output frequencies for the IRQ/fOUT pin on the ISL1208 + */ + enum OutputFrequency { + FOUT_DISABLED = 0, /**< Disable frequency generation on the IRQ/fOUT pin */ + FOUT_32768_HZ, /**< Generate 32.768kHz on the IRQ/fOUT pin */ + FOUT_4096_HZ, /**< Generate 4.096kHz on the IRQ/fOUT pin */ + FOUT_1024_HZ, /**< Generate 1.024kHz on the IRQ/fOUT pin */ + FOUT_64_HZ, /**< Generate 64Hz on the IRQ/fOUT pin */ + FOUT_32_HZ, /**< Generate 32Hz on the IRQ/fOUT pin */ + FOUT_16_HZ, /**< Generate 16Hz on the IRQ/fOUT pin */ + FOUT_8_HZ, /**< Generate 8Hz on the IRQ/fOUT pin */ + FOUT_4_HZ, /**< Generate 4Hz on the IRQ/fOUT pin */ + FOUT_2_HZ, /**< Generate 2Hz on the IRQ/fOUT pin */ + FOUT_1_HZ, /**< Generate 1Hz on the IRQ/fOUT pin */ + FOUT_1_2_HZ, /**< Generate 1/2Hz on the IRQ/fOUT pin */ + FOUT_1_4_HZ, /**< Generate 1/4Hz on the IRQ/fOUT pin */ + FOUT_1_8_HZ, /**< Generate 1/8Hz on the IRQ/fOUT pin */ + FOUT_1_16_HZ, /**< Generate 1/16Hz on the IRQ/fOUT pin */ + FOUT_1_32_HZ /**< Generate 1/32Hz on the IRQ/fOUT pin */ + }; + + /** Represents the power mode of the ISL1208 + */ + enum PowerMode { + POWER_NORMAL, /**< VBAT supply will be used when VDD < VBAT - VBATHYS and VDD < VTRIP */ + POWER_LPMODE /**< VBAT supply will be used when VDD < VBAT - VBATHYS */ + }; + + /** Represents the alarm mode of the ISL1208 + */ + enum AlarmMode { + ALARM_DISABLED, /**< The alarm function is disabled */ + 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 */ + 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 */ + }; + + /** Represents the different battery mode ATR selections of the ISL1208 + */ + enum BatteryModeATR { + BMATR_ZERO = 0, /**< Delta capacitance = 0pF */ + BMATR_MINUS_0_5, /**< Delta capacitance = -0.5pF (≈ +2ppm) */ + BMATR_PLUS_0_5, /**< Delta capacitance = +0.5pF (≈ -2ppm) */ + BMATR_PLUS_1_0 /**< Delta capacitance = +1pF (≈ -4ppm) */ + }; + + /** Represents the different digital trim selections of the ISL1208 + */ + enum DigitalTrim { + DTR_ZERO = 0, /**< Digital trim = 0ppm */ + DTR_PLUS_20, /**< Digital trim = ≈ +20ppm */ + DTR_PLUS_40, /**< Digital trim = ≈ +40ppm */ + DTR_PLUS_60, /**< Digital trim = ≈ +60ppm */ + DTR_MINUS_20 = 5, /**< Digital trim = ≈ -20ppm */ + DTR_MINUS_40, /**< Digital trim = ≈ -40ppm */ + DTR_MINUS_60 /**< Digital trim = ≈ -60ppm */ + }; + + /** Create a ISL1208 object connected to the specified I2C pins + * + * @param sda The I2C data pin. + * @param scl The I2C clock pin. + */ + ISL1208(PinName sda, PinName scl); + + /** Probe for the ISL1208 and configures the oscillator mode if present + * + * @param mode The oscillator mode. + * @returns + * 'true' if the device exists on the bus, + * 'false' if the device doesn't exist on the bus. + */ + bool open(OscillatorMode mode); + + /** Get the current time from the ISL1208 + * + * @returns The current time as a Unix timestamp. + */ + time_t time(void); + + /** Set the current time on the ISL1208 from a Unix timestamp + * + * @param t The current time as a Unix timestamp. + */ + void time(time_t t); + + /** Determine whether the RTC has completely lost power (and hence the time and SRAM) + * + * @returns Whether or not the RTC has completely lost power. + */ + bool powerFailed(void); + + /** Determine whether the RTC has been on battery backup + * + * @returns Whether or not the RTC has been on battery backup. + */ + bool batteryFlag(void); + + /** Clear the battery backup flag + */ + void clearBatteryFlag(void); + + /** Determine whether the alarm has matched the RTC + * + * @returns Whether or not the alarm has matched the RTC. + */ + bool alarmFlag(void); + + /** Clear the alarm flag + */ + void clearAlarmFlag(void); + + /** Get the current output frequency on the IRQ/fOUT pin + * + * @returns The current output frequency. + */ + ISL1208::OutputFrequency foutFrequency(void); + + /** Set the output frequency on the IRQ/fOUT pin + * + * @param freq The new output frequency. + */ + void foutFrequency(OutputFrequency freq); + + /** Determine whether or not the IRQ/fOUT pin will continue to output on battery power + * + * @returns Whether or not the IRQ/fOUT pin will continue to output on battery power. + */ + bool outputOnBattery(void); + + /** Set whether or not the IRQ/fOUT pin should continue to output on battery power + * + * @param output Whether or not the IRQ/fOUT pin should continue to output on battery power. + */ + void outputOnBattery(bool output); + + /** Get the current power mode of the ISL1208 + * + * @returns The current power mode as a PowerMode enum. + */ + ISL1208::PowerMode powerMode(void); + + /** Set the power mode of the ISL1208 + * + * @param mode The new power mode as a PowerMode enum. + */ + void powerMode(PowerMode mode); + + /** Get the current alarm mode of the ISL1208 + * + * @returns The current alarm mode as an AlarmMode enum. + */ + ISL1208::AlarmMode alarmMode(void); + + /** Set the alarm mode of the ISL1208 + * + * @param mode The new alarm mode as an AlarmMode enum. + */ + void alarmMode(AlarmMode mode); + + /** Get the current analog trim of the ISL1208 + * + * @returns The current analog trim in pF. + */ + float analogTrim(void); + + /** Set the analog trim of the ISL1208 + * + * @param trim The new analog trim in pF (valid range 4.5pF to 20.25pF in 0.25pF steps). + */ + void analogTrim(float trim); + + /** Get the current battery mode analog trim of the ISL1208 + * + * @returns The current battery mode analog trim as a BatteryModeATR enum. + */ + ISL1208::BatteryModeATR batteryModeATR(void); + + /** Set the battery mode analog trim of the ISL1208 + * + * @param mode The new battery mode analog trim as a BatteryModeATR enum. + */ + void batteryModeATR(BatteryModeATR atr); + + /** Get the current digital trim of the ISL1208 + * + * @returns The current digital trim as a DigitalTrim enum. + */ + ISL1208::DigitalTrim digitalTrim(void); + + /** Set the digital trim of the ISL1208 + * + * @param mode The new digital trim as a DigitalTrim enum. + */ + void digitalTrim(DigitalTrim dtr); + + /** Get the alarm time from the ISL1208 + * + * @returns The current alarm time as a Unix timestamp (with the current year) + */ + time_t alarmTime(void); + + /** Set the alarm time on the ISL1208 from a Unix timestamp + * + * @param t The alarm time as a Unix timestamp. + * @param sc Enable or disable seconds matching. + * @param mn Enable or disable minutes matching. + * @param hr Enable or disable hours matching. + * @param dt Enable or disable date matching. + * @param mo Enable or disable month matching. + * @param dw Enable or disable day of week matching. + */ + void alarmTime(time_t t, bool sc = true, bool mn = true, bool hr = true, bool dt = true, bool mo = true, bool dw = true); + + /** Read the contents of the battery-backed SRAM + * + * @returns The current contents of the SRAM. + */ + unsigned short sram(void); + + /** Write new data to the battery-backed SRAM + * + * @param data The new data for the SRAM. + */ + void sram(unsigned short data); + +private: + //I2C register addresses + enum Register { + REG_RTC_SC = 0x00, + REG_RTC_MN, + REG_RTC_HR, + REG_RTC_DT, + REG_RTC_MO, + REG_RTC_YR, + REG_RTC_DW, + REG_CTL_SR, + REG_CTL_INT, + REG_CTL_ATR = 0x0A, + REG_CTL_DTR, + REG_ALM_SCA, + REG_ALM_MNA, + REG_ALM_HRA, + REG_ALM_DTA, + REG_ALM_MOA, + REG_ALM_DWA, + REG_USR_USR1, + REG_USR_USR2 + }; + + //Member constants + static const int m_ADDR = (0x6F << 1); + + //Member variables + I2C m_I2C; + + //Internal functions + char read8(char reg); + void write8(char reg, char data); + unsigned short read16(char reg); + void write16(char reg, unsigned short data); + unsigned int bcd2bin(unsigned char val); + char bin2bcd(unsigned int val); +}; + +#endif