Yoshiyuki Uehara / Mbed 2 deprecated Maple

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
uehara00
Date:
Sun Oct 30 21:20:23 2011 +0000
Parent:
2:299a1c9a5795
Commit message:
OLED(MARY-OB) drivers and demonstrations are added.

Changed in this revision

Maple.cpp Show annotated file Show diff for this revision Revisions of this file
Maple.h Show annotated file Show diff for this revision Revisions of this file
Maple_LCD.cpp Show annotated file Show diff for this revision Revisions of this file
Maple_LCD.h Show annotated file Show diff for this revision Revisions of this file
Maple_OLED.cpp Show annotated file Show diff for this revision Revisions of this file
Maple_OLED.h Show annotated file Show diff for this revision Revisions of this file
Maple_alarm_clock.cpp Show annotated file Show diff for this revision Revisions of this file
Maple_alarm_clock.h Show annotated file Show diff for this revision Revisions of this file
Maple_console.cpp Show annotated file Show diff for this revision Revisions of this file
Maple_console.h Show annotated file Show diff for this revision Revisions of this file
Maple_test.cpp Show annotated file Show diff for this revision Revisions of this file
Maple_test.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/Maple.cpp	Sun Oct 16 01:27:35 2011 +0000
+++ b/Maple.cpp	Sun Oct 30 21:20:23 2011 +0000
@@ -8,9 +8,6 @@
 //====================================================================
 // MAPLE board[MARM01-BASE]
 // common functions
-#include "Maple_RTC.h"
-#include "Maple_I2C.h"
-#include "Maple_LCD.h"
 #include "Maple.h"
 #include "mbed.h"
 
@@ -132,77 +129,3 @@
     day     = bcd_to_int(bcd_day);
     return (day + (((month + 1) * 26 ) / 10) + year + year / 4 + century / 4 - century * 2 + 6) % 7;
 }
-
-// test
-// RTC read and raw print to LCD
-void RTC_to_LCD_raw() {
-    char d[17];
-
-    i2c_RTC_read(RTC_REG_CONTROL1, d, 16);
-    LCD_locate(0, 0);
-    for(int i = 0; i < 8; ++i) {
-        LCD_print_hex(d[i]);
-    }
-    LCD_locate(1, 0);
-    for(int i = 8; i < 16; ++i) {
-        LCD_print_hex(d[i]);
-    }
-}
-
-// test
-// LCD display 64 characters in 1st/2nd row and shift 
-//
-void LCD_display_all_char_shift() {
-        LCD_display_32char_shift(0x00);
-        LCD_display_32char_shift(0x40);
-        LCD_display_32char_shift(0x80);
-        LCD_display_32char_shift(0xC0);
-}
-
-static void LCD_display_32char_shift(char base) {
-    LCD_clear_display();                    // select 1st row and clear display
-    for(int i = 0; i < 32; ++i) {
-        LCD_print_char(base + i);           // write 32 characters
-    }
-    LCD_locate(1, 0);                       // select 2nd row
-    for(int i = 32; i < 64; ++i) {
-        LCD_print_char(base + i);           // write 32 characters
-    }
-    for(int i = 0; i < 24; ++i) {
-        LCD_cursor_or_display_shift(1, 0);  // shift right 24 times
-        wait_ms(1000);
-    }
-    for(int i = 0; i < 32; ++i) {
-        LCD_cursor_or_display_shift(1, 1);  // shift left 32 times
-        wait_ms(1000);
-    }
-    for(int i = 0; i < 8; ++i) {
-        LCD_cursor_or_display_shift(1, 0);  // shift right 8 times
-        wait_ms(1000);
-    }
-}
-
-// test
-// LCD display 16x2 characters with 1st and 2nd row 
-void LCD_display_all_char() { 
-    LCD_display_32char(0x00);
-    LCD_display_32char(0x20);
-    LCD_display_32char(0x40);
-    LCD_display_32char(0x60);
-    LCD_display_32char(0x80);
-    LCD_display_32char(0xa0);
-    LCD_display_32char(0xc0);
-    LCD_display_32char(0xe0);
-}
-
-static void LCD_display_32char(char base) {
-    LCD_clear_display();            // select 1st row and clear display
-    for(int i = 0; i < 16; ++i) {
-        LCD_print_char(base + i);   // write 1st-half 16 characters
-    }
-    LCD_locate(1, 0);               // select 2nd row
-    for(int i = 16; i < 32; ++i) {
-        LCD_print_char(base + i);   // write 2nd-half 16 characters
-    }
-    wait_ms(3000);
-}
--- a/Maple.h	Sun Oct 16 01:27:35 2011 +0000
+++ b/Maple.h	Sun Oct 30 21:20:23 2011 +0000
@@ -25,11 +25,4 @@
 char bcd_days_in_month(char bcd_century, char bcd_year, char bcd_month);
 int bcd_date_to_weekday(char bcd_century, char bcd_year, char bcd_month, char bcd_day);
 
-//prototypes for test
-void RTC_to_LCD_raw();
-void LCD_display_all_char_shift();
-static void LCD_display_32char_shift(char base);
-void LCD_display_all_char(); 
-static void LCD_display_32char(char base);
-
 #endif
--- a/Maple_LCD.cpp	Sun Oct 16 01:27:35 2011 +0000
+++ b/Maple_LCD.cpp	Sun Oct 30 21:20:23 2011 +0000
@@ -337,9 +337,12 @@
     LCD_set_DDRAM_address(row * 0x40 + column);
 }
 
