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

Dependents:   ISL1208_HelloWorld

Committer:
neilt6
Date:
Mon Sep 09 19:32:41 2013 +0000
Revision:
0:697ca602e934
Child:
2:f33dbb2535a3
Initial commit

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 #include "ISL1208.h"
neilt6 0:697ca602e934 18
neilt6 0:697ca602e934 19 ISL1208::ISL1208(PinName sda, PinName scl) : m_I2C(sda, scl)
neilt6 0:697ca602e934 20 {
neilt6 0:697ca602e934 21 //Nothing else to initialize
neilt6 0:697ca602e934 22 }
neilt6 0:697ca602e934 23
neilt6 0:697ca602e934 24 bool ISL1208::open(OscillatorMode mode)
neilt6 0:697ca602e934 25 {
neilt6 0:697ca602e934 26 //Probe for the ISL1208 using a Zero Length Transfer
neilt6 0:697ca602e934 27 if (!m_I2C.write(m_ADDR, NULL, 0)) {
neilt6 0:697ca602e934 28 //Read the current status register
neilt6 0:697ca602e934 29 char sr = read8(REG_CTL_SR);
neilt6 0:697ca602e934 30
neilt6 0:697ca602e934 31 //Configure the oscillator mode
neilt6 0:697ca602e934 32 if (mode == OSCILLATOR_CRYSTAL)
neilt6 0:697ca602e934 33 sr &= ~(1 << 6);
neilt6 0:697ca602e934 34 else
neilt6 0:697ca602e934 35 sr |= (1 << 6);
neilt6 0:697ca602e934 36
neilt6 0:697ca602e934 37 //Disable auto reset for BAT and ALM bits
neilt6 0:697ca602e934 38 sr &= ~(1 << 7);
neilt6 0:697ca602e934 39
neilt6 0:697ca602e934 40 //Write the new status register
neilt6 0:697ca602e934 41 write8(REG_CTL_SR, sr);
neilt6 0:697ca602e934 42
neilt6 0:697ca602e934 43 //Return success
neilt6 0:697ca602e934 44 return true;
neilt6 0:697ca602e934 45 } else {
neilt6 0:697ca602e934 46 //Return failure
neilt6 0:697ca602e934 47 return false;
neilt6 0:697ca602e934 48 }
neilt6 0:697ca602e934 49 }
neilt6 0:697ca602e934 50
neilt6 0:697ca602e934 51 time_t ISL1208::time(void)
neilt6 0:697ca602e934 52 {
neilt6 0:697ca602e934 53 //Setup a tm structure based on the RTC
neilt6 0:697ca602e934 54 struct tm timeinfo;
neilt6 0:697ca602e934 55 timeinfo.tm_sec = bcd2bin(read8(REG_RTC_SC));
neilt6 0:697ca602e934 56 timeinfo.tm_min = bcd2bin(read8(REG_RTC_MN));
neilt6 0:697ca602e934 57
neilt6 0:697ca602e934 58 //Make sure we get the proper hour regardless of the mode
neilt6 0:697ca602e934 59 char hours = read8(REG_RTC_HR);
neilt6 0:697ca602e934 60 if (hours & (1 << 7)) {
neilt6 0:697ca602e934 61 //RTC is in 24-hour mode
neilt6 0:697ca602e934 62 timeinfo.tm_hour = bcd2bin(hours & 0x3F);
neilt6 0:697ca602e934 63 } else {
neilt6 0:697ca602e934 64 //RTC is in 12-hour mode
neilt6 0:697ca602e934 65 timeinfo.tm_hour = bcd2bin(hours & 0x1F);
neilt6 0:697ca602e934 66
neilt6 0:697ca602e934 67 //Check for the PM flag
neilt6 0:697ca602e934 68 if (hours & (1 << 5))
neilt6 0:697ca602e934 69 timeinfo.tm_hour += 12;
neilt6 0:697ca602e934 70 }
neilt6 0:697ca602e934 71
neilt6 0:697ca602e934 72 //Continue reading the registers
neilt6 0:697ca602e934 73 timeinfo.tm_mday = bcd2bin(read8(REG_RTC_DT));
neilt6 0:697ca602e934 74 timeinfo.tm_mon = bcd2bin(read8(REG_RTC_MO)) - 1;
neilt6 0:697ca602e934 75 timeinfo.tm_year = bcd2bin(read8(REG_RTC_YR)) + 100;
neilt6 0:697ca602e934 76 timeinfo.tm_wday = bcd2bin(read8(REG_RTC_DW));
neilt6 0:697ca602e934 77
neilt6 0:697ca602e934 78 //Return as a timestamp
neilt6 0:697ca602e934 79 return mktime(&timeinfo);
neilt6 0:697ca602e934 80 }
neilt6 0:697ca602e934 81
neilt6 0:697ca602e934 82 void ISL1208::time(time_t t)
neilt6 0:697ca602e934 83 {
neilt6 0:697ca602e934 84 //Convert the time to a tm
neilt6 0:697ca602e934 85 struct tm *timeinfo = localtime(&t);
neilt6 0:697ca602e934 86
neilt6 0:697ca602e934 87 /* The clock has an 8 bit wide bcd-coded register (they never learn)
neilt6 0:697ca602e934 88 * for the year. tm_year is an offset from 1900 and we are interested
neilt6 0:697ca602e934 89 * in the 2000-2099 range, so any value less than 100 is invalid.
neilt6 0:697ca602e934 90 */
neilt6 0:697ca602e934 91 if (timeinfo->tm_year < 100)
neilt6 0:697ca602e934 92 return;
neilt6 0:697ca602e934 93
neilt6 0:697ca602e934 94 //Read the old SR register value
neilt6 0:697ca602e934 95 char sr = read8(REG_CTL_SR);
neilt6 0:697ca602e934 96
neilt6 0:697ca602e934 97 //Enable RTC writing
neilt6 0:697ca602e934 98 write8(REG_CTL_SR, sr | (1 << 4));
neilt6 0:697ca602e934 99
neilt6 0:697ca602e934 100 //Write the current time
neilt6 0:697ca602e934 101 write8(REG_RTC_SC, bin2bcd(timeinfo->tm_sec));
neilt6 0:697ca602e934 102 write8(REG_RTC_MN, bin2bcd(timeinfo->tm_min));
neilt6 0:697ca602e934 103 write8(REG_RTC_HR, bin2bcd(timeinfo->tm_hour) | (1 << 7)); //24-hour mode
neilt6 0:697ca602e934 104 write8(REG_RTC_DT, bin2bcd(timeinfo->tm_mday));
neilt6 0:697ca602e934 105 write8(REG_RTC_MO, bin2bcd(timeinfo->tm_mon + 1));
neilt6 0:697ca602e934 106 write8(REG_RTC_YR, bin2bcd(timeinfo->tm_year - 100));
neilt6 0:697ca602e934 107 write8(REG_RTC_DW, bin2bcd(timeinfo->tm_wday & 7));
neilt6 0:697ca602e934 108
neilt6 0:697ca602e934 109 //Disable RTC writing
neilt6 0:697ca602e934 110 write8(REG_CTL_SR, sr);
neilt6 0:697ca602e934 111 }
neilt6 0:697ca602e934 112
neilt6 0:697ca602e934 113 bool ISL1208::powerFailed(void)
neilt6 0:697ca602e934 114 {
neilt6 0:697ca602e934 115 //Read the 8-bit register value
neilt6 0:697ca602e934 116 char value = read8(REG_CTL_SR);
neilt6 0:697ca602e934 117
neilt6 0:697ca602e934 118 //Return the status of the RTCF bit
neilt6 0:697ca602e934 119 if (value & (1 << 0))
neilt6 0:697ca602e934 120 return true;
neilt6 0:697ca602e934 121 else
neilt6 0:697ca602e934 122 return false;
neilt6 0:697ca602e934 123 }
neilt6 0:697ca602e934 124
neilt6 0:697ca602e934 125 bool ISL1208::batteryFlag(void)
neilt6 0:697ca602e934 126 {
neilt6 0:697ca602e934 127 //Read the 8-bit register value
neilt6 0:697ca602e934 128 char value = read8(REG_CTL_SR);
neilt6 0:697ca602e934 129
neilt6 0:697ca602e934 130 //Return the status of the BAT bit
neilt6 0:697ca602e934 131 if (value & (1 << 1))
neilt6 0:697ca602e934 132 return true;
neilt6 0:697ca602e934 133 else
neilt6 0:697ca602e934 134 return false;
neilt6 0:697ca602e934 135 }
neilt6 0:697ca602e934 136
neilt6 0:697ca602e934 137 void ISL1208::clearBatteryFlag(void)
neilt6 0:697ca602e934 138 {
neilt6 0:697ca602e934 139 //Read the current 8-bit register value
neilt6 0:697ca602e934 140 char value = read8(REG_CTL_SR);
neilt6 0:697ca602e934 141
neilt6 0:697ca602e934 142 //Clear the BAT bit
neilt6 0:697ca602e934 143 value &= ~(1 << 1);
neilt6 0:697ca602e934 144
neilt6 0:697ca602e934 145 //Write the value back out
neilt6 0:697ca602e934 146 write8(REG_CTL_SR, value);
neilt6 0:697ca602e934 147 }
neilt6 0:697ca602e934 148
neilt6 0:697ca602e934 149 bool ISL1208::alarmFlag(void)
neilt6 0:697ca602e934 150 {
neilt6 0:697ca602e934 151 //Read the 8-bit register value
neilt6 0:697ca602e934 152 char value = read8(REG_CTL_SR);
neilt6 0:697ca602e934 153
neilt6 0:697ca602e934 154 //Return the status of the ALM bit
neilt6 0:697ca602e934 155 if (value & (1 << 2))
neilt6 0:697ca602e934 156 return true;
neilt6 0:697ca602e934 157 else
neilt6 0:697ca602e934 158 return false;
neilt6 0:697ca602e934 159 }
neilt6 0:697ca602e934 160
neilt6 0:697ca602e934 161 void ISL1208::clearAlarmFlag(void)
neilt6 0:697ca602e934 162 {
neilt6 0:697ca602e934 163 //Read the current 8-bit register value
neilt6 0:697ca602e934 164 char value = read8(REG_CTL_SR);
neilt6 0:697ca602e934 165
neilt6 0:697ca602e934 166 //Clear the ALM bit
neilt6 0:697ca602e934 167 value &= ~(1 << 2);
neilt6 0:697ca602e934 168
neilt6 0:697ca602e934 169 //Write the value back out
neilt6 0:697ca602e934 170 write8(REG_CTL_SR, value);
neilt6 0:697ca602e934 171 }
neilt6 0:697ca602e934 172
neilt6 0:697ca602e934 173 ISL1208::OutputFrequency ISL1208::foutFrequency(void)
neilt6 0:697ca602e934 174 {
neilt6 0:697ca602e934 175 //Read the 8-bit register value
neilt6 0:697ca602e934 176 char value = read8(REG_CTL_INT);
neilt6 0:697ca602e934 177
neilt6 0:697ca602e934 178 //Return the lower nibble
neilt6 0:697ca602e934 179 return (OutputFrequency)(value & 0x0F);
neilt6 0:697ca602e934 180 }
neilt6 0:697ca602e934 181
neilt6 0:697ca602e934 182 void ISL1208::foutFrequency(OutputFrequency freq)
neilt6 0:697ca602e934 183 {
neilt6 0:697ca602e934 184 //Read the current 8-bit register value
neilt6 0:697ca602e934 185 char value = read8(REG_CTL_INT);
neilt6 0:697ca602e934 186
neilt6 0:697ca602e934 187 //Clear the old frequency bits
neilt6 0:697ca602e934 188 value &= 0xF0;
neilt6 0:697ca602e934 189
neilt6 0:697ca602e934 190 //Set the new frequency bits
neilt6 0:697ca602e934 191 value |= freq;
neilt6 0:697ca602e934 192
neilt6 0:697ca602e934 193 //Write the value back out
neilt6 0:697ca602e934 194 write8(REG_CTL_INT, value);
neilt6 0:697ca602e934 195 }
neilt6 0:697ca602e934 196
neilt6 0:697ca602e934 197 bool ISL1208::outputOnBattery(void)
neilt6 0:697ca602e934 198 {
neilt6 0:697ca602e934 199 //Read the 8-bit register value
neilt6 0:697ca602e934 200 char value = read8(REG_CTL_INT);
neilt6 0:697ca602e934 201
neilt6 0:697ca602e934 202 //Return the status of the FOBATB bit
neilt6 0:697ca602e934 203 if (value & (1 << 4))
neilt6 0:697ca602e934 204 return false;
neilt6 0:697ca602e934 205 else
neilt6 0:697ca602e934 206 return true;
neilt6 0:697ca602e934 207 }
neilt6 0:697ca602e934 208
neilt6 0:697ca602e934 209 void ISL1208::outputOnBattery(bool output)
neilt6 0:697ca602e934 210 {
neilt6 0:697ca602e934 211 //Read the current 8-bit register value
neilt6 0:697ca602e934 212 char value = read8(REG_CTL_INT);
neilt6 0:697ca602e934 213
neilt6 0:697ca602e934 214 //Set or clear the FOBATB bit
neilt6 0:697ca602e934 215 if (output)
neilt6 0:697ca602e934 216 value &= ~(1 << 4);
neilt6 0:697ca602e934 217 else
neilt6 0:697ca602e934 218 value |= (1 << 4);
neilt6 0:697ca602e934 219
neilt6 0:697ca602e934 220 //Write the value back out
neilt6 0:697ca602e934 221 write8(REG_CTL_INT, value);
neilt6 0:697ca602e934 222 }
neilt6 0:697ca602e934 223
neilt6 0:697ca602e934 224 ISL1208::PowerMode ISL1208::powerMode(void)
neilt6 0:697ca602e934 225 {
neilt6 0:697ca602e934 226 //Read the 8-bit register value
neilt6 0:697ca602e934 227 char value = read8(REG_CTL_INT);
neilt6 0:697ca602e934 228
neilt6 0:697ca602e934 229 //Return the status of the LPMODE bit
neilt6 0:697ca602e934 230 if (value & (1 << 5))
neilt6 0:697ca602e934 231 return POWER_LPMODE;
neilt6 0:697ca602e934 232 else
neilt6 0:697ca602e934 233 return POWER_NORMAL;
neilt6 0:697ca602e934 234 }
neilt6 0:697ca602e934 235
neilt6 0:697ca602e934 236 void ISL1208::powerMode(PowerMode mode)
neilt6 0:697ca602e934 237 {
neilt6 0:697ca602e934 238 //Read the current 8-bit register value
neilt6 0:697ca602e934 239 char value = read8(REG_CTL_INT);
neilt6 0:697ca602e934 240
neilt6 0:697ca602e934 241 //Set or clear the LPMODE bit
neilt6 0:697ca602e934 242 if (mode == POWER_LPMODE)
neilt6 0:697ca602e934 243 value |= (1 << 5);
neilt6 0:697ca602e934 244 else
neilt6 0:697ca602e934 245 value &= ~(1 << 5);
neilt6 0:697ca602e934 246
neilt6 0:697ca602e934 247 //Write the value back out
neilt6 0:697ca602e934 248 write8(REG_CTL_INT, value);
neilt6 0:697ca602e934 249 }
neilt6 0:697ca602e934 250
neilt6 0:697ca602e934 251 ISL1208::AlarmMode ISL1208::alarmMode(void)
neilt6 0:697ca602e934 252 {
neilt6 0:697ca602e934 253 //Read the 8-bit register value
neilt6 0:697ca602e934 254 char value = read8(REG_CTL_INT);
neilt6 0:697ca602e934 255
neilt6 0:697ca602e934 256 //Return the status of the ALME and IM bits
neilt6 0:697ca602e934 257 if (value & (1 << 6)) {
neilt6 0:697ca602e934 258 if (value & (1 << 7))
neilt6 0:697ca602e934 259 return ALARM_INTERRUPT;
neilt6 0:697ca602e934 260 else
neilt6 0:697ca602e934 261 return ALARM_SINGLE;
neilt6 0:697ca602e934 262 } else
neilt6 0:697ca602e934 263 return ALARM_DISABLED;
neilt6 0:697ca602e934 264 }
neilt6 0:697ca602e934 265
neilt6 0:697ca602e934 266 void ISL1208::alarmMode(AlarmMode mode)
neilt6 0:697ca602e934 267 {
neilt6 0:697ca602e934 268 //Read the current 8-bit register value
neilt6 0:697ca602e934 269 char value = read8(REG_CTL_INT);
neilt6 0:697ca602e934 270
neilt6 0:697ca602e934 271 //Set or clear the ALME and IM bit
neilt6 0:697ca602e934 272 if (mode != ALARM_DISABLED) {
neilt6 0:697ca602e934 273 value |= (1 << 6);
neilt6 0:697ca602e934 274 if (mode == ALARM_INTERRUPT)
neilt6 0:697ca602e934 275 value |= (1 << 7);
neilt6 0:697ca602e934 276 else
neilt6 0:697ca602e934 277 value &= ~(1 << 7);
neilt6 0:697ca602e934 278 } else
neilt6 0:697ca602e934 279 value &= ~(1 << 6);
neilt6 0:697ca602e934 280
neilt6 0:697ca602e934 281 //Write the value back out
neilt6 0:697ca602e934 282 write8(REG_CTL_INT, value);
neilt6 0:697ca602e934 283 }
neilt6 0:697ca602e934 284
neilt6 0:697ca602e934 285 float ISL1208::analogTrim(void)
neilt6 0:697ca602e934 286 {
neilt6 0:697ca602e934 287 //Read the 8-bit register value
neilt6 0:697ca602e934 288 char value = read8(REG_CTL_ATR);
neilt6 0:697ca602e934 289
neilt6 0:697ca602e934 290 //Mask off the top 2 bits
neilt6 0:697ca602e934 291 value &= 0x3F;
neilt6 0:697ca602e934 292
neilt6 0:697ca602e934 293 //Invert bit 5
neilt6 0:697ca602e934 294 value ^= 1 << 5;
neilt6 0:697ca602e934 295
neilt6 0:697ca602e934 296 //Add an offset of 4.5pF (unit[atr] = 0.25pF)
neilt6 0:697ca602e934 297 value += 2 * 9;
neilt6 0:697ca602e934 298
neilt6 0:697ca602e934 299 //Return the analog trim in pF
neilt6 0:697ca602e934 300 return value * 0.25;
neilt6 0:697ca602e934 301 }
neilt6 0:697ca602e934 302
neilt6 0:697ca602e934 303 void ISL1208::analogTrim(float trim)
neilt6 0:697ca602e934 304 {
neilt6 0:697ca602e934 305 //Range limit trim
neilt6 0:697ca602e934 306 if (trim < 4.5)
neilt6 0:697ca602e934 307 trim = 4.5;
neilt6 0:697ca602e934 308 else if (trim > 20.25)
neilt6 0:697ca602e934 309 trim = 20.25;
neilt6 0:697ca602e934 310
neilt6 0:697ca602e934 311 //Convert the analog trim value to a 6-bit integer
neilt6 0:697ca602e934 312 char value = (char)(trim / 0.25);
neilt6 0:697ca602e934 313
neilt6 0:697ca602e934 314 //Remove the offset of 4.5pF (unit[atr] = 0.25pF)
neilt6 0:697ca602e934 315 value -= 2 * 9;
neilt6 0:697ca602e934 316
neilt6 0:697ca602e934 317 //Invert bit 5
neilt6 0:697ca602e934 318 value ^= 1 << 5;
neilt6 0:697ca602e934 319
neilt6 0:697ca602e934 320 //Read the current 8-bit register value
neilt6 0:697ca602e934 321 char reg = read8(REG_CTL_ATR);
neilt6 0:697ca602e934 322
neilt6 0:697ca602e934 323 //Clear the old ATR bits
neilt6 0:697ca602e934 324 reg &= 0xC0;
neilt6 0:697ca602e934 325
neilt6 0:697ca602e934 326 //Add the new ATR bits
neilt6 0:697ca602e934 327 reg |= value;
neilt6 0:697ca602e934 328
neilt6 0:697ca602e934 329 //Write the value back out
neilt6 0:697ca602e934 330 write8(REG_CTL_ATR, reg);
neilt6 0:697ca602e934 331 }
neilt6 0:697ca602e934 332
neilt6 0:697ca602e934 333 ISL1208::BatteryModeATR ISL1208::batteryModeATR(void)
neilt6 0:697ca602e934 334 {
neilt6 0:697ca602e934 335 //Read the 8-bit register value
neilt6 0:697ca602e934 336 char value = read8(REG_CTL_ATR);
neilt6 0:697ca602e934 337
neilt6 0:697ca602e934 338 //Shift out the ATR bits
neilt6 0:697ca602e934 339 value >>= 6;
neilt6 0:697ca602e934 340
neilt6 0:697ca602e934 341 //Return the value as a BatteryModeATR enum
neilt6 0:697ca602e934 342 return (BatteryModeATR)value;
neilt6 0:697ca602e934 343 }
neilt6 0:697ca602e934 344
neilt6 0:697ca602e934 345 void ISL1208::batteryModeATR(BatteryModeATR atr)
neilt6 0:697ca602e934 346 {
neilt6 0:697ca602e934 347 //Read the current 8-bit register value
neilt6 0:697ca602e934 348 char value = read8(REG_CTL_ATR);
neilt6 0:697ca602e934 349
neilt6 0:697ca602e934 350 //Clear the old battery mode ATR bits
neilt6 0:697ca602e934 351 value &= 0x3F;
neilt6 0:697ca602e934 352
neilt6 0:697ca602e934 353 //Add the new battery mode ATR bits
neilt6 0:697ca602e934 354 value |= (atr << 6);
neilt6 0:697ca602e934 355
neilt6 0:697ca602e934 356 //Write the value back out
neilt6 0:697ca602e934 357 write8(REG_CTL_ATR, value);
neilt6 0:697ca602e934 358 }
neilt6 0:697ca602e934 359
neilt6 0:697ca602e934 360 ISL1208::DigitalTrim ISL1208::digitalTrim(void)
neilt6 0:697ca602e934 361 {
neilt6 0:697ca602e934 362 //Read the 8-bit register value
neilt6 0:697ca602e934 363 char value = read8(REG_CTL_DTR);
neilt6 0:697ca602e934 364
neilt6 0:697ca602e934 365 //Mask off the reserved bit
neilt6 0:697ca602e934 366 value &= ~(1 << 7);
neilt6 0:697ca602e934 367
neilt6 0:697ca602e934 368 //Return the value as a DigitalTrim enum
neilt6 0:697ca602e934 369 return (DigitalTrim)value;
neilt6 0:697ca602e934 370 }
neilt6 0:697ca602e934 371
neilt6 0:697ca602e934 372 void ISL1208::digitalTrim(DigitalTrim dtr)
neilt6 0:697ca602e934 373 {
neilt6 0:697ca602e934 374 //Read the current 8-bit register value (to preserve the reserved bit)
neilt6 0:697ca602e934 375 char value = read8(REG_CTL_DTR);
neilt6 0:697ca602e934 376
neilt6 0:697ca602e934 377 //Clear the old DTR bits
neilt6 0:697ca602e934 378 value &= 0xF8;
neilt6 0:697ca602e934 379
neilt6 0:697ca602e934 380 //Add the new DTR bits
neilt6 0:697ca602e934 381 value |= dtr;
neilt6 0:697ca602e934 382
neilt6 0:697ca602e934 383 //Write the value back out
neilt6 0:697ca602e934 384 write8(REG_CTL_DTR, value);
neilt6 0:697ca602e934 385 }
neilt6 0:697ca602e934 386
neilt6 0:697ca602e934 387 time_t ISL1208::alarmTime(void)
neilt6 0:697ca602e934 388 {
neilt6 0:697ca602e934 389 //Setup a tm structure based on the RTC
neilt6 0:697ca602e934 390 struct tm timeinfo;
neilt6 0:697ca602e934 391
neilt6 0:697ca602e934 392 //MSB of each alarm register is an enable bit
neilt6 0:697ca602e934 393 timeinfo.tm_sec = bcd2bin(read8(REG_ALM_SCA) & 0x7F);
neilt6 0:697ca602e934 394 timeinfo.tm_min = bcd2bin(read8(REG_ALM_MNA) & 0x7F);
neilt6 0:697ca602e934 395 timeinfo.tm_hour = bcd2bin(read8(REG_ALM_HRA) & 0x3F);
neilt6 0:697ca602e934 396 timeinfo.tm_mday = bcd2bin(read8(REG_ALM_DTA) & 0x3F);
neilt6 0:697ca602e934 397 timeinfo.tm_mon = bcd2bin(read8(REG_ALM_MOA) & 0x1F) - 1;
neilt6 0:697ca602e934 398 timeinfo.tm_wday = bcd2bin(read8(REG_ALM_DWA) & 0x03);
neilt6 0:697ca602e934 399
neilt6 0:697ca602e934 400 //The alarm doesn't store the year, so get it from the RTC section
neilt6 0:697ca602e934 401 timeinfo.tm_year = bcd2bin(read8(REG_RTC_YR)) + 100;
neilt6 0:697ca602e934 402
neilt6 0:697ca602e934 403 //Return as a timestamp
neilt6 0:697ca602e934 404 return mktime(&timeinfo);
neilt6 0:697ca602e934 405 }
neilt6 0:697ca602e934 406
neilt6 0:697ca602e934 407 void ISL1208::alarmTime(time_t t, bool sc, bool mn, bool hr, bool dt, bool mo, bool dw)
neilt6 0:697ca602e934 408 {
neilt6 0:697ca602e934 409 //Convert the time to a tm
neilt6 0:697ca602e934 410 struct tm *timeinfo = localtime(&t);
neilt6 0:697ca602e934 411
neilt6 0:697ca602e934 412 //Write the new alarm time components (if enabled)
neilt6 0:697ca602e934 413 if (sc)
neilt6 0:697ca602e934 414 write8(REG_ALM_SCA, bin2bcd(timeinfo->tm_sec) | 0x80);
neilt6 0:697ca602e934 415 else
neilt6 0:697ca602e934 416 write8(REG_ALM_SCA, 0x0);
neilt6 0:697ca602e934 417 if (mn)
neilt6 0:697ca602e934 418 write8(REG_ALM_MNA, bin2bcd(timeinfo->tm_min) | 0x80);
neilt6 0:697ca602e934 419 else
neilt6 0:697ca602e934 420 write8(REG_ALM_MNA, 0x0);
neilt6 0:697ca602e934 421 if (hr)
neilt6 0:697ca602e934 422 write8(REG_ALM_HRA, bin2bcd(timeinfo->tm_hour) | 0x80);
neilt6 0:697ca602e934 423 else
neilt6 0:697ca602e934 424 write8(REG_ALM_HRA, 0x0);
neilt6 0:697ca602e934 425 if (hr)
neilt6 0:697ca602e934 426 write8(REG_ALM_DTA, bin2bcd(timeinfo->tm_mday) | 0x80);
neilt6 0:697ca602e934 427 else
neilt6 0:697ca602e934 428 write8(REG_ALM_DTA, 0x0);
neilt6 0:697ca602e934 429 if (mo)
neilt6 0:697ca602e934 430 write8(REG_ALM_MOA, bin2bcd(timeinfo->tm_mon + 1) | 0x80);
neilt6 0:697ca602e934 431 else
neilt6 0:697ca602e934 432 write8(REG_ALM_MOA, 0x0);
neilt6 0:697ca602e934 433 if (dw)
neilt6 0:697ca602e934 434 write8(REG_ALM_DWA, bin2bcd(timeinfo->tm_wday & 7) | 0x80);
neilt6 0:697ca602e934 435 else
neilt6 0:697ca602e934 436 write8(REG_ALM_DWA, 0x0);
neilt6 0:697ca602e934 437 }
neilt6 0:697ca602e934 438
neilt6 0:697ca602e934 439 unsigned short ISL1208::sram(void)
neilt6 0:697ca602e934 440 {
neilt6 0:697ca602e934 441 //Return the complete contents of the SRAM
neilt6 0:697ca602e934 442 return read16(REG_USR_USR1);
neilt6 0:697ca602e934 443 }
neilt6 0:697ca602e934 444
neilt6 0:697ca602e934 445 void ISL1208::sram(unsigned short data)
neilt6 0:697ca602e934 446 {
neilt6 0:697ca602e934 447 //Write the complete contents of the SRAM
neilt6 0:697ca602e934 448 write16(REG_USR_USR1, data);
neilt6 0:697ca602e934 449 }
neilt6 0:697ca602e934 450
neilt6 0:697ca602e934 451 char ISL1208::read8(char reg)
neilt6 0:697ca602e934 452 {
neilt6 0:697ca602e934 453 //Select the register
neilt6 0:697ca602e934 454 m_I2C.write(m_ADDR, &reg, 1);
neilt6 0:697ca602e934 455
neilt6 0:697ca602e934 456 //Read the 8-bit register
neilt6 0:697ca602e934 457 m_I2C.read(m_ADDR, &reg, 1);
neilt6 0:697ca602e934 458
neilt6 0:697ca602e934 459 //Return the byte
neilt6 0:697ca602e934 460 return reg;
neilt6 0:697ca602e934 461 }
neilt6 0:697ca602e934 462
neilt6 0:697ca602e934 463 void ISL1208::write8(char reg, char data)
neilt6 0:697ca602e934 464 {
neilt6 0:697ca602e934 465 //Create a temporary buffer
neilt6 0:697ca602e934 466 char buff[2];
neilt6 0:697ca602e934 467
neilt6 0:697ca602e934 468 //Load the register address and 8-bit data
neilt6 0:697ca602e934 469 buff[0] = reg;
neilt6 0:697ca602e934 470 buff[1] = data;
neilt6 0:697ca602e934 471
neilt6 0:697ca602e934 472 //Write the data
neilt6 0:697ca602e934 473 m_I2C.write(m_ADDR, buff, 2);
neilt6 0:697ca602e934 474 }
neilt6 0:697ca602e934 475
neilt6 0:697ca602e934 476 unsigned short ISL1208::read16(char reg)
neilt6 0:697ca602e934 477 {
neilt6 0:697ca602e934 478 //Create a temporary buffer
neilt6 0:697ca602e934 479 char buff[2];
neilt6 0:697ca602e934 480
neilt6 0:697ca602e934 481 //Select the register
neilt6 0:697ca602e934 482 m_I2C.write(m_ADDR, &reg, 1);
neilt6 0:697ca602e934 483
neilt6 0:697ca602e934 484 //Read the 16-bit register
neilt6 0:697ca602e934 485 m_I2C.read(m_ADDR, buff, 2);
neilt6 0:697ca602e934 486
neilt6 0:697ca602e934 487 //Return the combined 16-bit value
neilt6 0:697ca602e934 488 return (buff[0] << 8) | buff[1];
neilt6 0:697ca602e934 489 }
neilt6 0:697ca602e934 490
neilt6 0:697ca602e934 491 void ISL1208::write16(char reg, unsigned short data)
neilt6 0:697ca602e934 492 {
neilt6 0:697ca602e934 493 //Create a temporary buffer
neilt6 0:697ca602e934 494 char buff[3];
neilt6 0:697ca602e934 495
neilt6 0:697ca602e934 496 //Load the register address and 16-bit data
neilt6 0:697ca602e934 497 buff[0] = reg;
neilt6 0:697ca602e934 498 buff[1] = data >> 8;
neilt6 0:697ca602e934 499 buff[2] = data;
neilt6 0:697ca602e934 500
neilt6 0:697ca602e934 501 //Write the data
neilt6 0:697ca602e934 502 m_I2C.write(m_ADDR, buff, 3);
neilt6 0:697ca602e934 503 }
neilt6 0:697ca602e934 504
neilt6 0:697ca602e934 505 unsigned int ISL1208::bcd2bin(unsigned char val)
neilt6 0:697ca602e934 506 {
neilt6 0:697ca602e934 507 return (val & 0x0F) + (val >> 4) * 10;
neilt6 0:697ca602e934 508 }
neilt6 0:697ca602e934 509
neilt6 0:697ca602e934 510 char ISL1208::bin2bcd(unsigned int val)
neilt6 0:697ca602e934 511 {
neilt6 0:697ca602e934 512 return ((val / 10) << 4) + val % 10;
neilt6 0:697ca602e934 513 }