Index: EcnlProtoTool/trunk/ntshell/fatfs/ffarch.c
===================================================================
--- EcnlProtoTool/trunk/ntshell/fatfs/ffarch.c	(revision 435)
+++ EcnlProtoTool/trunk/ntshell/fatfs/ffarch.c	(revision 441)
@@ -42,24 +42,79 @@
 #include <kernel.h>
 #include <stdlib.h>
-//#include <string.h>
+#include <string.h>
 #include "t_stdlib.h"
 #include "syssvc/serial.h"
 #include "syssvc/syslog.h"
+#include "target_syssvc.h"
 #include "kernel_cfg.h"
 #include "diskio.h"
 #include "sdfs.h"
 #include "ff.h"
-#include "tlsf.h"
-#include "util/ntstdio.h"
+#include <stdio.h>
+#include "hal/rtc_api.h"
+#include "ffarch.h"
 
 #define SD_CARD_LOG_LEVEL LOG_INFO
 
-#define SIO_PORTID 1
-extern ntstdio_t ntstdio;
-
-static tlsf_t sys_tlsf;
-static pool_t sys_pool;
-
-uint8_t shell_heap[64 * 1024];
+enum ffarch_state_t {
+	FFS_IDLE,
+	FFS_RETRY_WAIT,
+};
+
+enum ffarch_state_t ffarch_state;
+volatile int ffarch_timer;
+int ffarch_retry_count;
+uint8_t sdfs_new_status, sdfs_prev_status;
+
+static void ffarch_initialize();
+
+/*
+ * FatFSタスク
+ */
+void ffarch_task(intptr_t exinf)
+{
+	ER ret, ret2;
+	SYSTIM prev, now;
+	int timer;
+
+	ffarch_initialize();
+
+	ret2 = get_tim(&now);
+	if (ret2 != E_OK){
+		syslog(LOG_NOTICE, "[ffarch] get_tim error: %s",
+			itron_strerror(ret2));
+		return;
+	}
+
+	for(;;){
+		prev = now;
+
+		/* タイマー取得 */
+		timer = ffarch_get_timer();
+
+		/* 待ち */
+		ret = tslp_tsk(timer);
+		if ((ret != E_OK) && (ret != E_TMOUT)) {
+			syslog(LOG_NOTICE, "[ffarch] tslp_tsk error: %s %d",
+				itron_strerror(ret), timer);
+			break;
+		}
+
+		ret2 = get_tim(&now);
+		if (ret2 != E_OK) {
+			syslog(LOG_NOTICE, "[ffarch] get_tim error: %s",
+				itron_strerror(ret2));
+			break;
+		}
+
+		/* 時間経過 */
+		int elapse = now - prev;
+		ffarch_progress(elapse);
+
+		/* タイムアウト処理 */
+		ffarch_timeout();
+	}
+}
+
 FATFS RomDisk;
 
@@ -75,14 +130,9 @@
 SD Sd;
 
-void sys_init(void);
 bool_t romdisk_init();
 bool_t SD_begin();
 
