Justin Jordan
/
DS3231_Alarm_Demo
Simple demo showing use of DS3231 Alarms
main.cpp@0:0cbd468ebbc1, 2017-02-28 (annotated)
- Committer:
- j3
- Date:
- Tue Feb 28 20:53:56 2017 +0000
- Revision:
- 0:0cbd468ebbc1
Init commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
j3 | 0:0cbd468ebbc1 | 1 | /****************************************************************************** |
j3 | 0:0cbd468ebbc1 | 2 | * MIT License |
j3 | 0:0cbd468ebbc1 | 3 | * |
j3 | 0:0cbd468ebbc1 | 4 | * Copyright (c) 2017 Justin J. Jordan |
j3 | 0:0cbd468ebbc1 | 5 | * |
j3 | 0:0cbd468ebbc1 | 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
j3 | 0:0cbd468ebbc1 | 7 | * of this software and associated documentation files (the "Software"), to deal |
j3 | 0:0cbd468ebbc1 | 8 | * in the Software without restriction, including without limitation the rights |
j3 | 0:0cbd468ebbc1 | 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
j3 | 0:0cbd468ebbc1 | 10 | * copies of the Software, and to permit persons to whom the Software is |
j3 | 0:0cbd468ebbc1 | 11 | * furnished to do so, subject to the following conditions: |
j3 | 0:0cbd468ebbc1 | 12 | |
j3 | 0:0cbd468ebbc1 | 13 | * The above copyright notice and this permission notice shall be included in all |
j3 | 0:0cbd468ebbc1 | 14 | * copies or substantial portions of the Software. |
j3 | 0:0cbd468ebbc1 | 15 | |
j3 | 0:0cbd468ebbc1 | 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
j3 | 0:0cbd468ebbc1 | 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
j3 | 0:0cbd468ebbc1 | 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
j3 | 0:0cbd468ebbc1 | 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
j3 | 0:0cbd468ebbc1 | 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
j3 | 0:0cbd468ebbc1 | 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
j3 | 0:0cbd468ebbc1 | 22 | * SOFTWARE. |
j3 | 0:0cbd468ebbc1 | 23 | ******************************************************************************/ |
j3 | 0:0cbd468ebbc1 | 24 | |
j3 | 0:0cbd468ebbc1 | 25 | |
j3 | 0:0cbd468ebbc1 | 26 | #include "mbed.h" |
j3 | 0:0cbd468ebbc1 | 27 | #include "ds3231.h" |
j3 | 0:0cbd468ebbc1 | 28 | |
j3 | 0:0cbd468ebbc1 | 29 | #define TERM_HOME ("\033[H") |
j3 | 0:0cbd468ebbc1 | 30 | #define TERM_CLEAR_FROM_CURSOR ("\033[0J") |
j3 | 0:0cbd468ebbc1 | 31 | #define TERM_CLEAR_EOL ("\033[K") |
j3 | 0:0cbd468ebbc1 | 32 | |
j3 | 0:0cbd468ebbc1 | 33 | #define DS3231_WRITE_ADRS (0x68 << 1) |
j3 | 0:0cbd468ebbc1 | 34 | #define DS3231_READ_ADRS ((0x68 << 1) | 1) |
j3 | 0:0cbd468ebbc1 | 35 | #define ALARM_1_BIT (1) |
j3 | 0:0cbd468ebbc1 | 36 | #define ALARM_2_BIT (2) |
j3 | 0:0cbd468ebbc1 | 37 | #define STATUS_REG_ADRS (0x0F) |
j3 | 0:0cbd468ebbc1 | 38 | |
j3 | 0:0cbd468ebbc1 | 39 | //I2C Bus |
j3 | 0:0cbd468ebbc1 | 40 | I2C i2c(D14, D15); |
j3 | 0:0cbd468ebbc1 | 41 | |
j3 | 0:0cbd468ebbc1 | 42 | //DS3231 INT pin connected to D2 with pull-up |
j3 | 0:0cbd468ebbc1 | 43 | InterruptIn rtc_int(D2); |
j3 | 0:0cbd468ebbc1 | 44 | |
j3 | 0:0cbd468ebbc1 | 45 | //Flags for loop |
j3 | 0:0cbd468ebbc1 | 46 | volatile bool alarm1_flag = false; |
j3 | 0:0cbd468ebbc1 | 47 | volatile bool alarm2_flag = false; |
j3 | 0:0cbd468ebbc1 | 48 | |
j3 | 0:0cbd468ebbc1 | 49 | void rtc_isr() |
j3 | 0:0cbd468ebbc1 | 50 | { |
j3 | 0:0cbd468ebbc1 | 51 | char data[2]; |
j3 | 0:0cbd468ebbc1 | 52 | uint8_t status; |
j3 | 0:0cbd468ebbc1 | 53 | data[0] = STATUS_REG_ADRS; |
j3 | 0:0cbd468ebbc1 | 54 | |
j3 | 0:0cbd468ebbc1 | 55 | //Set pointer in DS3231 |
j3 | 0:0cbd468ebbc1 | 56 | i2c.write(DS3231_WRITE_ADRS, data, 1); |
j3 | 0:0cbd468ebbc1 | 57 | //Read status register |
j3 | 0:0cbd468ebbc1 | 58 | i2c.read(DS3231_READ_ADRS, (data + 1), 1); |
j3 | 0:0cbd468ebbc1 | 59 | //Save status register in status var |
j3 | 0:0cbd468ebbc1 | 60 | status = data[1]; |
j3 | 0:0cbd468ebbc1 | 61 | //Clear data[1] for clearing flags in DS3231 |
j3 | 0:0cbd468ebbc1 | 62 | data[1] = 0; |
j3 | 0:0cbd468ebbc1 | 63 | i2c.write(DS3231_WRITE_ADRS, data, 2); |
j3 | 0:0cbd468ebbc1 | 64 | |
j3 | 0:0cbd468ebbc1 | 65 | if(status & ALARM_1_BIT) |
j3 | 0:0cbd468ebbc1 | 66 | { |
j3 | 0:0cbd468ebbc1 | 67 | alarm1_flag = true; |
j3 | 0:0cbd468ebbc1 | 68 | } |
j3 | 0:0cbd468ebbc1 | 69 | |
j3 | 0:0cbd468ebbc1 | 70 | if(status & ALARM_2_BIT) |
j3 | 0:0cbd468ebbc1 | 71 | { |
j3 | 0:0cbd468ebbc1 | 72 | alarm2_flag = true; |
j3 | 0:0cbd468ebbc1 | 73 | } |
j3 | 0:0cbd468ebbc1 | 74 | } |
j3 | 0:0cbd468ebbc1 | 75 | |
j3 | 0:0cbd468ebbc1 | 76 | int main() |
j3 | 0:0cbd468ebbc1 | 77 | { |
j3 | 0:0cbd468ebbc1 | 78 | //DS3231 rtc |
j3 | 0:0cbd468ebbc1 | 79 | Ds3231 rtc(i2c); |
j3 | 0:0cbd468ebbc1 | 80 | |
j3 | 0:0cbd468ebbc1 | 81 | // !!!**** Read DS3231 datasheet, page 12. ****!!! |
j3 | 0:0cbd468ebbc1 | 82 | ds3231_cntl_stat_t rtc_control_status; |
j3 | 0:0cbd468ebbc1 | 83 | //Bit2 - !INT/SQW pin used for Interrupts |
j3 | 0:0cbd468ebbc1 | 84 | //Bit1 - A2IE set to allow for Alarm2 interrupt |
j3 | 0:0cbd468ebbc1 | 85 | //Bit0 - A1IE set to allow for Alarm1 interrupt |
j3 | 0:0cbd468ebbc1 | 86 | rtc_control_status.control = 0x07; |
j3 | 0:0cbd468ebbc1 | 87 | rtc_control_status.status = 0; |
j3 | 0:0cbd468ebbc1 | 88 | |
j3 | 0:0cbd468ebbc1 | 89 | //write control, control/status registers |
j3 | 0:0cbd468ebbc1 | 90 | rtc.set_cntl_stat_reg(rtc_control_status); |
j3 | 0:0cbd468ebbc1 | 91 | |
j3 | 0:0cbd468ebbc1 | 92 | //Set time |
j3 | 0:0cbd468ebbc1 | 93 | ds3231_time_t rtc_time; |
j3 | 0:0cbd468ebbc1 | 94 | rtc_time.seconds = 0; |
j3 | 0:0cbd468ebbc1 | 95 | rtc_time.minutes = 0; |
j3 | 0:0cbd468ebbc1 | 96 | rtc_time.hours = 0; |
j3 | 0:0cbd468ebbc1 | 97 | rtc_time.mode = false; //24Hr mode |
j3 | 0:0cbd468ebbc1 | 98 | |
j3 | 0:0cbd468ebbc1 | 99 | //write timming registers |
j3 | 0:0cbd468ebbc1 | 100 | rtc.set_time(rtc_time); |
j3 | 0:0cbd468ebbc1 | 101 | |
j3 | 0:0cbd468ebbc1 | 102 | //Set date |
j3 | 0:0cbd468ebbc1 | 103 | ds3231_calendar_t rtc_calendar; |
j3 | 0:0cbd468ebbc1 | 104 | rtc_calendar.day = 3; |
j3 | 0:0cbd468ebbc1 | 105 | rtc_calendar.date = 28; |
j3 | 0:0cbd468ebbc1 | 106 | rtc_calendar.month = 2; |
j3 | 0:0cbd468ebbc1 | 107 | rtc_calendar.year = 17; |
j3 | 0:0cbd468ebbc1 | 108 | |
j3 | 0:0cbd468ebbc1 | 109 | //write calendar registers |
j3 | 0:0cbd468ebbc1 | 110 | rtc.set_calendar(rtc_calendar); |
j3 | 0:0cbd468ebbc1 | 111 | |
j3 | 0:0cbd468ebbc1 | 112 | // !!!**** Read DS3231 datasheet, page 12****!!! |
j3 | 0:0cbd468ebbc1 | 113 | // !!!**** Table 2 describes am A#M# bits****!!! |
j3 | 0:0cbd468ebbc1 | 114 | //Alarm configuration vars |
j3 | 0:0cbd468ebbc1 | 115 | ds3231_alrm_t alarm1_config, alarm2_config; |
j3 | 0:0cbd468ebbc1 | 116 | |
j3 | 0:0cbd468ebbc1 | 117 | //Configure Alarm1 to cause interrupt every minute at 30 second mark |
j3 | 0:0cbd468ebbc1 | 118 | alarm1_config.seconds = 30; |
j3 | 0:0cbd468ebbc1 | 119 | alarm1_config.minutes = 0; |
j3 | 0:0cbd468ebbc1 | 120 | alarm1_config.hours = 0; |
j3 | 0:0cbd468ebbc1 | 121 | alarm1_config.day = 1; |
j3 | 0:0cbd468ebbc1 | 122 | alarm1_config.date = 1; |
j3 | 0:0cbd468ebbc1 | 123 | alarm1_config.am4 = true; |
j3 | 0:0cbd468ebbc1 | 124 | alarm1_config.am3 = true; |
j3 | 0:0cbd468ebbc1 | 125 | alarm1_config.am2 = true; |
j3 | 0:0cbd468ebbc1 | 126 | alarm1_config.am1 = false; |
j3 | 0:0cbd468ebbc1 | 127 | alarm1_config.am_pm = false; |
j3 | 0:0cbd468ebbc1 | 128 | alarm1_config.mode = false; |
j3 | 0:0cbd468ebbc1 | 129 | alarm1_config.dy_dt = true; |
j3 | 0:0cbd468ebbc1 | 130 | |
j3 | 0:0cbd468ebbc1 | 131 | //write alarm1 registers |
j3 | 0:0cbd468ebbc1 | 132 | rtc.set_alarm(alarm1_config, true); |
j3 | 0:0cbd468ebbc1 | 133 | |
j3 | 0:0cbd468ebbc1 | 134 | //Configure Alarm2 to cause interrupt every minute |
j3 | 0:0cbd468ebbc1 | 135 | //Seconds and am1 not used for alarm2, |
j3 | 0:0cbd468ebbc1 | 136 | //can only trigger on minutes and longer |
j3 | 0:0cbd468ebbc1 | 137 | alarm2_config = alarm1_config; |
j3 | 0:0cbd468ebbc1 | 138 | |
j3 | 0:0cbd468ebbc1 | 139 | //write alarm2 registers |
j3 | 0:0cbd468ebbc1 | 140 | rtc.set_alarm(alarm2_config, false); |
j3 | 0:0cbd468ebbc1 | 141 | |
j3 | 0:0cbd468ebbc1 | 142 | //Tie D2 falling edge to rtc_isr |
j3 | 0:0cbd468ebbc1 | 143 | rtc_int.fall(&rtc_isr); |
j3 | 0:0cbd468ebbc1 | 144 | |
j3 | 0:0cbd468ebbc1 | 145 | char buffer[32]; |
j3 | 0:0cbd468ebbc1 | 146 | time_t epoch_time; |
j3 | 0:0cbd468ebbc1 | 147 | |
j3 | 0:0cbd468ebbc1 | 148 | while(1) |
j3 | 0:0cbd468ebbc1 | 149 | { |
j3 | 0:0cbd468ebbc1 | 150 | printf(TERM_HOME); |
j3 | 0:0cbd468ebbc1 | 151 | |
j3 | 0:0cbd468ebbc1 | 152 | //new epoch time fx |
j3 | 0:0cbd468ebbc1 | 153 | epoch_time = rtc.get_epoch(); |
j3 | 0:0cbd468ebbc1 | 154 | |
j3 | 0:0cbd468ebbc1 | 155 | printf("\nTime as seconds since January 1, 1970 = %d\n", epoch_time); |
j3 | 0:0cbd468ebbc1 | 156 | |
j3 | 0:0cbd468ebbc1 | 157 | printf("\nTime as a basic string = %s", ctime(&epoch_time)); |
j3 | 0:0cbd468ebbc1 | 158 | |
j3 | 0:0cbd468ebbc1 | 159 | strftime(buffer, 32, "%I:%M %p\n", localtime(&epoch_time)); |
j3 | 0:0cbd468ebbc1 | 160 | printf("\nTime as a custom formatted string = %s\n\n", buffer); |
j3 | 0:0cbd468ebbc1 | 161 | |
j3 | 0:0cbd468ebbc1 | 162 | printf(TERM_CLEAR_FROM_CURSOR); |
j3 | 0:0cbd468ebbc1 | 163 | |
j3 | 0:0cbd468ebbc1 | 164 | if(alarm1_flag) |
j3 | 0:0cbd468ebbc1 | 165 | { |
j3 | 0:0cbd468ebbc1 | 166 | alarm1_flag = false; |
j3 | 0:0cbd468ebbc1 | 167 | printf("\n!!! ALARM 1 Triggered !!!\n"); |
j3 | 0:0cbd468ebbc1 | 168 | wait(5.0); |
j3 | 0:0cbd468ebbc1 | 169 | } |
j3 | 0:0cbd468ebbc1 | 170 | |
j3 | 0:0cbd468ebbc1 | 171 | if(alarm2_flag) |
j3 | 0:0cbd468ebbc1 | 172 | { |
j3 | 0:0cbd468ebbc1 | 173 | alarm2_flag = false; |
j3 | 0:0cbd468ebbc1 | 174 | printf("\n*** ALARM 2 Triggered ***\n"); |
j3 | 0:0cbd468ebbc1 | 175 | wait(5.0); |
j3 | 0:0cbd468ebbc1 | 176 | } |
j3 | 0:0cbd468ebbc1 | 177 | } |
j3 | 0:0cbd468ebbc1 | 178 | } |