test rtc
Revision 0:fa906a89a756, committed 2020-06-17
- Comitter:
- irsanjul
- Date:
- Wed Jun 17 08:46:25 2020 +0000
- Commit message:
- test rtc
Changed in this revision
PCF85263AT.cpp | Show annotated file Show diff for this revision Revisions of this file |
PCF85263AT.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCF85263AT.cpp Wed Jun 17 08:46:25 2020 +0000 @@ -0,0 +1,128 @@ +#include "mbed.h" +#include "PCF85263AT.h" + +extern Serial dbg; + +PCF85263AT::PCF85263AT(PinName sda, PinName scl) : i2c (sda, scl) +{ + i2c.frequency(100000); +} + +PCF85263AT::~PCF85263AT() +{ + +} + +bool PCF85263AT::write(char adr, char data) +{ + w[0] = adr; + w[1] = data; + if (i2c.write(address, w, 2) != 0) return 0; + + return true; +} + +char PCF85263AT::read(char adr) +{ + char start = adr; + if (i2c.write(address, &start, 1, true) != 0) return 0; + if (i2c.read(address, r, 1) != 0) return 0; + + return r[0]; +} + +time_t PCF85263AT::now() +{ + struct tm now; + + char buffer[6]; + + buffer [0] = read(SEC); + buffer [1] = read(MIN); + buffer [2] = read(HOUR); + buffer [3] = read(DAY); + buffer [4] = read(MONTH); + buffer [5] = read(YEAR); + + now.tm_sec = bcdToDecimal(buffer[0] & 0x7F); + now.tm_min = bcdToDecimal(buffer[1] & 0x7F); + now.tm_hour = bcdToDecimal(buffer[2] & 0x3F); + now.tm_mday = bcdToDecimal(buffer[3] & 0x3F); + now.tm_mon = bcdToDecimal(buffer[4] & 0x1F) - 1; + now.tm_year = bcdToDecimal(buffer[5] & 0xFF) + 2000 - 1900; + + return mktime(&now); +} + +bool PCF85263AT::set_time(time_t time) +{ + struct tm *now; + char buffer[9]; + + now = localtime(&time); + + // send stop signal + buffer[0] = 0x01; + if(!write(STOPEN, buffer[0]))return 0; + + // clear prescaler + buffer[0] = 0xA4; + if(!write(RESET, buffer[0]))return 0; + + // set time + buffer[0] = decimalToBcd(now->tm_sec) & 0x7F; // VL = 0 + buffer[1] = decimalToBcd(now->tm_min) & 0x7F; + buffer[2] = decimalToBcd(now->tm_hour) & 0x3F; + buffer[3] = decimalToBcd(now->tm_mday) & 0x3F; + buffer[4] = now->tm_wday + 1; + buffer[5] = decimalToBcd(now->tm_mon+1) & 0x1F; + buffer[6] = decimalToBcd(now->tm_year + 1900 - 2000); + + if(!write(SEC, buffer[0]))return 0; + if(!write(MIN, buffer[1]))return 0; + if(!write(HOUR, buffer[2]))return 0; + if(!write(DAY, buffer[3]))return 0; + if(!write(WDAY, buffer[4]))return 0; + if(!write(MONTH, buffer[5]))return 0; + if(!write(YEAR, buffer[6]))return 0; + + // clear stop signal + buffer[0] = 0x00; + if(!write(STOPEN, buffer[0]))return 0; + + return true; +} + +bool PCF85263AT::IsConnected() +{ + bool ok = false; + + i2c.start(); + i2c.stop(); + + if (i2c.read(address, &data[0], 1) != 0) + { +// dbg.printf("PCF85263AT is not detected\r\n"); + ok = false; + } + else + { +// dbg.printf("PCF85263AT is detected\r\n"); + ok = true; + } + + data[0] = 0; + i2c.start(); + i2c.stop(); + + return ok; +} + +bool PCF85263AT::software_reset() +{ + char buffer = 0x2C; + + if(!write(RESET, buffer)) return 0; + + return 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PCF85263AT.h Wed Jun 17 08:46:25 2020 +0000 @@ -0,0 +1,83 @@ +#ifndef PCF85263AT_H +#define PCF85263AT_H + +#include "mbed.h" + +#define address 0xA2 + +class PCF85263AT +{ +public: + + enum RegisterName + { + // Time and Date Register | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | + MSEC = 0x00, // Mili Second | ( 0 - 99 ) | + SEC = 0x01, // Second | OS | ( 0 - 59 ) | + MIN = 0x02, // Minute | EMON | ( 0 - 59 ) | + HOUR = 0x03, // Hour | X | X | AM/PM | ( 1 - 12 ) | + // Hour | X | X | ( 0 - 23 ) | + DAY = 0x04, // Day | X | X | ( 1 - 31 ) | + WDAY = 0x05, // Day of week | X | X | X | X | X | ( 0 - 6 ) | + MONTH = 0x06, // month | X | X | X | ( 1 - 12 ) | + YEAR = 0x07, // year | ( 0 - 99 ) | + + // Alarm1 register + SECALARM = 0x08, // Second1 | X | ( 0 - 59 ) | + MINALARM = 0x09, // Minute1 | X | ( 0 - 59 ) | + HOURALARM = 0x0A, // Hour1 | X | X | AM/PM | ( 1 - 12 ) | + // Hour1 | X | X | ( 0 - 23 ) | + DAYALARM = 0x0B, // Day | X | X | ( 1 - 31 ) | + MONALARM = 0x0C, // Day of week | X | X | X | ( 1 - 12 ) | + + // Alarm2 register + MINALARM2 = 0x0D, // Minute1 | X | ( 0 - 59 ) | + HOURALARM2 = 0x0E, // Hour1 | X | X | AM/PM | ( 1 - 12 ) | + WDAYALARM2 = 0x0F, // Day | X | X | X | X | X | ( 0 - 6 ) | + + // RTC Alarm Enable + ALARMEN = 0x10, // Alarm Enable |WDAY2E | HR2E | MIN2E | MON1E | DAYE | HR1E | MIN1E | SEC1E | + + // OFFSET Register + OFFSET = 0x24, // Offset | [7:0] | + + // CONTROL REGISTER + OSCI = 0x25, // Oscilator | CLKIV | OFFM | 12_24 | LOWJ | OSCD[1:0] | CL[1:0] | + BTRSW = 0x26, // BatterySwitch| X | X | X | BSOFF | BSRR | BSM[1:0] | BSTH | + PINIO = 0x27, // Pin I/O | CLKPM | TSPULL| TSL | TSIM | TSPM[1:0] | INTAPM[1:0] | + FUNCT = 0x28, // Fungtion | 100TH | PI [2:0] | RTCM | STOPM | COF[2:0] | + FLAG = 0x2B, // Flags | PIF | A2F | A1F | WDF | BSF | TSR3F | TSR2F | TSR1F | + + // STOP + STOPEN = 0x2E, // Stop Enable | X | X | X | X | X | X | X | STOP | + + // RESET + RESET = 0x2F // Reset RTC | CPR | 0 | 1 | 0 | SR | 1 | 0 | CTS | + }; + + bool write(char adr, char data); + char read(char adr); + time_t now(); + bool set_time(time_t time); + bool IsConnected(); + bool software_reset(); + + PCF85263AT(PinName sda, PinName scl); + ~PCF85263AT(); + +private: + I2C i2c; + char data[64]; + char w[32]; + char r[32]; + + static int bcdToDecimal(int bcd) { + return ((bcd & 0xF0) >> 4) * 10 + (bcd & 0x0F); + } + + static int decimalToBcd(int dec) { + return (dec % 10) + ((dec / 10) << 4); + } +}; + +#endif // PCF85263AT_H