Dallas DS1307 real-time clock minimalistic driver

Dependents:   testing_RTC_OneWire EMIRv2

Committer:
alpov
Date:
Fri Apr 25 18:15:47 2014 +0000
Revision:
0:f29e45a25cba
Child:
1:60383faa35a9
initial version, working getNow() and setNow()

Who changed what in which revision?

UserRevisionLine numberNew contents of line
alpov 0:f29e45a25cba 1 #include "mbed.h"
alpov 0:f29e45a25cba 2 #include "DS1307.h"
alpov 0:f29e45a25cba 3
alpov 0:f29e45a25cba 4
alpov 0:f29e45a25cba 5 const char *DS1307::m_weekDays[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
alpov 0:f29e45a25cba 6
alpov 0:f29e45a25cba 7 #define DS1307_ADDR 0xd0
alpov 0:f29e45a25cba 8
alpov 0:f29e45a25cba 9
alpov 0:f29e45a25cba 10 DS1307::DS1307(PinName sda, PinName scl)
alpov 0:f29e45a25cba 11 {
alpov 0:f29e45a25cba 12 // create a new I2C object
alpov 0:f29e45a25cba 13 m_rtc = new I2C(sda, scl);
alpov 0:f29e45a25cba 14 if (m_rtc == NULL) error("DS1307");
alpov 0:f29e45a25cba 15
alpov 0:f29e45a25cba 16 // set the frequency to standard 100kHz
alpov 0:f29e45a25cba 17 m_rtc->frequency(100000);
alpov 0:f29e45a25cba 18 }
alpov 0:f29e45a25cba 19
alpov 0:f29e45a25cba 20
alpov 0:f29e45a25cba 21 DS1307::~DS1307()
alpov 0:f29e45a25cba 22 {
alpov 0:f29e45a25cba 23 if (m_rtc != NULL) delete m_rtc;
alpov 0:f29e45a25cba 24 }
alpov 0:f29e45a25cba 25
alpov 0:f29e45a25cba 26
alpov 0:f29e45a25cba 27 bool DS1307::read(int address, char *buffer, int len)
alpov 0:f29e45a25cba 28 {
alpov 0:f29e45a25cba 29 char data[1] = { (char)address };
alpov 0:f29e45a25cba 30
alpov 0:f29e45a25cba 31 if (m_rtc->write(DS1307_ADDR, data, 1) != 0) return false;
alpov 0:f29e45a25cba 32 if (m_rtc->read(DS1307_ADDR, buffer, len) != 0) return false;
alpov 0:f29e45a25cba 33
alpov 0:f29e45a25cba 34 return true;
alpov 0:f29e45a25cba 35 }
alpov 0:f29e45a25cba 36
alpov 0:f29e45a25cba 37
alpov 0:f29e45a25cba 38 bool DS1307::write(int address, char *buffer, int len)
alpov 0:f29e45a25cba 39 {
alpov 0:f29e45a25cba 40 char data[9] = { (char)address };
alpov 0:f29e45a25cba 41
alpov 0:f29e45a25cba 42 if (len > 8) return false;
alpov 0:f29e45a25cba 43 memcpy(&data[1], buffer, len);
alpov 0:f29e45a25cba 44
alpov 0:f29e45a25cba 45 if (m_rtc->write(DS1307_ADDR, data, len + 1) != 0) return false;
alpov 0:f29e45a25cba 46
alpov 0:f29e45a25cba 47 return true;
alpov 0:f29e45a25cba 48 }
alpov 0:f29e45a25cba 49
alpov 0:f29e45a25cba 50
alpov 0:f29e45a25cba 51 time_t DS1307::getNow()
alpov 0:f29e45a25cba 52 {
alpov 0:f29e45a25cba 53 struct tm now;
alpov 0:f29e45a25cba 54 char buffer[7];
alpov 0:f29e45a25cba 55
alpov 0:f29e45a25cba 56 if (!read(0, buffer, 7)) return 0;
alpov 0:f29e45a25cba 57 if (!(buffer[2] & 0x40)) return 0; // 12-hour format not supported
alpov 0:f29e45a25cba 58 now.tm_sec = bcdToDecimal(buffer[0] & 0x7F);
alpov 0:f29e45a25cba 59 now.tm_min = bcdToDecimal(buffer[1]);
alpov 0:f29e45a25cba 60 now.tm_hour = bcdToDecimal(buffer[2] & 0x3F);
alpov 0:f29e45a25cba 61 now.tm_wday = buffer[3];
alpov 0:f29e45a25cba 62 now.tm_mday = bcdToDecimal(buffer[4]);
alpov 0:f29e45a25cba 63 now.tm_mon = bcdToDecimal(buffer[5]) - 1;
alpov 0:f29e45a25cba 64 now.tm_year = bcdToDecimal(buffer[6]) + 2000 - 1900;
alpov 0:f29e45a25cba 65
alpov 0:f29e45a25cba 66 return mktime(&now);
alpov 0:f29e45a25cba 67 }
alpov 0:f29e45a25cba 68
alpov 0:f29e45a25cba 69
alpov 0:f29e45a25cba 70 bool DS1307::setNow(time_t t)
alpov 0:f29e45a25cba 71 {
alpov 0:f29e45a25cba 72 struct tm *now;
alpov 0:f29e45a25cba 73 char buffer[8];
alpov 0:f29e45a25cba 74
alpov 0:f29e45a25cba 75 now = localtime(&t);
alpov 0:f29e45a25cba 76
alpov 0:f29e45a25cba 77 buffer[0] = decimalToBcd(now->tm_sec) & 0x7f; // CH = 0
alpov 0:f29e45a25cba 78 buffer[1] = decimalToBcd(now->tm_min);
alpov 0:f29e45a25cba 79 buffer[2] = 0x40 | (decimalToBcd(now->tm_hour) & 0x3F); // 24-hour format
alpov 0:f29e45a25cba 80 buffer[3] = now->tm_wday + 1;
alpov 0:f29e45a25cba 81 buffer[4] = decimalToBcd(now->tm_mday);
alpov 0:f29e45a25cba 82 buffer[5] = decimalToBcd(now->tm_mon+1);
alpov 0:f29e45a25cba 83 buffer[6] = decimalToBcd(now->tm_year + 1900 - 2000);
alpov 0:f29e45a25cba 84 buffer[7] = 0x00; // OUT = 0
alpov 0:f29e45a25cba 85 if (!write(0, buffer, 8)) return false;
alpov 0:f29e45a25cba 86
alpov 0:f29e45a25cba 87 return true;
alpov 0:f29e45a25cba 88 }