Index: asp3_tinet_ecnl_rx/trunk/ntshell/src/mbed_api.c
===================================================================
--- asp3_tinet_ecnl_rx/trunk/ntshell/src/mbed_api.c	(revision 337)
+++ asp3_tinet_ecnl_rx/trunk/ntshell/src/mbed_api.c	(revision 364)
@@ -1,7 +1,7 @@
 /*
  *  TOPPERS ECHONET Lite Communication Middleware
- * 
- *  Copyright (C) 2014-2017 Cores Co., Ltd. Japan
- * 
+ *
+ *  Copyright (C) 2014-2018 Cores Co., Ltd. Japan
+ *
  *  上記著作権者は，以下の(1)～(4)の条件を満たす場合に限り，本ソフトウェ
  *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
@@ -26,5 +26,5 @@
  *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
  *      免責すること．
- * 
+ *
  *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
  *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
@@ -32,5 +32,5 @@
  *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
  *  の責任を負わない．
- * 
+ *
  *  @(#) $Id$
  */
@@ -42,4 +42,7 @@
 #include "rx630.h"
 #include "ff.h"
+#include "target_stddef.h"
+#include "target_kernel_impl.h"
+#include "scif.h"
 
  /* PWM出力(490Hz) */
@@ -64,4 +67,7 @@
 void gpio_init(gpio_t *obj, PinName pin)
 {
+	obj->pin = pin;
+	obj->dir = PIN_INPUT;
+	obj->mode = PullDefault;
 }
 
@@ -83,35 +89,37 @@
 	/* 汎用入出力ポートに設定 */
 	switch (pin) {
-	case 0:
+	case D0:
 		/* P21 */
 		sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) & ~PORT_PMR_B1_BIT);
 		break;
-	case 1:
+	case D1:
 		/* P20 */
 		sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) & ~PORT_PMR_B0_BIT);
 		break;
-	case 2:
+	case D2:
 		/* P22 */
 		sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) & ~PORT_PMR_B2_BIT);
 		break;
-	case 3:
+	case D3:
 		/* P23 */
 		sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) & ~PORT_PMR_B3_BIT);
 		break;
-	case 4:
+	case D4:
 		/* P24 */
 		sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) & ~PORT_PMR_B4_BIT);
 		break;
-	case 5:
+	case D5:
 		/* P25 */
 		sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) & ~PORT_PMR_B5_BIT);
 		break;
-	case 6:
+	case D6:
 		/* P32 */
 		sil_wrb_mem(PORT3_PMR_ADDR, sil_reb_mem(PORT3_PMR_ADDR) & ~PORT_PMR_B2_BIT);
 		break;
-	case 7:
+	case D7:
 		/* P33 */
 		sil_wrb_mem(PORT3_PMR_ADDR, sil_reb_mem(PORT3_PMR_ADDR) & ~PORT_PMR_B3_BIT);
+		break;
+	default:
 		break;
 	}
@@ -124,5 +132,5 @@
 	switch (pin) {
 		/* P21/TIOCA3 */
-	case 0:
+	case D0:
 		if (gpio) {
 			/* P21端子機能制御レジスタ P21とする */
@@ -136,5 +144,5 @@
 		break;
 		/* P20/TIOCB3 */
-	case 1:
+	case D1:
 		if (gpio) {
 			/* P20端子機能制御レジスタ P20とする */
@@ -148,5 +156,5 @@
 		break;
 		/* P22/TIOCC3 */
-	case 2:
+	case D2:
 		if (gpio) {
 			/* P22端子機能制御レジスタ P22とする */
@@ -160,5 +168,5 @@
 		break;
 		/* P23/TIOCD3 */
-	case 3:
+	case D3:
 		if (gpio) {
 			/* P23端子機能制御レジスタ P23とする */
@@ -172,5 +180,5 @@
 		break;
 		/* P24/TIOCB4 */
-	case 4:
+	case D4:
 		if (gpio) {
 			/* P24端子機能制御レジスタ P24とする */
@@ -184,5 +192,5 @@
 		break;
 		/* P25/TIOCA4 */
-	case 5:
+	case D5:
 		if (gpio) {
 			/* P25端子機能制御レジスタ P25とする */
@@ -196,5 +204,5 @@
 		break;
 		/* P32/TIOCC0 */
-	case 6:
+	case D6:
 		if (gpio) {
 			/* P32端子機能制御レジスタ P32とする */
@@ -208,5 +216,5 @@
 		break;
 		/* P33/TIOCD0 */
-	case 7:
+	case D7:
 		if (gpio) {
 			/* P33端子機能制御レジスタ P33とする */
@@ -218,4 +226,6 @@
 		}
 		result = E_OK;
+		break;
+	default:
 		break;
 	}
@@ -228,43 +238,45 @@
 		switch (pin) {
 			/* P21/TIOCA3 */
-		case 0:
+		case D0:
 			sil_wrb_mem(PORT2_PDR_ADDR, sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B1_BIT);
 			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B1_BIT);
 			break;
 			/* P20/TIOCB3 */
-		case 1:
+		case D1:
 			sil_wrb_mem(PORT2_PDR_ADDR, sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B0_BIT);
 			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B0_BIT);
 			break;
 			/* P22/TIOCC3 */
-		case 2:
+		case D2:
 			sil_wrb_mem(PORT2_PDR_ADDR, sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B2_BIT);
 			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B2_BIT);
 			break;
 			/* P23/TIOCD3 */
-		case 3:
+		case D3:
 			sil_wrb_mem(PORT2_PDR_ADDR, sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B3_BIT);
 			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B3_BIT);
 			break;
 			/* P24/TIOCB4 */
-		case 4:
+		case D4:
 			sil_wrb_mem(PORT2_PDR_ADDR, sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B4_BIT);
 			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B4_BIT);
 			break;
 			/* P25/TIOCA4 */
-		case 5:
+		case D5:
 			sil_wrb_mem(PORT2_PDR_ADDR, sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B5_BIT);
 			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B5_BIT);
 			break;
 			/* P32/TIOCC0 */
-		case 6:
+		case D6:
 			sil_wrb_mem(PORT3_PDR_ADDR, sil_reb_mem(PORT3_PDR_ADDR) | PORT_PDR_B2_BIT);
 			sil_wrb_mem(PORT3_PMR_ADDR, sil_reb_mem(PORT3_PMR_ADDR) | PORT_PMR_B2_BIT);
 			break;
 			/* P33/TIOCD0 */
-		case 7:
+		case D7:
 			sil_wrb_mem(PORT3_PDR_ADDR, sil_reb_mem(PORT3_PDR_ADDR) | PORT_PDR_B3_BIT);
 			sil_wrb_mem(PORT3_PMR_ADDR, sil_reb_mem(PORT3_PMR_ADDR) | PORT_PMR_B3_BIT);
 			break;
+		default:
+			break;
 		}
 	}
@@ -280,57 +292,57 @@
 
 	switch (obj->pin) {
-	case 0:
+	case D0:
 		/* P21 */
 		pdr = PORT2_PDR_ADDR; bit = PORT_PDR_B1_BIT;
 		break;
-	case 1:
+	case D1:
 		/* P20 */
 		pdr = PORT2_PDR_ADDR; bit = PORT_PDR_B0_BIT;
 		break;
-	case 2:
+	case D2:
 		/* P22 */
 		pdr = PORT2_PDR_ADDR; bit = PORT_PDR_B2_BIT;
 		break;
-	case 3:
+	case D3:
 		/* P23 */
 		pdr = PORT2_PDR_ADDR; bit = PORT_PDR_B3_BIT;
 		break;
-	case 4:
+	case D4:
 		/* P24 */
 		pdr = PORT2_PDR_ADDR; bit = PORT_PDR_B4_BIT;
 		break;
-	case 5:
+	case D5:
 		/* P25 */
 		pdr = PORT2_PDR_ADDR; bit = PORT_PDR_B5_BIT;
 		break;
-	case 6:
+	case D6:
 		/* P32 */
 		pdr = PORT3_PDR_ADDR; bit = PORT_PDR_B2_BIT;
 		break;
-	case 7:
+	case D7:
 		/* P33 */
 		pdr = PORT3_PDR_ADDR; bit = PORT_PDR_B3_BIT;
 		break;
-	case 8:
+	case D8:
 		/* PC2 */
 		pdr = PORTC_PDR_ADDR; bit = PORT_PDR_B2_BIT;
 		break;
-	case 9:
+	case D9:
 		/* PC3 */
 		pdr = PORTC_PDR_ADDR; bit = PORT_PDR_B3_BIT;
 		break;
-	case 10:
+	case D10:
 		/* PC4 */
 		pdr = PORTC_PDR_ADDR; bit = PORT_PDR_B4_BIT;
 		break;
-	case 11:
+	case D11:
 		/* PC6 */
 		pdr = PORTC_PDR_ADDR; bit = PORT_PDR_B6_BIT;
 		break;
-	case 12:
+	case D12:
 		/* PC7 */
 		pdr = PORTC_PDR_ADDR; bit = PORT_PDR_B7_BIT;
 		break;
-	case 13:
+	case D13:
 		/* PC5 */
 		pdr = PORTC_PDR_ADDR; bit = PORT_PDR_B5_BIT;
@@ -349,4 +361,6 @@
 		sil_wrb_mem(pdr, sil_reb_mem(pdr) | bit);
 		break;
+	default:
+		break;
 	}
 
