Dallas DS1307 real-time clock minimalistic driver
Dependents: testing_RTC_OneWire EMIRv2
DS1307.cpp@0:f29e45a25cba, 2014-04-25 (annotated)
- 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?
User | Revision | Line number | New 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 | } |