This short program illustrates how to use the DS130x_I2C library. My objective is to share the same RTC with Microchip 18F MCU.

Dependencies:   mbed DebugLibrary

main.cpp

Committer:
Yann
Date:
2011-02-11
Revision:
1:995212d326ca
Parent:
0:f30e2135b0db

File content as of revision 1:995212d326ca:

#include <string>
#include <iostream>
#include <iomanip>

#include "DS130x_I2C.h"
#include "EthernetNetIf.h"
#include "NTPClient.h"

/*
 * Declare functions
 */
void AvailableIndicator(); // LED1 flashing for program while program is alive
void TimeUpdate(); // Update time from SNTP server
void RtcClockEvent(); // Event rise on each RTC.SQW/OUT change
char DisplayMenuAndGetChoice(); // Display and get the user choice
// Time functions
void SetTimeFromSNTP();
void ForceTime();
void GetTime();
void GetTimeFieldByFiled();
// Memory functions
void WriteStdStringValue(const unsigned char p_address, const std::string & p_string); // Write a string
void ReadStdStringValue(const unsigned char p_address); // Read a string
void WriteShortValue(const unsigned char p_address, const short p_short, CDS130X_I2C::Mode p_mode); // Write a short value
void ReadShortValue(const unsigned char p_address, CDS130X_I2C::Mode p_mode); // Read a short value
void WriteIntegerValue(const unsigned char p_address, const int p_int, CDS130X_I2C::Mode p_mode); // Write an integer value
void ReadIntegerValue(const unsigned char p_address, CDS130X_I2C::Mode p_mode); // Read an integer value

/*
 * Declare statics
 */
EthernetNetIf g_eth;
Host g_ntpServer(IpAddr(), 123, "ntp.unice.fr");
NTPClient g_ntp;

DigitalOut g_availableLed(LED1); // To verify if program in running
InterruptIn g_rtcClock(p5); // Used to trigger event from RTC.SQW/OUT 
Ticker g_available; // LED1 will flash with a period of 2s
Ticker g_timeUpdate; // Update time from SNTP server

CDS130X_I2C g_myRTC(0xd0, p28, p27, CDS130X_I2C::One_Hz); // Create an instance of the class C24LCXX_I2C, p28: SDA, p29:SDL, Oscillator mode: 1Hz, on 5V I2C bus

int main() {

    // Launch available indicator
    g_available.attach(&AvailableIndicator, 2.0);
    // Initialize the module    
    if (!g_myRTC.Initialize()) {
        error("Module initialization failed");
    }
    // Initialize Ethernet
    std::cout << "Getting IP address..." << "\r" << std::endl;
    g_eth.setup();   
    wait(1); // Needed after Ethernet startup   
    IpAddr ip = g_eth.getIp();
    std::cout << "IP address: " << (int)ip[0] << "." << (int)ip[1] << "." << (int)ip[2] << "." << (int)ip[3] << "\r" << std::endl;
    // Update current time
    g_ntp.setTime(g_ntpServer);
    time_t ctTime = time(NULL);  
    std::cout << "Time is now: " << ctime(&ctTime) << " UTC\r" << std::endl; 
    // Start ticker
    g_timeUpdate.attach(&TimeUpdate, 60.0);
    
    // Start RTC.SQW/OUT trigger
    g_rtcClock.rise(&RtcClockEvent);

    while (true) {
        switch (DisplayMenuAndGetChoice()) {
            case 'a':
                SetTimeFromSNTP();
                break;
            case 'b':
                GetTime();
                break;
            case 'c':
                ForceTime();
                break;
            case 'd':
                GetTimeFieldByFiled();
                break;

            case 'j': {
                    std::string str("Wellcome to Evil...");
                    WriteStdStringValue(0x04, str);
#if defined(__DEBUG)
                    g_myRTC.DumpMemoryArea(0x04, str.length() + 4);
#else // __DEBUG
                    std::cout << "DEBUG mode is not set, nothing to do!\r" << std::endl;
#endif // __DEBUG
                }
                break;
            case 'k':
                ReadStdStringValue(0x04);
                break;
            case 'l':
                WriteShortValue(0x21, (short)0xbeef, CDS130X_I2C::BigEndian);
                break;
            case 'm':
                ReadShortValue(0x21, CDS130X_I2C::BigEndian);
                break;
            case 'n':
                WriteIntegerValue(0x23, (int)0xcafedeca, CDS130X_I2C::BigEndian);
                break;
            case 'o':
                ReadIntegerValue(0x23, CDS130X_I2C::BigEndian);
                break;
            case 'p':
#if defined(__DEBUG)
                std::cout << "Enter the addess to dump: " << std::flush;
                int address;
                scanf("%d", &address);                 
                std::cout << "\r\r" << std::endl;
                g_myRTC.DumpMemoryArea((unsigned char)address, 16);
#else // __DEBUG
                std::cout << "DEBUG mode is not set, nothing to do!\r" << std::endl;
#endif // __DEBUG
                break;
            case 'q':
                g_myRTC.EraseMemoryArea(0x21, 16);
                break;
            default:
                std::cout << "Invalid user choice\r" << std::endl;
                break;
        } // End of 'switch' statement
    } // End of 'while' statement
} // End of program - nerver reached

