Yoshiyuki Uehara / Mbed 2 deprecated Maple

Dependencies:   mbed

Maple_alarm_clock.cpp

Committer:
uehara00
Date:
2011-09-25
Revision:
0:0be38b583cf7
Child:
1:aefa1992ce0f

File content as of revision 0:0be38b583cf7:

// MAPLE board[MARM01-BASE]
// sample application - clock
//
#include "Maple_alarm_clock.h"
#include "Maple_RTC.h"
#include "Maple_I2C.h"
#include "Maple_LCD.h"
#include "Maple.h"
#include "mbed.h"

// timer interrupt to refresh display
Ticker alarm_clock_refresh_tick;

// global variables
int BTN_count[6];
int BTN_status[6];
int display_mode ;
int cursor_position;
const int cursor_position_date_time_max = 6;

// alarm_clock_initialize
void alarm_clock_initialize() {
    alarm_clock_refresh_tick.attach(&alarm_clock_refresh, ALARM_CLOCK_REFRESH_RATE);
}

// refresh display, called by a ticker
void alarm_clock_refresh() {
    char format_date[15];   // "yyyy.mm.dd www"
    char format_time[9];    // "hh:mm:ss"
    const int cursor_date_time_row[7]    = {0, 0, 0, 0, 1, 1, 1};
    const int cursor_date_time_column[7] = {1, 3, 6, 9, 1, 4, 7};

    if(display_mode == DISPLAY_MODE_DATE_TIME) {
        LCD_cursor(LCD_CURSOR_OFF);
        LCD_locate(1, 10);  LCD_print_string("      ");

        RTC_read_format(format_date, format_time);
        LCD_locate(0,  0);  LCD_print_string(format_date);
        LCD_locate(1,  0);  LCD_print_string(format_time);
    }
    
    if(display_mode == DISPLAY_MODE_DATE_TIME_ADJUST) {
        LCD_cursor(LCD_CURSOR_OFF);
        LCD_locate(1, 10);  LCD_print_string("adjust");

        RTC_read_format(format_date, format_time);
        LCD_locate(0,  0);  LCD_print_string(format_date);
        LCD_locate(1,  0);  LCD_print_string(format_time);

        LCD_locate(cursor_date_time_row[cursor_position], cursor_date_time_column[cursor_position]);
        LCD_cursor(LCD_CURSOR_ON);
    }

    BTN_check(BTN_count, BTN_status);
}

