Yoshiyuki Uehara / Mbed 2 deprecated Maple

Dependencies:   mbed

Maple_alarm_clock.cpp

Committer:
uehara00
Date:
2011-10-30
Revision:
3:eec13a411e94
Parent:
2:299a1c9a5795

File content as of revision 3:eec13a411e94:

//copyright 2011 Uehara Yoshiyuki
//====================================================================
//The author provide the programs without any guarantees or warranty.
//The author is not responsible for any damage or losses of any kind 
//caused by using or misusing of the programs.
//The author is under no obligation to provide support, service, 
//corrections, or upgrades to the programs.
//====================================================================
// MAPLE board[MARM01-BASE]
// alarm clock
#include "Maple_console.h"
#include "Maple_alarm_clock.h"
#include "Maple_RTC.h"
#include "Maple_I2C.h"
#include "Maple.h"
#include "mbed.h"

// global variables defined in console.cpp
extern int console_mode;
extern int console_cursor;

// make display data of RTC clock for console
void display_clock(char row0[], char row1[], int &cursor_r, int &cursor_c) {
    const int position_r[CURSOR_CLOCK_SIZE] = {  1,  1};
    const int position_c[CURSOR_CLOCK_SIZE] = { 12, 15};
    char d[17], s[4];

    i2c_RTC_read(RTC_REG_CONTROL1, d, 16);
    copy_string(row0, 0, 17, "XXXX.XX.XX XXX  ");
    copy_string(row1, 0, 17, "XX:XX:XX XXXXXXX");
    if((d[RTC_REG_SECOND] & RTC_VOLTAGE_LOW) == 0) {    // when RTC registers are valid: 
        copy_string(row0, 0, 2, "20");
        if((d[RTC_REG_MONTH_CENTURY   ] & RTC_CENTURY               ) != 0) { row0[ 1] = '1'; }
        copy_string(row0,  2, 2, int_to_hex2(d[RTC_REG_YEAR         ]       , s));
        copy_string(row0,  5, 2, int_to_hex2(d[RTC_REG_MONTH_CENTURY] & 0x1f, s));
        copy_string(row0,  8, 2, int_to_hex2(d[RTC_REG_DAY          ] & 0x3f, s));
        copy_string(row0, 11, 3, weekday_to_string(d[RTC_REG_WEEKDAY] & 0x07, s));
        copy_string(row1,  0, 2, int_to_hex2(d[RTC_REG_HOUR         ] & 0x3f, s));
        copy_string(row1,  3, 2, int_to_hex2(d[RTC_REG_MINUTE       ] & 0x7f, s));
        copy_string(row1,  6, 2, int_to_hex2(d[RTC_REG_SECOND       ] & 0x7f, s));
        copy_string(row1,  9, 7, "-------");
        if((d[RTC_REG_CONTROL2        ] & RTC_TIMER_PERIODIC        ) != 0) { row1[ 9] = 'p'; }
        if((d[RTC_REG_TIMER_CONTROL   ] & RTC_TIMER_ENABLE          ) != 0) { row1[10] = 't'; }
        if((d[RTC_REG_CONTROL2        ] & RTC_TIMER_INTERRUPT_ENABLE) != 0) { row1[11] = 'i'; }
        if((d[RTC_REG_CONTROL2        ] & RTC_TIMER_FLAG            ) != 0) { row1[12] = 'T'; }
        if((d[RTC_REG_ALARM_MINUTE    ] & RTC_ALARM_DISABLE         ) == 0) { row1[13] = 'a'; }
        if((d[RTC_REG_ALARM_HOUR      ] & RTC_ALARM_DISABLE         ) == 0) { row1[13] = 'a'; }
        if((d[RTC_REG_ALARM_DAY       ] & RTC_ALARM_DISABLE         ) == 0) { row1[13] = 'a'; }
        if((d[RTC_REG_ALARM_WEEKDAY   ] & RTC_ALARM_DISABLE         ) == 0) { row1[13] = 'a'; }
        if((d[RTC_REG_CONTROL2        ] & RTC_ALARM_INTERRUPT_ENABLE) != 0) { row1[14] = 'i'; }
        if((d[RTC_REG_CONTROL2        ] & RTC_ALARM_FLAG            ) != 0) { row1[15] = 'A'; }
    }
    cursor_r = position_r[console_cursor];
    cursor_c = position_c[console_cursor];
}