void AvailableIndicator()
{
    g_availableLed = !g_availableLed;
} // End of AvailableIndicator

void TimeUpdate()
{
    // Update current time
    g_ntp.setTime(g_ntpServer);
} // End of TimeUpdate funtion

void RtcClockEvent() { /* Www Mmm dd hh:mm:ss yyyy */
    struct tm t = g_myRTC.GetTime();
    char buffer[32];
    strftime(buffer, 32, "%a %m %d %H:%M:%S %Y", &t);
    DEBUG("RtcClockEvent: '%s'", buffer)
} // End of RtcClockEvent() funtion

char DisplayMenuAndGetChoice()
{
    char value;
    std::cout << "\r" << std::endl << "\r" << std::endl << "DS13X_I2C v0.2\r" << std::endl;
    std::cout << "\tSet time from SNTP server:\t\ta\r" << std::endl;
    std::cout << "\tRead time from RTC:\t\t\tb\r" << std::endl;
    std::cout << "\tForce time:\t\t\t\tc\r" << std::endl;
    std::cout << "\tRead time field:\t\t\td\r" << std::endl;
    std::cout << "\tSet second:\t\t\t\te\r" << std::endl;
    std::cout << "\tInc hour:\t\t\t\tf\r" << std::endl;
    std::cout << "\tDec hour:\t\t\t\tg\r" << std::endl;
    std::cout << "\tInc month:\t\t\t\th\r" << std::endl;
    std::cout << "\tDec month:\t\t\t\ti\r" << std::endl;
    std::cout << "\tWrite a string at address 0x04:\t\tj\r" << std::endl;
    std::cout << "\tRead a string at address 0x04:\t\tk\r" << std::endl;
    std::cout << "\tWrite a short value at address 0x21:\tl\r" << std::endl;
    std::cout << "\tRead a short value at address 0x21:\tm\r" << std::endl;
    std::cout << "\tWrite an int value at address 0x23:\tn\r" << std::endl;
    std::cout << "\tRead an int value at address 0x23:\to\r" << std::endl;
    std::cout << "\tHexadump from address 0x21:\t\tp\r" << std::endl;
    std::cout << "\tErase from address 0x21:\t\tq\r" << std::endl;
    std::cout << "Enter your choice: " << std::flush;
    value = getchar(); 
    std::cout << "\r" << std::endl;
    return value;
}

void SetTimeFromSNTP() {
    DEBUG_ENTER("SetTimeFromSNTP")

    char buffer[32];
    time_t seconds = time(NULL);
    strftime(buffer, 32, "%a %m %d %H:%M:%S %Y", localtime(&seconds)); /* Www Mmm dd hh:mm:ss yyyy */
    DEBUG("GetTime: Current date is '%s'", buffer)

    std::string str(buffer);
    g_myRTC.SetTime(str);

    DEBUG_LEAVE("SetTimeFromSNTP")
}

void ForceTime() {
    DEBUG_ENTER("ForceTime")

    // Get time frome user
    std::cout << "Enter the new date using the format 'Www Mmm dd hh:mm:ss yyyy': ";
    std::string line;
    std::cin >> line;
    int removeCR;
    if ((removeCR = line.rfind("\r")) != -1) {
        line.erase(removeCR);
    }
    // Set it
    g_myRTC.SetTime(line);

    DEBUG_LEAVE("ForceTime")
}