// read BTN and update BTN_on_count[i]
//   called by timer tick interrupt
static void BTN_check(int count[], int status[]) {
    char b;

    b = i2c_BTN_read();
    if((b & BTN_MASK_A    ) == BTN_ON) { ++count[BTN_A    ]; } else { count[BTN_A    ] = 0; status[BTN_A    ] = BTN_IDLE; }
    if((b & BTN_MASK_B    ) == BTN_ON) { ++count[BTN_B    ]; } else { count[BTN_B    ] = 0; status[BTN_B    ] = BTN_IDLE; }
    if((b & BTN_MASK_LEFT ) == BTN_ON) { ++count[BTN_LEFT ]; } else { count[BTN_LEFT ] = 0; status[BTN_LEFT ] = BTN_IDLE; }
    if((b & BTN_MASK_DOWN ) == BTN_ON) { ++count[BTN_DOWN ]; } else { count[BTN_DOWN ] = 0; status[BTN_DOWN ] = BTN_IDLE; }
    if((b & BTN_MASK_RIGHT) == BTN_ON) { ++count[BTN_RIGHT]; } else { count[BTN_RIGHT] = 0; status[BTN_RIGHT] = BTN_IDLE; }
    if((b & BTN_MASK_UP   ) == BTN_ON) { ++count[BTN_UP   ]; } else { count[BTN_UP   ] = 0; status[BTN_UP   ] = BTN_IDLE; }

    if((status[BTN_A] == BTN_IDLE) && (count[BTN_A] > BTN_THRESHOLD)) {
        status[BTN_A] = BTN_BUSY;
        BTN_A_action();     // one shot
    }

    if((status[BTN_B] == BTN_IDLE) && (count[BTN_B] > BTN_THRESHOLD)) {
        status[BTN_B] = BTN_BUSY;
        BTN_B_action();     // one shot
    }

    if((status[BTN_LEFT] == BTN_IDLE) && (count[BTN_LEFT] > BTN_THRESHOLD)) {
        status[BTN_LEFT] = BTN_BUSY;
        BTN_LEFT_action();  // one shot
    }
    else if((count[BTN_LEFT] > BTN_REPEAT) && (count[BTN_LEFT] % BTN_REPEAT_PERIOD == 0)) {
        BTN_LEFT_action();  // auto repeat
    }

    if((status[BTN_DOWN] == BTN_IDLE) && (count[BTN_DOWN] > BTN_THRESHOLD)) {
        status[BTN_DOWN] = BTN_BUSY;
        BTN_DOWN_action();  // one shot
    }
    else if((count[BTN_DOWN] > BTN_REPEAT_FAST) && (count[BTN_DOWN] % BTN_REPEAT_PERIOD_FAST == 0)) {
        BTN_DOWN_action();  // auto repeat fast
    }
    else if((count[BTN_DOWN] > BTN_REPEAT) && (count[BTN_DOWN] % BTN_REPEAT_PERIOD == 0)) {
        BTN_DOWN_action();  // auto repeat
    }

    if((status[BTN_RIGHT] == BTN_IDLE) && (count[BTN_RIGHT] > BTN_THRESHOLD)) {
        status[BTN_RIGHT] = BTN_BUSY;
        BTN_RIGHT_action(); // one shot
    }
    else if((count[BTN_RIGHT] > BTN_REPEAT) && (count[BTN_RIGHT] % BTN_REPEAT_PERIOD == 0)) {
        BTN_RIGHT_action(); // auto repeat
    }

    if((status[BTN_UP] == BTN_IDLE) && (count[BTN_UP] > BTN_THRESHOLD)) {
        status[BTN_UP] = BTN_BUSY;
        BTN_UP_action();    // one shot
    }
    else if((count[BTN_UP] > BTN_REPEAT_FAST) && (count[BTN_UP] % BTN_REPEAT_PERIOD_FAST == 0)) {
        BTN_UP_action();    // auto repeat fast
    }
    else if((count[BTN_UP] > BTN_REPEAT) && (count[BTN_UP] % BTN_REPEAT_PERIOD == 0)) {
        BTN_UP_action();    // auto repeat
    }
}

// BTN_A: enter function mode
static void BTN_A_action() {
    if(display_mode == DISPLAY_MODE_DATE_TIME) {
        display_mode = DISPLAY_MODE_DATE_TIME_ADJUST;
        cursor_position = CURSOR_DATE_TIME_SECOND;
    }
}

// BTN_A: exit to date-time mode
static void BTN_B_action() {
    display_mode = DISPLAY_MODE_DATE_TIME;
}

// BTN_RIGHT: move cursor backward
static void BTN_LEFT_action() {
    if(display_mode == DISPLAY_MODE_DATE_TIME_ADJUST) {
        if(cursor_position > 0) {
            --cursor_position;
        }
        else {
            cursor_position = cursor_position_date_time_max;
        }
    }
}

