copy from mbed

Files at this revision

API Documentation at this revision

Comitter:
irsanjul
Date:
Fri Mar 02 07:01:17 2018 +0000
Child:
1:41dd31bbbe6d
Commit message:
copy from mbed

Changed in this revision

PCF8523.cpp Show annotated file Show diff for this revision Revisions of this file
PCF8523.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PCF8523.cpp	Fri Mar 02 07:01:17 2018 +0000
@@ -0,0 +1,226 @@
+#include "mbed.h"
+#include "PCF8523.h"
+
+extern Serial dbg;
+
+PCF8523::PCF8523(PinName sda, PinName scl) : i2c (sda, scl)
+{
+    i2c.frequency(100000);
+}
+
+PCF8523::~PCF8523()
+{
+    
+}
+
+bool PCF8523::write(char adr, char data)
+{
+    w[0] = adr;
+    w[1] = data;
+    if (i2c.write(address, w, 2) != 0) return 0;
+    
+    return true;
+}
+
+char PCF8523::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 PCF8523::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 PCF8523::set_time(time_t time)
+{
+    struct tm *now;
+    char buffer[9];
+    
+    now = localtime(&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;
+    
+    return true;
+}
+
+bool PCF8523::IsConnected()
+{
+    bool ok = false;
+    
+    i2c.start();
+    i2c.stop();
+    
+    if (i2c.read(address, &data[0], 1) != 0)
+    {
+        dbg.printf("PCF8523 is not detected\r\n");
+        ok = false;
+    }
+    else
+    {
+        dbg.printf("PCF8523 is detected\r\n");
+        ok = true;
+    }
+        
+    data[0] = 0;
+    i2c.start();
+    i2c.stop();
+    
+    return ok;
+}
+
+bool PCF8523::set_alarm(const struct tm &now, bool min_en, bool hour_en, bool mday_en)
+{
+    /*
+    // Alarm register                   | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
+    CTRL1       = 0x00, // Ctrl 1       |Cap Sel|   T   | Stop  |  SR   | 12-24 |  SIE  |  AIE  |  CIE  |
+    
+    MINALARM    = 0x0A, // Minute       | AEN_M |                       ( 0 - 59 )                      |
+    HOURALARM   = 0x0B, // Hour         | AEN_H |   X   |               ( 0 - 23 )                      |
+                        // Hour         | AEN_H |   X   | AM/PM |       ( 1 - 12 )                      |
+    DAYALARM    = 0x0C, // Day          | AEN_D |   X   |               ( 1 - 31 )                      |
+    WDAYALARM   = 0x0D, // Day of week  | AEN_W |   X   |   X   |   X   |   X   |       ( 0 - 6 )       |
+    
+    AEN_M, AEN_H, AEN_D, AEN_W => 0 = enable; 1 = disable
+    */
+    
+    char buffer[3] = {0x00, 0x00, 0x00};
+    
+//    if(now.tm_min >= 60)
+//        now.tm_min = 0;
+//    
+//    if(now.tm_hour >= 24)
+//        now.tm_hour = 0;
+//        
+//    if(now.tm_mday >= 32)
+//        now.tm_mday = 1;
+//        
+    if(min_en)
+    {
+        buffer[0] = (decimalToBcd(now.tm_min) & 0x7F);
+        if(!write(MINALARM, buffer[0]))return 0;
+    }
+    else
+    {
+        buffer[0] = (decimalToBcd(now.tm_min) | 0x80);
+        if(!write(MINALARM, buffer[0]))return 0;
+    }
+    
+    if(hour_en)
+    {
+        buffer[1] = (decimalToBcd(now.tm_hour) & 0x3F);
+        if(!write(HOURALARM, buffer[1]))return 0;
+    }
+    else
+    {
+        buffer[1] = (decimalToBcd(now.tm_hour) | 0x80);
+        if(!write(HOURALARM, buffer[1]))return 0;
+    }
+    
+    if(mday_en)
+    {
+        buffer[2] = (decimalToBcd(now.tm_mday) & 0x3F);
+        if(!write(DAYALARM, buffer[2]))return 0;
+    }
+    else
+    {
+        buffer[2] = (decimalToBcd(now.tm_mday) | 0x80);
+        if(!write(DAYALARM, buffer[2]))return 0;
+    }
+    return true;
+}
+
+bool PCF8523::enable_alarm(bool enable)
+{
+    char buffer = read(CTRL1);
+    
+    if(enable)
+    {
+        // Disable Clockout & other Timers
+        if(!write(TMRCLKOUT, 0x38))
+        
+        // Clear any existing flags
+        alarm_off(0x08);
+        
+        // enable AIE bit
+        buffer = buffer | 0x02;
+    }
+    else
+    {
+        buffer &= ~0x02;
+    }
+    
+    if(!write(CTRL1, buffer)) return 0;
+    
+    return true;
+}
+
+bool PCF8523::alarm_off(char buffer)
+{   
+    // clear AF flag
+    buffer = buffer - 0x08;
+    
+    if(!write(CTRL2, buffer))return 0;
+    
+    return true;
+}
+
+bool PCF8523::check_alarm()
+{
+    char buffer;
+    
+    buffer = read(CTRL2);
+    
+    if(buffer & 0x08)
+    {
+        if(alarm_off(buffer))
+            return true;
+        else return 0;
+    }
+    else return 0;
+}
+
+bool PCF8523::software_reset()
+{
+    char buffer = 0x58;
+    
+    if(!write(CTRL1, buffer)) return 0;
+    
+    return 1;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PCF8523.h	Fri Mar 02 07:01:17 2018 +0000
@@ -0,0 +1,76 @@
+#ifndef PCF8523_H
+#define PCF8523_H
+
+#include "mbed.h"
+
+#define address 0xD0
+
+class PCF8523
+{
+public:
+    
+    enum RegisterName
+    {
+        // Control Register                 | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
+        CTRL1       = 0x00, // Ctrl 1       |Cap Sel|   T   | Stop  |  SR   | 12-24 |  SIE  |  AIE  |  CIE  |
+        CTRL2       = 0x01, // Ctrl 2       | WTAF  | CTAF  | CTBF  |  SF   |   AF  | WTAIE | CTAIE | CTBIE |
+        CTRL3       = 0x02, // Ctrl 3       |       PM [2:0]        |   X   |  BSF  |  BLF  | BSIE  |  BLIE |
+        
+        // Time and Date Register    
+        SEC         = 0x03, // Second       |   OS  |                       ( 0 - 59 )                      |
+        MIN         = 0x04, // Minute       |   X   |                       ( 0 - 59 )                      |
+        HOUR        = 0x05, // Hour         |   X   |   X   | AM/PM |       ( 1 - 12 )                      |
+                            // Hour         |   X   |   X   |               ( 0 - 23 )                      |
+        DAY         = 0x06, // Day          |   X   |   X   |               ( 1 - 31 )                      |
+        WDAY        = 0x07, // Day of week  |   X   |   X   |   X   |   X   |   X   |       ( 0 - 6 )       |
+        MONTH       = 0x08, // month        |   X   |   X   |   X   |               ( 1 - 12 )              |
+        YEAR        = 0x09, // year         |                           ( 0 - 99 )                          |
+        
+        // Alarm register
+        MINALARM    = 0x0A, // Minute       | AEN_M |                       ( 0 - 59 )                      |
+        HOURALARM   = 0x0B, // Hour         | AEN_H |   X   |               ( 0 - 23 )                      |
+                            // Hour         | AEN_H |   X   | AM/PM |       ( 1 - 12 )                      |
+        DAYALARM    = 0x0C, // Day          | AEN_D |   X   |               ( 1 - 31 )                      |
+        WDAYALARM   = 0x0D, // Day of week  | AEN_W |   X   |   X   |   X   |   X   |       ( 0 - 6 )       |
+        
+        // Offset Control Register
+        OFFSET      = 0x0E, // OffSet ctrl  | MODE  |                       OFFSET                          |
+        
+        // ClockOut adn Timer Register
+        TMRCLKOUT   = 0x0F, // Timer Clk Out|  TAM  |  TBM  |           COF         |       TAC     |  TBC  |
+        TIMERAFR    = 0x10, // Timer A Freq |   X   |   X   |   X   |   X   |   X   |           TAQ         |
+        TIMERARG    = 0x11, // Timer A Reg  |                           T_A   [7:0]                         |
+        TIMERBFR    = 0x12, // Timer B Freq |   X   |           TBW         |   X   |           TBQ         |
+        TIMERBRG    = 0x13, // Timer B Reg  |                           T_B   [7:0]                         |
+    };
+    
+    bool write(char adr, char data);
+    char read(char adr);
+    time_t now();
+    bool set_time(time_t time);
+    bool set_alarm(const struct tm &now, bool min_en=false, bool hour_en=false, bool mday_en=false);
+    bool enable_alarm(bool enable=false);
+    bool alarm_off(char buffer);
+    bool check_alarm();
+    bool IsConnected();
+    bool software_reset();
+    
+    PCF8523(PinName scl, PinName sda);
+    ~PCF8523();
+    
+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
\ No newline at end of file