Working Version of the Real Time Clock module DS1307.
Fork of RTC-DS1307 by
Rtc_Ds1307.cpp
- Committer:
- leihen
- Date:
- 2013-06-05
- Revision:
- 2:ee81f2c5a706
- Parent:
- 1:64274190e842
- Child:
- 3:e89d63f3342e
File content as of revision 2:ee81f2c5a706:
/* Rtc_Ds1307.cpp */ #include "Rtc_Ds1307.h" #define _DEBUG 1 #if (_DEBUG && !defined(TARGET_LPC11U24)) #define INFO(x, ...) std::printf("[Rtc_Ds1307 : INFO]"x"\r\n", ##__VA_ARGS__); #define WARN(x, ...) std::printf("[Rtc_Ds1307 : WARN]"x"\r\n", ##__VA_ARGS__); #define ERR(x, ...) std::printf("[Rtc_Ds1307 : ERR]"x"\r\n", ##__VA_ARGS__); #else #define INFO(x, ...) #define WARN(x, ...) #define ERR(x, ...) #endif const char *Rtc_Ds1307::m_weekDays[] = { "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" }; Rtc_Ds1307::Rtc_Ds1307(PinName sda, PinName scl) { // Create a new I2C object m_rtc = new I2C(sda, scl); if (m_rtc == NULL) error("Rtc_Ds1307"); // Set the frequency to standard 100kHz m_rtc->frequency(100000); } Rtc_Ds1307::~Rtc_Ds1307() { if (m_rtc != NULL) delete m_rtc; } bool Rtc_Ds1307::setTime(Time& time, bool start, bool thm) { char buffer[7]; INFO("reading clock registers to write the new time : %d:%d:%d\n", time.hour, time.min, time.sec); if (!read(0,buffer,7)) { ERR("Failed to read from RTC\n"); return false; } // Now update only the time part (saving the existing flags) if (start) { buffer[0] &= 0x7F; } else { buffer[0] |= 0x80; } buffer[0] = (buffer[0]&0x80) | (decimalToBcd(time.sec)& 0x7f); buffer[1] = decimalToBcd(time.min); if (thm) { // AM PM format buffer[2] = (buffer[2]& 196) | (time.hour>12 ? (0x20 | ((decimalToBcd(time.hour-12)))) : decimalToBcd(time.hour)); } else { // 24 hours format buffer[2] = (buffer[2]& 196) | (decimalToBcd(time.hour) & 0x3F); } buffer[3] = time.wday; buffer[4] = decimalToBcd(time.date); buffer[5] = decimalToBcd(time.mon); buffer[6] = decimalToBcd(time.year-2000); INFO("Writing new time and date data to RTC\n"); if (!write(0, buffer, 7) ) { ERR("Failed to write the data to RTC!\n"); return false; } return true; } bool Rtc_Ds1307::getTime(Time& time) { char buffer[7]; bool thm = false; INFO("Getting time from RTC\n"); if (!read(0, buffer, 7) ) { // Failed to read ERR("Failed to read from RTC\n"); return false; } thm = ((buffer[2] & 64) == 64); time.sec = bcdToDecimal(buffer[0]&0x7F); time.min = bcdToDecimal(buffer[1]); if (thm) { // in 12-hour-mode, we need to add 12 hours if PM bit is set time.hour = Rtc_Ds1307::bcdToDecimal( buffer[2] & 31 ); if ((buffer[2] & 32) == 32) time.hour += 12; } else { time.hour = Rtc_Ds1307::bcdToDecimal( buffer[2] & 63 ); } time.wday = buffer[3]; time.date = Rtc_Ds1307::bcdToDecimal( buffer[4]); time.mon = Rtc_Ds1307::bcdToDecimal( buffer[5]); time.year = Rtc_Ds1307::bcdToDecimal(buffer[6]) + 2000; // plus hundret is because RTC is giving the years since 2000, but std c struct tm needs years since 1900 return true; } bool Rtc_Ds1307::startClock() { char strtStop; INFO ("Reading clock start/stop register value\n"); if (!read(0, &strtStop, 1)) { ERR("Failed to read clock start stop register !\n"); return false; } strtStop &= 0x7F; INFO("Writing back start/stop register value\n"); if (!write(0, &strtStop, 1)) { ERR("Failed to write the start stop register !\n"); return false; } INFO("Start/stop register value successfully written\n"); return true; } bool Rtc_Ds1307::stopClock() { char strtStop; INFO ("Reading clock start/stop register value\n"); if (!read(0, &strtStop, 1)) { ERR("Failed to read clock start stop register !\n"); return false; } strtStop |= 0x80; INFO("Writing back start/stop register value\n"); if (!write(0, &strtStop, 1)) { ERR("Failed to write the start stop register !\n"); return false; } INFO("Start/stop register value successfully written\n"); return true; } bool Rtc_Ds1307::setSquareWaveOutput(bool ena, RateSelect_t rs) { char reg; INFO("Reading register value first\n"); if (!read(7,®, 1)) { ERR("Failed to read register value !\n"); return false; } INFO("[Reg:0x07] = %02x\n", reg); // preserve the OUT control bit while writing the frequency and enable bits reg = (reg & 0x80) | (ena ? 0x10 : 0) | ((char)rs & 0x03); INFO("Writing back register value\n"); INFO("[Reg:0x07] = %02x\n", reg); if (!write(7, ®, 1)) { ERR("Failed to write register value !\n"); return false; } INFO("Successfully changed the square wave output.\n"); return true; } bool Rtc_Ds1307::read(int address, char *buffer, int len) { char buffer2[2] = {(char)address, 0}; // m_rtc->start(); if (m_rtc->write(0xd0, buffer2, 1) != 0) { ERR("Failed to write register address on rtv!\n"); m_rtc->stop(); return false; } if (m_rtc->read(0xd0, buffer, len) != 0) { ERR("Failed to read register !\n"); return false; } m_rtc->stop(); INFO("Successfully read %d registers from RTC\n", len); return true; } bool Rtc_Ds1307::write(int address, char *buffer, int len) { char buffer2[10]; buffer2[0] = address&0xFF; for (int i = 0 ; i < len ; i++) buffer2[i+1] = buffer[i]; // m_rtc->start(); if (m_rtc->write(0xd0, buffer2, len+1) != 0) { ERR("Failed to write data to rtc\n"); m_rtc->stop(); return false; } m_rtc->stop(); return true; }