-// set cursor on/off
-//   c: cursor .. 0: off, 1: on
-//   blink = off
-void LCD_cursor(int c) {
-    LCD_display_on_off_control(1, c, 0);
+// set cursor on, blink off
+void LCD_cursor_on() {
+    LCD_display_on_off_control(1, 1, 0);
 }
+
+// set cursor off, blink off
+void LCD_cursor_off() {
+    LCD_display_on_off_control(1, 0, 0);
+}
--- a/Maple_LCD.h	Sun Oct 16 01:27:35 2011 +0000
+++ b/Maple_LCD.h	Sun Oct 30 21:20:23 2011 +0000
@@ -13,10 +13,6 @@
 #ifndef MAPLE_LCD_H_
 #define MAPLE_LCD_H_
 
-//constants
-#define LCD_CURSOR_ON   1
-#define LCD_CURSOR_OFF  0
-
 // prototypes
 void LCD_clear_display();
 void LCD_return_home();
@@ -36,6 +32,7 @@
 void LCD_print_string(char s[]);
 void LCD_print_hex(int i);
 void LCD_locate(int row, int column);
-void LCD_cursor(int c);
+void LCD_cursor_on();
+void LCD_cursor_off();
 
 #endif
--- a/Maple_OLED.cpp	Sun Oct 16 01:27:35 2011 +0000
+++ b/Maple_OLED.cpp	Sun Oct 30 21:20:23 2011 +0000
@@ -1,13 +1,1771 @@
-//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]
-// OLED() driver
-#include "Maple_OLED.h"
-#include "Maple.h"
-#include "mbed.h"
+//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]
+// OLED(UG-2828GDEDF11, SSD1351) driver
+#include "Maple_OLED.h"
+#include "Maple.h"
+#include "mbed.h"
+
+// create SPI for OLED in SLOT-1/2 of MARM01-BASE
+//   3-wire SPI and power-control, reset-control
+SPI OLED_spi(p5, p6, p7);       // mosi, miso, sclk for SLOT-1/2 
+DigitalOut OLED_cs1(p8);        // cs       for SLOT-1
+DigitalOut OLED_power1(p11);    // power-on for SLOT-1(GPIO2)
+DigitalOut OLED_reset1(p30);    // reset    for SLOT-1(GPIO4)
+DigitalOut OLED_cs2(p26);       // cs       for SLOT-2
+DigitalOut OLED_power2(p17);    // power-on for SLOT-2(GPIO2)
+DigitalOut OLED_reset2(p21);    // reset    for SLOT-2(GPIO4)
+
+// global variables
+int OLED_color_a1;  // foreground color a
+int OLED_color_b1;  // foreground color b
+int OLED_color_c1;  // forebround color c
+int OLED_color_a2;  // background color a
+int OLED_color_b2;  // background color b
+int OLED_color_c2;  // background color c
+int OLED_cursor_x;  // cursor position x (column-left)
+int OLED_cursor_y;  // cursor position y (row-upper)
+
+// assert cs for the OLED selected
+//  slot: 1..SLOT-1, 2..SLOT-2
+void OLED_cs_assert(int slot) {
+    switch(slot){
+    case 1: OLED_cs1 = CS_ASSERT;  break;
+    case 2: OLED_cs2 = CS_ASSERT;  break;
+    }
+}
+
+// negate cs for all OLEDs
+void OLED_cs_negate() {
+    OLED_cs1 = CS_NEGATE;
+    OLED_cs2 = CS_NEGATE;
+}
+
+// OLED set column address
+//  a: start address (0x00-0x7f, 0x00 by reset)
+//  b: end address   (0x00-0x7f, 0x7f by reset)
+void OLED_set_column_address(int a, int b) {
+    OLED_spi.write(0x15);
+    OLED_spi.write(0x100 | a);
+    OLED_spi.write(0x100 | b);
+}
+
+// OLED set row address
+//  a: start address (0x00-0x7f, 0x00 by reset)
+//  b: end address   (0x00-0x7f, 0x7f by reset)
+void OLED_set_row_address(int a, int b) {
+    OLED_spi.write(0x75);
+    OLED_spi.write(0x100 | a);
+    OLED_spi.write(0x100 | b);
+}
+
+// OLED write RAM
+void OLED_write_ram_command() {
+    OLED_spi.write(0x5c);
+}
+
+// OLED read RAM .. not supported by SPI
+void OLED_read_ram_command() {
+    OLED_spi.write(0x5d);
+}
+
+// OLED set re-map/color depth
+//   a(0): 0..horizontal address increment  1..vertical address increment    (0 by reset) 
+//   a(1): 0..column address 0 is to SEG0   1..column address 127 is to SEG0 (0 by reset)
+//   a(2): 0..color sequence A->B->C        1..color sequence C->B->A        (0 by reset)
+//   a(3): 0..reserved                      1..reserved
+//   a(4): 0..scan COM(0)->COM(N-1)         1..scan COM(N-1)->COM(0)         (0 by reset)
+//   a(5): 0..disable COM split odd even    1..enable COM split odd even     (1 by reset)
+//   a(7-6): 00..65k color
+//           01..65k color (reset)
+//           10..262k color
+//           11..262k color 16-bit format 2
+void OLED_set_remap_color_depth(int a) {
+    OLED_spi.write(0xa0);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED set display start line
+//  a: start line (0x00-0x7f, 0x00 by reset)
+void OLED_set_display_start_line(int a) {
+    OLED_spi.write(0xa1);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED set display offset
+//  a: offset (0x00-0x7f, 0x60 by reset)
+void OLED_set_display_offset(int a) {
+    OLED_spi.write(0xa2);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED set display mode all off
+void OLED_set_display_mode_all_off() {
+    OLED_spi.write(0xa4);
+}
+
+// OLED set display mode all on
+void OLED_set_display_mode_all_on() {
+    OLED_spi.write(0xa5);
+}
+
+// OLED set display mode reset to normal display (reset)
+void OLED_set_display_mode_normal() {
+    OLED_spi.write(0xa6);
+}
+
+// OLED set display mode reset to inverse display
+void OLED_set_display_mode_inverse() {
+    OLED_spi.write(0xa7);
+}
+
+// OLED function selection
+//  a(0): 0..select external VDD  1..enable internal regulator (1 by reset)
+//  a(7-6): 00..select  8-bit parallel interface (reset)
+//          01..select 16-bit parallel interface
+//          11..select 18-bit parallel interface
+void OLED_function_selection(int a) {
+    OLED_spi.write(0xab);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED no operation
+void OLED_no_operation_ad() {
+    OLED_spi.write(0xad);
+}
+
+// OLED set sleep mode on
+void OLED_set_sleep_mode_on() {
+    OLED_spi.write(0xae);
+}
+
+// OLED set sleep mode off
+void OLED_set_sleep_mode_off() {
+    OLED_spi.write(0xaf);
+}
+
+// OLED no operation
+void OLED_no_operation_b0() {
+    OLED_spi.write(0xb0);
+}
+
+// OLED set reset / pre-charge period
+//  a(3-0): phase 1 period (0x2..0xf, 0x2 by reset)
+//  a(7-4): phase 2 period (0x3..0xf, 0x8 by reset)
+void OLED_set_reset_pre_charge_period(int a) {
+    OLED_spi.write(0xb1);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED display enhancement
+//  a, b, c: 0x00, 0x00, 0x00..normal (reset)
+//           0xa4, 0x00, 0x00..enhance display
+void OLED_display_enhancement(int a, int b, int c) {
+    OLED_spi.write(0xb2);
+    OLED_spi.write(0x100 | a);
+    OLED_spi.write(0x100 | b);
+    OLED_spi.write(0x100 | c);
+}
+
+// OLED front clock divider / oscillator frequency
+//  a(3-0): divset (0x0-0xa, 0x1 by reset)
+//  a(7-4): oscillator frequency (0xd by reset)
+void OLED_front_clock_divider_oscillator_frequency(int a) {
+    OLED_spi.write(0xb3);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED set segment low voltage
+void OLED_set_segment_low_voltage() {
+    OLED_spi.write(0xb4);
+    OLED_spi.write(0x1a0);
+    OLED_spi.write(0x1b5);
+    OLED_spi.write(0x155);
+}
+
+// OLED set GPIO
+//  a(1-0): GPIO0
+//  a(3-2): GPIO1
+//    00..pin Hi-Z, input disabled
+//    01..pin Hi-Z, input enabled
+//    10..pin output low (reset)
+//    11..pin output high
+void OLED_set_GPIO(int a) {
+    OLED_spi.write(0xb5);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED set second pre-charge period
+//  a(3-0): period (0x1-0xf, 0x8 by reset)
+void OLED_set_second_pre_charge_period(int a) {
+    OLED_spi.write(0xb6);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED look up table for gray scale pulse width
+void OLED_look_up_table_for_gray_scale_pulse_width() {
+    const int a[63] = {
+        0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
+        0x12, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f, 0x21, 0x23, 0x25, 0x27, 0x2a, 0x2d, 0x30, 0x33,
+        0x36, 0x39, 0x3c, 0x3f, 0x42, 0x45, 0x48, 0x4c, 0x50, 0x54, 0x58, 0x5c, 0x60, 0x64, 0x68, 0x6c,
+        0x70, 0x74, 0x78, 0x7d, 0x82, 0x87, 0x8c, 0x91, 0x96, 0x9b, 0xa0, 0xa5, 0xaa, 0xaf, 0xb4
+    };
+
+    OLED_spi.write(0xb8);
+    for(int i = 0; i < 63; ++i) {
+        OLED_spi.write(0x100 | a[i]);
+    }
+}
+
+// OLED use built-in linear look up table (linear by reset)
+void OLED_use_built_in_linear_lut() {
+    OLED_spi.write(0xb9);
+}
+
+// OLED set pre-charge voltage
+//  a: 0x00-0x1f (0x17 by reset)
+void OLED_set_pre_charge_voltage(int a) {
+    OLED_spi.write(0xbb);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED set VCOMH_voltage
+//  a: 0x00-0x07 (0x05 by reset)
+void OLED_set_vcomh_voltage(int a) {
+    OLED_spi.write(0xbe);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED set contrast current for color A, B, C
+//  a: contrast value for color A (0x8a by reset)
+//  b: contrast value for color B (0x51 by reset)
+//  c: contrast value for color C (0x8a by reset)
+void OLED_set_contrast_for_color_abc(int a, int b, int c) {
+    OLED_spi.write(0xc1);
+    OLED_spi.write(0x100 | a);
+    OLED_spi.write(0x100 | b);
+    OLED_spi.write(0x100 | c);
+}
+
+// OLED master contrast current control
+//  a: 0x00-0x0e..reduce output current for all colors
+//          0x0f..no change (reset)
+void OLED_master_contrast_current_control(int a) {
+    OLED_spi.write(0xc7);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED set MUX ratio
+//  a: 0x0f-0x7f..16MUX-128MUX (0x7f by reset)
+void OLED_set_mux_ratio(int a) {
+    OLED_spi.write(0xca);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED no operation
+void OLED_no_operation_d1() {
+    OLED_spi.write(0xd1);
+}
+
+// OLED no operation
+void OLED_no_operation_e3() {
+    OLED_spi.write(0xe3);
+}
+
+// OLED set command lock
+//  a: MCU protection status
+//    0x12..unlock OLED driver IC MCU interface from entering command (reset)
+//    0x16..Lock OLED driver IC MCU interface from entering command
+//    0xb0..command a2, b1, b3, bb, be, c1 inaccessible in both lock and unlock state (reset)
+//    0xb1..command a2, b1, b3, bb, be, c1 accessible if in unlock state
+void OLED_set_command_lock(int a) {
+    OLED_spi.write(0xfd);
+    OLED_spi.write(0x100 | a);
+}
+
+// OLED horizontal scroll
+//  a: 0x00     ..no scrolling
+//     0x01-0x3f..scroll towards SEG127 with 1 column offset
+//     0x40-0xff..scroll towards SEG0   with 1 column offset
+//  b: 0x00-0x7f..start row address
+//  c: 0x00-0xff..number of rows to be h-scrolled  (b + c <= 0x80)
+//  d: reserved (0x00 by reset)
+//  e: scrolling time interval
+//      0x00..test mode
+//      0x01..normal
+//      0x02..slow
+//      0x03..slowest
+void OLED_horizontal_scroll(int a, int b, int c, int d, int e) {
+    OLED_spi.write(0x96);
+    OLED_spi.write(0x100 | a);
+    OLED_spi.write(0x100 | b);
+    OLED_spi.write(0x100 | c);
+    OLED_spi.write(0x100 | d);
+    OLED_spi.write(0x100 | e);
+}
+
+// OLED stop horizontal scroll
+void OLED_stop_moving() {
+    OLED_spi.write(0x9e);
+}
+
+// OLED start horizontal scroll
+void OLED_start_moving() {
+    OLED_spi.write(0x9f);
+}
+
+// OLED initialize
+void OLED_initialize() {
+    OLED_power1 = OLED_POWER_OFF;
+    OLED_power2 = OLED_POWER_OFF;
+
+    OLED_cs_negate();   
+    OLED_spi.format(9, 3);          // 9bit mode, CPOL=1(inactive-H), CPHA=1(edge-UP)
+    OLED_spi.frequency(20000000);   // 20MHz (50ns)
+
+    OLED_reset1 = OLED_RESET_ON;
+    OLED_reset2 = OLED_RESET_ON;
+    wait_us(10);
+    OLED_reset1 = OLED_RESET_OFF;
+    OLED_reset2 = OLED_RESET_OFF;
+
+    OLED_set_color(0, 0, 0, 0);             // background color
+    OLED_set_color(1, 0x3f, 0x3f, 0x3f);    // foreground color
+    OLED_set_cursor(0, 0);
+
+    OLED_cs_assert(1);              // SLOT-1
+    OLED_initialize_sub();
+    OLED_cs_negate();
+
+    OLED_cs_assert(2);              // SLOT-2
+    OLED_initialize_sub();
+    OLED_cs_negate();
+
+    OLED_power1 = OLED_POWER_ON;
+    OLED_power2 = OLED_POWER_ON;
+    wait_ms(200);
+}
+
+// OLED initialize sub-program
+//  slot: 1..SLOT-1, 2..SLOT-2
+static void OLED_initialize_sub() {
+    OLED_set_command_lock(0x12);
+    OLED_set_command_lock(0xb1);
+    OLED_set_sleep_mode_on();
+    OLED_front_clock_divider_oscillator_frequency(0xf1);
+    OLED_set_mux_ratio(0x7f);
+    OLED_set_display_offset(0x00);
+    OLED_set_display_start_line(0x00);
+    OLED_set_remap_color_depth(0xb4);   // 262k(18bit) color format-1 
+    OLED_set_GPIO(0x00);
+    OLED_function_selection(0x01);
+    OLED_set_segment_low_voltage();
+    OLED_set_contrast_for_color_abc(0xc8, 0x80, 0xc8);
+    OLED_master_contrast_current_control(0x0f);
+    OLED_look_up_table_for_gray_scale_pulse_width();
+    OLED_set_reset_pre_charge_period(0x32);
+    OLED_display_enhancement(0xa4, 0x00, 0x00);
+    OLED_set_pre_charge_voltage(0x17);    
+    OLED_set_second_pre_charge_period(0x01);
+    OLED_set_vcomh_voltage(0x05);
+    OLED_set_display_mode_normal();
+    OLED_clear_screen(0);               // by background color
+    OLED_set_sleep_mode_off();
+}
+
+// OLED set color
+//  mode: 0..backgound, else..foreground
+void OLED_set_color(int mode, int a, int b, int c) {
+    if(mode == 0) {
+        OLED_color_a2 = a;
+        OLED_color_b2 = b;
+        OLED_color_c2 = c;
+    }
+    else {
+        OLED_color_a1 = a;
+        OLED_color_b1 = b;
+        OLED_color_c1 = c;
+    }
+}
+
+// OLED set print position
+void OLED_set_cursor(int x, int y) {
+    OLED_cursor_x = x;
+    OLED_cursor_y = y;
+}
+
+// OLED clear screen = fill-out with a color
+//  mode: 0..backgound, else..foreground
+void OLED_clear_screen(int mode) {
+    OLED_fill_rectangle(mode, 0, OLED_COLUMN_MAX + 1, 0, OLED_ROW_MAX + 1);
+}
+
+// OLED fill rectangle
+//  mode: 0..backgound, else..foreground
+//  cs: column-start  (0x00..OLED_COLUMN_MAX)
+//  cl: column-length (0x01..OLED_COLUMN_MAX+1)
+//  rs: row-start     (0x00..OLED_ROW_MAX)
+//  rl: row-length    (0x01..OLED_ROW_MAX+1)
+void OLED_fill_rectangle(int mode, int cs, int cl, int rs, int rl) {
+    OLED_set_column_address(cs, cs + cl - 1);
+    OLED_set_row_address(rs, rs + rl - 1);
+    OLED_write_ram_command();
+    for(int i = 0; i < cl * rl; ++i) {
+        OLED_write_pixel(mode);
+    }
+}
+
+// OLED write a pixel in 18-bit color mode
+//  mode: 0..backgound, else..foreground
+void OLED_write_pixel(int mode) {
+    if(mode == 0) {
+        OLED_spi.write(0x100 | OLED_color_a2);
+        OLED_spi.write(0x100 | OLED_color_b2);
+        OLED_spi.write(0x100 | OLED_color_c2);
+    }
+    else {
+        OLED_spi.write(0x100 | OLED_color_a1);
+        OLED_spi.write(0x100 | OLED_color_b1);
+        OLED_spi.write(0x100 | OLED_color_c1);
+    }
+}
+
+// OLED print string
+void OLED_print_string(char s[]) {
+    for(int i = 0; s[i] != '\0'; ++i) {
+        OLED_print_character(s[i]);
+    }
+}
+
+// OLED print integer(1 byte) in hex format
+void OLED_print_hex(int i) {
+    OLED_print_character(int_to_hex1(i >> 4));
+    OLED_print_character(int_to_hex1(i));
+}
+
+// OLED print character of 6*9 font
+//  ch: character
+void OLED_print_character(char ch) {
+static char font[0x80][OLED_FONT_SIZE_Y] = {
+        { 0x90, //  1--1----  0x00 NUL
+          0xd0, //  11-1----
+          0xb0, //  1-11----
+          0x90, //  1--1----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x38, //  --111---
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x01 SOH
+          0x80, //  1-------
+          0x40, //  -1------
+          0x20, //  --1-----
+          0xc0, //  11------
+          0x28, //  --1-1---
+          0x38, //  --111---
+          0x28, //  --1-1---
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x02 STX
+          0x80, //  1-------
+          0x40, //  -1------
+          0x20, //  --1-----
+          0xc0, //  11------
+          0x28, //  --1-1---
+          0x10, //  ---1----
+          0x28, //  --1-1---
+          0x00, //  --------
+        },
+        { 0xe0, //  111-----  0x03 ETX
+          0x80, //  1-------
+          0xe0, //  111-----
+          0x80, //  1-------
+          0xe0, //  111-----
+          0x28, //  --1-1---
+          0x10, //  ---1----
+          0x28, //  --1-1---
+          0x00, //  --------
+        },
+        { 0xe0, //  111-----  0x04 EOT
+          0x80, //  1-------
+          0xe0, //  111-----
+          0x80, //  1-------
+          0xe0, //  111-----
+          0x38, //  --111---
+          0x28, //  --1-1---
+          0x38, //  --111---
+          0x00, //  --------
+        },
+        { 0xe0, //  111-----  0x05 ENQ
+          0x80, //  1-------
+          0xe0, //  111-----
+          0x80, //  1-------
+          0xf0, //  1111----
+          0x48, //  -1--1---
+          0x58, //  -1-11---
+          0x38, //  --111---
+          0x00, //  --------
+        },
+        { 0x40, //  -1------  0x06 ACK
+          0xa0, //  1-1-----
+          0xa0, //  1-1-----
+          0xe0, //  111-----
+          0xa0, //  1-1-----
+          0x28, //  --1-1---
+          0x30, //  --11----
+          0x28, //  --1-1---
+          0x00, //  --------
+        },
+        { 0xc0, //  11------  0x07 BEL
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x38, //  --111---
+          0x00, //  --------
+        },
+        { 0xc0, //  11------  0x08 BS
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0xb8, //  1-111---
+          0xe0, //  111-----
+          0x10, //  ---1----
+          0x08, //  ----1---
+          0x30, //  --11----
+          0x00, //  --------
+        },
+        { 0xa0, //  1-1-----  0x09 HT
+          0xa0, //  1-1-----
+          0xe0, //  111-----
+          0xa0, //  1-1-----
+          0xb8, //  1-111---
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x00, //  --------
+        },
+        { 0x80, //  1-------  0x0a LF
+          0x80, //  1-------
+          0x80, //  1-------
+          0xf8, //  11111---
+          0x20, //  --1-----
+          0x38, //  --111---
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+        },
+        { 0xa0, //  1-1-----  0x0b VT
+          0xa0, //  1-1-----
+          0xa0, //  1-1-----
+          0x40, //  -1------
+          0x38, //  --111---
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x00, //  --------
+        },
+        { 0xe0, //  111-----  0x0c FF
+          0x80, //  1-------
+          0xe0, //  111-----
+          0xb8, //  1-111---
+          0xa0, //  1-1-----
+          0x38, //  --111---
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x0d CR
+          0x80, //  1-------
+          0x80, //  1-------
+          0xb0, //  1-11----
+          0x68, //  -11-1---
+          0x30, //  --11----
+          0x28, //  --1-1---
+          0x28, //  --1-1---
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x0e SO
+          0x80, //  1-------
+          0x40, //  -1------
+          0x20, //  --1-----
+          0xc0, //  11------
+          0x38, //  --111---
+          0x28, //  --1-1---
+          0x38, //  --111---
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x0f SI
+          0x80, //  1-------
+          0x40, //  -1------
+          0x20, //  --1-----
+          0xc0, //  11------
+          0x38, //  --111---
+          0x10, //  ---1----
+          0x38, //  --111---
+          0x00, //  --------
+        },
+        { 0xc0, //  11------  0x10 DLE
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0x38, //  --111---
+          0x20, //  --1-----
+          0x38, //  --111---
+          0x20, //  --1-----
+          0x38, //  --111---
+          0x00, //  --------
+        },
+        { 0xc0, //  11------  0x11 DC1
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0x30, //  --11----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x38, //  --111---
+          0x00, //  --------
+        },
+        { 0xc0, //  11------  0x12 DC2
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0x30, //  --11----
+          0x08, //  ----1---
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x38, //  --111---
+          0x00, //  --------
+        },
+        { 0xc0, //  11------  0x13 DC3
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0x30, //  --11----
+          0x08, //  ----1---
+          0x30, //  --11----
+          0x08, //  ----1---
+          0x30, //  --11----
+          0x00, //  --------
+        },
+        { 0xc0, //  11------  0x14 DC4
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0x28, //  --1-1---
+          0x28, //  --1-1---
+          0x38, //  --111---
+          0x08, //  ----1---
+          0x08, //  ----1---
+          0x00, //  --------
+        },
+        { 0x90, //  1--1----  0x15 NAK
+          0xd0, //  11-1----
+          0xb0, //  1-11----
+          0x90, //  1--1----
+          0x90, //  1--1----
+          0x28, //  --1-1---
+          0x30, //  --11----
+          0x28, //  --1-1---
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x16 SYN
+          0x80, //  1-------
+          0x40, //  -1------
+          0x28, //  --1-----
+          0xc8, //  11--1---
+          0x68, //  -11-1---
+          0x58, //  -1-11---
+          0x48, //  -1--1---
+          0x00, //  --------
+        },
+        { 0xe0, //  111-----  0x17 ETB
+          0x80, //  1-------
+          0xe0, //  111-----
+          0xb0, //  1-11----
+          0xe8, //  111-1---
+          0x30, //  --11----
+          0x28, //  --1-1---
+          0x30, //  --11----
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x18 CAN
+          0x80, //  1-------
+          0x80, //  1-------
+          0x60, //  -11-----
+          0x48, //  -1--1---
+          0x68, //  -11-1---
+          0x58, //  -1-11---
+          0x48, //  -1--1---
+          0x00, //  --------
+        },
+        { 0xe0, //  111-----  0x19 EM
+          0x80, //  1-------
+          0xe0, //  111-----
+          0x80, //  1-------
+          0xe0, //  111-----
+          0x88, //  1---1---
+          0xd8, //  11-11---
+          0xa8, //  1-1-1---
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x1a SUB
+          0x80, //  1-------
+          0x40, //  -1------
+          0x30, //  --11----
+          0xe8, //  111-1---
+          0x30, //  --11----
+          0x28, //  --1-1---
+          0x30, //  --11----
+          0x00, //  --------
+        },
+        { 0xe0, //  111-----  0x1b ESC
+          0x80, //  1-------
+          0xe0, //  111-----
+          0x80, //  1-------
+          0xf8, //  11111---
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x18, //  ---11---
+          0x00, //  --------
+        },
+        { 0xe0, //  111-----  0x1c FS
+          0x80, //  1-------
+          0xe0, //  111-----
+          0x98, //  1--11---
+          0xa0, //  1-1-----
+          0x10, //  ---1----
+          0x08, //  ----1---
+          0x30, //  --11----
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x1d GS
+          0x80, //  1-------
+          0xb0, //  1-11----
+          0x98, //  1--11---
+          0x60, //  -11-----
+          0x10, //  ---1----
+          0x08, //  ----1---
+          0x30, //  --11----
+          0x00, //  --------
+        },
+        { 0xc0, //  11------  0x1e RS
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0xb8, //  1-111---
+          0xa0, //  1-1-----
+          0x10, //  ---1----
+          0x08, //  ----1---
+          0x30, //  --11----
+          0x00, //  --------
+        },
+        { 0xa0, //  1-1-----  0x1f US
+          0xa0, //  1-1-----
+          0xe0, //  111-----
+          0x18, //  ---11---
+          0x20, //  --1-----
+          0x10, //  ---1----
+          0x08, //  ----1---
+          0x30, //  --11----
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x20 space
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x20, //  --1-----  0x21 !
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x50, //  -1-1----  0x22 "
+          0x50, //  -1-1----
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x50, //  -1-1----  0x23 #
+          0x50, //  -1-1----
+          0xf8, //  11111---
+          0x50, //  -1-1----
+          0xf8, //  11111---
+          0x50, //  -1-1----
+          0x50, //  -1-1----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x20, //  --1-----  0x24 $
+          0x78, //  -1111---
+          0xa0, //  1-1-----
+          0x70, //  -111----
+          0x28, //  --1-1---
+          0xf0, //  1111----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xc0, //  11------  0x25 %
+          0xc8, //  11--1---
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x98, //  1--11---
+          0x18, //  ---11---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x40, //  -1------  0x26 &
+          0xa0, //  1-1-----
+          0xa0, //  1-1-----
+          0x40, //  -1------
+          0xa8, //  1-1-1---
+          0x90, //  1--1----
+          0x68, //  -11-1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x30, //  --11----  0x27 '
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x10, //  ---1----  0x28 (
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x40, //  -1------
+          0x40, //  -1------
+          0x20, //  --1-----
+          0x10, //  ---1----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x40, //  -1------  0x29 )
+          0x20, //  --1-----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x2a *
+          0x20, //  --1-----
+          0xa8, //  1-1-1---
+          0x70, //  -111----
+          0xa8, //  1-1-1---
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x2b +
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0xf8, //  11111---
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x2c ,
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x60, //  -11-----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x2d -
+          0x00, //  --------
+          0x00, //  --------
+          0xf8, //  11111---
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x2e .
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x60, //  -11-----
+          0x60, //  -11-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x2f /
+          0x08, //  ----1---
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x80, //  1-------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x30 0
+          0x88, //  1---1---
+          0x98, //  1--11---
+          0xa8, //  1-1-1---
+          0xc8, //  11--1---
+          0x88, //  1---1---
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x20, //  --1-----  0x31 1
+          0x60, //  -11-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x32 2
+          0x88, //  1---1---
+          0x08, //  ----1---
+          0x30, //  --11----
+          0x40, //  -1------
+          0x80, //  1-------
+          0xf8, //  11111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x33 3
+          0x88, //  1---1---
+          0x08, //  ----1---
+          0x30, //  --11----
+          0x08, //  ----1---
+          0x88, //  1---1---
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x10, //  ---1----  0x34 4
+          0x30, //  --11----
+          0x50, //  -1-1----
+          0x90, //  1--1----
+          0xf8, //  11111---
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xf8, //  11111---  0x35 5
+          0x80, //  1-------
+          0xf0, //  1111----
+          0x08, //  ----1---
+          0x08, //  ----1---
+          0x88, //  1---1---
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x30, //  --11----  0x36 6
+          0x40, //  -1------
+          0x80, //  1-------
+          0xf0, //  1111----
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xf8, //  11111---  0x37 7
+          0x08, //  ----1---
+          0x08, //  ----1---
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x40, //  -1------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x38 8
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x70, //  -111----
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x39 9
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x78, //  -1111---
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x3a :
+          0x30, //  --11----
+          0x30, //  --11----
+          0x00, //  --------
+          0x30, //  --11----
+          0x30, //  --11----
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x3b ;
+          0x30, //  --11----
+          0x30, //  --11----
+          0x00, //  --------
+          0x30, //  --11----
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x08, //  ----1---  0x3c <
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x20, //  --1-----
+          0x10, //  ---1----
+          0x08, //  ----1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x3d =
+          0x00, //  --------
+          0xf8, //  11111---
+          0x00, //  --------
+          0xf8, //  11111---
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x80, //  1-------  0x3e >
+          0x40, //  -1------
+          0x20, //  --1-----
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x80, //  1-------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x3f ?
+          0x88, //  1---1---
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x40 @
+          0x88, //  1---1---
+          0x98, //  1--11---
+          0xa8, //  1-1-1---
+          0xa8, //  1-1-1---
+          0x98, //  1--11---
+          0x40, //  -1------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x20, //  --1-----  0x41 A
+          0x50, //  -1-1----
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0xf8, //  11111---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xf0, //  1111----  0x42 B
+          0x48, //  -1--1---
+          0x48, //  -1--1---
+          0x70, //  -111----
+          0x48, //  -1--1---
+          0x48, //  -1--1---
+          0xf0, //  1111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x78, //  -1111---  0x43 C
+          0x80, //  1-------
+          0x80, //  1-------
+          0x80, //  1-------
+          0x80, //  1-------
+          0x80, //  1-------
+          0x78, //  -1111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xf0, //  1111----  0x44 D
+          0x48, //  -1--1---
+          0x48, //  -1--1---
+          0x48, //  -1--1---
+          0x48, //  -1--1---
+          0x48, //  -1--1---
+          0xf0, //  1111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xf8, //  11111---  0x45 E
+          0x80, //  1-------
+          0x80, //  1-------
+          0xf0, //  1111----
+          0x80, //  1-------
+          0x80, //  1-------
+          0xf8, //  11111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xf8, //  11111---  0x46 F
+          0x80, //  1-------
+          0x80, //  1-------
+          0xf0, //  1111----
+          0x80, //  1-------
+          0x80, //  1-------
+          0x80, //  1-------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x78, //  -1111---  0x47 G
+          0x80, //  1-------
+          0x80, //  1-------
+          0xb8, //  1-111---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x78, //  -1111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x88, //  1---1---  0x48 H
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0xf8, //  11111---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x49 I
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x38, //  --111---  0x4a J
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0xe0, //  111-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x88, //  1---1---  0x4b K
+          0x90, //  1--1----
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0xa0, //  1-1-----
+          0x90, //  1--1----
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x80, //  1-------  0x4c L
+          0x80, //  1-------
+          0x80, //  1-------
+          0x80, //  1-------
+          0x80, //  1-------
+          0x80, //  1-------
+          0xf8, //  11111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x88, //  1---1---  0x4d M
+          0xd8, //  11-11---
+          0xa8, //  1-1-1---
+          0xa8, //  1-1-1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x88, //  1---1---  0x4e N
+          0x88, //  1---1---
+          0xc8, //  11--1---
+          0xa8, //  1-1-1---
+          0x98, //  1--11---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x4f O
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xf0, //  1111----  0x50 P
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0xf0, //  1111----
+          0x80, //  1-------
+          0x80, //  1-------
+          0x80, //  1-------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x51 Q
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0xa8, //  1-1-1---
+          0x90, //  1--1----
+          0x68, //  -11-1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xf0, //  1111----  0x52 R
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0xf0, //  1111----
+          0xa0, //  1-1-----
+          0x90, //  1--1----
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x78, //  -1111---  0x53 S
+          0x80, //  1-------
+          0x80, //  1-------
+          0x70, //  -111----
+          0x08, //  ----1---
+          0x08, //  ----1---
+          0xf0, //  1111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xf8, //  11111---  0x54 T
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x88, //  1---1---  0x55 U
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x88, //  1---1---  0x56 V
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x50, //  -1-1----
+          0x50, //  -1-1----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x88, //  1---1---  0x57 W
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0xa8, //  1-1-1---
+          0xa8, //  1-1-1---
+          0xa8, //  1-1-1---
+          0x50, //  -1-1----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x88, //  1---1---  0x58 X
+          0x88, //  1---1---
+          0x50, //  -1-1----
+          0x20, //  --1-----
+          0x50, //  -1-1----
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x88, //  1---1---  0x59 Y
+          0x88, //  1---1---
+          0x50, //  -1-1----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xf8, //  11111---  0x5a Z
+          0x08, //  ----1---
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x80, //  1-------
+          0xf8, //  11111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x5b [
+          0x40, //  -1------
+          0x40, //  -1------
+          0x40, //  -1------
+          0x40, //  -1------
+          0x40, //  -1------
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x5c back slash
+          0x80, //  1-------
+          0x40, //  -1------
+          0x20, //  --1-----
+          0x10, //  ---1----
+          0x08, //  ----1---
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x70, //  -111----  0x5d ]
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x20, //  --1-----  0x5e ^
+          0x50, //  -1-1----
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x5f _
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0xf8, //  11111---
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x60 `
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x61 a
+          0x00, //  --------
+          0x70, //  -111----
+          0x08, //  ----1---
+          0x78, //  -1111---
+          0x88, //  1---1---
+          0x78, //  -1111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x80, //  1-------  0x62 b
+          0x80, //  1-------
+          0xf0, //  1111----
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0xf0, //  1111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x63 c
+          0x00, //  --------
+          0x78, //  -1111---
+          0x80, //  1-------
+          0x80, //  1-------
+          0x80, //  1-------
+          0x78, //  -1111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x08, //  ----1---  0x64 d
+          0x08, //  ----1---
+          0x78, //  -1111---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x78, //  -1111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x65 e
+          0x00, //  --------
+          0x70, //  -111----
+          0x88, //  1---1---
+          0xf8, //  11111---
+          0x80, //  1-------
+          0x78, //  -1111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x18, //  ---11---  0x66 f
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0xf8, //  11111---
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x67 g
+          0x00, //  --------
+          0x78, //  -1111---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x78, //  -1111---
+          0x08, //  ----1---
+          0x70, //  -111----
+        },
+        { 0x80, //  1-------  0x68 h
+          0x80, //  1-------
+          0xf0, //  1111----
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x20, //  --1-----  0x69 i
+          0x00, //  --------
+          0x60, //  -11-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x20, //  --1-----  0x6a j
+          0x00, //  --------
+          0x60, //  -11-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x80, //  1-------
+        },
+        { 0x80, //  1-------  0x6b k
+          0x80, //  1-------
+          0x88, //  1---1---
+          0x90, //  1--1----
+          0xe0, //  111-----
+          0x90, //  1--1----
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x6c l
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x6d m
+          0x00, //  --------
+          0xd0, //  11-1----
+          0xa8, //  1-1-1---
+          0xa8, //  1-1-1---
+          0xa8, //  1-1-1---
+          0xa8, //  1-1-1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x6e n
+          0x00, //  --------
+          0xf0, //  1111----
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x6f o
+          0x00, //  --------
+          0x70, //  -111----
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x70 p
+          0x00, //  --------
+          0xf0, //  1111----
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0xf0, //  1111----
+          0x80, //  1-------
+          0x80, //  1-------
+        },
+        { 0x00, //  --------  0x71 q
+          0x00, //  --------
+          0x78, //  -1111---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x78, //  -1111---
+          0x08, //  ----1---
+          0x08, //  ----1---
+        },
+        { 0x00, //  --------  0x72 r
+          0x00, //  --------
+          0x98, //  1--11---
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0x80, //  1-------
+          0x80, //  1-------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x73 s
+          0x00, //  --------
+          0x78, //  -1111---
+          0x80, //  1-------
+          0x70, //  -111----
+          0x08, //  ----1---
+          0xf0, //  1111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x20, //  --1-----  0x74 t
+          0x20, //  --1-----
+          0xf8, //  11111---
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x18, //  ---11---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x75 u
+          0x00, //  --------
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x70, //  -111----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x76 v
+          0x00, //  --------
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x50, //  -1-1----
+          0x50, //  -1-1----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x77 w
+          0x00, //  --------
+          0x88, //  1---1---
+          0xa8, //  1-1-1---
+          0xa8, //  1-1-1---
+          0xa8, //  1-1-1---
+          0x50, //  -1-1----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x78 x
+          0x00, //  --------
+          0x88, //  1---1---
+          0x50, //  -1-1----
+          0x20, //  --1-----
+          0x50, //  -1-1----
+          0x88, //  1---1---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x00, //  --------  0x79 y
+          0x00, //  --------
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x88, //  1---1---
+          0x50, //  -1-1----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0x80, //  1-------
+        },
+        { 0x00, //  --------  0x7a z
+          0x00, //  --------
+          0xf8, //  11111---
+          0x10, //  ---1----
+          0x20, //  --1-----
+          0x40, //  -1------
+          0xf8, //  11111---
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x30, //  --11----  0x7b {
+          0x40, //  -1------
+          0x40, //  -1------
+          0x80, //  1-------
+          0x40, //  -1------
+          0x40, //  -1------
+          0x30, //  --11----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x20, //  --1-----  0x7c |
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x60, //  -11-----  0x7d }
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x08, //  ----1---
+          0x10, //  ---1----
+          0x10, //  ---1----
+          0x60, //  -11-----
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0x40, //  -1------  0x7e ~
+          0xa8, //  1-1-1---
+          0x10, //  ---1----
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+          0x00, //  --------
+        },
+        { 0xc0, //  11------  0x7f DEL
+          0xa0, //  1-1-----
+          0xa0, //  1-1-----
+          0xc0, //  11------
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x20, //  --1-----
+          0x38, //  --111---
+          0x00, //  --------
+        },
+    };
+
+    switch(ch) {
+    case 0x0a:  // LF
+        OLED_cursor_y += OLED_FONT_SIZE_Y;
+        if(OLED_cursor_y > OLED_ROW_MAX - OLED_FONT_SIZE_Y) {
+            OLED_cursor_y = 0;
+        }
+        break;
+
+    case 0x0d:  // CR
+        OLED_cursor_x = 0;
+        break;
+
+    default:
+        // print a font
+        OLED_set_column_address(OLED_cursor_x, OLED_cursor_x + OLED_FONT_SIZE_X - 1);
+        OLED_set_row_address(OLED_cursor_y, OLED_cursor_y + OLED_FONT_SIZE_Y - 1);
+        OLED_write_ram_command();
+        for(int i = 0; i < OLED_FONT_SIZE_Y; ++i) {
+            for(int j = 0x80; j > (0x80 >> OLED_FONT_SIZE_X); j >>= 1) {
+                OLED_write_pixel(font[ch][i] & j);
+            }
+        }
+        // increment cursor position
+        OLED_cursor_x += OLED_FONT_SIZE_X;
+        if(OLED_cursor_x > OLED_COLUMN_MAX - OLED_FONT_SIZE_X) {
+            OLED_cursor_x = 0;
+            OLED_cursor_y += OLED_FONT_SIZE_Y;
+            if(OLED_cursor_y > OLED_ROW_MAX - OLED_FONT_SIZE_Y) {
+                OLED_cursor_y = 0;
+            }
+        }
+    }
+
+}
--- a/Maple_OLED.h	Sun Oct 16 01:27:35 2011 +0000
+++ b/Maple_OLED.h	Sun Oct 30 21:20:23 2011 +0000
@@ -1,14 +1,85 @@
-//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]
-// OLED) driver
-#ifndef MAPLE_OLED_H_
-#define MAPLE_OLED_H_
-
-#endif
+//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]
+// OLED(UG-2828GDEDF11, SSD1351) driver
+#ifndef MAPLE_OLED_H_
+#define MAPLE_OLED_H_
+
+// SPI interface
+#define CS_ASSERT   0
+#define CS_NEGATE   1
+
+// OLED interface
+#define OLED_POWER_ON   1
+#define OLED_POWER_OFF  0
+#define OLED_RESET_ON   0
+#define OLED_RESET_OFF  1
+
+// OLED specification 
+#define OLED_COLUMN_MAX     0x7f
+#define OLED_ROW_MAX        0x7f
+
+// OLED font related 
+#define OLED_FONT_SIZE_X    6
+#define OLED_FONT_SIZE_Y    9
+
+// prototypes
+void OLED_cs_assert(int slot);
+void OLED_cs_negate();
+
+void OLED_set_column_address(int a, int b);
+void OLED_set_row_address(int a, int b);
+void OLED_write_ram_command();
+void OLED_read_ram_command();
+void OLED_set_remap_color_depth(int a);
+void OLED_set_display_start_line(int a);
+void OLED_set_display_offset(int a);
+void OLED_set_display_mode_all_off();
+void OLED_set_display_mode_all_on();
+void OLED_set_display_mode_normal();
+void OLED_set_display_mode_inverse();
+void OLED_function_selection(int a);
+void OLED_no_operation_ad();
+void OLED_set_sleep_mode_on();
+void OLED_set_sleep_mode_off();
+void OLED_no_operation_b0();
+void OLED_set_reset_pre_charge_period(int a);
+void OLED_display_enhancement(int a, int b, int c);
+void OLED_front_clock_divider_oscillator_frequency(int a);
+void OLED_set_segment_low_voltage();
+void OLED_set_GPIO(int a);
+void OLED_set_second_pre_charge_period(int a);
+void OLED_look_up_table_for_gray_scale_pulse_width();
+void OLED_use_built_in_linear_lut();
+void OLED_set_pre_charge_voltage(int a);
+void OLED_set_vcomh_voltage(int a);
+void OLED_set_contrast_for_color_abc(int a, int b, int c);
+void OLED_master_contrast_current_control(int a);
+void OLED_set_mux_ratio(int a);
+void OLED_no_operation_d1();
+void OLED_no_operation_e3();
+void OLED_set_command_lock(int a);
+void OLED_horizontal_scroll(int a, int b, int c, int d, int e);
+void OLED_stop_moving();
+void OLED_start_moving();
+
+void OLED_initialize();
+static void OLED_initialize_sub();
+
+void OLED_set_color(int mode, int a, int b, int c);
+void OLED_set_cursor(int x, int y);
+void OLED_clear_screen(int mode);
+void OLED_fill_rectangle(int mode, int cs, int cl, int rs, int rl);
+void OLED_write_pixel(int mode);
+
+void OLED_print_string(char s[]);
+void OLED_print_hex(int i);
+void OLED_print_character(char ch);
+
+#endif
--- a/Maple_alarm_clock.cpp	Sun Oct 16 01:27:35 2011 +0000
+++ b/Maple_alarm_clock.cpp	Sun Oct 30 21:20:23 2011 +0000
@@ -8,293 +8,203 @@
 //====================================================================
 // 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_LCD.h"
 #include "Maple.h"
 #include "mbed.h"
 
-// timer interrupt to refresh display
-Ticker alarm_clock_refresh_tick;
+// global variables defined in console.cpp
+extern int console_mode;
+extern int console_cursor;
 
-// global variables
-int alarm_clock_mode;
-int alarm_clock_cursor;
-int button_count[6];
-int button_status[6];
+// 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];
 
-// alarm_clock_initialize
-void alarm_clock_initialize() {
-    alarm_clock_refresh_tick.attach(&alarm_clock_refresh, ALARM_CLOCK_REFRESH_RATE);
-    alarm_clock_mode = MODE_NORMAL;
-    alarm_clock_cursor = CURSOR_NORMAL_ALARM_FLAG;
-    for (int i = 0; i < 6; ++i) {
-        button_count[i] = 0;
-        button_status[i] = BUTTON_IDLE;
+    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];
 }
 
-// refresh display, called by a ticker
-void alarm_clock_refresh() {
-    alarm_clock_refresh_display();
-    button_check();
+// 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];
 }
 
-// read RTC and print to LCD
-static void alarm_clock_refresh_display() {
-    const int cursor_row[4][10] = {
-        { 1,  1, 16, 16, 16, 16, 16, 16, 16, 16},   // MODE_NORMAL
-        { 0,  0,  0,  0,  1,  1,  1, 16, 16, 16},   // MODE_ADJUST
-        { 0,  0,  0,  0,  0,  0,  1,  1,  1,  1},   // MODE_ALARM
-        { 0,  0,  0,  0,  0,  0,  0,  1, 16, 16},   // MODE_TIMER
-    };
-    const int cursor_column[4][10] = {
-        {12, 15, 16, 16, 16, 16, 16, 16, 16, 16},   // NODE_NORMAL
-        { 1,  3,  6,  9,  1,  4,  7, 16, 16, 16},   // MODE_ADJUST
-        { 4,  6,  8, 11, 14, 15,  0,  2,  4,  6},   // MODE_ALARM
-        { 3,  8, 11, 12, 13, 14, 15,  6, 16, 16},   // MODE_TIMER
-    };
-    const char frequency_select[4][6] = { "32768", " 1024", "   32", "    1" };
-    const char timer_select[4][5] = { "4096", "  64", "   1", "1/60" };
-    char row0[17], row1[17], d[17], s[4];
+// 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);
-
-    switch(alarm_clock_mode) {
-    case MODE_NORMAL:
-        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'; }
-        }
-        break;
-
-    case MODE_ADJUST:
-        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));
-        }
-        break;
+    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];
+}
 
-    case MODE_ALARM:
-        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'; }
-        }
-        break;
+// 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];
 
-    case MODE_TIMER:
-        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, timer_select[d[RTC_REG_TIMER_CONTROL] & 0x03]);
-            copy_string(row0,  7, 2, int_to_hex2(d[RTC_REG_TIMER], s));
-            copy_string(row1,  2, 5, frequency_select[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'; }
-        }
-        break;
-    }    
-
-    LCD_cursor(LCD_CURSOR_OFF);
-    LCD_locate(0, 0);
-    LCD_print_string(row0);
-    LCD_locate(1, 0);
-    LCD_print_string(row1);
-    LCD_locate(cursor_row[alarm_clock_mode][alarm_clock_cursor], cursor_column[alarm_clock_mode][alarm_clock_cursor]);
-    LCD_cursor(LCD_CURSOR_ON);
+    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];
 }
 
-// read button and update button_on_count[i]
-//   called by timer tick interrupt
-static void button_check() {
-    char r = i2c_BTN_read();
-    button_on_check(r, BUTTON_A    );
-    button_on_check(r, BUTTON_B    );
-    button_on_check(r, BUTTON_LEFT );
-    button_on_check(r, BUTTON_DOWN );
-    button_on_check(r, BUTTON_RIGHT);
-    button_on_check(r, BUTTON_UP   );
-    if(button_trigger(BUTTON_A,     0, 0)) { button_exit();         }
-    if(button_trigger(BUTTON_B,     0, 0)) { button_function();     }
-    if(button_trigger(BUTTON_LEFT,  1, 0)) { button_cursor_move(0); }
-    if(button_trigger(BUTTON_RIGHT, 1, 0)) { button_cursor_move(1); }
-    if(button_trigger(BUTTON_DOWN,  1, 1)) { button_xxcrement(0);   }
-    if(button_trigger(BUTTON_UP,    1, 1)) { button_xxcrement(1);   }
+// enter mode clock
+void enter_mode_clock() {
+    console_mode = MODE_CLOCK;
+    console_cursor = CURSOR_CLOCK_INIT;
 }
 
-// button on check
-static void button_on_check(int read_data, int button_number) {
-    if((read_data & (0x01 << button_number)) == BUTTON_ON) {
-        ++button_count[button_number];
-    }
-    else {
-        button_count[button_number] = 0;
-        button_status[button_number] = BUTTON_IDLE;
-    }
+// enter mode adjust
+void enter_mode_adjust() {
+    console_mode = MODE_ADJUST;
+    console_cursor = CURSOR_ADJUST_INIT;
 }
 
-// button action trigger check
-//   b: button number
-//   r: repeat enable
-//   f: fast-repeat enable
-static bool button_trigger(int b, int r, int f) {
-    if((button_status[b] == BUTTON_IDLE) && (button_count[b] > BUTTON_THRESHOLD)) {
-        button_status[b] = BUTTON_BUSY;
-        return true;    // one shot
-    }
-    else if((f != 0) && (button_count[b] > BUTTON_FAST) && (button_count[b] % BUTTON_PERIOD_FAST == 0)) {
-        return true;    // repeat fast
-    }
-    else if((r != 0) && (button_count[b] > BUTTON_REPEAT) && (button_count[b] % BUTTON_PERIOD_REPEAT == 0)) {
-        return true;    // repeat
-    }
-    else {
-        return false;
-    }
+// enter mode alarm
+void enter_mode_alarm() {
+    console_mode = MODE_ALARM;
+    console_cursor = CURSOR_ALARM_INIT;
 }
 
-// exit to normal mode
-static void button_exit() {
-    alarm_clock_mode = MODE_NORMAL;
-    alarm_clock_cursor = CURSOR_NORMAL_ALARM_FLAG;
+// enter mode timer
+void enter_mode_timer() {
+    console_mode = MODE_TIMER;
+    console_cursor = CURSOR_TIMER_INIT;
 }
 
-// select a function
-static void button_function() {
-    switch(alarm_clock_mode) {
-    case MODE_NORMAL:
-        alarm_clock_mode = MODE_ADJUST;
-        alarm_clock_cursor = CURSOR_ADJUST_SECOND;
-        break;
-    case MODE_ADJUST:
-        alarm_clock_mode = MODE_ALARM;
-        alarm_clock_cursor = CURSOR_ALARM_FLAG;
-        break;
-    case MODE_ALARM:
-        alarm_clock_mode = MODE_TIMER;
-        alarm_clock_cursor = CURSOR_TIMER_FLAG;
-        break;
-    case MODE_TIMER:
-        alarm_clock_mode = MODE_NORMAL;
-        alarm_clock_cursor = CURSOR_NORMAL_ALARM_FLAG;
-        break;
-    }
+// 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
+// move cursor of alarm
 //   flag  0:left, 1:right
-static void button_cursor_move(int flag) {
-    const int max[4] = { CURSOR_NORMAL_MAX, CURSOR_ADJUST_MAX, CURSOR_ALARM_MAX, CURSOR_TIMER_MAX };
-
-    switch(flag) {
-    case 0:  // move left .. decrement
-        if(alarm_clock_cursor > 0) {
-            --alarm_clock_cursor;
-        }
-        else {
-            alarm_clock_cursor = max[alarm_clock_mode];
-        }
-        break;
-    case 1:  // move right .. increment
-        ++alarm_clock_cursor;
-        if(alarm_clock_cursor > max[alarm_clock_mode]) {
-            alarm_clock_cursor = 0;
-        }
-        break;
-    }
+void cursor_move_alarm(int flag) {
+    cursor_move(flag, CURSOR_ALARM_SIZE);
 }
 
-// increment/decrement
-//   flag 0:decrement, 1:increment
-static void button_xxcrement(int flag) {
-    switch(alarm_clock_mode) {
-    case MODE_NORMAL:
-        button_xxcrement_normal(flag);
-        break;
-    case MODE_ADJUST:
-        button_xxcrement_adjust(flag);
-        break;
-    case MODE_ALARM:
-        button_xxcrement_alarm(flag);
-        break;
-    case MODE_TIMER:
-        button_xxcrement_timer(flag);
-        break;
-    }
+// move cursor of timer
+//   flag  0:left, 1:right
+void cursor_move_timer(int flag) {
+    cursor_move(flag, CURSOR_TIMER_SIZE);
 }
 
-// increment/decrement for NORMAL
+// increment/decrement of clock
 //   flag  0:decrement, 1:increment
-static void button_xxcrement_normal(int flag) {
+void button_xxcrement_clock(int flag) {
     char d;
 
     d = RTC_read1(RTC_REG_CONTROL2);
-    switch(alarm_clock_cursor) {
-    case CURSOR_NORMAL_TIMER_FLAG:
+    switch(console_cursor) {
+    case CURSOR_CLOCK_TIMER_FLAG:
         d = d & 0x1b | (flag == 0 ? 0x00 : 0x04);
         break;
-    case CURSOR_NORMAL_ALARM_FLAG:
+    case CURSOR_CLOCK_ALARM_FLAG:
         d = d & 0x17 | (flag == 0 ? 0x00 : 0x08);
         break;
     }
     RTC_write1(RTC_REG_CONTROL2, d);
 }
 
-// increment/decrement for ADJUST
+// increment/decrement of adjust
 //   flag  0:decrement, 1:increment
-static void button_xxcrement_adjust(int flag) {
+void button_xxcrement_adjust(int flag) {
     char d;
 
-    switch(alarm_clock_cursor) {
+    switch(console_cursor) {
     case CURSOR_ADJUST_HOUR:
         d = RTC_stop_read1(RTC_REG_HOUR) & 0x3F;
         d = xxcrement_bcd(flag, d, 0x00, 0x23);
@@ -321,7 +231,7 @@
     char century, bcd_year, bcd_month, bcd_day, weekday, d;
 
     RTC_stop_read_date(century, bcd_year, bcd_month, bcd_day);
-    switch(alarm_clock_cursor) {
+    switch(console_cursor) {
     case CURSOR_ADJUST_CENTURY:
         century = xxcrement_bcd(flag, century, 0x00, 0x01);
         break;    
@@ -343,12 +253,12 @@
     RTC_write_date_start(century, bcd_year, bcd_month, bcd_day, weekday);
 }
 
-// increment/decrement for ALARM
+// increment/decrement of alarm
 //   flag  0:decrement, 1:increment
-static void button_xxcrement_alarm(int flag) {
+void button_xxcrement_alarm(int flag) {
     char d;
 
-    switch(alarm_clock_cursor) {
+    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);
@@ -396,12 +306,12 @@
     }
 }
 
-// increment/decrement for TIMER
+// increment/decrement of timer
 //   flag  0:decrement, 1:increment
-static void button_xxcrement_timer(int flag) {
+void button_xxcrement_timer(int flag) {
     char d;
 
-    switch(alarm_clock_cursor) {
+    switch(console_cursor) {
     case CURSOR_TIMER_SELECT:
         d = RTC_read1(RTC_REG_TIMER_CONTROL);
         d = xxcrement_bcd(flag, d & 0x03, 0x00, 0x03) | d & 0x80;
@@ -410,8 +320,8 @@
     case CURSOR_TIMER_COUNT:
         d = RTC_read1(RTC_REG_TIMER);
         switch(flag) {
-        case 0: --d; break;
-        case 1: ++d; break;
+        case 0:  --d; break;
+        default: ++d;
         }
         RTC_write1(RTC_REG_TIMER, d);
         break;
--- a/Maple_alarm_clock.h	Sun Oct 16 01:27:35 2011 +0000
+++ b/Maple_alarm_clock.h	Sun Oct 30 21:20:23 2011 +0000
@@ -12,16 +12,10 @@
 #define MAPLE_ALARM_CLOCK_H_
 
 // constants
-#define ALARM_CLOCK_REFRESH_RATE    0.1 // 100ms
-
-#define MODE_NORMAL 0
-#define MODE_ADJUST 1
-#define MODE_ALARM  2
-#define MODE_TIMER  3
-
-#define CURSOR_NORMAL_TIMER_FLAG    0
-#define CURSOR_NORMAL_ALARM_FLAG    1
-#define CURSOR_NORMAL_MAX           1
+#define CURSOR_CLOCK_TIMER_FLAG    0
+#define CURSOR_CLOCK_ALARM_FLAG    1
+#define CURSOR_CLOCK_SIZE          2
+#define CURSOR_CLOCK_INIT          1
 
 #define CURSOR_ADJUST_CENTURY   0
 #define CURSOR_ADJUST_YEAR      1
@@ -30,7 +24,8 @@
 #define CURSOR_ADJUST_HOUR      4
 #define CURSOR_ADJUST_MINUTE    5
 #define CURSOR_ADJUST_SECOND    6
-#define CURSOR_ADJUST_MAX       6
+#define CURSOR_ADJUST_SIZE      7
+#define CURSOR_ADJUST_INIT      6
 
 #define CURSOR_ALARM_DAY_DISABLE        0
 #define CURSOR_ALARM_DAY                1
@@ -42,7 +37,8 @@
 #define CURSOR_ALARM_HOUR               7
 #define CURSOR_ALARM_MINUTE_DISABLE     8
 #define CURSOR_ALARM_MINUTE             9
-#define CURSOR_ALARM_MAX                9
+#define CURSOR_ALARM_SIZE               10
+#define CURSOR_ALARM_INIT               5
 
 #define CURSOR_TIMER_SELECT     0
 #define CURSOR_TIMER_COUNT      1
@@ -52,43 +48,29 @@
 #define CURSOR_TIMER_INTERRUPT  5
 #define CURSOR_TIMER_FLAG       6
 #define CURSOR_CLKOUT_FREQUENCY 7
-#define CURSOR_TIMER_MAX        7
-
-#define BUTTON_A       0
-#define BUTTON_B       1
-#define BUTTON_LEFT    2
-#define BUTTON_DOWN    3
-#define BUTTON_RIGHT   4
-#define BUTTON_UP      5
+#define CURSOR_TIMER_SIZE       8
+#define CURSOR_TIMER_INIT       6
 
-#define BUTTON_ON      0
-#define BUTTON_OFF     1
-
-#define BUTTON_THRESHOLD        0   // 0 x 100ms
-#define BUTTON_REPEAT           10  // 1s
-#define BUTTON_FAST             40  // 4s
-#define BUTTON_PERIOD_REPEAT    3   // 300ms
-#define BUTTON_PERIOD_FAST      1   // 100ms
+// proto types
+void display_clock( char row0[], char row1[], int &cursor_r, int &cursor_c);
+void display_adjust(char row0[], char row1[], int &cursor_r, int &cursor_c);
+void display_alarm( char row0[], char row1[], int &cursor_r, int &cursor_c);
+void display_timer( char row0[], char row1[], int &cursor_r, int &cursor_c);
 
-#define BUTTON_IDLE 0   // button status not active
-#define BUTTON_BUSY 1   // button status active once and repeat
-
-// prototypes
-void alarm_clock_initialize();
-void alarm_clock_refresh();
+void enter_mode_clock();
+void enter_mode_adjust();
+void enter_mode_alarm();
+void enter_mode_timer();
 
-static void alarm_clock_refresh_display();
-static void button_check();
-static void button_on_check(int read_data, int button_numer);
-static bool button_trigger(int button_numer, int repeat_enable, int fast_repeat_enable);
-static void button_exit();
-static void button_function();
-static void button_cursor_move(int flag);
-static void button_xxcrement(int flag);
-static void button_xxcrement_normal(int flag);
-static void button_xxcrement_adjust(int flag);
+void cursor_move_clock( int flag);
+void cursor_move_adjust(int flag);
+void cursor_move_alarm( int flag);
+void cursor_move_timer( int flag);
+
+void button_xxcrement_clock( int flag);
+void button_xxcrement_adjust(int flag);
 static void button_xxcrement_adjust_date(int flag);
-static void button_xxcrement_alarm(int flag);
-static void button_xxcrement_timer(int flag);
+void button_xxcrement_alarm( int flag);
+void button_xxcrement_timer( int flag);
 
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Maple_console.cpp	Sun Oct 30 21:20:23 2011 +0000
@@ -0,0 +1,188 @@
+//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]
+// operation console utilizing text-LCD and buttons
+#include "Maple_console.h"
+#include "Maple_alarm_clock.h"
+#include "Maple_test.h"
+#include "Maple_RTC.h"
+#include "Maple_I2C.h"
+#include "Maple_LCD.h"
+#include "Maple.h"
+#include "mbed.h"
+
+// global variables
+int console_mode;       // console function selected
+int console_cursor;     // cursor position
+int console_display;    // console display on/off
+int button_count[BUTTON_SIZE];
+int button_status[BUTTON_SIZE];
+int test_mode;          // used within test
+
+// timer interrupt to refresh console
+Ticker console_refresh_tick;
+
+// initialize console
+void console_initialize() {
+    enter_mode_clock();
+    console_display = DISPLAY_ON;
+    for (int i = 0; i < BUTTON_SIZE; ++i) {
+        button_count[i] = 0;
+        button_status[i] = BUTTON_IDLE;
+    }
+    console_refresh_tick.attach(&console_refresh, CONSOLE_REFRESH_RATE);
+}
+
+// refresh console called by ticker interrupt
+void console_refresh() {
+    refresh_display();
+    button_action();
+}
+
+// read RTC and print to LCD
+static void refresh_display() {
+    char row0[17], row1[17];
+    int cursor_r, cursor_c;
+
+    switch(console_mode) {
+    case MODE_ADJUST:  display_adjust(row0, row1, cursor_r, cursor_c);  break;
+    case MODE_ALARM:   display_alarm( row0, row1, cursor_r, cursor_c);  break;
+    case MODE_TIMER:   display_timer( row0, row1, cursor_r, cursor_c);  break;
+    case MODE_TEST:    display_test(  row0, row1, cursor_r, cursor_c);  break;
+    default:           display_clock( row0, row1, cursor_r, cursor_c);
+    }
+    if(console_display == DISPLAY_ON) {
+        LCD_cursor_off();
+        LCD_locate(0, 0);  LCD_print_string(row0);
+        LCD_locate(1, 0);  LCD_print_string(row1);
+        LCD_locate(cursor_r, cursor_c);
+        LCD_cursor_on();
+    }
+}
+
+// read button and launch action
+//   called by timer tick interrupt
+static void button_action() {
+    char r = i2c_BTN_read();
+    button_check(r, BUTTON_A    );
+    button_check(r, BUTTON_B    );
+    button_check(r, BUTTON_LEFT );
+    button_check(r, BUTTON_DOWN );
+    button_check(r, BUTTON_RIGHT);
+    button_check(r, BUTTON_UP   );
+    if(button_trigger(BUTTON_A,     0, 0)) { button_exit();         }
+    if(button_trigger(BUTTON_B,     1, 0)) { button_function();     }
+    if(button_trigger(BUTTON_LEFT,  1, 0)) { button_cursor_move(0); }
+    if(button_trigger(BUTTON_RIGHT, 1, 0)) { button_cursor_move(1); }
+    if(button_trigger(BUTTON_DOWN,  1, 1)) { button_xxcrement(0);   }
+    if(button_trigger(BUTTON_UP,    1, 1)) { button_xxcrement(1);   }
+}
+
+// button check and count up
+static void button_check(int r, int button_number) {
+    if((r & (0x01 << button_number)) == BUTTON_ON) {
+        ++button_count[button_number];
+    }
+    else {
+        button_count[button_number] = 0;
+        button_status[button_number] = BUTTON_IDLE;
+    }
+}
+
+// button action trigger
+//   b: button number
+//   r: repeat enable
+//   f: fast-repeat enable
+static bool button_trigger(int b, int r, int f) {
+    if((button_status[b] == BUTTON_IDLE) && (button_count[b] > BUTTON_THRESHOLD)) {
+        button_status[b] = BUTTON_BUSY;
+        return true;    // one shot
+    }
+    else if((f != 0) && (button_count[b] > BUTTON_FAST) && (button_count[b] % BUTTON_PERIOD_FAST == 0)) {
+        return true;    // repeat fast
+    }
+    else if((r != 0) && (button_count[b] > BUTTON_REPEAT) && (button_count[b] % BUTTON_PERIOD_REPEAT == 0)) {
+        return true;    // repeat
+    }
+    else {
+        return false;
+    }
+}
+
+// exit to normal mode
+void button_exit() {
+    LCD_clear_display();
+    console_display = DISPLAY_ON;
+    enter_mode_clock();
+}
+
+// select a function
+static void button_function() {
+    switch(console_mode) {
+    case MODE_CLOCK:   enter_mode_adjust();  break;
+    case MODE_ADJUST:  enter_mode_alarm();   break;
+    case MODE_ALARM:   enter_mode_timer();   break;
+    case MODE_TIMER:   enter_mode_test();    break;
+    case MODE_TEST:    test_function();      break;
+    default:           button_exit();
+    }
+}
+
+// move cursor
+//   flag  0:left, 1:right
+static void button_cursor_move(int flag) {
+    switch(console_mode) {
+    case MODE_ADJUST:  cursor_move_adjust(flag);  break;
+    case MODE_ALARM:   cursor_move_alarm( flag);  break;
+    case MODE_TIMER:   cursor_move_timer( flag);  break;
+    case MODE_TEST:    cursor_move_test(  flag);  break;
+    default:           cursor_move_clock( flag);
+    }
+}
+
+// move cursor common
+//   flag  0:left, 1:right
+void cursor_move(int flag, int cursor_size) {
+    switch(flag) {
+    case 0:     // move left .. decrement
+        if(console_cursor > 0) {
+            --console_cursor;
+        }
+        else {
+            console_cursor = cursor_size - 1;
+        }
+        break;
+    default:    // move right .. increment
+        ++console_cursor;
+        if(console_cursor >= cursor_size) {
+            console_cursor = 0;
+        }
+    }
+}
+
+// increment/decrement
+//   flag 0:decrement, 1:increment
+static void button_xxcrement(int flag) {
+    switch(console_mode) {
+    case MODE_ADJUST:
+        button_xxcrement_adjust(flag);
+        break;
+    case MODE_ALARM:
+        button_xxcrement_alarm(flag);
+        break;
+    case MODE_TIMER:
+        button_xxcrement_timer(flag);
+        break;
+    case MODE_TEST:
+        button_xxcrement_test(flag);
+        break;
+    default:
+        button_xxcrement_clock(flag);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Maple_console.h	Sun Oct 30 21:20:23 2011 +0000
@@ -0,0 +1,60 @@
+//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]
+// operation console utilizing text-LCD and buttons
+#ifndef MAPLE_CONSOLE_H_
+#define MAPLE_CONSOLE_H_
+
+// constants
+#define CONSOLE_REFRESH_RATE    0.1 // 100ms
+
+#define DISPLAY_OFF     0
+#define DISPLAY_ON      1
+
+#define MODE_CLOCK      0
+#define MODE_ADJUST     1
+#define MODE_ALARM      2
+#define MODE_TIMER      3
+#define MODE_TEST       4
+
+#define BUTTON_A        0
+#define BUTTON_B        1
+#define BUTTON_LEFT     2
+#define BUTTON_DOWN     3
+#define BUTTON_RIGHT    4
+#define BUTTON_UP       5
+#define BUTTON_SIZE     6
+
+#define BUTTON_OFF      1
+#define BUTTON_ON       0
+
+#define BUTTON_THRESHOLD        0   // 0 x 100ms
+#define BUTTON_REPEAT           10  // 1s
+#define BUTTON_FAST             40  // 4s
+#define BUTTON_PERIOD_REPEAT    3   // 300ms
+#define BUTTON_PERIOD_FAST      1   // 100ms
+
+#define BUTTON_IDLE 0   // button status not active
+#define BUTTON_BUSY 1   // button status active once and repeat
+
+// proto types
+void console_initialize();
+void console_refresh();
+
+static void refresh_display();
+static void button_action();
+static void button_check(int r, int button_number);
+static bool button_trigger(int b, int r, int f);
+void button_exit();
+static void button_function();
+static void button_cursor_move(int flag);
+void cursor_move(int flag, int cursor_max);
+static void button_xxcrement(int flag);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Maple_test.cpp	Sun Oct 30 21:20:23 2011 +0000
@@ -0,0 +1,412 @@
+//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]
+// main
+#include "Maple_test.h"
+#include "Maple_console.h"
+#include "Maple_OLED.h"
+#include "Maple_LCD.h"
+#include "Maple_RTC.h"
+#include "Maple_I2C.h"
+#include "Maple.h"
+#include "mbed.h"
+
+// global variables
+extern int console_mode;
+extern int console_cursor;
+extern int console_display;
+extern int test_mode;
+int test_choice;
+int test_char_base;
+int test_color[6];
+int test_color_cursor;
+
+// test
+// display menu
+void display_test(char row0[], char row1[], int &cursor_r, int &cursor_c) {
+    const int position_r[CURSOR_TEST_SIZE] = {  0};
+    const int position_c[CURSOR_TEST_SIZE] = {  0};
+    const char select_t[9][17] = {
+        "(select Up/Down)",
+        " LCD all-font   ",
+        " LCD shift-R/L  ",
+        " RTC raw-read   ",
+        " OLED color 1   ",
+        " OLED color 2a  ",
+        " OLED color 2b  ",
+        " OLED color 2c  ",
+        " OLED color font",
+    };
+    char d[17], s[3];
+
+    switch(test_mode) {
+    case TEST_FONT:
+        console_display = DISPLAY_OFF;
+        break;
+        
+    case TEST_SHIFT:
+        console_display = DISPLAY_OFF;
+        break;
+        
+    case TEST_RTCRAW:
+        LCD_return_home();
+        console_display = DISPLAY_ON;
+        i2c_RTC_read(RTC_REG_CONTROL1, d, 16);
+        for(int i = 0; i < 8; ++i) {
+            copy_string(row0, i * 2, 2, int_to_hex2(d[i], s));
+            row0[16] = '\0';
+        }
+        for(int i = 0; i < 8; ++i) {
+            copy_string(row1, i * 2, 2, int_to_hex2(d[i + 8], s));
+            row1[16] = '\0';
+        }
+        break;
+        
+    case TEST_OLEDCF:
+        LCD_return_home();
+        console_display = DISPLAY_ON;
+        copy_string(row0, 0, 17, ">OLED color font");
+        copy_string(row1, 0, 17, "exit<B>     test");
+        break;
+        
+    default:
+        LCD_return_home();
+        console_display = DISPLAY_ON;
+        copy_string(row0, 0, 17, select_t[test_choice]);
+        copy_string(row1, 0, 17, "exec<B>     test");
+    }
+    cursor_r = position_r[console_cursor];
+    cursor_c = position_c[console_cursor];
+}
+
+// enter mode test
+void enter_mode_test() {
+    console_mode = MODE_TEST;
+    console_cursor = CURSOR_TEST_INIT;
+    test_mode = TEST_HOME;
+    test_choice = TEST_HOME;
+}
+
+// function select
+void test_function() {
+    switch(test_choice) {
+    case TEST_FONT:
+        if(test_mode == TEST_FONT) {
+            test_mode = TEST_HOME;
+        }
+        else {
+            test_mode = TEST_FONT;
+            test_char_base = 0x20;
+            LCD_print_n_char(test_char_base, 0x10);
+        }
+        break;
+
+    case TEST_SHIFT:
+        if(test_mode == TEST_SHIFT) {
+            test_mode = TEST_HOME;
+        }
+        else {
+            test_mode = TEST_SHIFT;
+            test_char_base = 0x40;
+            LCD_print_n_char(test_char_base, 0x20);
+        }
+        break;
+
+    case TEST_RTCRAW:
+        if(test_mode == TEST_RTCRAW) {
+            test_mode = TEST_HOME;
+        }
+        else {
+            test_mode = TEST_RTCRAW;
+        }
+        break;
+
+    case TEST_OLEDC1:
+        test_mode = TEST_HOME;
+        OLED_test_c1();
+        break;
+
+    case TEST_OLEDC2A:
+        test_mode = TEST_HOME;
+        OLED_test_c2a();
+        break;
+
+    case TEST_OLEDC2B:
+        test_mode = TEST_HOME;
+        OLED_test_c2b();
+        break;
+
+    case TEST_OLEDC2C:
+        test_mode = TEST_HOME;
+        OLED_test_c2c();
+        break;
+
+    case TEST_OLEDCF:
+        if(test_mode == TEST_OLEDCF) {
+            test_mode = TEST_HOME;
+        }
+        else {
+            test_mode = TEST_OLEDCF;
+            test_color_cursor = 0;
+            test_color[0] = 0x30;
+            test_color[1] = 0x30;
+            test_color[2] = 0x30;
+            test_color[3] = 0x10;
+            test_color[4] = 0x10;
+            test_color[5] = 0x10;
+            OLED_test_cf();
+        }
+        break;
+
+    default:
+        button_exit();
+    }
+}
+
+// left, right
+void cursor_move_test(int flag) {
+    switch(test_mode) {
+    case TEST_SHIFT:
+        LCD_cursor_or_display_shift(1, flag?0:1);
+        break;
+
+    case TEST_OLEDCF:
+        switch(flag) {
+        case 0:     // move left .. decrement
+            if(test_color_cursor == 0) {
+                test_color_cursor = 6;
+            }
+            --test_color_cursor;
+            break;
+        default:    // move right .. increment
+            ++test_color_cursor;
+            if(test_color_cursor >= 6) {
+                test_color_cursor = 0;
+            }
+        }
+        OLED_test_cf();
+        break;
+
+    default:
+        test_mode = TEST_HOME;
+    }
+}
+
+// increment, decrement
+void button_xxcrement_test(int flag) {
+    switch(test_mode) {
+    case TEST_HOME:
+        switch(flag) {
+        case 0:
+            ++test_choice;
+            if(test_choice == TEST_SIZE) {
+                test_choice = 0;
+            }
+            break;    
+        default:
+            if(test_choice == 0) {
+                test_choice = TEST_SIZE;
+            }
+            --test_choice;
+        }
+        break;
+
+    case TEST_FONT:
+        switch(flag) {
+        case 0:
+            if(test_char_base > 0x00) {
+                test_char_base -= 0x20;
+            }
+            break;
+        default:
+            if(test_char_base < 0xe0) {
+                test_char_base += 0x20;
+            }
+        }
+        LCD_print_n_char(test_char_base, 0x10);
+        break;
+
+    case TEST_SHIFT:
+        switch(flag) {
+        case 0:
+            if(test_char_base > 0x00) {
+                test_char_base -= 0x40;
+            }
+            break;    
+        default:
+            if(test_char_base < 0xc0) {
+                test_char_base += 0x40;
+            }
+        }
+        LCD_print_n_char(test_char_base, 0x20);
+        break;
+
+    case TEST_OLEDCF:
+        switch(flag) {
+        case 0:
+            if(test_color[test_color_cursor] > 0) {
+                --test_color[test_color_cursor];
+            }
+            break;
+        default:
+            if(test_color[test_color_cursor] < 0x3f) {
+                ++test_color[test_color_cursor];
+            }
+        }
+        OLED_test_cf();
+        break;
+
+    default:
+        test_mode = TEST_HOME;
+    }
+}
+
+// print n characters in 2 lines
+static void LCD_print_n_char(char base, int length) {
+    LCD_locate(0, 0);
+    for(int i = 0; i < length; ++i) {
+        LCD_print_char(base + i);
+    }
+    LCD_locate(1, 0);
+    for(int i = length; i < length * 2; ++i) {
+        LCD_print_char(base + i);
+    }
+}
+
+// OLED test: color variation 1
+void OLED_test_c1() {
+    int a, b, c;
+
+    OLED_cs_assert(1);
+    OLED_cs_assert(2);
+    for(b = 0; b < 0x40; ++b) {
+        for(c = 0; c < 0x40; ++c) {
+            OLED_set_color(1, 0, b, c);
+            OLED_fill_rectangle(1, c, 1, b, 1);
+        }
+    }
+    for(c = 0; c < 0x40; ++c) {
+        for(a = 0; a < 0x40; ++a) {
+            OLED_set_color(1, a, 0, c);
+            OLED_fill_rectangle(1, 0x40 + a, 1, c, 1);
+        }
+    }
+    for(a = 0; a < 0x40; ++a) {
+        for(b = 0; b < 0x40; ++b) {
+            OLED_set_color(1, a, b, 0);
+            OLED_fill_rectangle(1, b, 1, 0x40 + a, 1);
+        }
+    }
+    for(int i = 0; i < 0x40; ++i) {
+        OLED_set_color(1, i, 0, 0);
+        OLED_fill_rectangle(1, 0x40 + i, 1, 0x40, 0x10);
+        OLED_set_color(1, 0, i, 0);
+        OLED_fill_rectangle(1, 0x40 + i, 1, 0x50, 0x10);
+        OLED_set_color(1, 0, 0, i);
+        OLED_fill_rectangle(1, 0x40 + i, 1, 0x60, 0x10);
+        OLED_set_color(1, i, i, i);
+        OLED_fill_rectangle(1, 0x40 + i, 1, 0x70, 0x10);
+    }
+    OLED_cs_negate();
+}
+
+// OLED test: color variation 2a
+void OLED_test_c2a() {
+    OLED_cs_assert(1);
+    OLED_cs_assert(2);
+    for(int i = 0; i < 0x80; ++i) {
+        for(int j = 0; j < 0x80; ++j) {
+            OLED_set_color(1, (j / 0x20) * 0x10 + (i / 0x20) * 0x04, (i % 0x20) * 2, (j % 0x20) * 2);
+            OLED_fill_rectangle(1, i, 1, j, 1);
+        }
+    }
+    OLED_cs_negate();
+}
+
+// OLED test: color variation 2b
+void OLED_test_c2b() {
+    OLED_cs_assert(1);
+    OLED_cs_assert(2);
+    for(int i = 0; i < 0x80; ++i) {
+        for(int j = 0; j < 0x80; ++j) {
+            OLED_set_color(1, (j % 0x20) * 2, (j / 0x20) * 0x10 + (i / 0x20) * 0x04, (i % 0x20) * 2);
+            OLED_fill_rectangle(1, i, 1, j, 1);
+        }
+    }
+    OLED_cs_negate();
+}
+
+// OLED test: color variation 2c
+void OLED_test_c2c() {
+    OLED_cs_assert(1);
+    OLED_cs_assert(2);
+    for(int i = 0; i < 0x80; ++i) {
+        for(int j = 0; j < 0x80; ++j) {
+            OLED_set_color(1, (i % 0x20) * 2, (j % 0x20) * 2, (j / 0x20) * 0x10 + (i / 0x20) * 0x04);
+            OLED_fill_rectangle(1, i, 1, j, 1);
+        }
+    }
+    OLED_cs_negate();
+}
+
+// OLED test: color variation 1
+void OLED_test_cf() {
+    OLED_cs_assert(1);
+    OLED_cs_assert(2);
+
+    OLED_set_color(0, 0, 0, 0);
+    OLED_clear_screen(0);
+
+    for(int i = 0; i < 6; ++i) {
+        if(i < 3) {
+            OLED_set_cursor( i * 0x10, 0x71);
+        }
+        else {
+            OLED_set_cursor( i * 0x10 + 0x10, 0x71);
+        }
+        if(i == test_color_cursor) {
+            OLED_set_color(1, 0, 0, 0);
+            OLED_set_color(0, 0x3f, 0x3f, 0x3f);
+        }
+        else {
+            OLED_set_color(0, 0, 0, 0);
+            OLED_set_color(1, 0x3f, 0x3f, 0x3f);
+        }
+        OLED_print_hex(test_color[i]);
+    } 
+
+    OLED_set_color(1, test_color[0], test_color[1], test_color[2]);
+    OLED_fill_rectangle(1, 0x00, 0x30, 0x40, 0x10);
+    OLED_set_color(1, test_color[0], 0, 0);
+    OLED_fill_rectangle(1, 0x00, 0x10, 0x50, 0x20);
+    OLED_set_color(1, 0, test_color[1], 0);
+    OLED_fill_rectangle(1, 0x10, 0x10, 0x50, 0x20);
+    OLED_set_color(1, 0, 0, test_color[2]);
+    OLED_fill_rectangle(1, 0x20, 0x10, 0x50, 0x20);
+
+    OLED_set_color(0, test_color[3], test_color[4], test_color[5]);
+    OLED_fill_rectangle(0, 0x40, 0x30, 0x40, 0x10);
+    OLED_set_color(0, test_color[3], 0, 0);
+    OLED_fill_rectangle(0, 0x40, 0x10, 0x50, 0x20);
+    OLED_set_color(0, 0, test_color[4], 0);
+    OLED_fill_rectangle(0, 0x50, 0x10, 0x50, 0x20);
+    OLED_set_color(0, 0, 0, test_color[5]);
+    OLED_fill_rectangle(0, 0x60, 0x10, 0x50, 0x20);
+
+    OLED_set_color(1, test_color[0], test_color[1], test_color[2]);
+    OLED_set_color(0, test_color[3], test_color[4], test_color[5]);
+    OLED_set_cursor(0, 0);
+    for(int i = 0x20; i < 0x80; i += 0x10) {
+        for(char ch = i; ch < i + 0x10; ++ch) {
+            OLED_print_character(ch);
+        }
+        OLED_print_string("\r\n");
+    }
+    OLED_cs_negate();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Maple_test.h	Sun Oct 30 21:20:23 2011 +0000
@@ -0,0 +1,42 @@
+//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]
+// common functions
+#ifndef MAPLE_TEST_H_
+#define MAPLE_TEST_H_
+
+// constants
+#define CURSOR_TEST_HOME    0
+#define CURSOR_TEST_SIZE    1
+#define CURSOR_TEST_INIT    0
+
+#define TEST_HOME       0
+#define TEST_FONT       1
+#define TEST_SHIFT      2
+#define TEST_RTCRAW     3
+#define TEST_OLEDC1     4
+#define TEST_OLEDC2A    5
+#define TEST_OLEDC2B    6
+#define TEST_OLEDC2C    7
+#define TEST_OLEDCF     8
+#define TEST_SIZE       9
+
+//prototypes for test
+void display_test(char row0[], char row1[], int &cursor_r, int &cursor_c);
+void enter_mode_test();
+void test_function();
+void cursor_move_test(int flag);
+void button_xxcrement_test(int flag);
+static void LCD_print_n_char(char base, int length);
+static void OLED_test_c1();
+static void OLED_test_c2a();
+static void OLED_test_c2b();
+static void OLED_test_c2c();
+static void OLED_test_cf();
+#endif
\ No newline at end of file
--- a/main.cpp	Sun Oct 16 01:27:35 2011 +0000
+++ b/main.cpp	Sun Oct 30 21:20:23 2011 +0000
@@ -8,18 +8,21 @@
 //====================================================================
 // MAPLE board[MARM01-BASE]
 // main
-#include "Maple_alarm_clock.h"
+#include "Maple_test.h"
+#include "Maple_console.h"
+#include "Maple_OLED.h"
+#include "Maple_LCD.h"
 #include "Maple_RTC.h"
 #include "Maple_I2C.h"
-#include "Maple_LCD.h"
 #include "Maple.h"
 #include "mbed.h"
 
 int main() {
+    OLED_initialize();
     LCD_initialize();
     RTC_initialize();
-    alarm_clock_initialize();
-
+    console_initialize();
+    
     // wait interrupt
     while(1) {
     }