// make display data of RTC adjust for console
void display_adjust(char row0[], char row1[], int &cursor_r, int &cursor_c) {
    const int position_r[CURSOR_ADJUST_SIZE] = {  0,  0,  0,  0,  1,  1,  1};
    const int position_c[CURSOR_ADJUST_SIZE] = {  1,  3,  6,  9,  1,  4,  7};
    char d[17], s[4];

    i2c_RTC_read(RTC_REG_CONTROL1, d, 16);
    copy_string(row0, 0, 17, "XXXX.XX.XX XXX  ");
    copy_string(row1, 0, 17, "XX:XX:XX  adjust");
    if((d[RTC_REG_SECOND] & RTC_VOLTAGE_LOW) == 0) {    // when RTC registers are valid: 
        copy_string(row0, 0, 2, "20");
        if((d[RTC_REG_MONTH_CENTURY   ] & RTC_CENTURY               ) != 0) { row0[ 1] = '1'; }
        copy_string(row0,  2, 2, int_to_hex2(d[RTC_REG_YEAR         ]       , s));
        copy_string(row0,  5, 2, int_to_hex2(d[RTC_REG_MONTH_CENTURY] & 0x1f, s));
        copy_string(row0,  8, 2, int_to_hex2(d[RTC_REG_DAY          ] & 0x3f, s));
        copy_string(row0, 11, 3, weekday_to_string(d[RTC_REG_WEEKDAY] & 0x07, s));
        copy_string(row1,  0, 2, int_to_hex2(d[RTC_REG_HOUR         ] & 0x3f, s));
        copy_string(row1,  3, 2, int_to_hex2(d[RTC_REG_MINUTE       ] & 0x7f, s));
        copy_string(row1,  6, 2, int_to_hex2(d[RTC_REG_SECOND       ] & 0x7f, s));
    }
    cursor_r = position_r[console_cursor];
    cursor_c = position_c[console_cursor];
}

// make display data of RTC alarm for console
void display_alarm(char row0[], char row1[], int &cursor_r, int &cursor_c) {
    const int position_r[CURSOR_ALARM_SIZE] = {  0,  0,  0,  0,  0,  0,  1,  1,  1,  1};
    const int position_c[CURSOR_ALARM_SIZE] = {  4,  6,  8, 11, 14, 15,  0,  2,  4,  6};
    char d[17], s[4];

    i2c_RTC_read(RTC_REG_CONTROL1, d, 16);
    copy_string(row0, 0, 17, "day:XXX XXXX XXX");
    copy_string(row1, 0, 17, "XXX:XXX    alarm");
    if((d[RTC_REG_SECOND] & RTC_VOLTAGE_LOW) == 0) {    // when RTC registers are valid: 
        row0[ 4] = '-';
        row0[ 8] = '-';
        copy_string(row0, 13, 3, "---");
        row1[ 0] = '-';
        row1[ 4] = '-';
        copy_string(row0, 5, 2, int_to_hex2(d[RTC_REG_ALARM_DAY          ] & 0x3f, s));
        copy_string(row0, 9, 3, weekday_to_string(d[RTC_REG_ALARM_WEEKDAY] & 0x07, s));
        copy_string(row1, 1, 2, int_to_hex2(d[RTC_REG_ALARM_HOUR         ] & 0x3f, s));
        copy_string(row1, 5, 2, int_to_hex2(d[RTC_REG_ALARM_MINUTE       ] & 0x7f, s));
        if((d[RTC_REG_ALARM_DAY    ] & RTC_ALARM_DISABLE         ) == 0) { row0[13] = 'a';  row0[ 4] = '*'; }
        if((d[RTC_REG_ALARM_WEEKDAY] & RTC_ALARM_DISABLE         ) == 0) { row0[13] = 'a';  row0[ 8] = '*'; }
        if((d[RTC_REG_ALARM_HOUR   ] & RTC_ALARM_DISABLE         ) == 0) { row0[13] = 'a';  row1[ 0] = '*'; }
        if((d[RTC_REG_ALARM_MINUTE ] & RTC_ALARM_DISABLE         ) == 0) { row0[13] = 'a';  row1[ 4] = '*'; }
        if((d[RTC_REG_CONTROL2     ] & RTC_ALARM_INTERRUPT_ENABLE) != 0) { row0[14] = 'i'; }
        if((d[RTC_REG_CONTROL2     ] & RTC_ALARM_FLAG            ) != 0) { row0[15] = 'A'; }
    }
    cursor_r = position_r[console_cursor];
    cursor_c = position_c[console_cursor];
}