-int mruby_arduino_init()
-{
-	int result = -1;
-
-	sys_init();
-
+void ffarch_init(void)
+{
 	/* SD_CD */
 	gpio_init_in(&ins, P7_8);
@@ -91,65 +141,25 @@
 	sdfs_init(&sdfs, P8_5, P8_6, P8_3, P8_4, "sd");
 
-	result = SD_begin() ? 0 : -1;
-	if (result == 0) {
-		ntstdio_printf(&ntstdio, "SD card (1:) OK!\n");
+	ffarch_state = FFS_IDLE;
+	ffarch_timer = 0;
+	ffarch_retry_count = 3;
+	sdfs_new_status = 0;
+	sdfs_prev_status = STA_NODISK;
+
+	ffarch_timeout();
+
+	act_tsk(FFARCH_TASK);
+
+	if (romdisk_init()) {
+		syslog(LOG_NOTICE, "ROM disk (0:) OK!");
 	}
 	else {
-		ntstdio_printf(&ntstdio, "SD card (1:) NG!\n");
-	}
+		syslog(LOG_NOTICE, "ROM disk (0:) NG!");
+	}
+}
+
+void ffarch_initialize()
+{
 	sta_cyc(SDFS_CYC);
-
-	if (romdisk_init())
-		result = 0;
-
-	if (result == 0) {
-		ntstdio_printf(&ntstdio, "ROM disk (0:) OK!\n");
-	}
-	else {
-		ntstdio_printf(&ntstdio, "ROM disk (0:) NG!\n");
-	}
-
-	/* uploadディレクトリを作成しておく */
-	f_mkdir("1:/upload");
-
-	serial_ctl_por(SIO_PORTID, IOCTL_FCSND | IOCTL_FCRCV);
-
-	return result;
-}
-
-void sys_init(void)
-{
-	sys_tlsf = tlsf_create(&shell_heap);
-	if (sys_tlsf == NULL)
-		return;
-
-	sys_pool = tlsf_add_pool(sys_tlsf, ((uint8_t *)&shell_heap) + tlsf_size(), sizeof(shell_heap) - tlsf_size());
-}
-
-void sys_fini(void)
-{
-	tlsf_destroy(sys_tlsf);
-}
-
-void *sys_malloc(size_t size)
-{
-	return tlsf_malloc(sys_tlsf, size);
-}
-
-void *sys_calloc(size_t size, size_t count)
-{
-	void *result = tlsf_malloc(sys_tlsf, count * size);
-	memset(result, 0, count * size);
-	return result;
-}
-
-void *sys_realloc(void *ptr, size_t size)
-{
-	return tlsf_realloc(sys_tlsf, ptr, size);
-}
-
-void sys_free(void *ptr)
-{
-	tlsf_free(sys_tlsf, ptr);
 }
 
@@ -219,5 +229,5 @@
 		return ramdisk_get_status();
 	case 1:
-		return sdfs_status(&sdfs);
+		return sdfs._is_initialized;
 	}
 	return STA_NOINIT;
@@ -246,4 +256,6 @@
 }
 
+DRESULT sdfs_ioctl(BYTE ctrl, void *buff);
+
 DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff)
 {
@@ -252,31 +264,166 @@
 		return RES_PARERR; /* ramdisk_ioctl(cmd, buff); */
 	case 1:
-		switch(cmd) {
-		case CTRL_SYNC:
-			return sdfs_sync(&sdfs);
-		case GET_SECTOR_COUNT:
-			return sdfs_sectors(&sdfs);
-		case GET_BLOCK_SIZE:
-			*((DWORD*)buff) = 1; // default when not known
-			return RES_OK;
-		}
+		return sdfs_ioctl(cmd, buff);
 	}
 	return RES_PARERR;
 }
 
