Simple demo showing use of DS3231 Alarms

Dependencies:   ds3231 mbed

main.cpp

Committer:
j3
Date:
2017-02-28
Revision:
0:0cbd468ebbc1

File content as of revision 0:0cbd468ebbc1:

/******************************************************************************
* MIT License
*
* Copyright (c) 2017 Justin J. Jordan
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:

* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
******************************************************************************/


#include "mbed.h"
#include "ds3231.h"

#define TERM_HOME ("\033[H")
#define TERM_CLEAR_FROM_CURSOR ("\033[0J")
#define TERM_CLEAR_EOL ("\033[K")

#define DS3231_WRITE_ADRS (0x68 << 1)
#define DS3231_READ_ADRS ((0x68 << 1) | 1)
#define ALARM_1_BIT (1)
#define ALARM_2_BIT (2)
#define STATUS_REG_ADRS (0x0F)

//I2C Bus
I2C i2c(D14, D15);

//DS3231 INT pin connected to D2 with pull-up
InterruptIn rtc_int(D2);

//Flags for loop
volatile bool alarm1_flag = false;
volatile bool alarm2_flag = false;

void rtc_isr()
{
    char data[2];
    uint8_t status;
    data[0] = STATUS_REG_ADRS;
    
    //Set pointer in DS3231
    i2c.write(DS3231_WRITE_ADRS, data, 1);
    //Read status register
    i2c.read(DS3231_READ_ADRS, (data + 1), 1);
    //Save status register in status var
    status = data[1];
    //Clear data[1] for clearing flags in DS3231
    data[1] = 0;
    i2c.write(DS3231_WRITE_ADRS, data, 2);
    
    if(status & ALARM_1_BIT)
    {
        alarm1_flag = true;
    }
    
    if(status & ALARM_2_BIT)
    {
        alarm2_flag = true;
    }
}

int main()
{
    //DS3231 rtc
    Ds3231 rtc(i2c);
    
    // !!!**** Read DS3231 datasheet, page 12. ****!!!
    ds3231_cntl_stat_t rtc_control_status;
    //Bit2 - !INT/SQW pin used for Interrupts
    //Bit1 - A2IE set to allow for Alarm2 interrupt
    //Bit0 - A1IE set to allow for Alarm1 interrupt
    rtc_control_status.control =  0x07;
    rtc_control_status.status = 0;
    
    //write control, control/status registers
    rtc.set_cntl_stat_reg(rtc_control_status);
    
    //Set time
    ds3231_time_t rtc_time;
    rtc_time.seconds = 0;
    rtc_time.minutes = 0;
    rtc_time.hours = 0;
    rtc_time.mode = false; //24Hr mode
    
    //write timming registers
    rtc.set_time(rtc_time);
    
    //Set date
    ds3231_calendar_t rtc_calendar;
    rtc_calendar.day = 3;
    rtc_calendar.date = 28;
    rtc_calendar.month = 2;
    rtc_calendar.year = 17;
    
    //write calendar registers
    rtc.set_calendar(rtc_calendar);
    
    // !!!**** Read DS3231 datasheet, page 12****!!!
    // !!!**** Table 2 describes am A#M# bits****!!!
    //Alarm configuration vars
    ds3231_alrm_t alarm1_config, alarm2_config;
    
    //Configure Alarm1 to cause interrupt every minute at 30 second mark
    alarm1_config.seconds = 30;
    alarm1_config.minutes = 0;
    alarm1_config.hours = 0;
    alarm1_config.day = 1;
    alarm1_config.date = 1;
    alarm1_config.am4 = true;
    alarm1_config.am3 = true;
    alarm1_config.am2 = true;
    alarm1_config.am1 = false;
    alarm1_config.am_pm = false;
    alarm1_config.mode = false;
    alarm1_config.dy_dt = true;
    
    //write alarm1 registers
    rtc.set_alarm(alarm1_config, true);
    
    //Configure Alarm2 to cause interrupt every minute
    //Seconds and am1 not used for alarm2, 
    //can only trigger on minutes and longer
    alarm2_config = alarm1_config;
    
    //write alarm2 registers
    rtc.set_alarm(alarm2_config, false);
    
    //Tie D2 falling edge to rtc_isr
    rtc_int.fall(&rtc_isr);
    
    char buffer[32];
    time_t epoch_time;
    
    while(1)
    {
        printf(TERM_HOME);
        
        //new epoch time fx
        epoch_time = rtc.get_epoch();
        
        printf("\nTime as seconds since January 1, 1970 = %d\n", epoch_time);
        
        printf("\nTime as a basic string = %s", ctime(&epoch_time));
 
        strftime(buffer, 32, "%I:%M %p\n", localtime(&epoch_time));
        printf("\nTime as a custom formatted string = %s\n\n", buffer);
        
        printf(TERM_CLEAR_FROM_CURSOR);
        
        if(alarm1_flag)
        {
            alarm1_flag = false;
            printf("\n!!! ALARM 1 Triggered !!!\n");
            wait(5.0);
        }
        
        if(alarm2_flag)
        {
            alarm2_flag = false;
            printf("\n*** ALARM 2 Triggered ***\n");
            wait(5.0);
        }
    }
}