// make display data of RTC timer for console
void display_timer(char row0[], char row1[], int &cursor_r, int &cursor_c) {
    const int position_r[CURSOR_TIMER_SIZE] = {  0,  0,  0,  0,  0,  0,  0,  1};
    const int position_c[CURSOR_TIMER_SIZE] = {  3,  8, 11, 12, 13, 14, 15,  6};
    const char select_f[4][6] = { "32768", " 1024", "   32", "    1" };
    const char select_t[4][5] = { "4096", "  64", "   1", "1/60" };
    char d[17], s[3];

    i2c_RTC_read(RTC_REG_CONTROL1, d, 16);
    copy_string(row0, 0, 17, "XXXXHz XX  XXXXX");
    copy_string(row1, 0, 17, "f=XXXXXHz  timer");
    if((d[RTC_REG_SECOND] & RTC_VOLTAGE_LOW) == 0) {    // when RTC registers are valid: 
        copy_string(row0,  0, 4, select_t[d[RTC_REG_TIMER_CONTROL] & 0x03]);
        copy_string(row0,  7, 2, int_to_hex2(d[RTC_REG_TIMER], s));
        copy_string(row1,  2, 5, select_f[d[RTC_REG_CLKOUT_FREQUENCY] & 0x03]);
        copy_string(row0, 11, 5, "-----");
        if((d[RTC_REG_CLKOUT_FREQUENCY] & RTC_CLKOUT_ENABLE         ) != 0) { row0[11] = 'f'; }
        if((d[RTC_REG_CONTROL2        ] & RTC_TIMER_PERIODIC        ) != 0) { row0[12] = 'p'; }
        if((d[RTC_REG_TIMER_CONTROL   ] & RTC_TIMER_ENABLE          ) != 0) { row0[13] = 't'; }
        if((d[RTC_REG_CONTROL2        ] & RTC_TIMER_INTERRUPT_ENABLE) != 0) { row0[14] = 'i'; }
        if((d[RTC_REG_CONTROL2        ] & RTC_TIMER_FLAG            ) != 0) { row0[15] = 'T'; }
    }
    cursor_r = position_r[console_cursor];
    cursor_c = position_c[console_cursor];
}

// enter mode clock
void enter_mode_clock() {
    console_mode = MODE_CLOCK;
    console_cursor = CURSOR_CLOCK_INIT;
}

// enter mode adjust
void enter_mode_adjust() {
    console_mode = MODE_ADJUST;
    console_cursor = CURSOR_ADJUST_INIT;
}

// enter mode alarm
void enter_mode_alarm() {
    console_mode = MODE_ALARM;
    console_cursor = CURSOR_ALARM_INIT;
}

// enter mode timer
void enter_mode_timer() {
    console_mode = MODE_TIMER;
    console_cursor = CURSOR_TIMER_INIT;
}

// move cursor of clock
//   flag  0:left, 1:right
void cursor_move_clock(int flag) {
    cursor_move(flag, CURSOR_CLOCK_SIZE);
}

// move cursor of adjust
//   flag  0:left, 1:right
void cursor_move_adjust(int flag) {
    cursor_move(flag, CURSOR_ADJUST_SIZE);
}

// move cursor of alarm
//   flag  0:left, 1:right
void cursor_move_alarm(int flag) {
    cursor_move(flag, CURSOR_ALARM_SIZE);
}

// move cursor of timer
//   flag  0:left, 1:right
void cursor_move_timer(int flag) {
    cursor_move(flag, CURSOR_TIMER_SIZE);
}

