Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
PCF8523.cpp@1:41dd31bbbe6d, 2020-06-18 (annotated)
- Committer:
- irsanjul
- Date:
- Thu Jun 18 08:57:58 2020 +0000
- Revision:
- 1:41dd31bbbe6d
- Parent:
- 0:b7ac3add7d83
pcf8523
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| irsanjul | 0:b7ac3add7d83 | 1 | #include "mbed.h" |
| irsanjul | 0:b7ac3add7d83 | 2 | #include "PCF8523.h" |
| irsanjul | 0:b7ac3add7d83 | 3 | |
| irsanjul | 0:b7ac3add7d83 | 4 | extern Serial dbg; |
| irsanjul | 0:b7ac3add7d83 | 5 | |
| irsanjul | 0:b7ac3add7d83 | 6 | PCF8523::PCF8523(PinName sda, PinName scl) : i2c (sda, scl) |
| irsanjul | 0:b7ac3add7d83 | 7 | { |
| irsanjul | 0:b7ac3add7d83 | 8 | i2c.frequency(100000); |
| irsanjul | 0:b7ac3add7d83 | 9 | } |
| irsanjul | 0:b7ac3add7d83 | 10 | |
| irsanjul | 0:b7ac3add7d83 | 11 | PCF8523::~PCF8523() |
| irsanjul | 0:b7ac3add7d83 | 12 | { |
| irsanjul | 0:b7ac3add7d83 | 13 | |
| irsanjul | 0:b7ac3add7d83 | 14 | } |
| irsanjul | 0:b7ac3add7d83 | 15 | |
| irsanjul | 0:b7ac3add7d83 | 16 | bool PCF8523::write(char adr, char data) |
| irsanjul | 0:b7ac3add7d83 | 17 | { |
| irsanjul | 0:b7ac3add7d83 | 18 | w[0] = adr; |
| irsanjul | 0:b7ac3add7d83 | 19 | w[1] = data; |
| irsanjul | 0:b7ac3add7d83 | 20 | if (i2c.write(address, w, 2) != 0) return 0; |
| irsanjul | 0:b7ac3add7d83 | 21 | |
| irsanjul | 0:b7ac3add7d83 | 22 | return true; |
| irsanjul | 0:b7ac3add7d83 | 23 | } |
| irsanjul | 0:b7ac3add7d83 | 24 | |
| irsanjul | 0:b7ac3add7d83 | 25 | char PCF8523::read(char adr) |
| irsanjul | 0:b7ac3add7d83 | 26 | { |
| irsanjul | 0:b7ac3add7d83 | 27 | char start = adr; |
| irsanjul | 0:b7ac3add7d83 | 28 | if (i2c.write(address, &start, 1, true) != 0) return 0; |
| irsanjul | 0:b7ac3add7d83 | 29 | if (i2c.read(address, r, 1) != 0) return 0; |
| irsanjul | 0:b7ac3add7d83 | 30 | |
| irsanjul | 0:b7ac3add7d83 | 31 | return r[0]; |
| irsanjul | 0:b7ac3add7d83 | 32 | } |
| irsanjul | 0:b7ac3add7d83 | 33 | |
| irsanjul | 0:b7ac3add7d83 | 34 | time_t PCF8523::now() |
| irsanjul | 0:b7ac3add7d83 | 35 | { |
| irsanjul | 0:b7ac3add7d83 | 36 | struct tm now; |
| irsanjul | 0:b7ac3add7d83 | 37 | |
| irsanjul | 0:b7ac3add7d83 | 38 | char buffer[6]; |
| irsanjul | 0:b7ac3add7d83 | 39 | |
| irsanjul | 0:b7ac3add7d83 | 40 | buffer [0] = read(SEC); |
| irsanjul | 0:b7ac3add7d83 | 41 | buffer [1] = read(MIN); |
| irsanjul | 0:b7ac3add7d83 | 42 | buffer [2] = read(HOUR); |
| irsanjul | 0:b7ac3add7d83 | 43 | buffer [3] = read(DAY); |
| irsanjul | 0:b7ac3add7d83 | 44 | buffer [4] = read(MONTH); |
| irsanjul | 0:b7ac3add7d83 | 45 | buffer [5] = read(YEAR); |
| irsanjul | 0:b7ac3add7d83 | 46 | |
| irsanjul | 0:b7ac3add7d83 | 47 | now.tm_sec = bcdToDecimal(buffer[0] & 0x7F); |
| irsanjul | 0:b7ac3add7d83 | 48 | now.tm_min = bcdToDecimal(buffer[1] & 0x7F); |
| irsanjul | 0:b7ac3add7d83 | 49 | now.tm_hour = bcdToDecimal(buffer[2] & 0x3F); |
| irsanjul | 0:b7ac3add7d83 | 50 | now.tm_mday = bcdToDecimal(buffer[3] & 0x3F); |
| irsanjul | 0:b7ac3add7d83 | 51 | now.tm_mon = bcdToDecimal(buffer[4] & 0x1F) - 1; |
| irsanjul | 0:b7ac3add7d83 | 52 | now.tm_year = bcdToDecimal(buffer[5] & 0xFF) + 2000 - 1900; |
| irsanjul | 0:b7ac3add7d83 | 53 | |
| irsanjul | 0:b7ac3add7d83 | 54 | return mktime(&now); |
| irsanjul | 0:b7ac3add7d83 | 55 | } |
| irsanjul | 0:b7ac3add7d83 | 56 | |
| irsanjul | 0:b7ac3add7d83 | 57 | bool PCF8523::set_time(time_t time) |
| irsanjul | 0:b7ac3add7d83 | 58 | { |
| irsanjul | 0:b7ac3add7d83 | 59 | struct tm *now; |
| irsanjul | 0:b7ac3add7d83 | 60 | char buffer[9]; |
| irsanjul | 0:b7ac3add7d83 | 61 | |
| irsanjul | 0:b7ac3add7d83 | 62 | now = localtime(&time); |
| irsanjul | 0:b7ac3add7d83 | 63 | |
| irsanjul | 0:b7ac3add7d83 | 64 | buffer[0] = decimalToBcd(now->tm_sec) & 0x7F; // VL = 0 |
| irsanjul | 0:b7ac3add7d83 | 65 | buffer[1] = decimalToBcd(now->tm_min) & 0x7F; |
| irsanjul | 0:b7ac3add7d83 | 66 | buffer[2] = decimalToBcd(now->tm_hour) & 0x3F; |
| irsanjul | 0:b7ac3add7d83 | 67 | buffer[3] = decimalToBcd(now->tm_mday) & 0x3F; |
| irsanjul | 0:b7ac3add7d83 | 68 | buffer[4] = now->tm_wday + 1; |
| irsanjul | 0:b7ac3add7d83 | 69 | buffer[5] = decimalToBcd(now->tm_mon+1) & 0x1F; |
| irsanjul | 0:b7ac3add7d83 | 70 | buffer[6] = decimalToBcd(now->tm_year + 1900 - 2000); |
| irsanjul | 0:b7ac3add7d83 | 71 | |
| irsanjul | 0:b7ac3add7d83 | 72 | if(!write(SEC, buffer[0]))return 0; |
| irsanjul | 0:b7ac3add7d83 | 73 | if(!write(MIN, buffer[1]))return 0; |
| irsanjul | 0:b7ac3add7d83 | 74 | if(!write(HOUR, buffer[2]))return 0; |
| irsanjul | 0:b7ac3add7d83 | 75 | if(!write(DAY, buffer[3]))return 0; |
| irsanjul | 0:b7ac3add7d83 | 76 | if(!write(WDAY, buffer[4]))return 0; |
| irsanjul | 0:b7ac3add7d83 | 77 | if(!write(MONTH, buffer[5]))return 0; |
| irsanjul | 0:b7ac3add7d83 | 78 | if(!write(YEAR, buffer[6]))return 0; |
| irsanjul | 0:b7ac3add7d83 | 79 | |
| irsanjul | 0:b7ac3add7d83 | 80 | return true; |
| irsanjul | 0:b7ac3add7d83 | 81 | } |
| irsanjul | 0:b7ac3add7d83 | 82 | |
| irsanjul | 1:41dd31bbbe6d | 83 | bool PCF8523::Initialize(char adr, uint8_t val) |
| irsanjul | 1:41dd31bbbe6d | 84 | { |
| irsanjul | 1:41dd31bbbe6d | 85 | char buffer[4]; |
| irsanjul | 1:41dd31bbbe6d | 86 | buffer[0] = val; |
| irsanjul | 1:41dd31bbbe6d | 87 | if(!write(adr, buffer[0]))return 0; |
| irsanjul | 1:41dd31bbbe6d | 88 | |
| irsanjul | 1:41dd31bbbe6d | 89 | return true; |
| irsanjul | 1:41dd31bbbe6d | 90 | } |
| irsanjul | 1:41dd31bbbe6d | 91 | |
| irsanjul | 0:b7ac3add7d83 | 92 | bool PCF8523::IsConnected() |
| irsanjul | 0:b7ac3add7d83 | 93 | { |
| irsanjul | 0:b7ac3add7d83 | 94 | bool ok = false; |
| irsanjul | 0:b7ac3add7d83 | 95 | |
| irsanjul | 0:b7ac3add7d83 | 96 | i2c.start(); |
| irsanjul | 0:b7ac3add7d83 | 97 | i2c.stop(); |
| irsanjul | 0:b7ac3add7d83 | 98 | |
| irsanjul | 0:b7ac3add7d83 | 99 | if (i2c.read(address, &data[0], 1) != 0) |
| irsanjul | 0:b7ac3add7d83 | 100 | { |
| irsanjul | 0:b7ac3add7d83 | 101 | dbg.printf("PCF8523 is not detected\r\n"); |
| irsanjul | 0:b7ac3add7d83 | 102 | ok = false; |
| irsanjul | 0:b7ac3add7d83 | 103 | } |
| irsanjul | 0:b7ac3add7d83 | 104 | else |
| irsanjul | 0:b7ac3add7d83 | 105 | { |
| irsanjul | 0:b7ac3add7d83 | 106 | dbg.printf("PCF8523 is detected\r\n"); |
| irsanjul | 0:b7ac3add7d83 | 107 | ok = true; |
| irsanjul | 0:b7ac3add7d83 | 108 | } |
| irsanjul | 0:b7ac3add7d83 | 109 | |
| irsanjul | 0:b7ac3add7d83 | 110 | data[0] = 0; |
| irsanjul | 0:b7ac3add7d83 | 111 | i2c.start(); |
| irsanjul | 0:b7ac3add7d83 | 112 | i2c.stop(); |
| irsanjul | 0:b7ac3add7d83 | 113 | |
| irsanjul | 0:b7ac3add7d83 | 114 | return ok; |
| irsanjul | 0:b7ac3add7d83 | 115 | } |
| irsanjul | 0:b7ac3add7d83 | 116 | |
| irsanjul | 0:b7ac3add7d83 | 117 | bool PCF8523::set_alarm(const struct tm &now, bool min_en, bool hour_en, bool mday_en) |
| irsanjul | 0:b7ac3add7d83 | 118 | { |
| irsanjul | 0:b7ac3add7d83 | 119 | /* |
| irsanjul | 0:b7ac3add7d83 | 120 | // Alarm register | Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 | |
| irsanjul | 0:b7ac3add7d83 | 121 | CTRL1 = 0x00, // Ctrl 1 |Cap Sel| T | Stop | SR | 12-24 | SIE | AIE | CIE | |
| irsanjul | 0:b7ac3add7d83 | 122 | |
| irsanjul | 0:b7ac3add7d83 | 123 | MINALARM = 0x0A, // Minute | AEN_M | ( 0 - 59 ) | |
| irsanjul | 0:b7ac3add7d83 | 124 | HOURALARM = 0x0B, // Hour | AEN_H | X | ( 0 - 23 ) | |
| irsanjul | 0:b7ac3add7d83 | 125 | // Hour | AEN_H | X | AM/PM | ( 1 - 12 ) | |
| irsanjul | 0:b7ac3add7d83 | 126 | DAYALARM = 0x0C, // Day | AEN_D | X | ( 1 - 31 ) | |
| irsanjul | 0:b7ac3add7d83 | 127 | WDAYALARM = 0x0D, // Day of week | AEN_W | X | X | X | X | ( 0 - 6 ) | |
| irsanjul | 0:b7ac3add7d83 | 128 | |
| irsanjul | 0:b7ac3add7d83 | 129 | AEN_M, AEN_H, AEN_D, AEN_W => 0 = enable; 1 = disable |
| irsanjul | 0:b7ac3add7d83 | 130 | */ |
| irsanjul | 0:b7ac3add7d83 | 131 | |
| irsanjul | 0:b7ac3add7d83 | 132 | char buffer[3] = {0x00, 0x00, 0x00}; |
| irsanjul | 0:b7ac3add7d83 | 133 | |
| irsanjul | 0:b7ac3add7d83 | 134 | // if(now.tm_min >= 60) |
| irsanjul | 0:b7ac3add7d83 | 135 | // now.tm_min = 0; |
| irsanjul | 0:b7ac3add7d83 | 136 | // |
| irsanjul | 0:b7ac3add7d83 | 137 | // if(now.tm_hour >= 24) |
| irsanjul | 0:b7ac3add7d83 | 138 | // now.tm_hour = 0; |
| irsanjul | 0:b7ac3add7d83 | 139 | // |
| irsanjul | 0:b7ac3add7d83 | 140 | // if(now.tm_mday >= 32) |
| irsanjul | 0:b7ac3add7d83 | 141 | // now.tm_mday = 1; |
| irsanjul | 0:b7ac3add7d83 | 142 | // |
| irsanjul | 0:b7ac3add7d83 | 143 | if(min_en) |
| irsanjul | 0:b7ac3add7d83 | 144 | { |
| irsanjul | 0:b7ac3add7d83 | 145 | buffer[0] = (decimalToBcd(now.tm_min) & 0x7F); |
| irsanjul | 0:b7ac3add7d83 | 146 | if(!write(MINALARM, buffer[0]))return 0; |
| irsanjul | 0:b7ac3add7d83 | 147 | } |
| irsanjul | 0:b7ac3add7d83 | 148 | else |
| irsanjul | 0:b7ac3add7d83 | 149 | { |
| irsanjul | 0:b7ac3add7d83 | 150 | buffer[0] = (decimalToBcd(now.tm_min) | 0x80); |
| irsanjul | 0:b7ac3add7d83 | 151 | if(!write(MINALARM, buffer[0]))return 0; |
| irsanjul | 0:b7ac3add7d83 | 152 | } |
| irsanjul | 0:b7ac3add7d83 | 153 | |
| irsanjul | 0:b7ac3add7d83 | 154 | if(hour_en) |
| irsanjul | 0:b7ac3add7d83 | 155 | { |
| irsanjul | 0:b7ac3add7d83 | 156 | buffer[1] = (decimalToBcd(now.tm_hour) & 0x3F); |
| irsanjul | 0:b7ac3add7d83 | 157 | if(!write(HOURALARM, buffer[1]))return 0; |
| irsanjul | 0:b7ac3add7d83 | 158 | } |
| irsanjul | 0:b7ac3add7d83 | 159 | else |
| irsanjul | 0:b7ac3add7d83 | 160 | { |
| irsanjul | 0:b7ac3add7d83 | 161 | buffer[1] = (decimalToBcd(now.tm_hour) | 0x80); |
| irsanjul | 0:b7ac3add7d83 | 162 | if(!write(HOURALARM, buffer[1]))return 0; |
| irsanjul | 0:b7ac3add7d83 | 163 | } |
| irsanjul | 0:b7ac3add7d83 | 164 | |
| irsanjul | 0:b7ac3add7d83 | 165 | if(mday_en) |
| irsanjul | 0:b7ac3add7d83 | 166 | { |
| irsanjul | 0:b7ac3add7d83 | 167 | buffer[2] = (decimalToBcd(now.tm_mday) & 0x3F); |
| irsanjul | 0:b7ac3add7d83 | 168 | if(!write(DAYALARM, buffer[2]))return 0; |
| irsanjul | 0:b7ac3add7d83 | 169 | } |
| irsanjul | 0:b7ac3add7d83 | 170 | else |
| irsanjul | 0:b7ac3add7d83 | 171 | { |
| irsanjul | 0:b7ac3add7d83 | 172 | buffer[2] = (decimalToBcd(now.tm_mday) | 0x80); |
| irsanjul | 0:b7ac3add7d83 | 173 | if(!write(DAYALARM, buffer[2]))return 0; |
| irsanjul | 0:b7ac3add7d83 | 174 | } |
| irsanjul | 0:b7ac3add7d83 | 175 | return true; |
| irsanjul | 0:b7ac3add7d83 | 176 | } |
| irsanjul | 0:b7ac3add7d83 | 177 | |
| irsanjul | 0:b7ac3add7d83 | 178 | bool PCF8523::enable_alarm(bool enable) |
| irsanjul | 0:b7ac3add7d83 | 179 | { |
| irsanjul | 0:b7ac3add7d83 | 180 | char buffer = read(CTRL1); |
| irsanjul | 0:b7ac3add7d83 | 181 | |
| irsanjul | 0:b7ac3add7d83 | 182 | if(enable) |
| irsanjul | 0:b7ac3add7d83 | 183 | { |
| irsanjul | 0:b7ac3add7d83 | 184 | // Disable Clockout & other Timers |
| irsanjul | 0:b7ac3add7d83 | 185 | if(!write(TMRCLKOUT, 0x38)) |
| irsanjul | 0:b7ac3add7d83 | 186 | |
| irsanjul | 0:b7ac3add7d83 | 187 | // Clear any existing flags |
| irsanjul | 0:b7ac3add7d83 | 188 | alarm_off(0x08); |
| irsanjul | 0:b7ac3add7d83 | 189 | |
| irsanjul | 0:b7ac3add7d83 | 190 | // enable AIE bit |
| irsanjul | 0:b7ac3add7d83 | 191 | buffer = buffer | 0x02; |
| irsanjul | 0:b7ac3add7d83 | 192 | } |
| irsanjul | 0:b7ac3add7d83 | 193 | else |
| irsanjul | 0:b7ac3add7d83 | 194 | { |
| irsanjul | 0:b7ac3add7d83 | 195 | buffer &= ~0x02; |
| irsanjul | 0:b7ac3add7d83 | 196 | } |
| irsanjul | 0:b7ac3add7d83 | 197 | |
| irsanjul | 0:b7ac3add7d83 | 198 | if(!write(CTRL1, buffer)) return 0; |
| irsanjul | 0:b7ac3add7d83 | 199 | |
| irsanjul | 0:b7ac3add7d83 | 200 | return true; |
| irsanjul | 0:b7ac3add7d83 | 201 | } |
| irsanjul | 0:b7ac3add7d83 | 202 | |
| irsanjul | 0:b7ac3add7d83 | 203 | bool PCF8523::alarm_off(char buffer) |
| irsanjul | 0:b7ac3add7d83 | 204 | { |
| irsanjul | 0:b7ac3add7d83 | 205 | // clear AF flag |
| irsanjul | 0:b7ac3add7d83 | 206 | buffer = buffer - 0x08; |
| irsanjul | 0:b7ac3add7d83 | 207 | |
| irsanjul | 0:b7ac3add7d83 | 208 | if(!write(CTRL2, buffer))return 0; |
| irsanjul | 0:b7ac3add7d83 | 209 | |
| irsanjul | 0:b7ac3add7d83 | 210 | return true; |
| irsanjul | 0:b7ac3add7d83 | 211 | } |
| irsanjul | 0:b7ac3add7d83 | 212 | |
| irsanjul | 0:b7ac3add7d83 | 213 | bool PCF8523::check_alarm() |
| irsanjul | 0:b7ac3add7d83 | 214 | { |
| irsanjul | 0:b7ac3add7d83 | 215 | char buffer; |
| irsanjul | 0:b7ac3add7d83 | 216 | |
| irsanjul | 0:b7ac3add7d83 | 217 | buffer = read(CTRL2); |
| irsanjul | 0:b7ac3add7d83 | 218 | |
| irsanjul | 0:b7ac3add7d83 | 219 | if(buffer & 0x08) |
| irsanjul | 0:b7ac3add7d83 | 220 | { |
| irsanjul | 0:b7ac3add7d83 | 221 | if(alarm_off(buffer)) |
| irsanjul | 0:b7ac3add7d83 | 222 | return true; |
| irsanjul | 0:b7ac3add7d83 | 223 | else return 0; |
| irsanjul | 0:b7ac3add7d83 | 224 | } |
| irsanjul | 0:b7ac3add7d83 | 225 | else return 0; |
| irsanjul | 0:b7ac3add7d83 | 226 | } |
| irsanjul | 0:b7ac3add7d83 | 227 | |
| irsanjul | 0:b7ac3add7d83 | 228 | bool PCF8523::software_reset() |
| irsanjul | 0:b7ac3add7d83 | 229 | { |
| irsanjul | 0:b7ac3add7d83 | 230 | char buffer = 0x58; |
| irsanjul | 0:b7ac3add7d83 | 231 | |
| irsanjul | 0:b7ac3add7d83 | 232 | if(!write(CTRL1, buffer)) return 0; |
| irsanjul | 0:b7ac3add7d83 | 233 | |
| irsanjul | 0:b7ac3add7d83 | 234 | return 1; |
| irsanjul | 0:b7ac3add7d83 | 235 | } |