+DRESULT sdfs_ioctl(BYTE ctrl, void *buff)
+{
+	DRESULT res;
+	uint32_t *dp = (uint32_t *)buff;
+	uint8_t *ptr = (uint8_t *)buff;
+
+	if (sdfs._is_initialized & STA_NOINIT)
+		return RES_NOTRDY;
+
+	res = RES_ERROR;
+
+	switch (ctrl) {
+	case CTRL_SYNC:
+		if (sdfs_sync(&sdfs) == 0) {
+			res = RES_OK;
+		}
+		break;
+	case GET_SECTOR_SIZE:
+		*(WORD*)buff = 512;
+		res = RES_OK;
+		break;
+	case GET_SECTOR_COUNT:
+		*(DWORD*)buff = sdfs._capacity / 512;
+		res = RES_OK;
+		break;
+	case GET_BLOCK_SIZE:
+		*(DWORD*)buff = sdfs._block_len;
+		res = RES_OK;
+		break;
+	case CTRL_TRIM:
+		res = sdfs_trim(&sdfs, dp[0], dp[1]);
+		break;
+	case MMC_GET_TYPE:
+		*ptr = sdfs._card_type;
+		res = RES_OK;
+		break;
+	case MMC_GET_CSD:
+		memcpy(ptr, sdfs._csd, sizeof(sdfs._csd));
+		res = RES_OK;
+		break;
+	case MMC_GET_CID:
+		memcpy(ptr, sdfs._cid, sizeof(sdfs._cid));
+		res = RES_OK;
+		break;
+	case MMC_GET_OCR:
+		if (sdfs_get_ocr(&sdfs, buff) == 0) {
+			res = RES_OK;
+		}
+		break;
+	case MMC_GET_SDSTAT:
+		if (sdfs_get_sdstat(&sdfs, buff) == 0) {
+			res = RES_OK;
+		}
+		break;
+	default:
+		res = RES_PARERR;
+	}
+
+	return res;
+}
+
 void sdfs_cychdr(intptr_t exinf)
 {
-	BYTE s;
-
-	s = sdfs._is_initialized;
-	if (WP())		/* Write protected */
+	BYTE s = 0;
+             
+	/* Write protected */
+	if (WP())
 		s |= STA_PROTECT;
-	else		/* Write enabled */
+	else
 		s &= ~STA_PROTECT;
-	if (gpio_read(&ins))	/* Card is in socket */
+
+	/* Card is in socket */
+	if (gpio_read(&ins))
+		s |= (STA_NODISK | STA_NOINIT);
+	else
 		s &= ~STA_NODISK;
-	else		/* Socket empty */
-		s |= (STA_NODISK | STA_NOINIT);
-	sdfs._is_initialized = s;
+
+	sdfs_new_status = s;
+
+	if ((sdfs_prev_status != sdfs_new_status) && (ffarch_state == FFS_IDLE)) {
+		ffarch_timer = 0;
+		wup_tsk(FFARCH_TASK);
+	}
+}
+
+int ffarch_get_timer(void)
+{
+	return ffarch_timer;
+}
+
+void ffarch_progress(int elapse)
+{
+	if (ffarch_timer != TMO_FEVR) {
+		ffarch_timer -= elapse;
+		if (ffarch_timer < 0) {
+			ffarch_timer = 0;
+		}
+	}
+}
+
+void ffarch_timeout(void)
+{
+	if (ffarch_timer != 0)
+		return;
+
+	switch (ffarch_state) {
+	case FFS_RETRY_WAIT:
+		if (ffarch_retry_count == 0) {
+			syslog(SD_CARD_LOG_LEVEL, "SD card (1:) initialize tired...");
+
+			ffarch_state = FFS_IDLE;
+			ffarch_timer = TMO_FEVR;
+			ffarch_retry_count = 3;
+			break;
+		}
+		ffarch_retry_count--;
+		//goto case FFS_IDLE;
+	case FFS_IDLE:
+ 		/* SDカードが入れられた場合 */
+ 		if ((sdfs._is_initialized & STA_NOINIT)
+ 			|| (((sdfs_prev_status & STA_NODISK) != 0) && ((sdfs_new_status & STA_NODISK) == 0))) {
+			syslog(SD_CARD_LOG_LEVEL, "SD card initializing ...");
+
+			if (SD_begin()) {
+				syslog(SD_CARD_LOG_LEVEL, "SD card (1:) OK!");
+
+				/* uploadディレクトリを作成しておく */
+				f_mkdir("1:/upload");
+
+				ffarch_state = FFS_IDLE;
+				ffarch_timer = TMO_FEVR;
+				ffarch_retry_count = 3;
+			}
+			else {
+				syslog(SD_CARD_LOG_LEVEL, "SD card (1:) NG!");
+				ffarch_state = FFS_RETRY_WAIT;
+				ffarch_timer = 1000 * 1000;
+			}
+		}
+		/* SDカードが抜かれた場合 */
+		else if (((sdfs_prev_status & STA_NODISK) == 0) && ((sdfs_new_status & STA_NODISK) != 0)) {
+			syslog(SD_CARD_LOG_LEVEL, "SD card unmount");
+
+			f_mount(&Sd.FatFs, "1:", 0);
+			ffarch_state = FFS_IDLE;
+			ffarch_timer = TMO_FEVR;
+			ffarch_retry_count = 3;
+		}
+		if (((sdfs_prev_status ^ sdfs_new_status) & STA_PROTECT) != 0) {
+			if ((sdfs_new_status & STA_PROTECT) != 0)
+				sdfs._is_initialized |= STA_PROTECT;
+			else
+				sdfs._is_initialized &= ~STA_PROTECT;
+		}
+		sdfs_prev_status = sdfs_new_status;
+		break;
+	}
 }
 
@@ -314,10 +461,10 @@
 void* ff_memalloc (UINT msize)
 {
-	return sys_malloc(msize);
+	return malloc(msize);
 }
 
 void ff_memfree (void* mblock)
 {
-	sys_free(mblock);
+	free(mblock);
 }
 