// increment/decrement of clock
//   flag  0:decrement, 1:increment
void button_xxcrement_clock(int flag) {
    char d;

    d = RTC_read1(RTC_REG_CONTROL2);
    switch(console_cursor) {
    case CURSOR_CLOCK_TIMER_FLAG:
        d = d & 0x1b | (flag == 0 ? 0x00 : 0x04);
        break;
    case CURSOR_CLOCK_ALARM_FLAG:
        d = d & 0x17 | (flag == 0 ? 0x00 : 0x08);
        break;
    }
    RTC_write1(RTC_REG_CONTROL2, d);
}

// increment/decrement of adjust
//   flag  0:decrement, 1:increment
void button_xxcrement_adjust(int flag) {
    char d;

    switch(console_cursor) {
    case CURSOR_ADJUST_HOUR:
        d = RTC_stop_read1(RTC_REG_HOUR) & 0x3F;
        d = xxcrement_bcd(flag, d, 0x00, 0x23);
        RTC_write1_start(RTC_REG_HOUR, d);
        break;
    case CURSOR_ADJUST_MINUTE:
        d = RTC_stop_read1(RTC_REG_MINUTE) & 0x7F;
        d = xxcrement_bcd(flag, d, 0x00, 0x59);
        RTC_write1_start(RTC_REG_MINUTE, d);
        break;
    case CURSOR_ADJUST_SECOND:
        d = RTC_stop_read1(RTC_REG_SECOND) & 0x7f;
        d = (flag == 0 ? 0x30 : 0x00);
        RTC_write1_start(RTC_REG_SECOND, d);
        break;
    default:
        button_xxcrement_adjust_date(flag);
    }
}

// increment/decrement century, year, month, day
//   flag  0:decrement, 1:increment
static void button_xxcrement_adjust_date(int flag) {
    char century, bcd_year, bcd_month, bcd_day, weekday, d;

    RTC_stop_read_date(century, bcd_year, bcd_month, bcd_day);
    switch(console_cursor) {
    case CURSOR_ADJUST_CENTURY:
        century = xxcrement_bcd(flag, century, 0x00, 0x01);
        break;    
    case CURSOR_ADJUST_YEAR:
        bcd_year = xxcrement_bcd(flag, bcd_year, 0x00, 0x99);
        break;
    case CURSOR_ADJUST_MONTH:
        bcd_month = xxcrement_bcd(flag, bcd_month, 0x01, 0x12);
        break;
    case CURSOR_ADJUST_DAY:
        bcd_day = xxcrement_bcd(flag, bcd_day, 0x01, bcd_days_in_month(century, bcd_year, bcd_month));
        break;
    }
    d = bcd_days_in_month(century, bcd_year, bcd_month);
    if(bcd_day > d) {
        bcd_day = d;
    }
    weekday = bcd_date_to_weekday(century, bcd_year, bcd_month, bcd_day);
    RTC_write_date_start(century, bcd_year, bcd_month, bcd_day, weekday);
}

