/*----------------------------------------------------------------------* * Set an alarm time. Sets the alarm registers only. To cause the * * INT pin to be asserted on alarm match, use alarmInterrupt(). * * This method can set either Alarm 1 or Alarm 2, depending on the * * value of alarmType (use a value from the ALARM_TYPES_t enumeration). * * When setting Alarm 2, the seconds value must be supplied but is * * ignored, recommend using zero. (Alarm 2 has no seconds register.) * *----------------------------------------------------------------------*/ void DS3232RTC::setAlarm(ALARM_TYPES_t alarmType, byte seconds, byte minutes, byte hours, byte daydate) { uint8_t addr; seconds = dec2bcd(seconds); minutes = dec2bcd(minutes); hours = dec2bcd(hours); daydate = dec2bcd(daydate); if (alarmType & 0x01) seconds |= _BV(A1M1); if (alarmType & 0x02) minutes |= _BV(A1M2); if (alarmType & 0x04) hours |= _BV(A1M3); if (alarmType & 0x10) hours |= _BV(DYDT); if (alarmType & 0x08) daydate |= _BV(A1M4); if ( !(alarmType & 0x80) ) { //alarm 1 addr = ALM1_SECONDS; writeRTC(addr++, seconds); } else { addr = ALM2_MINUTES; } writeRTC(addr++, minutes); writeRTC(addr++, hours); writeRTC(addr++, daydate); }
/*----------------------------------------------------------------------* * Returns the value of the oscillator stop flag (OSF) bit in the * * control/status register which indicates that the oscillator is or * * was stopped, and that the timekeeping data may be invalid. * * Optionally clears the OSF bit depending on the argument passed. * *----------------------------------------------------------------------*/ bool DS3232RTC::oscStopped(bool clearOSF) { uint8_t s = readRTC(RTC_STATUS); //read the status register bool ret = s & _BV(OSF); //isolate the osc stop flag to return to caller if (ret && clearOSF) { //clear OSF if it's set and the caller wants to clear it writeRTC( RTC_STATUS, s & ~_BV(OSF) ); } return ret; }
/*----------------------------------------------------------------------* * Enable or disable an alarm "interrupt" which asserts the INT pin * * on the RTC. * *----------------------------------------------------------------------*/ void DS3232RTC::alarmInterrupt(byte alarmNumber, boolean interruptEnabled) { uint8_t controlReg, mask; controlReg = readRTC(RTC_CONTROL); mask = _BV(A1IE) << (alarmNumber - 1); if (interruptEnabled) controlReg |= mask; else controlReg &= ~mask; writeRTC(RTC_CONTROL, controlReg); }
/*----------------------------------------------------------------------* * Enable or disable the square wave output. * * Use a value from the SQWAVE_FREQS_t enumeration for the parameter. * *----------------------------------------------------------------------*/ void DS3232RTC::squareWave(SQWAVE_FREQS_t freq) { uint8_t controlReg; controlReg = readRTC(RTC_CONTROL); if (freq >= SQWAVE_NONE) { controlReg |= _BV(INTCN); } else { controlReg = (controlReg & 0xE3) | (freq << RS1); } writeRTC(RTC_CONTROL, controlReg); }
/*------------------------------------------------------*/ int SetAlarm (void) { rtime t = Time; int i,j,k,n; char s[8][8]; for(i=0; i<8; ++i) { writeRTC(i,0); s[i][0] = 0; } n=sscanf(&LinkBuff[1],"%2d:%02d:%02d%s%s%s%s%s", &i,&j,&k,&s[0],&s[1],&s[2],&s[3],&s[4]); if(n>=3) { if(n==3) { t.hour=i; t.min=j; t.sec=k; AlarmEnable(&t); puts_pc("Wakeup on\r\n"); } if(n>3) { writeRTC(0,i); writeRTC(1,j); writeRTC(2,k); n -=3; for(i=0; n--; ++i) writeRTC(i+3,chrtx(s[i])); puts_pc("Submit on\r\n"); } } else { AlarmDisable(); puts_pc("Wakeup off\r\n"); } shutdown_save(NULL); return(null); }
/*----------------------------------------------------------------------* * Returns true or false depending on whether the given alarm has been * * triggered, and resets the alarm flag bit. * *----------------------------------------------------------------------*/ boolean DS3232RTC::alarm(byte alarmNumber) { uint8_t statusReg, mask; statusReg = readRTC(RTC_STATUS); mask = _BV(A1F) << (alarmNumber - 1); if (statusReg & mask) { statusReg &= ~mask; writeRTC(RTC_STATUS, statusReg); return true; } else { return false; } }
/*----------------------------------------------------------------------* * Sets the RTC's time from a tmElements_t structure and clears the * * oscillator stop flag (OSF) in the Control/Status register. * * Returns the I2C status (zero if successful). * *----------------------------------------------------------------------*/ byte DS3232RTC::write(tmElements_t &tm) { i2cBeginTransmission(RTC_ADDR); i2cWrite((uint8_t)RTC_SECONDS); i2cWrite(dec2bcd(tm.Second)); i2cWrite(dec2bcd(tm.Minute)); i2cWrite(dec2bcd(tm.Hour)); //sets 24 hour format (Bit 6 == 0) i2cWrite(tm.Wday); i2cWrite(dec2bcd(tm.Day)); i2cWrite(dec2bcd(tm.Month)); i2cWrite(dec2bcd(tmYearToY2k(tm.Year))); byte ret = i2cEndTransmission(); uint8_t s = readRTC(RTC_STATUS); //read the status register writeRTC( RTC_STATUS, s & ~_BV(OSF) ); //clear the Oscillator Stop Flag return ret; }
//-------------------------------------------------------------------------------- // Sets time of RTC device and returns whether the operation was successful. bool DS3232Controller::setDeviceTime(byte dayOfWeek, byte day, byte month, byte y2kYear, byte hour, byte minute, byte second) { Wire.beginTransmission(RTC_ADDR); Wire.write((uint8_t) RTC_SECONDS); Wire.write(dec2bcd(second)); Wire.write(dec2bcd(minute)); Wire.write(dec2bcd(hour)); //sets 24 hour format (Bit 6 == 0) Wire.write(dayOfWeek); Wire.write(dec2bcd(day)); Wire.write(dec2bcd(month)); Wire.write(dec2bcd(y2kYear + 30)); // convert Y2K year to year from 1970 byte i2cStatus = Wire.endTransmission(); uint8_t s = readRTC(RTC_STATUS); //read the status register writeRTC(RTC_STATUS, s & ~_BV(OSF)); //clear the Oscillator Stop Flag readCurrentTimeFromDevice(); // sync time with device return (i2cStatus == 0); }
// -------------------------------------------------------- // Set the RTC's time from a tmElements_t structure. // Returns the bus status (zero if successful). uint8_t DS1302RTC::write(tmElements_t &tm) { uint8_t buff[8]; writeEN(true); if(!writeEN()) return 255; // Error! Write-protect not disabled buff[0] = dec2bcd(tm.Second); // Disable Clock halt flag buff[1] = dec2bcd(tm.Minute); buff[2] = dec2bcd(tm.Hour); // 24-hour mode buff[3] = dec2bcd(tm.Day); buff[4] = dec2bcd(tm.Month); buff[5] = tm.Wday; buff[6] = dec2bcd(tmYearToY2k(tm.Year)); buff[7] = B10000000; // Write protect enable writeRTC(buff); return writeEN(); }
/*----------------------------------------------------------------------* * Write a single byte to RTC RAM. * * Valid address range is 0x00 - 0xFF, no checking. * * Returns the I2C status (zero if successful). * *----------------------------------------------------------------------*/ byte DS3232RTC::writeRTC(byte addr, byte value) { return ( writeRTC(addr, &value, 1) ); }
// -------------------------------------------------------- // Set or clear Write-protect bit // Before any write operation to the clock or RAM, must be 0. // When 1, the write-protect bit prevents a write operation // to any other register. void DS1302RTC::writeEN(uint8_t value) { uint8_t wp = readRTC(DS1302_ENABLE); bitWrite(wp, DS1302_WP, !value); writeRTC(DS1302_ENABLE, wp); }
// -------------------------------------------------------- // Set or clear Clock halt flag bit // When this bit is set to logic 1, the clock oscillator // is stopped and the DS1302 is placed into a low-power // standby mode with a current drain of less than 100nA. When // this bit is written to logic 0, the clock will start. void DS1302RTC::haltRTC(uint8_t value) { uint8_t seconds = readRTC(DS1302_SECONDS); bitWrite(seconds, DS1302_CH, value); writeRTC(DS1302_SECONDS, seconds); }
//-------------------------------------------------------------------------------- // Write a single byte to RTC RAM. // Valid address range is 0x00 - 0xFF, no checking. // Returns the I2C status (zero if successful). byte DS3232Controller::writeRTC(byte addr, byte value) { return (writeRTC(addr, &value, 1)); }