void GetTime() {
    struct tm t = g_myRTC.GetTime();
    DEBUG("GetTime: %d %d %d %d:%d:%d %d", /* ww mm dd hh:mm:ss yyyy */
          t.tm_wday,
          t.tm_mon,
          t.tm_mday,
          t.tm_hour,
          t.tm_min,
          t.tm_sec,
          t.tm_year);
    char buffer[32];
    strftime(buffer, 32, "%a %m %d %H:%M:%S %Y", &t);
    DEBUG("GetTime: Current date is '%s'", buffer)
}

void GetTimeFieldByFiled() {
    unsigned char value = 0xff;

    // Get seconds in BCD format
    g_myRTC.Read(CDS130X_I2C::SecondsAddress, &value);
    DEBUG("\tSeconds in BCD: 0x%02x", value)
    std::cout << "\tSeconds in BCD: 0x" << std::setw(2) << std::setfill('0') << std::ios::hex << (unsigned char)value << "\r" << std::endl;
    // Get seconds in BCD format
    g_myRTC.Read(CDS130X_I2C::MinutesAddress, &value);
    DEBUG("\tMinutes in BCD: 0x%02x", value)
    std::cout << "\tMinutes in BCD: 0x" << std::setw(2) << std::setfill('0') << std::ios::hex << (unsigned char)value << "\r" << std::endl;
    // Get seconds in BCD format
    g_myRTC.Read(CDS130X_I2C::HoursAddress, &value);
    DEBUG("\tHours in BCD: 0x%02x", value)
    std::cout << "\tHours in BCD: 0x" << std::setw(2) << std::setfill('0') << std::ios::hex << (unsigned char)value << "\r" << std::endl;
    // Get seconds in BCD format
    g_myRTC.Read(CDS130X_I2C::DayAddress, &value);
    DEBUG("\tDay in BCD: 0x%02x", value)
    std::cout << "\tDay in BCD: 0x" << std::setw(2) << std::setfill('0') << std::ios::hex << (unsigned char)value << "\r" << std::endl;
}

void WriteStdStringValue(const unsigned char p_address, const std::string & p_string) {
    std::cout << "Write string '" << p_string << "' at address 0x" << std::setw(2) << std::setfill('0') << std::ios::hex << p_address << "\r" << std::endl;
    g_myRTC.WriteMemory(p_address, p_string);
}

void ReadStdStringValue(const unsigned char p_address) {
    std::string str;
    g_myRTC.ReadMemory(p_address, str);
    std::cout << "String at address 0x" << std::setw(2) << std::setfill('0') << std::ios::hex << p_address << " is: " << str << "\r" << std::endl;
}

void WriteShortValue(const unsigned char p_address, const short p_short, CDS130X_I2C::Mode p_mode) {
    std::cout << "Write short '" << p_short << "' at address 0x" << std::setw(2) << std::setfill('0') << std::ios::hex << p_address << "\r" << std::endl;
    if (p_mode == CDS130X_I2C::BigEndian) {
        g_myRTC.WriteMemory(p_address, p_short);
    } else {
        g_myRTC.WriteMemory(p_address, p_short, p_mode);
    }
}

void ReadShortValue(const unsigned char p_address, CDS130X_I2C::Mode p_mode) {
    short value;
    if (p_mode == CDS130X_I2C::BigEndian) {
        g_myRTC.ReadMemory(p_address, (short *)&value);
    } else {
        g_myRTC.ReadMemory(p_address, (short *)&value, p_mode);
    }
    std::cout << "Short at address 0x" << std::setw(2) << std::setfill('0') << std::ios::hex << p_address << " is: " << std::setw(4) << value << "\r" << std::endl;
}

void WriteIntegerValue(const unsigned char p_address, const int p_int, CDS130X_I2C::Mode p_mode) {
    std::cout << "Write integer '" << p_int << "' at address 0x" << std::setw(2) << std::setfill('0') << std::ios::hex << p_address << "\r" << std::endl;
    g_myRTC.WriteMemory(p_address, p_int, p_mode);
}

void ReadIntegerValue(const unsigned char p_address, CDS130X_I2C::Mode p_mode) {
    int value;
    if (p_mode == CDS130X_I2C::BigEndian) {
        g_myRTC.ReadMemory(p_address, (int *)&value);
    } else {
        g_myRTC.ReadMemory(p_address, (int *)&value, p_mode);
    }
    std::cout << "Integer at address 0x" << std::setw(2) << std::setfill('0') << std::ios::hex << p_address << " is: " << std::setw(8) << value << "\r" << std::endl;
}