@@ -387,57 +401,57 @@
 
 	switch (obj->pin) {
-	case 0:
+	case D0:
 		/* P21 */
 		podr = PORT2_PODR_ADDR; bit = PORT_PODR_B1_BIT;
 		break;
-	case 1:
+	case D1:
 		/* P20 */
 		podr = PORT2_PODR_ADDR; bit = PORT_PODR_B0_BIT;
 		break;
-	case 2:
+	case D2:
 		/* P22 */
 		podr = PORT2_PODR_ADDR; bit = PORT_PODR_B2_BIT;
 		break;
-	case 3:
+	case D3:
 		/* P23 */
 		podr = PORT2_PODR_ADDR; bit = PORT_PODR_B3_BIT;
 		break;
-	case 4:
+	case D4:
 		/* P24 */
 		podr = PORT2_PODR_ADDR; bit = PORT_PODR_B4_BIT;
 		break;
-	case 5:
+	case D5:
 		/* P25 */
 		podr = PORT2_PODR_ADDR; bit = PORT_PODR_B5_BIT;
 		break;
-	case 6:
+	case D6:
 		/* P32 */
 		podr = PORT3_PODR_ADDR; bit = PORT_PODR_B2_BIT;
 		break;
-	case 7:
+	case D7:
 		/* P33 */
 		podr = PORT3_PODR_ADDR; bit = PORT_PODR_B3_BIT;
 		break;
-	case 8:
+	case D8:
 		/* PC2 */
 		podr = PORTC_PODR_ADDR; bit = PORT_PODR_B2_BIT;
 		break;
-	case 9:
+	case D9:
 		/* PC3 */
 		podr = PORTC_PODR_ADDR; bit = PORT_PODR_B3_BIT;
 		break;
-	case 10:
+	case D10:
 		/* PC4 */
 		podr = PORTC_PODR_ADDR; bit = PORT_PODR_B4_BIT;
 		break;
-	case 11:
+	case D11:
 		/* PC6 */
 		podr = PORTC_PODR_ADDR; bit = PORT_PODR_B6_BIT;
 		break;
-	case 12:
+	case D12:
 		/* PC7 */
 		podr = PORTC_PODR_ADDR; bit = PORT_PODR_B7_BIT;
 		break;
-	case 13:
+	case D13:
 		/* PC5 */
 		podr = PORTC_PODR_ADDR; bit = PORT_PODR_B5_BIT;
@@ -463,57 +477,57 @@
 
 	switch (obj->pin) {
-	case 0:
+	case D0:
 		/* P21 */
 		pidr = PORT2_PIDR_ADDR; bit = PORT_PIDR_B1_BIT;
 		break;
-	case 1:
+	case D1:
 		/* P20 */
 		pidr = PORT2_PIDR_ADDR; bit = PORT_PIDR_B0_BIT;
 		break;
-	case 2:
+	case D2:
 		/* P22 */
 		pidr = PORT2_PIDR_ADDR; bit = PORT_PIDR_B2_BIT;
 		break;
-	case 3:
+	case D3:
 		/* P23 */
 		pidr = PORT2_PIDR_ADDR; bit = PORT_PIDR_B3_BIT;
 		break;
-	case 4:
+	case D4:
 		/* P24 */
 		pidr = PORT2_PIDR_ADDR; bit = PORT_PIDR_B4_BIT;
 		break;
-	case 5:
+	case D5:
 		/* P25 */
 		pidr = PORT2_PIDR_ADDR; bit = PORT_PIDR_B5_BIT;
 		break;
-	case 6:
+	case D6:
 		/* P32 */
 		pidr = PORT3_PIDR_ADDR; bit = PORT_PIDR_B2_BIT;
 		break;
-	case 7:
+	case D7:
 		/* P33 */
 		pidr = PORT3_PIDR_ADDR; bit = PORT_PIDR_B3_BIT;
 		break;
-	case 8:
+	case D8:
 		/* PC2 */
 		pidr = PORTC_PIDR_ADDR; bit = PORT_PIDR_B2_BIT;
 		break;
-	case 9:
+	case D9:
 		/* PC3 */
 		pidr = PORTC_PIDR_ADDR; bit = PORT_PIDR_B3_BIT;
 		break;
-	case 10:
+	case D10:
 		/* PC4 */
 		pidr = PORTC_PIDR_ADDR; bit = PORT_PIDR_B4_BIT;
 		break;
-	case 11:
+	case D11:
 		/* PC6 */
 		pidr = PORTC_PIDR_ADDR; bit = PORT_PIDR_B6_BIT;
 		break;
-	case 12:
+	case D12:
 		/* PC7 */
 		pidr = PORTC_PIDR_ADDR; bit = PORT_PIDR_B7_BIT;
 		break;
-	case 13:
+	case D13:
 		/* PC5 */
 		pidr = PORTC_PIDR_ADDR; bit = PORT_PIDR_B5_BIT;
@@ -581,36 +595,38 @@
 
 	switch (obj->pin) {
-	case 14:
+	case A0:
 		/* *value = sil_reh_mem(S12AD_ADDR0_ADDR); */
 		result = (arduino_ad_avelage[0] / (arduino_ad_table_count));
 		break;
-	case 15:
+	case A1:
 		/* *value = sil_reh_mem(S12AD_ADDR1_ADDR); */
 		result = (arduino_ad_avelage[1] / (arduino_ad_table_count));
 		break;
-	case 16:
+	case A2:
 		/* *value = sil_reh_mem(S12AD_ADDR2_ADDR); */
 		result = (arduino_ad_avelage[2] / (arduino_ad_table_count));
 		break;
-	case 17:
+	case A3:
 		/* *value = sil_reh_mem(S12AD_ADDR3_ADDR); */
 		result = (arduino_ad_avelage[3] / (arduino_ad_table_count));
 		break;
-	case 18:
+	case A4:
 		/* *value = sil_reh_mem(S12AD_ADDR4_ADDR); */
 		result = (arduino_ad_avelage[4] / (arduino_ad_table_count));
 		break;
-	case 19:
+	case A5:
 		/* *value = sil_reh_mem(S12AD_ADDR5_ADDR); */
 		result = (arduino_ad_avelage[5] / (arduino_ad_table_count));
 		break;
-	case 20:
+	case A6:
 		/* *value = sil_reh_mem(S12AD_ADDR6_ADDR); */
 		result = (arduino_ad_avelage[6] / (arduino_ad_table_count));
 		break;
-	case 21:
+	case A7:
 		/* *value = sil_reh_mem(S12AD_ADDR7_ADDR); */
 		result = (arduino_ad_avelage[7] / (arduino_ad_table_count));
 		break;
+	default:
+		return 0;
 	}
 
@@ -677,7 +693,7 @@
 	/* 波形出力レベルの選択 */
 	sil_wrb_mem(TPU0_TIORL_ADDR, (5 << TPU_TIORL_IOC_OFFSET) | (5 << TPU_TIORL_IOD_OFFSET));
-	sil_wrb_mem(TPU3_TIORH_ADDR, (5 << TPU_TIORL_IOA_OFFSET) | (5 << TPU_TIORL_IOB_OFFSET));
+	sil_wrb_mem(TPU3_TIORH_ADDR, (5 << TPU_TIORH_IOA_OFFSET) | (5 << TPU_TIORH_IOB_OFFSET));
 	sil_wrb_mem(TPU3_TIORL_ADDR, (5 << TPU_TIORL_IOC_OFFSET) | (5 << TPU_TIORL_IOD_OFFSET));
-	sil_wrb_mem(TPU4_TIOR_ADDR, (5 << TPU_TIORL_IOA_OFFSET) | (5 << TPU_TIORL_IOB_OFFSET));
+	sil_wrb_mem(TPU4_TIOR_ADDR, (5 << TPU_TIOR_IOA_OFFSET) | (5 << TPU_TIOR_IOB_OFFSET));
 	/* TGRyの設定 */
 	sil_wrh_mem(TPU0_TGRA_ADDR, TPU_BASE_COUNTER);
@@ -714,96 +730,961 @@
 }
 
+typedef enum {
+	sciSerial,
+	sciI2C,
+	sciSPIM,
+	sciSPIS,
+} sci_mode_t;
+
+void sci_enable(void *base_address, sci_mode_t mode)
+{
+	/*
+	 *  モジュールストップ機能の設定
+	 */
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, (uint16_t)0xA502);	/* 書込み許可 */
+	sil_wrw_mem(SYSTEM_MSTPCRB_ADDR,
+		sil_rew_mem(SYSTEM_MSTPCRB_ADDR) & ~SCI_MSTPCRB_BIT(base_address));
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, (uint16_t)0xA500);	/* 書込み禁止 */
+
+	/* 送受信禁止, SCKn端子は入出力ポートとして使用 */
+	sil_wrb_mem(SCI_SCR(base_address), 0x00U);
+
+	switch ((uint32_t)base_address) {
+	/* TXD/SDA/MOSI:P20, RXD/SCL/MISO:P21, SCK:P22 */
+	case SCI0_BASE:
+		switch (mode) {
+		case sciSerial:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT2_PODR_ADDR,
+				sil_reb_mem(PORT2_PODR_ADDR) | PORT_PODR_B0_BIT | PORT_PODR_B1_BIT);
+			/* TX出力/RX入力ポート設定 */
+			sil_wrb_mem(PORT2_PDR_ADDR, (sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B0_BIT) & ~PORT_PDR_B1_BIT);
+			/* プルアップ無効 */
+			sil_wrb_mem(PORT2_PCR_ADDR, sil_reb_mem(PORT2_PCR_ADDR) & ~(PORT_PCR_B0_BIT | PORT_PCR_B1_BIT));
+			/* RX CMOS */
+			sil_wrb_mem(PORT2_ODR0_ADDR,
+				(sil_reb_mem(PORT2_ODR0_ADDR) & ~(PORT_ODR_Pm0_MASK | PORT_ODR_Pm1_MASK))
+				| (PORT_ODR_CMOS << PORT_ODR_Pm0_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm1_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B0_BIT | PORT_PMR_B1_BIT);
+			break;
+		case sciI2C:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT2_PODR_ADDR,
+				sil_reb_mem(PORT2_PODR_ADDR) | PORT_PODR_B0_BIT | PORT_PODR_B1_BIT);
+			/* SCL,SDA 出力ポート設定 */
+			sil_wrb_mem(PORT2_PDR_ADDR, sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B0_BIT | PORT_PDR_B1_BIT);
+			/* プルアップ有効 */
+			sil_wrb_mem(PORT2_PCR_ADDR, sil_reb_mem(PORT2_PCR_ADDR) | PORT_PCR_B0_BIT | PORT_PCR_B1_BIT);
+			/* Nチャネルオープンドレイン */
+			sil_wrb_mem(PORT2_ODR0_ADDR,
+				(sil_reb_mem(PORT2_ODR0_ADDR) & ~(PORT_ODR_Pm0_MASK | PORT_ODR_Pm1_MASK))
+				| (PORT_ODR_NCH_OPEN_DRAIN << PORT_ODR_Pm0_OFFSET) | (PORT_ODR_NCH_OPEN_DRAIN << PORT_ODR_Pm1_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B0_BIT | PORT_PMR_B1_BIT);
+			break;
+		case sciSPIM:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT2_PODR_ADDR,
+				sil_reb_mem(PORT2_PODR_ADDR) | PORT_PODR_B0_BIT | PORT_PODR_B1_BIT | PORT_PODR_B2_BIT);
+			/* MOSI出力/MISO入力/SCK入出力ポート設定 */
+			sil_wrb_mem(PORT2_PDR_ADDR, (sil_reb_mem(PORT2_PDR_ADDR) | PORT_PDR_B0_BIT | PORT_PDR_B2_BIT) & ~PORT_PDR_B1_BIT);
+			/* プルアップ無効 */
+			sil_wrb_mem(PORT2_PCR_ADDR, sil_reb_mem(PORT2_PCR_ADDR) & ~(PORT_PCR_B0_BIT | PORT_PCR_B1_BIT | PORT_PCR_B2_BIT));
+			/* MISO CMOS */
+			sil_wrb_mem(PORT2_ODR0_ADDR,
+				(sil_reb_mem(PORT2_ODR0_ADDR) & ~(PORT_ODR_Pm0_MASK | PORT_ODR_Pm1_MASK | PORT_ODR_Pm2_MASK))
+				| (PORT_ODR_CMOS << PORT_ODR_Pm0_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm1_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm2_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT2_PMR_ADDR, sil_reb_mem(PORT2_PMR_ADDR) | PORT_PMR_B0_BIT | PORT_PMR_B1_BIT | PORT_PMR_B2_BIT);
+			break;
+		}
+		/* 書き込みプロテクトレジスタの設定 PFSWEビットへの書き込みを許可 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x00);
+		/* 書き込みプロテクトレジスタの設定 PxxFSレジスタへの書き込みを許可 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x40);
+
+		/* P20端子機能制御レジスタ TXD0/SMOSI0/SSDA0とする */
+		sil_wrb_mem(MPC_P20PFS_ADDR, 0x0A);
+		/* P21端子機能制御レジスタ RXD0/SMISO0/SSCL0とする */
+		sil_wrb_mem(MPC_P21PFS_ADDR, 0x0A);
+		if (mode == sciSPIM) {
+			/* P22端子機能制御レジスタ SCK0とする */
+			sil_wrb_mem(MPC_P22PFS_ADDR, 0x0A);
+		}
+
+		/* 書き込みプロテクトレジスタの設定 書き込みを禁止 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x80);
+		break;
+	/* TXD/SDA/MOSI:P50, RXD/SCL/MISO:P52, SCK:P51 */
+	case SCI2_BASE:
+		switch (mode) {
+		case sciSerial:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT5_PODR_ADDR,
+				sil_reb_mem(PORT5_PODR_ADDR) | PORT_PODR_B0_BIT | PORT_PODR_B2_BIT);
+			/* TX出力/RX入力ポート設定 */
+			sil_wrb_mem(PORT5_PDR_ADDR, (sil_reb_mem(PORT5_PDR_ADDR) | PORT_PDR_B0_BIT) & ~PORT_PDR_B2_BIT);
+			/* プルアップ無効 */
+			sil_wrb_mem(PORT5_PCR_ADDR, sil_reb_mem(PORT5_PCR_ADDR) & ~(PORT_PCR_B0_BIT | PORT_PCR_B2_BIT));
+			/* RX CMOS */
+			sil_wrb_mem(PORT5_ODR0_ADDR,
+				(sil_reb_mem(PORT5_ODR0_ADDR) & ~(PORT_ODR_Pm0_MASK | PORT_ODR_Pm2_MASK))
+				| (PORT_ODR_CMOS << PORT_ODR_Pm0_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm2_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT5_PMR_ADDR, sil_reb_mem(PORT5_PMR_ADDR) | PORT_PMR_B0_BIT | PORT_PMR_B2_BIT);
+			break;
+		case sciI2C:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT5_PODR_ADDR,
+				sil_reb_mem(PORT5_PODR_ADDR) | PORT_PODR_B0_BIT | PORT_PODR_B2_BIT);
+			/* SCL,SDA 出力ポート設定 */
+			sil_wrb_mem(PORT5_PDR_ADDR, sil_reb_mem(PORT5_PDR_ADDR) | PORT_PDR_B0_BIT | PORT_PDR_B2_BIT);
+			/* プルアップ有効 */
+			sil_wrb_mem(PORT5_PCR_ADDR, sil_reb_mem(PORT5_PCR_ADDR) | PORT_PCR_B0_BIT | PORT_PCR_B2_BIT);
+			/* Nチャネルオープンドレイン */
+			sil_wrb_mem(PORT5_ODR0_ADDR,
+				(sil_reb_mem(PORT5_ODR0_ADDR) & ~(PORT_ODR_Pm0_MASK | PORT_ODR_Pm2_MASK))
+				| (PORT_ODR_NCH_OPEN_DRAIN << PORT_ODR_Pm0_OFFSET) | (PORT_ODR_NCH_OPEN_DRAIN << PORT_ODR_Pm2_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT5_PMR_ADDR, sil_reb_mem(PORT5_PMR_ADDR) | PORT_PMR_B0_BIT | PORT_PMR_B2_BIT);
+			break;
+		case sciSPIM:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT5_PODR_ADDR,
+				sil_reb_mem(PORT5_PODR_ADDR) | PORT_PODR_B0_BIT | PORT_PODR_B1_BIT | PORT_PODR_B2_BIT);
+			/* MOSI出力/MISO入力/SCK入出力ポート設定 */
+			sil_wrb_mem(PORT5_PDR_ADDR, (sil_reb_mem(PORT5_PDR_ADDR) | PORT_PDR_B0_BIT | PORT_PDR_B1_BIT) & ~PORT_PDR_B2_BIT);
+			/* プルアップ無効 */
+			sil_wrb_mem(PORT5_PCR_ADDR, sil_reb_mem(PORT5_PCR_ADDR) & ~(PORT_PCR_B0_BIT | PORT_PCR_B1_BIT | PORT_PCR_B2_BIT));
+			/* MISO CMOS */
+			sil_wrb_mem(PORT5_ODR0_ADDR,
+				(sil_reb_mem(PORT5_ODR0_ADDR) & ~(PORT_ODR_Pm0_MASK | PORT_ODR_Pm1_MASK | PORT_ODR_Pm2_MASK))
+				| (PORT_ODR_CMOS << PORT_ODR_Pm0_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm1_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm2_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT5_PMR_ADDR, sil_reb_mem(PORT5_PMR_ADDR) | PORT_PMR_B0_BIT | PORT_PMR_B1_BIT | PORT_PMR_B1_BIT | PORT_PMR_B2_BIT);
+			break;
+		}
+		/* 書き込みプロテクトレジスタの設定 PFSWEビットへの書き込みを許可 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x00);
+		/* 書き込みプロテクトレジスタの設定 PxxFSレジスタへの書き込みを許可 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x40);
+
+		/* P50端子機能制御レジスタ SSDA2とする */
+		sil_wrb_mem(MPC_P50PFS_ADDR, 0x0A);
+		/* P52端子機能制御レジスタ SSCL2とする */
+		sil_wrb_mem(MPC_P52PFS_ADDR, 0x0A);
+		if (mode == sciSPIM) {
+			/* P51端子機能制御レジスタ SCK2とする */
+			sil_wrb_mem(MPC_P51PFS_ADDR, 0x0A);
+		}
+
+		/* 書き込みプロテクトレジスタの設定 書き込みを禁止 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x80);
+		break;
+	/* TXD/SDA/MOSI:P32, RXD/SCL/MISO:P33, SCK:P34 */
+	case SCI6_BASE:
+		switch (mode) {
+		case sciSerial:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT3_PODR_ADDR,
+				sil_reb_mem(PORT3_PODR_ADDR) | PORT_PODR_B2_BIT | PORT_PODR_B3_BIT);
+			/* TX出力/RX入力ポート設定 */
+			sil_wrb_mem(PORT3_PDR_ADDR, (sil_reb_mem(PORT3_PDR_ADDR) | PORT_PDR_B2_BIT) & ~PORT_PDR_B3_BIT);
+			/* プルアップ無効 */
+			sil_wrb_mem(PORT3_PCR_ADDR, sil_reb_mem(PORT3_PCR_ADDR) & ~(PORT_PCR_B2_BIT | PORT_PCR_B3_BIT));
+			/* RX CMOS */
+			sil_wrb_mem(PORT3_ODR0_ADDR,
+				(sil_reb_mem(PORT3_ODR0_ADDR) & ~(PORT_ODR_Pm2_MASK | PORT_ODR_Pm3_MASK))
+				| (PORT_ODR_CMOS << PORT_ODR_Pm2_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm3_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT3_PMR_ADDR, sil_reb_mem(PORT3_PMR_ADDR) | PORT_PMR_B2_BIT | PORT_PMR_B3_BIT);
+			break;
+		case sciI2C:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT3_PODR_ADDR,
+				sil_reb_mem(PORT3_PODR_ADDR) | PORT_PODR_B2_BIT | PORT_PODR_B3_BIT);
+			/* SCL,SDA 出力ポート設定 */
+			sil_wrb_mem(PORT3_PDR_ADDR, sil_reb_mem(PORT3_PDR_ADDR) | PORT_PDR_B2_BIT | PORT_PDR_B3_BIT);
+			/* プルアップ有効 */
+			sil_wrb_mem(PORT3_PCR_ADDR, sil_reb_mem(PORT3_PCR_ADDR) | PORT_PCR_B2_BIT | PORT_PCR_B3_BIT);
+			/* Nチャネルオープンドレイン */
+			sil_wrb_mem(PORT3_ODR0_ADDR,
+				(sil_reb_mem(PORT3_ODR0_ADDR) & ~(PORT_ODR_Pm2_MASK | PORT_ODR_Pm3_MASK))
+				| (PORT_ODR_NCH_OPEN_DRAIN << PORT_ODR_Pm2_OFFSET) | (PORT_ODR_NCH_OPEN_DRAIN << PORT_ODR_Pm3_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT3_PMR_ADDR, sil_reb_mem(PORT3_PMR_ADDR) | PORT_PMR_B2_BIT | PORT_PMR_B3_BIT);
+			break;
+		case sciSPIM:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORT3_PODR_ADDR,
+				sil_reb_mem(PORT3_PODR_ADDR) | PORT_PODR_B2_BIT | PORT_PODR_B3_BIT | PORT_PODR_B4_BIT);
+			/* MOSI出力/MISO入力/SCK入出力ポート設定 */
+			sil_wrb_mem(PORT3_PDR_ADDR, (sil_reb_mem(PORT3_PDR_ADDR) | PORT_PDR_B2_BIT | PORT_PDR_B4_BIT) & ~PORT_PDR_B3_BIT);
+			/* プルアップ無効 */
+			sil_wrb_mem(PORT3_PCR_ADDR, sil_reb_mem(PORT3_PCR_ADDR) & ~(PORT_PCR_B2_BIT | PORT_PCR_B3_BIT | PORT_PCR_B4_BIT));
+			/* MISO CMOS */
+			sil_wrb_mem(PORT3_ODR0_ADDR,
+				(sil_reb_mem(PORT3_ODR0_ADDR) & ~(PORT_ODR_Pm2_MASK | PORT_ODR_Pm3_MASK | PORT_ODR_Pm4_MASK))
+				| (PORT_ODR_CMOS << PORT_ODR_Pm2_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm3_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm4_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORT3_PMR_ADDR, sil_reb_mem(PORT3_PMR_ADDR) | PORT_PMR_B2_BIT | PORT_PMR_B3_BIT | PORT_PMR_B4_BIT);
+			break;
+		}
+
+		/* 書き込みプロテクトレジスタの設定 PFSWEビットへの書き込みを許可 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x00);
+		/* 書き込みプロテクトレジスタの設定 PxxFSレジスタへの書き込みを許可 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x40);
+
+		/* P32端子機能制御レジスタ TXD6/SMOSI6/SSDA6とする */
+		sil_wrb_mem(MPC_P32PFS_ADDR, 0x0A);
+		/* P33端子機能制御レジスタ RXD6/SMISO6/SSCL6とする */
+		sil_wrb_mem(MPC_P33PFS_ADDR, 0x0A);
+		if (mode == sciSPIM) {
+			/* P34端子機能制御レジスタ SCK6とする */
+			sil_wrb_mem(MPC_P34PFS_ADDR, 0x0A);
+		}
+
+		/* 書き込みプロテクトレジスタの設定 書き込みを禁止 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x80);
+		break;
+	/* TXD/SDA/MOSI:PC7, RXD/SCL/MISO:PC6, SCK:PC5 */
+	case SCI8_BASE:
+		switch (mode) {
+		case sciSerial:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORTC_PODR_ADDR,
+				sil_reb_mem(PORTC_PODR_ADDR) | PORT_PODR_B6_BIT | PORT_PODR_B7_BIT);
+			/* TX出力/RX入力ポート設定 */
+			sil_wrb_mem(PORTC_PDR_ADDR, (sil_reb_mem(PORTC_PDR_ADDR) | PORT_PDR_B6_BIT) & ~PORT_PDR_B7_BIT);
+			/* プルアップ無効 */
+			sil_wrb_mem(PORTC_PCR_ADDR, sil_reb_mem(PORTC_PCR_ADDR) & ~(PORT_PCR_B6_BIT | PORT_PCR_B7_BIT));
+			/* RX CMOS */
+			sil_wrb_mem(PORTC_ODR0_ADDR,
+				(sil_reb_mem(PORTC_ODR0_ADDR) & ~(PORT_ODR_Pm6_MASK | PORT_ODR_Pm7_MASK))
+				| (PORT_ODR_CMOS << PORT_ODR_Pm6_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm7_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORTC_PMR_ADDR, sil_reb_mem(PORTC_PMR_ADDR) | PORT_PMR_B6_BIT | PORT_PMR_B7_BIT);
+			break;
+		case sciI2C:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORTC_PODR_ADDR,
+				sil_reb_mem(PORTC_PODR_ADDR) | PORT_PODR_B6_BIT | PORT_PODR_B7_BIT);
+			/* SCL,SDA 出力ポート設定 */
+			sil_wrb_mem(PORTC_PDR_ADDR, sil_reb_mem(PORTC_PDR_ADDR) | PORT_PDR_B6_BIT | PORT_PDR_B7_BIT);
+			/* プルアップ有効 */
+			sil_wrb_mem(PORTC_PCR_ADDR, sil_reb_mem(PORTC_PCR_ADDR) | PORT_PCR_B6_BIT | PORT_PCR_B7_BIT);
+			/* Nチャネルオープンドレイン */
+			sil_wrb_mem(PORTC_ODR0_ADDR,
+				(sil_reb_mem(PORTC_ODR0_ADDR) & ~(PORT_ODR_Pm6_MASK | PORT_ODR_Pm7_MASK))
+				| (PORT_ODR_NCH_OPEN_DRAIN << PORT_ODR_Pm6_OFFSET) | (PORT_ODR_NCH_OPEN_DRAIN << PORT_ODR_Pm7_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORTC_PMR_ADDR, sil_reb_mem(PORTC_PMR_ADDR) | PORT_PMR_B6_BIT | PORT_PMR_B7_BIT);
+			break;
+		case sciSPIM:
+			/* HIGH状態に設定 */
+			sil_wrb_mem(PORTC_PODR_ADDR,
+				sil_reb_mem(PORTC_PODR_ADDR) | PORT_PODR_B7_BIT | PORT_PODR_B6_BIT | PORT_PODR_B5_BIT);
+			/* MOSI出力/MISO入力/SCK入出力ポート設定 */
+			sil_wrb_mem(PORTC_PDR_ADDR, (sil_reb_mem(PORTC_PDR_ADDR) | PORT_PDR_B5_BIT | PORT_PDR_B7_BIT) & ~PORT_PDR_B6_BIT);
+			/* プルアップ無効 */
+			sil_wrb_mem(PORTC_PCR_ADDR, sil_reb_mem(PORTC_PCR_ADDR) & ~(PORT_PCR_B5_BIT | PORT_PCR_B7_BIT | PORT_PCR_B6_BIT));
+			/* MISO CMOS */
+			sil_wrb_mem(PORTC_ODR0_ADDR,
+				(sil_reb_mem(PORTC_ODR0_ADDR) & ~(PORT_ODR_Pm5_MASK | PORT_ODR_Pm6_MASK | PORT_ODR_Pm7_MASK))
+				| (PORT_ODR_CMOS << PORT_ODR_Pm5_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm6_OFFSET) | (PORT_ODR_CMOS << PORT_ODR_Pm7_OFFSET));
+			/* 周辺機能として使用 */
+			sil_wrb_mem(PORTC_PMR_ADDR, sil_reb_mem(PORTC_PMR_ADDR) | PORT_PMR_B5_BIT | PORT_PMR_B6_BIT | PORT_PMR_B7_BIT);
+			break;
+		}
+
+		/* 書き込みプロテクトレジスタの設定 PFSWEビットへの書き込みを許可 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x00);
+		/* 書き込みプロテクトレジスタの設定 PxxFSレジスタへの書き込みを許可 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x40);
+
+		/* PC7端子機能制御レジスタ TXD8/SMOSI8/SSDA8とする */
+		sil_wrb_mem(MPC_PC7PFS_ADDR, 0x0A);
+		/* PC6端子機能制御レジスタ RXD8/SMISO8/SSCL8とする */
+		sil_wrb_mem(MPC_PC6PFS_ADDR, 0x0A);
+		if (mode == sciSPIM) {
+			/* PC5端子機能制御レジスタ SCK8とする */
+			sil_wrb_mem(MPC_PC5PFS_ADDR, 0x0A);
+		}
+
+		/* 書き込みプロテクトレジスタの設定 書き込みを禁止 */
+		sil_wrb_mem(MPC_PWPR_ADDR, 0x80);
+		break;
+	}
+}
+
+void sci_disable(void *base_address)
+{
+	/* 送受信禁止, SCKn端子は入出力ポートとして使用 */
+	sil_wrb_mem(SCI_SCR(base_address), 0x00U);
+
+	/*
+	 *  モジュールストップ機能の設定
+	 */
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, (uint16_t)0xA502);	/* 書込み許可 */
+	sil_wrw_mem(SYSTEM_MSTPCRB_ADDR,
+		sil_rew_mem(SYSTEM_MSTPCRB_ADDR) | SCI_MSTPCRB_BIT(base_address));
+	sil_wrh_mem(SYSTEM_PRCR_ADDR, (uint16_t)0xA500);	/* 書込み禁止 */
+}
+
+void sci_set_frequency(void *base_address, int hz)
+{
+	uint_t	cnt, brr, clk;
+
+	cnt = (FREQ_PCLK * 1000) / (16 * hz);
+	if (cnt < 512)
+		clk = 0;
+	else if (cnt < 4 * 512)
+		clk = 1;
+	else if (cnt < 16 * 512)
+		clk = 2;
+	else if (cnt < 64 * 512)
+		clk = 3;
+	else
+		return;
+
+	brr = cnt / (1 << (2 * clk));
+	brr = (brr / 2) + (brr % 2) - 1;
+
+	/* SMRに送信／ 受信フォーマットを設定 */
+	/* クロック選択ビット(SMR.CKS[1:0]ビットを設定)、それ以外のビットを“0”に設定します。 */
+	sil_wrb_mem(SCI_SMR(base_address), clk);
+
+	/* SCMRレジスタはSDIRビットを“1”、SINVビットを“0”、SMIFビットを“0”に設定します。 */
+	sil_wrb_mem(SCI_SCMR(base_address),
+		(sil_reb_mem(SCI_SCMR(base_address)) & ~(SINV | SMIF)) | SDIR);
+
+	/* ビットレートを設定 */
+	sil_wrb_mem(SCI_BRR(base_address), brr);
+}
+
 void serial_init(serial_t *obj, PinName tx, PinName rx)
 {
+#ifdef TOPPERS_GRCITRUS
+	if ((rx == D0) && (tx == D1)) {
+		obj->base_address = (void *)SCI0_BASE;
+		obj->rxi_intno = INT_SCI0_RXI;
+		obj->tei_intno = INT_SCI0_TEI;
+	}
+	else if ((rx == D5) && (tx == D6)) {
+		obj->base_address = (void *)SCI2_BASE;
+		obj->rxi_intno = INT_SCI2_RXI;
+		obj->tei_intno = INT_SCI2_TEI;
+	}
+	else if ((rx == D7) && (tx == D8)) {
+		obj->base_address = (void *)SCI6_BASE;
+		obj->rxi_intno = INT_SCI6_RXI;
+		obj->tei_intno = INT_SCI6_TEI;
+	}
+	else if ((rx == D11) && (tx == D12)) {
+		obj->base_address = (void *)SCI8_BASE;
+		obj->rxi_intno = INT_SCI8_RXI;
+		obj->tei_intno = INT_SCI8_TEI;
+	}
+	else {
+		obj->base_address = NULL;
+		return;
+	}
+#else
+	if ((rx == D0) && (tx == D1)) {
+		obj->base_address = (void *)SCI0_BASE;
+		obj->rxi_intno = INT_SCI0_RXI;
+		obj->tei_intno = INT_SCI0_TEI;
+	}
+	else if ((rx == D6) && (tx == D7)) {
+		obj->base_address = (void *)SCI6_BASE;
+		obj->rxi_intno = INT_SCI6_RXI;
+		obj->tei_intno = INT_SCI6_TEI;
+	}
+	else if ((rx == D11) && (tx == D12)) {
+		obj->base_address = (void *)SCI8_BASE;
+		obj->rxi_intno = INT_SCI8_RXI;
+		obj->tei_intno = INT_SCI8_TEI;
+}
+	else {
+		obj->base_address = NULL;
+		return;
+	}
+#endif // TOPPERS_GRCITRUS
+	/* SCI有効 */
+	sci_enable(obj->base_address, sciSerial);
+
+	/* SIMR1.IICMビットを“0”に設定 */
+	sil_wrb_mem(SCI_SIMR1(obj->base_address),
+		sil_reb_mem(SCI_SIMR1(obj->base_address)) & ~IICM);
+
+	/* SPMR.CKPH, CKPOLビットを“0”に設定 */
+	sil_wrb_mem(SCI_SPMR(obj->base_address),
+		sil_reb_mem(SCI_SPMR(obj->base_address)) & ~(CKPH | CKPOL));
+
+	sci_set_frequency(obj->base_address, 9600);
+
+	/* SMRに送信／ 受信フォーマットを設定 */
+	serial_format(obj, 8, ParityNone, 1);
+
+	/* 送受信許可 */
+	sil_wrb_mem(SCI_SCR(obj->base_address),
+		(sil_reb_mem(SCI_SCR(obj->base_address)) | RE | TE));
 }
 
 void serial_free(serial_t *obj)
 {
+	/* SCI無効 */
+	sci_disable(obj->base_address);
+
+	obj->base_address = NULL;
 }
 
 void serial_baud(serial_t *obj, int baudrate)
 {
+	uint8_t scr = sil_reb_mem(SCI_SCR(obj->base_address));
+
+	/* 送受信禁止, SCKn端子は入出力ポートとして使用 */
+	sil_wrb_mem(SCI_SCR(obj->base_address), 0x00U);
+
+	sci_set_frequency(obj->base_address, baudrate);
+
+	/* 送受信許可 */
+	sil_wrb_mem(SCI_SCR(obj->base_address), scr);
 }
 
 void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
 {
+	uint8_t smr = sil_reb_mem(SCI_SMR(obj->base_address));
+
+	smr &= ~(PE | PM | CHR | STOP);
+
+	switch (parity) {
+	case ParityNone:
+		break;
+	case ParityOdd:
+		smr |= PE | PM;
+		break;
+	case ParityEven:
+		smr |= PE;
+		break;
+	default:
+		break;
+	}
+
+	switch (data_bits) {
+	case 7:
+		smr |= CHR;
+		break;
+	case 8:
+		break;
+	default:
+		break;
+	}
+
+	switch (stop_bits) {
+	case 1:
+		break;
+	case 2:
+		smr |= STOP;
+		break;
+	default:
+		break;
+	}
+
+	sil_wrb_mem(SCI_SMR(obj->base_address), smr);
 }
 
 int serial_getc(serial_t *obj)
 {
+	uint8_t ssr;
+	int c;
+
+	for (;;) {
+		/* SSR.ORER, PER, FERフラグをリード */
+		ssr = sil_reb_mem(SCI_SSR(obj->base_address));
+
+		/* 受信エラーが発生したとき */
+		if ((ssr & (ORER | PER | FER)) != 0) {
+			/* オーバランエラー */
+			if ((ssr & ORER) != 0) {
+				/* RDRレジスタをリード */
+				c = (int)sil_reb_mem(SCI_RDR(obj->base_address));
+			}
+			/* フレーミングエラー */
+			if ((ssr & FER) != 0) {
+			}
+			/* パリティエラー */
+			if ((ssr & PER) != 0) {
+			}
+		}
+
+		/* SSR.ORER, PER, FERフラグを“0”に設定 */
+		sil_wrb_mem(SCI_SSR(obj->base_address), ssr & ~(ORER | PER | FER));
+
+		/* SSR.ORER, PER, FERフラグをリード */
+		ssr = sil_reb_mem(SCI_SSR(obj->base_address));
+
+		/* RXI割り込み */
+		if (serial_readable(obj)) {
+			clear_int(obj->rxi_intno);
+			break;
+		}
+
+		dly_tsk(10);
+	}
+
+	/* RDRレジスタをリード */
+	c = (int)sil_reb_mem(SCI_RDR(obj->base_address));
+
+	return c;
+}
+
+void serial_putc(serial_t *obj, int c)
+{
+	while (serial_writable(obj))
+		dly_tsk(10);
+
+	clear_int(obj->tei_intno);
+
+	sil_wrb_mem(SCI_TDR(obj->base_address), (char)c);
+}
+
+int serial_readable(serial_t *obj)
+{
+	return probe_int(obj->rxi_intno);
+}
+
+int serial_writable(serial_t *obj)
+{
+	return probe_int(obj->tei_intno);
+}
+
+uart_irq_handler sci_irq_handler[7];
+
+void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id)
+{
+	int no = SCI_NUM(obj->base_address);
+
+	sci_irq_handler[no] = handler;
+}
+
+void i2c_init(i2c_t *obj, PinName sda, PinName scl)
+{
+	if ((sda == I2C_SDA) && (scl == I2C_SCL)) {
+#ifdef TOPPERS_GRCITRUS
+		obj->base_address = (void *)SCI6_BASE;
+		obj->rxi_intno = INT_SCI6_RXI;
+		obj->txi_intno = INT_SCI6_TXI;
+		obj->tei_intno = INT_SCI6_TEI;
+#else
+		obj->base_address = (void *)SCI2_BASE;
+		obj->rxi_intno = INT_SCI2_RXI;
+		obj->txi_intno = INT_SCI2_TXI;
+		obj->tei_intno = INT_SCI2_TEI;
+#endif
+	}
+	else {
+		obj->base_address = NULL;
+		return;
+	}
+
+	/* SCI有効 */
+	sci_enable(obj->base_address, sciI2C);
+
+	/* SIMR3.IICSDAS[1:0](b5-b4), IICSCLS[1:0](b7-b6)ビットを“11b”に設定 */
+	sil_wrb_mem(SCI_SIMR3(obj->base_address), 0xF0U);
+
+	sci_set_frequency(obj->base_address, 100000);
+
+	/* SEMR、SNFR、SIMR1、SIMR2、SPMRレジスタに値を設定します。 */
+	/* SEMRレジスタは、NFENビットを設定します。 */
+	sil_wrb_mem(SCI_SEMR(obj->base_address), NFEN);
+
+	/* SNFRレジスタは、NFCS[2:0]ビットを設定します。*/
+	sil_wrb_mem(SCI_SNFR(obj->base_address), 1);
+
+	/* SIMR1レジスタは、IICMビットを“1”に設定し、IICDL[4:0]ビ	ットを設定します。 */
+	sil_wrb_mem(SCI_SIMR1(obj->base_address), IICM | (3 << 3));
+
+	/* SIMR2レジスタは、IICACKT、IICCSCビットを“1”に設定し、IICINTMビットを設定します。 */
+	sil_wrb_mem(SCI_SIMR2(obj->base_address), IICACKT | IICCSC | IICINTM);
+
+	/* SPMRレジスタは、全ビット“0”に設定します。 */
+	sil_wrb_mem(SCI_SPMR(obj->base_address), 0);
+
+	/* 送受信許可 */
+	sil_wrb_mem(SCI_SCR(obj->base_address),
+		(sil_reb_mem(SCI_SCR(obj->base_address)) | RE | TE));
+}
+
+void i2c_frequency(i2c_t *obj, int hz)
+{
+	uint8_t scr = sil_reb_mem(SCI_SCR(obj->base_address));
+
+	/* 送受信禁止, SCKn端子は入出力ポートとして使用 */
+	sil_wrb_mem(SCI_SCR(obj->base_address), 0x00U);
+
+	sci_set_frequency(obj->base_address, hz);
+
+	/* 送受信許可 */
+	sil_wrb_mem(SCI_SCR(obj->base_address), scr);
+}
+
+int i2c_start(i2c_t *obj)
+{
+	if (obj->base_address == NULL)
+		return 0;
+
+	/* SIMR3.IICSTAREQビットを“1”に設定すると同時に、
+	 * SIMR3.IICSCLS[1:0],IICSDAS[1:0]ビットを“01b”に設定 */
+	sil_wrb_mem(SCI_SIMR3(obj->base_address), IICSTAREQ | (1 << 4) | (1 << 6));
+
 	return 0;
 }
 
