Izvorne datoteke za TinyRTC DS1307 sa I2C komunikacijom.
Dependents: Detektor_Pokreta Dino_Martic_Programski
Rtc_Ds1307.cpp
00001 #include "mbed.h" 00002 #include "Rtc_Ds1307.h" 00003 00004 #ifndef DEBUG 00005 #define DEBUG 00006 #endif 00007 #include "debug.h" 00008 00009 const char *Rtc_Ds1307::m_weekDays[] = { "Ponedjeljak", "Utorak", "Srijeda", "Cetvrtak", "Petak", "Subota", "Nedjelja" }; 00010 00011 00012 Rtc_Ds1307::Rtc_Ds1307(PinName sda, PinName scl) 00013 { 00014 // Create a new I2C object 00015 m_rtc = new I2C(sda, scl); 00016 if (m_rtc == NULL) 00017 error("Rtc_Ds1307"); 00018 00019 // Set the frequency to standard 100kHz 00020 m_rtc->frequency(100000); 00021 } 00022 00023 Rtc_Ds1307::~Rtc_Ds1307() 00024 { 00025 if (m_rtc != NULL) 00026 delete m_rtc; 00027 } 00028 00029 bool Rtc_Ds1307::setTime(Time_rtc& time, bool start, bool thm) 00030 { 00031 char buffer[7]; 00032 INFO("reading clock registers to write the new time : %d:%d:%d\n", time.hour , time.min , time.sec ); 00033 if (!read(0,buffer,7)) { 00034 ERR("Failed to read from RTC\n"); 00035 return false; 00036 } 00037 // Now update only the time part (saving the existing flags) 00038 if (start) { buffer[0] &= 0x7F; } else { buffer[0] |= 0x80; } 00039 buffer[0] = (buffer[0]&0x80) | (decimalToBcd(time.sec )& 0x7f); 00040 buffer[1] = decimalToBcd(time.min ); 00041 if (thm) { 00042 // AM PM format 00043 buffer[2] = (buffer[2]& 196) | (time.hour >12 ? (0x20 | ((decimalToBcd(time.hour -12)))) : decimalToBcd(time.hour )); 00044 } 00045 else { 00046 // 24 hours format 00047 buffer[2] = (buffer[2]& 196) | (decimalToBcd(time.hour ) & 0x3F); 00048 } 00049 buffer[3] = time.wday ; 00050 buffer[4] = decimalToBcd(time.date ); 00051 buffer[5] = decimalToBcd(time.mon ); 00052 buffer[6] = decimalToBcd(time.year -2000); 00053 INFO("Writing new time and date data to RTC\n"); 00054 if (!write(0, buffer, 7) ) { 00055 ERR("Failed to write the data to RTC!\n"); 00056 return false; 00057 } 00058 return true; 00059 } 00060 00061 bool Rtc_Ds1307::getTime(Time_rtc& time) 00062 { 00063 char buffer[7]; 00064 bool thm = false; 00065 00066 if (!read(0, buffer, 7) ) { 00067 // Failed to read 00068 ERR("Failed to read from RTC\n"); 00069 return false; 00070 } 00071 thm = ((buffer[2] & 64) == 64); 00072 time.sec = bcdToDecimal(buffer[0]&0x7F); 00073 time.min = bcdToDecimal(buffer[1]); 00074 if (thm) { 00075 // in 12-hour-mode, we need to add 12 hours if PM bit is set 00076 time.hour = Rtc_Ds1307::bcdToDecimal( buffer[2] & 31 ); 00077 if ((buffer[2] & 32) == 32) 00078 time.hour += 12; 00079 } 00080 else { 00081 time.hour = Rtc_Ds1307::bcdToDecimal( buffer[2] & 63 ); 00082 } 00083 time.wday = buffer[3]; 00084 time.date = Rtc_Ds1307::bcdToDecimal( buffer[4]); 00085 time.mon = Rtc_Ds1307::bcdToDecimal( buffer[5]); 00086 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 00087 00088 return true; 00089 } 00090 00091 00092 bool Rtc_Ds1307::startClock() 00093 { 00094 char strtStop; 00095 00096 INFO ("Reading clock start/stop register value\n"); 00097 if (!read(0, &strtStop, 1)) { 00098 ERR("Failed to read clock start stop register !\n"); 00099 return false; 00100 } 00101 00102 strtStop &= 0x7F; 00103 00104 INFO("Writing back start/stop register value\n"); 00105 if (!write(0, &strtStop, 1)) { 00106 ERR("Failed to write the start stop register !\n"); 00107 return false; 00108 } 00109 00110 INFO("Start/stop register value successfully written\n"); 00111 return true; 00112 } 00113 00114 bool Rtc_Ds1307::stopClock() 00115 { 00116 char strtStop; 00117 00118 INFO ("Reading clock start/stop register value\n"); 00119 if (!read(0, &strtStop, 1)) { 00120 ERR("Failed to read clock start stop register !\n"); 00121 return false; 00122 } 00123 00124 strtStop |= 0x80; 00125 00126 INFO("Writing back start/stop register value\n"); 00127 if (!write(0, &strtStop, 1)) { 00128 ERR("Failed to write the start stop register !\n"); 00129 return false; 00130 } 00131 00132 INFO("Start/stop register value successfully written\n"); 00133 return true; 00134 } 00135 00136 bool Rtc_Ds1307::setSquareWaveOutput(bool ena, SqwRateSelect_t rs) 00137 { 00138 char reg; 00139 INFO("Reading register value first\n"); 00140 00141 if (!read(7,®, 1)) { 00142 ERR("Failed to read register value !\n"); 00143 return false; 00144 } 00145 INFO("[Reg:0x07] = %02x\n", reg); 00146 00147 // preserve the OUT control bit while writing the frequency and enable bits 00148 reg = (reg & 0x80) | (ena ? 0x10 : 0) | ((char)rs & 0x03); 00149 00150 INFO("Writing back register value\n"); 00151 INFO("[Reg:0x07] = %02x\n", reg); 00152 00153 if (!write(7, ®, 1)) { 00154 ERR("Failed to write register value !\n"); 00155 return false; 00156 } 00157 00158 INFO("Successfully changed the square wave output.\n"); 00159 return true; 00160 } 00161 00162 00163 00164 bool Rtc_Ds1307::read(int address, char *buffer, int len) 00165 { 00166 char buffer2[2] = {(char)address, 0}; 00167 00168 // m_rtc->start(); 00169 if (m_rtc->write(0xd0, buffer2, 1) != 0) { 00170 ERR("Failed to write register address on rtv!\n"); 00171 m_rtc->stop(); 00172 return false; 00173 } 00174 if (m_rtc->read(0xd0, buffer, len) != 0) { 00175 ERR("Failed to read register !\n"); 00176 return false; 00177 } 00178 m_rtc->stop(); 00179 00180 return true; 00181 } 00182 00183 bool Rtc_Ds1307::write(int address, char *buffer, int len) 00184 { 00185 char buffer2[10]; 00186 buffer2[0] = address&0xFF; 00187 for (int i = 0 ; i < len ; i++) 00188 buffer2[i+1] = buffer[i]; 00189 00190 // m_rtc->start(); 00191 if (m_rtc->write(0xd0, buffer2, len+1) != 0) { 00192 ERR("Failed to write data to rtc\n"); 00193 m_rtc->stop(); 00194 return false; 00195 } 00196 m_rtc->stop(); 00197 return true; 00198 } 00199 00200 00201 00202 00203 RtcCls::RtcCls(PinName sda, PinName scl, PinName sqw, bool bUseSqw) 00204 : Rtc_Ds1307(sda, scl), m_sqw(sqw), m_bUseSqw(bUseSqw), m_bAlarmEnabled(false), m_alarmfunc(NULL) 00205 { 00206 Time_rtc t; 00207 // query time from device 00208 getTime(t); 00209 // sync the time with MBED RTC 00210 struct tm now = {t.sec, t.min, t.hour, t.date, t.mon-1, t.year-1900}; 00211 m_time = mktime(&now); 00212 set_time(m_time); 00213 00214 // Only register the callback and start the SQW if requested to do so. Otherwise the system 00215 // will use the MBED built-in RTC. 00216 if (m_bUseSqw) { 00217 // start the wave 00218 setSquareWaveOutput(true, RS1Hz); 00219 // register callback from now on the time will be maintained by the square wave input 00220 m_sqw.rise(this, &RtcCls::_callback); 00221 } 00222 } 00223 00224 void RtcCls::_callback(void) 00225 { 00226 // INFO("Tick!"); 00227 // Simply increase the number of seconds 00228 m_time++; 00229 // if (m_bAlarmEnabled && (m_time == m_alarmTime)) { 00230 // if (m_alarmfunc != NULL) 00231 // m_alarmfunc(); 00232 // m_bAlarmEnabled = false; 00233 // } 00234 } 00235 00236 time_t RtcCls::getTime() 00237 { 00238 // when not using the HW support, we have to query the RTC chip. Other wise we can just return out stored value 00239 if (!m_bUseSqw) { 00240 Time_rtc t; 00241 getTime(t); 00242 struct tm now = {t.sec, t.min, t.hour, t.date, t.mon-1, t.year-1900}; 00243 m_time = mktime(&now); 00244 INFO("getting time %02d.%02d.%04d %02d:%02d:%02d Ticks=%08lx", t.date, t.mon, t.year, t.hour, t.min, t.sec, m_time); 00245 } 00246 else { 00247 INFO("getting time Ticks=%08lx", m_time); 00248 } 00249 return m_time; 00250 } 00251 00252 void RtcCls::setTime(time_t t) 00253 { 00254 Time_rtc tim; 00255 struct tm *now; 00256 now = localtime(&t); 00257 00258 tim.sec = now->tm_sec; 00259 tim.min = now->tm_min; 00260 tim.hour = now->tm_hour; 00261 tim.date = now->tm_mday; 00262 tim.mon = now->tm_mon+1; 00263 tim.year = now->tm_year + 1900; 00264 tim.wday = now->tm_wday +1; 00265 00266 setTime( tim, true, true); 00267 set_time(t); 00268 }
Generated on Wed Jul 13 2022 19:34:43 by
1.7.2