// increment/decrement of alarm
//   flag  0:decrement, 1:increment
void button_xxcrement_alarm(int flag) {
    char d;

    switch(console_cursor) {
    case CURSOR_ALARM_DAY_DISABLE:
        d = RTC_read1(RTC_REG_ALARM_DAY) & 0x3f | (flag == 0 ? 0x80 : 0x00);
        RTC_write1(RTC_REG_ALARM_DAY, d);
        break;
    case CURSOR_ALARM_DAY:
        d = RTC_read1(RTC_REG_ALARM_DAY);
        d = xxcrement_bcd(flag, d & 0x3f, 0x00, 0x31) | d & 0x80;
        RTC_write1(RTC_REG_ALARM_DAY, d);
        break;
    case CURSOR_ALARM_WEEKDAY_DISABLE:
        d = RTC_read1(RTC_REG_ALARM_WEEKDAY) & 0x07 | (flag == 0 ? 0x80 : 0x00);
        RTC_write1(RTC_REG_ALARM_WEEKDAY, d);
        break;
    case CURSOR_ALARM_WEEKDAY:
        d = RTC_read1(RTC_REG_ALARM_WEEKDAY);
        d = xxcrement_bcd(flag, d & 0x07, 0x00, 0x06) | d & 0x80;
        RTC_write1(RTC_REG_ALARM_WEEKDAY, d);
        break;
    case CURSOR_ALARM_INTERRUPT:
        d = RTC_read1(RTC_REG_CONTROL2) & 0x1d | (flag == 0 ? 0x00 : 0x02);
        RTC_write1(RTC_REG_CONTROL2, d);
        break;
    case CURSOR_ALARM_FLAG:
        d = RTC_read1(RTC_REG_CONTROL2) & 0x17 | (flag == 0 ? 0x00 : 0x08);
        RTC_write1(RTC_REG_CONTROL2, d);
        break;
    case CURSOR_ALARM_HOUR_DISABLE:
        d = RTC_read1(RTC_REG_ALARM_HOUR) & 0x3f | (flag == 0 ? 0x80 : 0x00);
        RTC_write1(RTC_REG_ALARM_HOUR, d);
        break;
    case CURSOR_ALARM_HOUR:
        d = RTC_read1(RTC_REG_ALARM_HOUR);
        d = xxcrement_bcd(flag, d & 0x3f, 0x00, 0x23) | d & 0x80;
        RTC_write1(RTC_REG_ALARM_HOUR, d);
        break;
    case CURSOR_ALARM_MINUTE_DISABLE:
        d = RTC_read1(RTC_REG_ALARM_MINUTE) & 0x7f | (flag == 0 ? 0x80 : 0x00);
        RTC_write1(RTC_REG_ALARM_MINUTE, d);
        break;
    case CURSOR_ALARM_MINUTE:
        d = RTC_read1(RTC_REG_ALARM_MINUTE);
        d = xxcrement_bcd(flag, d & 0x7f, 0x00, 0x59) | d & 0x80;
        RTC_write1(RTC_REG_ALARM_MINUTE, d);
        break;
    }
}

// increment/decrement of timer
//   flag  0:decrement, 1:increment
void button_xxcrement_timer(int flag) {
    char d;

    switch(console_cursor) {
    case CURSOR_TIMER_SELECT:
        d = RTC_read1(RTC_REG_TIMER_CONTROL);
        d = xxcrement_bcd(flag, d & 0x03, 0x00, 0x03) | d & 0x80;
        RTC_write1(RTC_REG_TIMER_CONTROL, d);
        break;
    case CURSOR_TIMER_COUNT:
        d = RTC_read1(RTC_REG_TIMER);
        switch(flag) {
        case 0:  --d; break;
        default: ++d;
        }
        RTC_write1(RTC_REG_TIMER, d);
        break;
    case CURSOR_CLKOUT_ENABLE:
        d = RTC_read1(RTC_REG_CLKOUT_FREQUENCY) & 0x03 | (flag == 0 ? 0x00 : 0x80);
        RTC_write1(RTC_REG_CLKOUT_FREQUENCY, d);
        break;
    case CURSOR_TIMER_PERIODIC:
        d = RTC_read1(RTC_REG_CONTROL2) & 0x0f | (flag == 0 ? 0x00 : 0x10);
        RTC_write1(RTC_REG_CONTROL2, d);
        break;
    case CURSOR_TIMER_ENABLE:
        d = RTC_read1(RTC_REG_TIMER_CONTROL) & 0x03 | (flag == 0 ? 0x00 : 0x80);
        RTC_write1(RTC_REG_TIMER_CONTROL, d);
        break;
    case CURSOR_TIMER_INTERRUPT:
        d = RTC_read1(RTC_REG_CONTROL2) & 0x1e | (flag == 0 ? 0x00 : 0x01);
        RTC_write1(RTC_REG_CONTROL2, d);
        break;
    case CURSOR_TIMER_FLAG:
        d = RTC_read1(RTC_REG_CONTROL2) & 0x1b | (flag == 0 ? 0x00 : 0x04);
        RTC_write1(RTC_REG_CONTROL2, d);
        break;
    case CURSOR_CLKOUT_FREQUENCY:
        d = RTC_read1(RTC_REG_CLKOUT_FREQUENCY);
        d = xxcrement_bcd(flag, d & 0x03, 0x00, 0x03) | d & 0x80;
        RTC_write1(RTC_REG_CLKOUT_FREQUENCY, d);
        break;
    }
}