// decrement date/time
static void BTN_DOWN_action() {
    char century, bcd_year, bcd_month, bcd_day, weekday, d, t;

    if(display_mode == DISPLAY_MODE_DATE_TIME_ADJUST) {

        switch(cursor_position) {

        case CURSOR_DATE_TIME_CENTURY:
            RTC_stop_and_read_date(century, bcd_year, bcd_month, bcd_day);
            century = decrement_bcd(century, 0x00, 0x01);
            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_and_start(century, bcd_year, bcd_month, bcd_day, weekday);
            break;

        case CURSOR_DATE_TIME_YEAR:
            RTC_stop_and_read_date(century, bcd_year, bcd_month, bcd_day);
            bcd_year = decrement_bcd(bcd_year, 0x00, 0x99);
            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_and_start(century, bcd_year, bcd_month, bcd_day, weekday);
            break;

        case CURSOR_DATE_TIME_MONTH:
            RTC_stop_and_read_date(century, bcd_year, bcd_month, bcd_day);
            bcd_month = decrement_bcd(bcd_month, 0x01, 0x12);
            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_and_start(century, bcd_year, bcd_month, bcd_day, weekday);
            break;

        case CURSOR_DATE_TIME_DAY:
            RTC_stop_and_read_date(century, bcd_year, bcd_month, bcd_day);
            bcd_day = decrement_bcd(bcd_day, 0x01, bcd_days_in_month(century, bcd_year, bcd_month));
            weekday = bcd_date_to_weekday(century, bcd_year, bcd_month, bcd_day);
            RTC_write_date_and_start(century, bcd_year, bcd_month, bcd_day, weekday);
           break;

        case CURSOR_DATE_TIME_HOUR:
            t = RTC_stop_and_read1(RTC_REG_HOUR) & 0x3F;
            t = decrement_bcd(t, 0x00, 0x23);
            RTC_write1_and_start(RTC_REG_HOUR, t);
            break;

        case CURSOR_DATE_TIME_MINUTE:
            t = RTC_stop_and_read1(RTC_REG_MINUTE) & 0x7F;
            t = decrement_bcd(t, 0x00, 0x59);
            RTC_write1_and_start(RTC_REG_MINUTE, t);
            break;

        case CURSOR_DATE_TIME_SECOND:
            t = RTC_stop_and_read1(RTC_REG_SECOND) & 0x7f;
            t = 0x30;
            RTC_write1_and_start(RTC_REG_SECOND, t);
            break;
        }
    }
}

// BTN_RIGHT: move cursor forward
static void BTN_RIGHT_action() {
    if(display_mode == DISPLAY_MODE_DATE_TIME_ADJUST) {
        ++cursor_position;
        if(cursor_position > cursor_position_date_time_max) {
            cursor_position = 0;
        }
    }
}

// increment date/time
static void BTN_UP_action() {
    char century, bcd_year, bcd_month, bcd_day, weekday, d, t;

    if(display_mode == DISPLAY_MODE_DATE_TIME_ADJUST) {

        switch(cursor_position) {

        case CURSOR_DATE_TIME_CENTURY:
            RTC_stop_and_read_date(century, bcd_year, bcd_month, bcd_day);
            century = increment_bcd(century, 0x00, 0x01);
            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_and_start(century, bcd_year, bcd_month, bcd_day, weekday);
            break;

        case CURSOR_DATE_TIME_YEAR:
            RTC_stop_and_read_date(century, bcd_year, bcd_month, bcd_day);
            bcd_year = increment_bcd(bcd_year, 0x00, 0x99);
            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_and_start(century, bcd_year, bcd_month, bcd_day, weekday);
            break;

        case CURSOR_DATE_TIME_MONTH:
            RTC_stop_and_read_date(century, bcd_year, bcd_month, bcd_day);
            bcd_month = increment_bcd(bcd_month, 0x01, 0x12);
            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_and_start(century, bcd_year, bcd_month, bcd_day, weekday);
            break;

        case CURSOR_DATE_TIME_DAY:
            RTC_stop_and_read_date(century, bcd_year, bcd_month, bcd_day);
            bcd_day = increment_bcd(bcd_day, 0x01, bcd_days_in_month(century, bcd_year, bcd_month));
            weekday = bcd_date_to_weekday(century, bcd_year, bcd_month, bcd_day);
            RTC_write_date_and_start(century, bcd_year, bcd_month, bcd_day, weekday);
           break;

        case CURSOR_DATE_TIME_HOUR:
            t = RTC_stop_and_read1(RTC_REG_HOUR) & 0x3F;
            t = increment_bcd(t, 0x00, 0x23);
            RTC_write1_and_start(RTC_REG_HOUR, t);
            break;

        case CURSOR_DATE_TIME_MINUTE:
            t = RTC_stop_and_read1(RTC_REG_MINUTE) & 0x7F;
            t = increment_bcd(t, 0x00, 0x59);
            RTC_write1_and_start(RTC_REG_MINUTE, t);
            break;

        case CURSOR_DATE_TIME_SECOND:
            t = RTC_stop_and_read1(RTC_REG_SECOND) & 0x7f;
            t = 0x00;
            RTC_write1_and_start(RTC_REG_SECOND, t);
            break;
        }
    }
}