-void serial_putc(serial_t *obj, int c)
-{
-}
-
-int serial_readable(serial_t *obj)
-{
+int i2c_restart(i2c_t *obj)
+{
+	if (obj->base_address == NULL)
+		return 0;
+
+	sil_wrb_mem(SCI_SIMR3(obj->base_address), IICRSTAREQ | (1 << 4) | (1 << 6));
+
 	return 0;
 }
 
-int serial_writable(serial_t *obj)
-{
+int i2c_stop(i2c_t *obj)
+{
+	if (obj->base_address == NULL)
+		return 0;
+
+	/* SIMR3.IICSTPREQビットを“1”に設定すると同時に、
+	 * SIMR3.IICSCLS[1:0],IICSDAS[1:0]ビットを“01b”に設定 */
+	sil_wrb_mem(SCI_SIMR3(obj->base_address), IICSTPREQ | (1 << 4) | (1 << 6));
+
 	return 0;
 }
 
-void i2c_init(i2c_t *obj, PinName sda, PinName scl)
-{
-}
-
-void i2c_frequency(i2c_t *obj, int hz)
-{
-}
-
-int i2c_start(i2c_t *obj)
-{
+int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
+{
+	if (obj->base_address == NULL)
+		return 0;
+
+	/* 送信割り込み要求を禁止 */
+	sil_wrb_mem(SCI_SCR(obj->base_address),
+		(sil_reb_mem(SCI_SCR(obj->base_address)) & ~(RIE)) | TEIE | TIE);
+
+	/* 開始条件の生成 */
+	i2c_start(obj);
+
+	/* STI(TEI)割り込み発生確認 */
+	while (!probe_int(obj->tei_intno))
+		dly_tsk(2);
+	clear_int(obj->tei_intno);
+
+	/* SIMR3.IICSTIFフラグを“0”に設定し、 */
+	sil_wrb_mem(SCI_SIMR3(obj->base_address),
+		sil_reb_mem(SCI_SIMR3(obj->base_address)) & ~IICSTIF);
+	/* SIMR3.IICSCLS[1:0], IICSDAS[1:0]ビットを“00b”に設定 */
+	sil_wrb_mem(SCI_SIMR3(obj->base_address),
+		sil_reb_mem(SCI_SIMR3(obj->base_address)) & ~((3 << 4) | (3 << 6)));
+
+	/* TDRレジスタにスレーブアドレス、R/Wビットをライト */
+	sil_wrb_mem(SCI_TDR(obj->base_address), address | 1);
+
+	/* TXI割り込み発生確認 */
+	while (!probe_int(obj->txi_intno))
+		dly_tsk(10);
+	clear_int(obj->txi_intno);
+
+	/* スレーブデバイスからのACKを確認 */
+	if ((sil_reb_mem(SCI_SISR(obj->base_address)) & IICACKR) == 0) {
+		/* SIMR2.IICACKTビットを“0”に設定 */
+		sil_wrb_mem(SCI_SIMR2(obj->base_address), sil_reb_mem(SCI_SIMR2(obj->base_address)) & ~IICACKT);
+		/* SCR.RIEビットを“1”に設定 */
+		sil_wrb_mem(SCI_SCR(obj->base_address), sil_reb_mem(SCI_SCR(obj->base_address)) | RIE);
+
+		for (int i = 0; i < length; i++) {
+			/* 次データが最終 */
+			if (i == length - 1) {
+				/* SIMR2.IICACKTビットを“1”に設定 */
+				sil_wrb_mem(SCI_SIMR2(obj->base_address), sil_reb_mem(SCI_SIMR2(obj->base_address)) | IICACKT);
+			}
+
+			/* TDRレジスタにダミーデータ“FFh”をライト */
+			sil_wrb_mem(SCI_TDR(obj->base_address), 0xFF);
+
+			/* RXI割り込み発生確認 */
+			while (!probe_int(obj->rxi_intno))
+				dly_tsk(10);
+			clear_int(obj->rxi_intno);
+
+			/* RDRレジスタの受信データをリード */
+			*data = sil_reb_mem(SCI_RDR(obj->base_address));
+			data++;
+
+			/* TXI割り込み発生確認 */
+			while (!probe_int(obj->txi_intno))
+				dly_tsk(10);
+			clear_int(obj->txi_intno);
+		}
+	}
+
+	if (stop) {
+		/* 停止条件の生成 */
+		i2c_stop(obj);
+
+		/* STI(TEI)割り込み発生確認 */
+		while (!probe_int(obj->tei_intno))
+			dly_tsk(2);
+		clear_int(obj->tei_intno);
+
+		/* SIMR3.IICSTIFフラグを“0”に設定し、*/
+		sil_wrb_mem(SCI_SIMR3(obj->base_address),
+			sil_reb_mem(SCI_SIMR3(obj->base_address)) & ~IICSTIF);
+		/* SIMR3.IICSCLS[1:0], IICSDAS[1:0]ビットを“11b”に設定 */
+		sil_wrb_mem(SCI_SIMR3(obj->base_address),
+			sil_reb_mem(SCI_SIMR3(obj->base_address)) | ((3 << 4) | (3 << 6)));
+	}
+
+	return length;
+}
+
+int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
+{
+	if (obj->base_address == NULL)
+		return 0;
+
+	/* 受信割り込み要求を禁止 */
+	sil_wrb_mem(SCI_SCR(obj->base_address),
+		(sil_reb_mem(SCI_SCR(obj->base_address)) & ~(RIE)) | TEIE | TIE);
+
+	/* 開始条件の生成 */
+	i2c_start(obj);
+
+	/* STI(TEI)割り込み発生確認 */
+	while (!probe_int(obj->tei_intno))
+		dly_tsk(2);
+	clear_int(obj->tei_intno);
+
+	/* SIMR3.IICSTIFフラグを“0”に設定し、 */
+	sil_wrb_mem(SCI_SIMR3(obj->base_address),
+		sil_reb_mem(SCI_SIMR3(obj->base_address)) & ~IICSTIF);
+	/* SIMR3.IICSCLS[1:0], IICSDAS[1:0]ビットを“00b”に設定 */
+	sil_wrb_mem(SCI_SIMR3(obj->base_address),
+		sil_reb_mem(SCI_SIMR3(obj->base_address)) & ~((3 << 4) | (3 << 6)));
+
+	/* TDRレジスタにスレーブアドレス、R/Wビットをライト */
+	sil_wrb_mem(SCI_TDR(obj->base_address), address);
+
+	/* TXI割り込み発生確認 */
+	while (!probe_int(obj->txi_intno))
+		dly_tsk(10);
+	clear_int(obj->txi_intno);
+
+	/* スレーブデバイスからのACKを確認 */
+	if ((sil_reb_mem(SCI_SISR(obj->base_address)) & IICACKR) == 0) {
+
+		for (int i = 0; i < length; i++) {
+			/* TDRレジスタにスレーブアドレス、R/Wビットをライト */
+			sil_wrb_mem(SCI_TDR(obj->base_address), *data);
+			data++;
+
+			/* TXI割り込み発生確認 */
+			while (!probe_int(obj->txi_intno))
+				dly_tsk(10);
+			clear_int(obj->txi_intno);
+		}
+	}
+
+	if (stop) {
+		/* 停止条件の生成 */
+		i2c_stop(obj);
+
+		/* STI(TEI)割り込み発生確認 */
+		while (!probe_int(obj->tei_intno))
+			dly_tsk(2);
+		clear_int(obj->tei_intno);
+
+		/* SIMR3.IICSTIFフラグを“0”に設定し、*/
+		sil_wrb_mem(SCI_SIMR3(obj->base_address),
+			sil_reb_mem(SCI_SIMR3(obj->base_address)) & ~IICSTIF);
+		/* SIMR3.IICSCLS[1:0], IICSDAS[1:0]ビットを“11b”に設定 */
+		sil_wrb_mem(SCI_SIMR3(obj->base_address),
+			sil_reb_mem(SCI_SIMR3(obj->base_address)) | ((3 << 4) | (3 << 6)));
+	}
+
+	return length;
+}
+
+int i2c_byte_read(i2c_t *obj, int last)
+{
+	if (obj->base_address == NULL)
+		return 0;
+
 	return 0;
 }
 
-int i2c_stop(i2c_t *obj)
-{
+int i2c_byte_write(i2c_t *obj, int data)
+{
+	if (obj->base_address == NULL)
+		return 0;
+
 	return 0;
 }
 
-int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
-{
-	return 0;
-}
-
-int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
-{
-	return 0;
-}
-
-int i2c_byte_read(i2c_t *obj, int last)
-{
-	return 0;
-}
-
-int i2c_byte_write(i2c_t *obj, int data)
-{
-	return 0;
-}
-
 void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel)
 {
+	if ((mosi == D11) && (miso == D12) && (sclk == D13) && ((ssel == D10) || (ssel == NC))) {
+		obj->base_address = (void *)SCI8_BASE;
+		obj->txi_intno = INT_SCI8_TXI;
+		obj->rxi_intno = INT_SCI8_RXI;
+		obj->tei_intno = INT_SCI8_TEI;
+	}
+	else {
+		obj->base_address = NULL;
+		return;
+	}
+
+	/* SCI有効 */
+	sci_enable(obj->base_address, (ssel == D10) ? sciSPIS : sciSPIM);
+
+	/* SIMR1.IICMビットを“0”に設定 */
+	sil_wrb_mem(SCI_SIMR1(obj->base_address),
+		sil_reb_mem(SCI_SIMR1(obj->base_address)) & ~IICM);
+
+	if (ssel == NC) {
+		/* SPMR.SSE, CTSE, MSS, MFF, CKPH, CKPOLビットを“0”に設定 */
+		sil_wrb_mem(SCI_SPMR(obj->base_address), 0);
+	}
+	else {
+		/* SPMR, CTSE, MSS, MFF, CKPH, CKPOLビットを“0”に設定 */
+		/* SPMR.SSEビットを“1”に設定 */
+		sil_wrb_mem(SCI_SPMR(obj->base_address), SSE);
+	}
+
+	/* SCMR.SMIF ビットを“0”に設定 */
+	sil_wrb_mem(SCI_SCMR(obj->base_address),
+		sil_reb_mem(SCI_SCMR(obj->base_address)) & ~SMIF);
+
+	/* SMRに送信／ 受信フォーマットをクロック同期式モードで動作で設定 */
+	sil_wrb_mem(SCI_SMR(obj->base_address), CM);
+
+	sci_set_frequency(obj->base_address, 1000000);
+
+	/* 送受信許可 */
+	sil_wrb_mem(SCI_SCR(obj->base_address),
+		(sil_reb_mem(SCI_SCR(obj->base_address)) | RE | TE));
 }
 
 void spi_free(spi_t *obj)
 {
+	/* SCI無効 */
+	sci_disable(obj->base_address);
+
+	obj->base_address = NULL;
 }
 
 void spi_format(spi_t *obj, int bits, int mode, int slave)
 {
+	int polarity = (mode & 0x2) ? 1 : 0;
+	int phase = (mode & 0x1) ? 1 : 0;
+	uint8_t spmr;
+
+	if ((bits != 8) || (mode < 0) || (mode > 3)) {
+		return;
+	}
+
+	/* 送受信禁止, SCKn端子は入出力ポートとして使用 */
+	sil_wrb_mem(SCI_SCR(obj->base_address), 0x00U);
+
+	spmr = sil_reb_mem(SCI_SPMR(obj->base_address));
+
+	/* クロック極性反転あり/なし */
+	if (polarity)
+		spmr |= CKPOL;
+	else
+		spmr &= ~CKPOL;
+
+	/* クロック位相反転あり/なし */
+	if (phase)
+		spmr |= CKPH;
+	else
+		spmr &= ~CKPH;
+
+	if (slave) {
+		/* SCKn端子はクロック入力として使用 */
+		sil_wrb_mem(SCI_SCR(obj->base_address), 
+			(sil_reb_mem(SCI_SCR(obj->base_address)) & ~CKE) | 2);
+
+		/* SPMR.MSSビットを“1”に設定 */
+		sil_wrb_mem(SCI_SPMR(obj->base_address), spmr | MSS);
+	}
+	else {
+		/* SCKn端子はクロック出力として使用 */
+		sil_wrb_mem(SCI_SCR(obj->base_address),
+			sil_reb_mem(SCI_SCR(obj->base_address)) & ~CKE);
+
+		/* SPMR.MSSビットを“0”に設定 */
+		sil_wrb_mem(SCI_SPMR(obj->base_address), spmr & ~MSS);
+	}
+
+	/* 送受信許可 */
+	sil_wrb_mem(SCI_SCR(obj->base_address),
+		(sil_reb_mem(SCI_SCR(obj->base_address)) | RE | TE));
 }
 
 void spi_frequency(spi_t *obj, int hz)
 {
+	uint8_t scr = sil_reb_mem(SCI_SCR(obj->base_address));
+
+	/* 送受信禁止, SCKn端子は入出力ポートとして使用 */
+	sil_wrb_mem(SCI_SCR(obj->base_address), 0x00U);
+
+	sci_set_frequency(obj->base_address, hz);
+
+	/* 送受信許可 */
+	sil_wrb_mem(SCI_SCR(obj->base_address), scr);
 }
 
 int spi_master_write(spi_t *obj, int value)
 {
-	return 0;
+	/* TXI割り込み発生確認 */
+	while (!probe_int(obj->txi_intno))
+		;
+
+	/* 送信データをライト */
+	sil_wrb_mem(SCI_TDR(obj->base_address), (char)value);
+
+	do {
+		uint8_t ssr = sil_reb_mem(SCI_SSR(obj->base_address));
+		if ((ssr & ORER) != 0) {
+			ssr &= ~ORER;
+			sil_wrb_mem(SCI_SSR(obj->base_address), ssr);
+			return -1;
+		}
+	}
+	/* RXI割り込み発生確認 */
+	while (!probe_int(obj->rxi_intno));
+
+	/* 受信データをリード */
+	return sil_reb_mem(SCI_RDR(obj->base_address));
+}
+
+int spi_master_block_write(spi_t *obj, const char *tx_buffer, int tx_length,
+	char *rx_buffer, int rx_length, char write_fill)
+{
+	int total = (tx_length > rx_length) ? tx_length : rx_length;
+
+	for (int i = 0; i < total; i++) {
+		char out = (i < tx_length) ? tx_buffer[i] : write_fill;
+		char in = spi_master_write(obj, out);
+		if (i < rx_length) {
+			rx_buffer[i] = in;
+		}
+	}
+
+	return total;
 }
 
@@ -858,2 +1739,129 @@
 	sil_wrb_mem((uint8_t *)RTC_RSECCNT_ADDR, DecToBcd(tm.tm_sec));
 }
+
+void sci_rxi_handler(uint32_t id)
+{
+	uart_irq_handler hdr = sci_irq_handler[id];
+	if (hdr == NULL)
+		return;
+
+	hdr(id, RxIrq);
+}
+
+void sci_txi_handler(uint32_t id)
+{
+	uart_irq_handler hdr = sci_irq_handler[id];
+	if (hdr == NULL)
+		return;
+
+	hdr(id, TxIrq);
+}
+
+void sci_tei_handler(int no)
+{
+}
+
+void sci0_rxi_handler(void)
+{
+	sci_rxi_handler(0);
+}
+
+void sci0_txi_handler(void)
+{
+	sci_txi_handler(0);
+}
+
+void sci0_tei_handler(void)
+{
+	sci_tei_handler(0);
+}
+
+void sci1_rxi_handler(void)
+{
+	sci_rxi_handler(1);
+}
+
+void sci1_txi_handler(void)
+{
+	sci_txi_handler(1);
+}
+
+void sci1_tei_handler(void)
+{
+	sci_tei_handler(1);
+}
+
+void sci2_rxi_handler(void)
+{
+	sci_rxi_handler(2);
+}
+
+void sci2_txi_handler(void)
+{
+	sci_txi_handler(2);
+}
+
+void sci2_tei_handler(void)
+{
+	sci_tei_handler(2);
+}
+
+void sci3_rxi_handler(void)
+{
+	sci_rxi_handler(3);
+}
+
+void sci3_txi_handler(void)
+{
+	sci_txi_handler(3);
+}
+
+void sci3_tei_handler(void)
+{
+	sci_tei_handler(3);
+}
+
+void sci4_rxi_handler(void)
+{
+	sci_rxi_handler(4);
+}
+
+void sci4_txi_handler(void)
+{
+	sci_txi_handler(4);
+}
+
+void sci4_tei_handler(void)
+{
+	sci_tei_handler(4);
+}
+
+void sci5_rxi_handler(void)
+{
+	sci_rxi_handler(5);
+}
+
+void sci5_txi_handler(void)
+{
+	sci_txi_handler(5);
+}
+
+void sci5_tei_handler(void)
+{
+	sci_tei_handler(5);
+}
+
+void sci6_rxi_handler(void)
+{
+	sci_rxi_handler(6);
+}
+
+void sci6_txi_handler(void)
+{
+	sci_txi_handler(6);
+}
+
+void sci6_tei_handler(void)
+{
+	sci_tei_handler(6);
+}
