1919 * visit http://creativecommons.org/licenses/by-sa/3.0/ or send a *
2020 * letter to Creative Commons, 171 Second Street, Suite 300, *
2121 * San Francisco, California, 94105, USA. *
22- *----------------------------------------------------------------------*/
22+ *----------------------------------------------------------------------*/
2323
24- #include < Wire.h>
25- #include < TinyWireM.h>
2624#include " MCP79412RTC.h"
2725
26+ // define release-independent I2C functions
27+ #if defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
28+ #include < TinyWireM.h>
29+ #define i2cBegin TinyWireM.begin
30+ #define i2cBeginTransmission TinyWireM.beginTransmission
31+ #define i2cEndTransmission TinyWireM.endTransmission
32+ #define i2cRequestFrom TinyWireM.requestFrom
33+ #define i2cRead TinyWireM.receive
34+ #define i2cWrite TinyWireM.send
35+ #elif ARDUINO >= 100
36+ #include < Wire.h>
37+ #define i2cBegin Wire.begin
38+ #define i2cBeginTransmission Wire.beginTransmission
39+ #define i2cEndTransmission Wire.endTransmission
40+ #define i2cRequestFrom Wire.requestFrom
41+ #define i2cRead Wire.read
42+ #define i2cWrite Wire.write
43+ #else
44+ #include < Wire.h>
45+ #define i2cBegin Wire.begin
46+ #define i2cBeginTransmission Wire.beginTransmission
47+ #define i2cEndTransmission Wire.endTransmission
48+ #define i2cRequestFrom Wire.requestFrom
49+ #define i2cRead Wire.receive
50+ #define i2cWrite Wire.send
51+ #endif
52+
2853/* ----------------------------------------------------------------------*
2954 * Constructor. *
3055 *----------------------------------------------------------------------*/
3156MCP79412RTC::MCP79412RTC ()
3257{
3358 i2cBegin ();
3459}
35-
60+
3661/* ----------------------------------------------------------------------*
3762 * Read the current time from the RTC and return it as a time_t value. *
3863 * Returns a zero value if RTC not present (I2C I/O error). *
3964 *----------------------------------------------------------------------*/
4065time_t MCP79412RTC::get (void )
4166{
4267 tmElements_t tm;
43-
68+
4469 if ( read (tm) )
4570 return ( makeTime (tm) );
4671 else
@@ -55,7 +80,7 @@ void MCP79412RTC::set(time_t t)
5580 tmElements_t tm;
5681
5782 breakTime (t, tm);
58- write (tm);
83+ write (tm);
5984}
6085
6186/* ----------------------------------------------------------------------*
@@ -72,7 +97,7 @@ boolean MCP79412RTC::read(tmElements_t &tm)
7297 else {
7398 // request 7 bytes (secs, min, hr, dow, date, mth, yr)
7499 i2cRequestFrom (RTC_ADDR, tmNbrFields);
75- tm.Second = bcd2dec (i2cRead () & ~_BV (ST));
100+ tm.Second = bcd2dec (i2cRead () & ~_BV (ST));
76101 tm.Minute = bcd2dec (i2cRead ());
77102 tm.Hour = bcd2dec (i2cRead () & ~_BV (HR1224)); // assumes 24hr clock
78103 tm.Wday = i2cRead () & ~(_BV (OSCON) | _BV (VBAT) | _BV (VBATEN)); // mask off OSCON, VBAT, VBATEN bits
@@ -90,19 +115,19 @@ void MCP79412RTC::write(tmElements_t &tm)
90115{
91116 i2cBeginTransmission (RTC_ADDR);
92117 i2cWrite ((uint8_t )TIME_REG);
93- i2cWrite ((uint8_t )0x00 ); // stops the oscillator (Bit 7, ST == 0)
118+ i2cWrite ((uint8_t )0x00 ); // stops the oscillator (Bit 7, ST == 0)
94119 i2cWrite (dec2bcd (tm.Minute ));
95120 i2cWrite (dec2bcd (tm.Hour )); // sets 24 hour format (Bit 6 == 0)
96121 i2cWrite (tm.Wday | _BV (VBATEN)); // enable battery backup operation
97122 i2cWrite (dec2bcd (tm.Day ));
98123 i2cWrite (dec2bcd (tm.Month ));
99- i2cWrite (dec2bcd (tmYearToY2k (tm.Year )));
100- i2cEndTransmission ();
124+ i2cWrite (dec2bcd (tmYearToY2k (tm.Year )));
125+ i2cEndTransmission ();
101126
102127 i2cBeginTransmission (RTC_ADDR);
103128 i2cWrite ((uint8_t )TIME_REG);
104129 i2cWrite (dec2bcd (tm.Second ) | _BV (ST)); // set the seconds and start the oscillator (Bit 7, ST == 1)
105- i2cEndTransmission ();
130+ i2cEndTransmission ();
106131}
107132
108133/* ----------------------------------------------------------------------*
@@ -125,7 +150,7 @@ void MCP79412RTC::ramWrite(byte addr, byte *values, byte nBytes)
125150 i2cBeginTransmission (RTC_ADDR);
126151 i2cWrite (addr);
127152 for (byte i=0 ; i<nBytes; i++) i2cWrite (values[i]);
128- i2cEndTransmission ();
153+ i2cEndTransmission ();
129154}
130155
131156/* ----------------------------------------------------------------------*
@@ -135,7 +160,7 @@ void MCP79412RTC::ramWrite(byte addr, byte *values, byte nBytes)
135160byte MCP79412RTC::ramRead (byte addr)
136161{
137162 byte value;
138-
163+
139164 ramRead (addr, &value, 1 );
140165 return value;
141166}
@@ -150,7 +175,7 @@ void MCP79412RTC::ramRead(byte addr, byte *values, byte nBytes)
150175{
151176 i2cBeginTransmission (RTC_ADDR);
152177 i2cWrite (addr);
153- i2cEndTransmission ();
178+ i2cEndTransmission ();
154179 i2cRequestFrom ( (uint8_t )RTC_ADDR, nBytes );
155180 for (byte i=0 ; i<nBytes; i++) values[i] = i2cRead ();
156181}
@@ -191,7 +216,7 @@ void MCP79412RTC::sramWrite(byte addr, byte *values, byte nBytes)
191216byte MCP79412RTC::sramRead (byte addr)
192217{
193218 byte value;
194-
219+
195220 ramRead ( (addr & (SRAM_SIZE - 1 ) ) + SRAM_START_ADDR, &value, 1 );
196221 return value;
197222}
@@ -257,7 +282,7 @@ byte MCP79412RTC::eepromRead(byte addr)
257282{
258283 byte value;
259284
260- eepromRead ( addr & (EEPROM_SIZE - 1 ), &value, 1 );
285+ eepromRead ( addr & (EEPROM_SIZE - 1 ), &value, 1 );
261286 return value;
262287}
263288
@@ -279,7 +304,7 @@ void MCP79412RTC::eepromRead(byte addr, byte *values, byte nBytes)
279304#endif
280305 i2cBeginTransmission (EEPROM_ADDR);
281306 i2cWrite ( addr & (EEPROM_SIZE - 1 ) );
282- i2cEndTransmission ();
307+ i2cEndTransmission ();
283308 i2cRequestFrom ( (uint8_t )EEPROM_ADDR, nBytes );
284309 for (byte i=0 ; i<nBytes; i++) values[i] = i2cRead ();
285310 }
@@ -292,16 +317,16 @@ byte MCP79412RTC::eepromWait(void)
292317{
293318 byte waitCount = 0 ;
294319 byte txStatus;
295-
320+
296321 do
297322 {
298323 ++waitCount;
299324 i2cBeginTransmission (EEPROM_ADDR);
300325 i2cWrite ((uint8_t )0 );
301326 txStatus = i2cEndTransmission ();
302-
327+
303328 } while (txStatus != 0 );
304-
329+
305330 return waitCount;
306331}
307332
@@ -314,9 +339,9 @@ byte MCP79412RTC::eepromWait(void)
314339int MCP79412RTC::calibRead (void )
315340{
316341 byte val = ramRead (CALIB_REG);
317-
342+
318343 if ( val & 0x80 ) return -(val & 0x7F );
319- else return val;
344+ else return val;
320345}
321346
322347/* ----------------------------------------------------------------------*
@@ -327,7 +352,7 @@ int MCP79412RTC::calibRead(void)
327352void MCP79412RTC::calibWrite (int value)
328353{
329354 byte calibVal;
330-
355+
331356 if (value >= -127 && value <= 127 ) {
332357 calibVal = abs (value);
333358 if (value < 0 ) calibVal += 128 ;
@@ -344,7 +369,7 @@ void MCP79412RTC::idRead(byte *uniqueID)
344369{
345370 i2cBeginTransmission (EEPROM_ADDR);
346371 i2cWrite (UNIQUE_ID_ADDR);
347- i2cEndTransmission ();
372+ i2cEndTransmission ();
348373 i2cRequestFrom ( EEPROM_ADDR, UNIQUE_ID_SIZE );
349374 for (byte i=0 ; i<UNIQUE_ID_SIZE; i++) uniqueID[i] = i2cRead ();
350375}
@@ -359,7 +384,7 @@ void MCP79412RTC::idRead(byte *uniqueID)
359384void MCP79412RTC::getEUI64 (byte *uniqueID)
360385{
361386 byte rtcID[8 ];
362-
387+
363388 idRead (rtcID);
364389 if (rtcID[0 ] == 0xFF && rtcID[1 ] == 0xFF ) {
365390 rtcID[0 ] = rtcID[2 ];
@@ -418,10 +443,10 @@ boolean MCP79412RTC::powerFail(time_t *powerDown, time_t *powerUp)
418443 up.Day = bcd2dec (i2cRead ());
419444 up.Month = bcd2dec (i2cRead () & 0x1F ); // mask off the day, we don't need it
420445 up.Year = yr; // assume current year
421-
446+
422447 *powerDown = makeTime (dn);
423448 *powerUp = makeTime (up);
424-
449+
425450 // clear the VBAT bit, which causes the RTC hardware to clear the timestamps too.
426451 // I suppose there is a risk here that the day has changed since we read it,
427452 // but the Day of Week is actually redundant data and the makeTime() function
@@ -481,7 +506,7 @@ void MCP79412RTC::setAlarm(uint8_t alarmNumber, time_t alarmTime)
481506 i2cWrite ( (day & 0xF8 ) + tm.Wday );
482507 i2cWrite (dec2bcd (tm.Day ));
483508 i2cWrite (dec2bcd (tm.Month ));
484- i2cEndTransmission ();
509+ i2cEndTransmission ();
485510}
486511
487512/* ----------------------------------------------------------------------*
@@ -534,7 +559,7 @@ boolean MCP79412RTC::alarm(uint8_t alarmNumber)
534559void MCP79412RTC::out (boolean level)
535560{
536561 uint8_t ctrlReg;
537-
562+
538563 ramRead (CTRL_REG, &ctrlReg, 1 );
539564 if (level)
540565 ctrlReg |= _BV (OUT);
@@ -558,7 +583,7 @@ void MCP79412RTC::out(boolean level)
558583void MCP79412RTC::alarmPolarity (boolean polarity)
559584{
560585 uint8_t alm0Day;
561-
586+
562587 ramRead (ALM0_DAY, &alm0Day, 1 );
563588 if (polarity)
564589 alm0Day |= _BV (OUT);
@@ -590,31 +615,31 @@ boolean MCP79412RTC::isRunning(void)
590615void MCP79412RTC::vbaten (boolean enable)
591616{
592617 uint8_t day;
593-
618+
594619 ramRead (DAY_REG, &day, 1 );
595620 if (enable)
596621 day |= _BV (VBATEN);
597622 else
598623 day &= ~_BV (VBATEN);
599-
624+
600625 ramWrite (DAY_REG, &day, 1 );
601626 return ;
602627}
603628
604629/* ----------------------------------------------------------------------*
605630 * Decimal-to-BCD conversion *
606631 *----------------------------------------------------------------------*/
607- uint8_t MCP79412RTC::dec2bcd (uint8_t num )
632+ uint8_t MCP79412RTC::dec2bcd (uint8_t n )
608633{
609- return ((num / 10 * 16 ) + (num % 10 ) );
634+ return n + 6 * (n / 10 );
610635}
611636
612637/* ----------------------------------------------------------------------*
613638 * BCD-to-Decimal conversion *
614639 *----------------------------------------------------------------------*/
615- uint8_t MCP79412RTC::bcd2dec (uint8_t num )
640+ uint8_t __attribute__ ((noinline)) MCP79412RTC::bcd2dec (uint8_t n )
616641{
617- return ((num / 16 * 10 ) + (num % 16 ) );
642+ return n - 6 * (n >> 4 );
618643}
619644
620645MCP79412RTC RTC = MCP79412RTC (); // instantiate an RTC object
0 commit comments