Erick / Mbed 2 deprecated ICE-F412

Dependencies:   mbed-rtos mbed

ICE-Application/src/Drivers/rtc.cpp

Committer:
jmarkel44
Date:
2017-01-24
Revision:
0:61364762ee0e

File content as of revision 0:61364762ee0e:

// rtc.c - real time clock (MCP7940N)
// -------------------------------------------------------------------------------------------------

#include "mbed.h"
#include "rtc.h"
#include "global.h"

// -------------------------------------------------------------------------------------------------
// globals

int rtc_verbose = 0;

// -------------------------------------------------------------------------------------------------
// initialization

void rtc_init(void)
{
    if(rtc_verbose)
    {
        printf("\r\n[rtc_init] \r\n\r\n");
    }
    
    char data[2];


    data[0] = RTC_CONTROL_ADDR;

    if(i2c->write(RTC_ADDR, data, RTC_SIZE_ADDR, true )) printf("no ack 1\r\n");
    if(i2c->read (RTC_ADDR, data, RTC_SIZE_CONTROL, false)) printf("no ack 2\r\n");

    if(rtc_verbose)
    {
        for(int i=0; i<RTC_SIZE_CONTROL; i++) { printf("   %d = ", i); printf("%d\r\n", data[i]); };
    }

    unsigned char control_reg = data[0];

    if((control_reg & 0x80) == 1) // !EOSC
    {
        data[0] = RTC_CONTROL_ADDR;
        data[1] = (control_reg & 0x7F); // clear !EOSC

        if(i2c->write(RTC_ADDR, data, (RTC_SIZE_ADDR+RTC_SIZE_DATA), false)) printf("no ack 3\r\n");
        
        if(rtc_verbose) printf("   !EOSC bit reset (0x%x)\r\n\r\n", data[1]);
    }

    if(!rtc_verbose) printf("\r\nRTC: ");
    rtc_print();
}

// -------------------------------------------------------------------------------------------------
// read registers

void rtc_regs(void)
{
    char data[RTC_SIZE_DATA];
    
    if(rtc_verbose)
    {
        printf("\r\n[rtc_regs] \r\n\r\n");
    }

    data[0] = 0x00; // address 0x00

    if(i2c->write(RTC_ADDR, data, RTC_SIZE_ADDR, true )) printf("no ack 1\r\n");
    if(i2c->read (RTC_ADDR, data, RTC_SIZE_DATA, false)) printf("no ack 2\r\n");

    for(int i=0; i<RTC_SIZE_DATA; i++) { printf("   %d = ", i); printf("%d\r\n", data[i]); }
}

// -------------------------------------------------------------------------------------------------
// RTC functions

void rtc_get_time(int* iyr, int* imo, int* idy, int* ihr, int* imn, int* isc)
{
    char data[RTC_SIZE_DATA];
    data[0] = 0x00;

    if(i2c->write(RTC_ADDR, data, RTC_SIZE_ADDR, true )) printf("no ack 1\r\n");
    if(i2c->read (RTC_ADDR, data, RTC_SIZE_DATA, false)) printf("no ack 2\r\n");

    if(rtc_verbose)
    {
        printf("\r\n[rtc_get_time] \r\n\r\n");
        for(int i=0; i<RTC_SIZE_DATA; i++) { printf("   %d = ", i); printf("%d\r\n", data[i]); };
    }

    *isc = 10*( (data[0] & 0x70)>>4 ) + (data[0] & 0x0F); // tens = 0b01110000(0x70), ones = 0b00001111(0x0F)
    *imn = 10*( (data[1] & 0x70)>>4 ) + (data[1] & 0x0F); // tens = 0b01110000(0x70), ones = 0b00001111(0x0F)
    *ihr = 10*( (data[2] & 0x10)>>4 ) + (data[2] & 0x0F); // tens = 0b00110000(0x30), ones = 0b00001111(0x0F)
     // day of week
    *idy = 10*( (data[4] & 0x30)>>4 ) + (data[4] & 0x0F); // tens = 0b00110000(0x30), ones = 0b00001111(0x0F)
    *imo = 10*( (data[5] & 0x10)>>4 ) + (data[5] & 0x0F); // tens = 0b00010000(0x10), ones = 0b00001111(0x0F)
    *iyr = 10*( (data[6] & 0xF0)>>4 ) + (data[6] & 0x0F); // tens = 0b11110000(0xF0), ones = 0b00001111(0x0F)
    
    *iyr += 2000;
}

void rtc_set_time(int iyr, int  imo, int  idy, int  ihr, int  imn, int  isc)
{
    char data[(RTC_SIZE_DATA+RTC_SIZE_ADDR)];
    
    int jyr = iyr; if(jyr >= 2000) jyr -= 2000;

    data[0] = 0x00; // address byte
    data[1] = 0x00; // data byte 0: seconds
    data[2] = 0x00; // data byte 1: minutes
    data[3] = 0x00; // data byte 2: hours
    data[4] = 0x00; // data byte 3: weekday, set to 0x00 ? (usually reads 0x21 with OSCRUN and no PWRFAIL
    data[5] = 0x00; // data byte 4: day
    data[6] = 0x00; // data byte 5: month
    data[7] = 0x00; // data byte 6: year

    data[1] = ((isc/10)<<4) | (isc%10); // seconds
    data[2] = ((imn/10)<<4) | (imn%10); // minutes
    data[3] = ((ihr/10)<<4) | (ihr%10); // hours
    data[5] = ((idy/10)<<4) | (idy%10); // days
    data[6] = ((imo/10)<<4) | (imo%10); // months
    data[7] = ((jyr/10)<<4) | (jyr%10); // years

    if(i2c->write(RTC_ADDR, data, (RTC_SIZE_DATA+RTC_SIZE_ADDR), false)) printf("no ack\r\n");

    if(rtc_verbose)
    {
        printf("\r\n[rtc_set_time] \r\n\r\n");
        printf("   raw data\r\n");
        for(int i=0; i<(RTC_SIZE_DATA+RTC_SIZE_ADDR); i++) { printf("   %d = ", i); printf("%d\r\n", data[i]); };
    }
}

void rtc_set(const char* s)
{
    int iyr, imo, idy, ihr, imn, isc;

    if(sscanf(s, "%d-%d-%d %d:%d:%d", &iyr, &imo, &idy, &ihr, &imn, &isc) != 6)
    {
        printf("   [rtc_set] parse error\r\n");
    }
    else
    {
        if(rtc_verbose) printf("   date: %04d-%02d-%02d %02d:%02d:%02d\r\n", iyr, imo, idy, ihr, imn, isc);

        rtc_set_time(iyr, imo, idy, ihr, imn, isc);

        printf("   [rtc_set] "); rtc_print();
    }
}

void rtc_print(void)
{
    int iyr=0, imo=0, idy=0, ihr=0, imn=0, isc=0;

    rtc_get_time(&iyr, &imo, &idy, &ihr, &imn, &isc);

    printf("%04d-%02d-%02d %02d:%02d:%02d", iyr, imo, idy, ihr, imn, isc);
}

// -------------------------------------------------------------------------------------------------