Subversion Repositories Code-Repo

Rev

Blame | Last modification | View Log | RSS feed

#include "defines.h"
#include "sensor_rtc_DS3231.h"
#include "base_I2C.h"

void DS3231_Begin() {
    char reg[3];
    reg[0] = DS3231_CONTROL;
    
    /* Control Register (0x0E)
     * Bit 7 - !EOSC
     * Bit 6 - BBSQW
     * Bit 5 - CONV
     * Bit 4 - RS2
     * Bit 3 - RS1
     * Bit 2 - INTCN
     * Bit 1 - A2IE
     * Bit 0 - A1IE
     */
    reg[1] = 0x04;

    /* Control Register 2 (0x0F)
     * Bit 3 = EN32kHZ
     */
    reg[2] = 0x00;

    // Set the configuration registers
    I2C_Master_Send(DS3231_ADDRESS, 3, reg);
    char result;
    do {
        result = I2C_Get_Status();
    } while (!result);
}

char DS3231_Get_Status(void) {
    /* Status Register (0x0F)
     * Bit 7 - OSF
     * Bit 3 - EN32kHz
     * Bit 2 - BSY
     * Bit 1 - A2F
     * Bit 0 - A1F
     */
    char value;
    I2C_Master_Restart(DS3231_ADDRESS, 0x0F, 1);
    char result;
    do {
        result = I2C_Get_Status();
    } while (!result);
    I2C_Read_Buffer(&value);
    return value;
}

void DS3231_Set_Time(char sec, char min, char hour, char day, char date,
        char month, char year, char h_mil, char h_am_pm) {

    // Format the data in a way that the chip expects
    char output[8];
    output[0] = DS3231_SECONDS;
    output[1] = ((sec / 10) << 4) | (sec % 10);
    output[2] = ((min / 10) << 4) | (min % 10);
    output[3] = ((hour / 10) << 4) | (hour % 10);
    if (!h_mil) {
        output[3] |= (h_am_pm) ? 0x60 : 0x40;
    }
    output[4] = day;
    output[5] = ((date / 10) << 4) | (date % 10);
    output[6] = ((month / 10) << 4) | (month % 10);
    output[7] = ((year / 10) << 4) | (year % 10);

    // Check the status to make sure that it isnt currently busy
    char status = DS3231_Get_Status();
    while (status & 0x04)
        status = DS3231_Get_Status();

    // Write the data to the chip
    I2C_Master_Send(DS3231_ADDRESS, 8, output);
    char result;
    do {
        result = I2C_Get_Status();
    } while (!result);
}

void DS3231_Get_Time(char *sec, char *min, char *hour, char *day, char *date,
        char *month, char *year, char *h_mil, char *h_am_pm) {

    // Check the status to make sure that it isnt currently busy
    char status = DS3231_Get_Status();
    while (status & 0x04)
        status = DS3231_Get_Status();

    // Request time data from the chip
    char input[7];
    I2C_Master_Restart(DS3231_ADDRESS, 0x00, 7);
    char result;
    do {
        result = I2C_Get_Status();
    } while (!result);
    I2C_Read_Buffer(input);

    // Parse BCD format into decimal and return
    *sec = ((input[0] >> 4) * 10) + (input[0] & 0x0F);
    *min = ((input[1] >> 4) * 10) + (input[1] & 0x0F);
    if (input[2] & 0x40) {
        *h_mil = 0;
        *h_am_pm = (input[2] & 0x20) ? 1 : 0;
        *hour = (((input[2] >> 4) & 0x01) * 10) + (input[2] & 0x0F);
    } else {
        *h_mil = 1;
        *hour = ((input[2] >> 4) * 10) + (input[2] & 0x0F);
    }
    *day = input[3];
    *date = ((input[4] >> 4) * 10) + (input[4] & 0x0F);
    *month = ((input[5] >> 4) * 10) + (input[5] & 0x0F);
    *year = ((input[6] >> 4) * 10) + (input[6] & 0x0F);
}