DPPU / PCF8523
Revision:
0:b7ac3add7d83
Child:
1:41dd31bbbe6d
diff -r 000000000000 -r b7ac3add7d83 PCF8523.cpp
--- /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