Test program for FlashAir with iSDIO

Dependencies:   FlashAir_iSDIO SDFileSystem

Files at this revision

API Documentation at this revision

Comitter:
kenjiArai
Date:
Wed Aug 28 22:48:37 2019 +0000
Parent:
2:e891da5a46a1
Commit message:
Test program for FlashAir/TOSHIBA with iSDIO

Changed in this revision

FlashAir_monitor/mon.cpp Show annotated file Show diff for this revision Revisions of this file
FlashAir_monitor/mon.h Show annotated file Show diff for this revision Revisions of this file
SDFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
check_revision.cpp 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
mbed-os.lib Show annotated file Show diff for this revision Revisions of this file
mbed_app.json Show annotated file Show diff for this revision Revisions of this file
tests/README.md Show diff for this revision Revisions of this file
tests/blinky.log Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FlashAir_monitor/mon.cpp	Wed Aug 28 22:48:37 2019 +0000
@@ -0,0 +1,1382 @@
+/*
+ * mbed Application program for the mbed
+ *  FlashAir Check program
+ *
+ * Copyright (c) 2015,'19 Kenji Arai / JH1PJL
+ *  http://www.page.sannet.ne.jp/kenjia/index.html
+ *  https://os.mbed.com/users/kenjiArai/
+ *      Created:    May        5th, 2015
+ *      Revised:    August    27th, 2019
+ */
+
+//  Include --------------------------------------------------------------------
+#include "mbed.h"
+#include "FlashAir_iSDIO.h"
+#include "mon.h"
+
+//  Definition -----------------------------------------------------------------
+#define DO_DEBUG    0
+
+#if DO_DEBUG
+#define DEBUG_LINE  pc.printf("line:%d\r\n", __LINE__);
+#else
+#define DEBUG_LINE  {;}
+#endif
+
+// from ffconf.h
+#define _VOLUMES    1
+
+//  RAM ------------------------------------------------------------------------
+BYTE Buff[4096];
+char linebuf[64];           // Console input buffer
+FATFS Fatfs[_VOLUMES];      // File system object for each logical drive
+FIL File1, File2;           // File objects
+FATFS_DIR* Dirx;
+FILINFO Finfo;
+char Lfname[512];
+DWORD AccSize;              // Work register for fs command
+WORD AccFiles, AccDirs;
+
+uint8_t buffer[512];
+uint32_t nextSequenceId = 0;
+
+//  ROM / Constant data --------------------------------------------------------
+const char *const monmsg0 =
+    "Start monitor program for FlashAir & FatFs/SD File System\r\n";
+const char *const monmsg1 =
+    " <Please press any key to start the monitor>";
+const char *const hisdmsg0 =
+    "Entered FlashAir/TOSHIBA iSDIO control commands\r\n";
+const char *const hisdmsg1 =
+    " retrun=q Help=?\r\n";
+const char *const rtnmsg =
+    "Return to Root Mode\r\n";
+const char *const msg_ok =
+    "\r\nSuccess\r\n";
+const char *const msg_ng =
+    "\r\nFailed\r\n";
+
+static const char HelpMsg0[] =
+    "i     FlashAir, iSDIO\r\n"
+    "dir   <full_pass>\r\n"
+    "type  <file_name>\r\n"
+    "vol\r\n"
+    "ren   <org_file_name> <new_file_name>\r\n"
+    "copy  <file_name> <file_name>\r\n"
+    "mkdir <dir_name>\r\n"
+    "cd    <dir_name>\r\n"
+    "q     Return to main\r\n"
+    "t     Show current time or Adjust time\r\n"
+    "      e.g. t 19 8 24 14 15 16 -> August 24,'19, 14:15:16\r\n"
+    "?     Help/You know the command\r\n"
+    "\r\n";
+
+static const char HelpMsg1[] =
+    "a  Set as AP(Access Point) mode / Act as Host\r\n"
+    "s  Set as STA(Station) mode / Connect to Host\r\n"
+    "q  Return to File control monitor\r\n"
+    "\r\n";
+
+static const char HelpMsg2[] =
+    "Connect to Host: step d->s->c->g\r\n"
+    "s  Scan sounded host\r\n"
+    "c  Connect specific host\r\n"
+    "d  Disconnect line\r\n"
+    "g  Get status\r\n"
+    "t  Current time(JST)\r\n"
+    "q  Return to previous monitor\r\n"
+    "\r\n";
+
+static const char HelpMsg3[] =
+    "Estblish as Host: step d->e->g\r\n"
+    "e  Establish connection\r\n"
+    "d  Disconnect line\r\n"
+    "g  Get status\r\n"
+    "q  Return to previous monitor\r\n"
+    "\r\n";
+
+// Host information @ STA mode
+const char *const ssid       = "pr500m-c86a71-1";
+const char *const networkKey = "7daaa01146644";
+
+// FlashAir Host name & password @ AP mode
+const char *const name_as_host = "flashair";
+const char *const password_ap  = "12345678";
+
+//  Function prototypes --------------------------------------------------------
+
+//  Object ---------------------------------------------------------------------
+extern Serial pc;
+extern FlashAir_iSDIO sd;
+Timer   t;
+
+//------------------------------------------------------------------------------
+//  Control Program
+//------------------------------------------------------------------------------
+// Monitor program for File control
+void mon ()
+{
+    char *ptr;
+
+    Dirx = new FATFS_DIR;
+    /* Open Uart to communicate with Host PC */
+    pc.puts(monmsg0);
+    pc.puts(monmsg1);
+    crlf();
+    /* monitor is running all time when systen is running */
+    char c = pc.getc();
+    Finfo.lfname = Lfname;
+    Finfo.lfsize = sizeof Lfname;
+    //pc.printf("0x%x, 0x%x\r\n", mon, HelpMsg0);
+    for (;;) {
+        DEBUG_LINE
+        pc.putc('>');
+        ptr = linebuf;
+        get_line( ptr, sizeof(linebuf) );
+        switch ( *ptr++ ) {
+            // iSDIO, goto sub functions
+            case 'i' :
+                isdio_mon(ptr);
+                break;
+            // vol
+            case 'v' :
+                v_next(ptr);
+                break;
+            // dir
+            case 'd' :
+                d_next(ptr);
+                break;
+            // cd, copy
+            case 'c' :
+                c_next(ptr);
+                break;
+            // mkdir
+            case 'm' :
+                m_next(ptr);
+                break;
+            // ren
+            case 'r' :
+                r_next(ptr);
+                break;
+            // type, set time
+            case 't' :
+                t_next(ptr);
+                break;
+            // Help
+            case '?' :
+                pc.puts(HelpMsg0);
+                break;
+            // Exit monitor (return to main())
+            case 'q' :
+                pc.puts("Return to main\r\n");
+                return;
+            // Not a command
+            default:
+                DEBUG_LINE
+                pc.puts("? [HELP]=?");
+                crlf();
+                break;
+        }
+    }
+}
+
+uint32_t get_disk_freespace(void)
+{
+    long  p1;
+    UINT   s1, s2;
+    FATFS  *fs;
+    BYTE res;
+
+    if (Dirx == NULL) {
+        Dirx = new FATFS_DIR;
+    }
+    char p = NULL;
+    res = f_opendir(Dirx, &p);
+    if (res) {
+        return 0;
+    }
+    p1 = s1 = s2 = 0;
+    for(;;) {
+        res = f_readdir(Dirx, &Finfo);
+        if ((res != FR_OK) || !Finfo.fname[0]) break;
+        if (Finfo.fattrib & AM_DIR) {
+            s2++;
+        } else {
+            s1++;
+            p1 += Finfo.fsize;
+        }
+    }
+    res = f_getfree(&p, (DWORD*)&p1, &fs);
+    uint32_t size = p1 * fs->csize * 512;
+    if (res == FR_OK) {
+        return size;
+    } else {
+        return 0;
+    }
+}
+
+static void isdio_mon(char *ptr)
+{
+    pc.puts(hisdmsg0);
+    pc.puts(hisdmsg1);
+    for (uint32_t i=0; i==0; ) {
+        pc.puts("iSDIO>");
+        ptr = linebuf;
+        get_line(ptr, sizeof(linebuf));
+        switch(*ptr++) {
+            case 'a' :
+                ap_mon(ptr);
+                break;
+            case 's' :
+                sta_mon(ptr);
+                break;
+            case 'q' :
+                i = 1;  // return
+                break;
+            case '?' :
+                pc.puts(HelpMsg1);
+                break;
+            default:
+                pc.putc('?');
+                crlf();
+        }
+    }
+    pc.puts(rtnmsg);
+}
+
+// Station Mode (connect to Host)
+static void sta_mon(char *ptr)
+{
+    static char str[512];
+    time_t seconds_jst;
+
+    pc.puts("Enterd FlashAir STA(Station) Mode -> connect to Host Device\r\n");
+    pc.puts(hisdmsg1);
+    //Initialise card
+    FILE *fp = fopen("/sd/mbed.txt", "a");
+    sprintf((char *)buffer, "..");
+    fprintf(fp,(char *)buffer);
+    fclose(fp);
+    DEBUG_LINE
+    // Read the previous sequence ID.
+    if (sd.readExtMemory(1, 1, 0x420, 0x34, buffer)) {
+        DEBUG_LINE
+        if (buffer[0x20] == 0x01) {
+            DEBUG_LINE
+            nextSequenceId = get_u32(buffer + 0x24);
+            sd.waitResponse(nextSequenceId);
+            nextSequenceId++;
+        } else {
+            DEBUG_LINE
+            nextSequenceId = 0;
+        }
+    } else {
+        DEBUG_LINE
+        pc.puts("Failed to read status\r\n");
+        nextSequenceId = 0;
+    }
+    for (uint32_t i=0; i==0; ) {
+        DEBUG_LINE
+        pc.puts("STA>");
+        ptr = linebuf;
+        get_line(ptr, sizeof(linebuf));
+        switch(*ptr++) {
+            case 's' :
+                DEBUG_LINE
+                if (iSDIO_scan(nextSequenceId) &&
+                        iSDIO_waitResponse(nextSequenceId) &&
+                        iSDIO_showScanResult()) {
+                    pc.puts(msg_ok);
+                } else {
+                    pc.puts(msg_ng);
+                }
+                nextSequenceId++;
+                break;
+            case 'c' :
+                DEBUG_LINE
+                if (iSDIO_connect(nextSequenceId, ssid, networkKey) &&
+                        iSDIO_waitResponse(nextSequenceId)) {
+                    pc.puts(msg_ok);
+                } else {
+                    pc.puts(msg_ng);
+                }
+                nextSequenceId++;
+                break;
+            case 'e' :
+                DEBUG_LINE
+                if (iSDIO_establish(nextSequenceId)) {
+                    pc.puts(msg_ok);
+                } else {
+                    pc.puts(msg_ng);
+                }
+                break;
+            case 'd' :
+                DEBUG_LINE
+                if (iSDIO_disconnect(nextSequenceId)) {
+                    pc.puts(msg_ok);
+                } else {
+                    pc.puts(msg_ng);
+                }
+                break;
+            case 't' :
+                DEBUG_LINE
+                seconds_jst = time(NULL);   // Read Int. RTC time
+                strftime(
+                    str, 40,
+                    "%B %d,'%y, %H:%M:%S",
+                    localtime(&seconds_jst));
+                pc.printf("Time(JST): %s\r\n", str);
+                break;
+            case 'g' :
+                DEBUG_LINE
+                if (iSDIO_status() == false) {
+                    pc.puts(msg_ng);
+                }
+                break;
+            case 'q' :
+                i = 1;  // return
+                break;
+            case '?' :
+                pc.puts(HelpMsg2);
+                break;
+            default:
+                DEBUG_LINE
+                pc.putc('?');
+                crlf();
+        }
+    }
+    pc.puts(rtnmsg);
+}
+
+// Access Point Mode (Act as Host)
+static void ap_mon(char *ptr)
+{
+    pc.puts("Enterd FlashAir AP(Access Point) Mode -> Act as Host\r\n");
+    pc.puts(hisdmsg1);
+    for (uint32_t i=0; i==0; ) {
+        pc.puts("AP>");
+        ptr = linebuf;
+        get_line(ptr, sizeof(linebuf));
+        switch(*ptr++) {
+            case 'e' :
+                if (iSDIO_establish(nextSequenceId)) {
+                    pc.puts(msg_ok);
+                } else {
+                    pc.puts(msg_ng);
+                }
+                break;
+            case 'd' :
+                if (iSDIO_disconnect(nextSequenceId)) {
+                    pc.puts(msg_ok);
+                } else {
+                    pc.puts(msg_ng);
+                }
+                break;
+            case 'g' :
+                if (iSDIO_status() == false) {
+                    pc.puts(msg_ng);
+                }
+                break;
+            case 'q' :
+                i = 1;  // return
+                break;
+            case '?' :
+                pc.puts(HelpMsg3);
+                break;
+            default:
+                pc.putc('?');
+                crlf();
+        }
+    }
+    pc.puts(rtnmsg);
+}
+
+//------------------------------------------------------------------------------
+// iSDIO
+void printByte(uint8_t value)
+{
+    pc.printf("%x", value >> 4);
+    pc.printf("%x", value & 0xF);
+}
+
+void printBytes(uint8_t* p, uint32_t len)
+{
+    for (uint32_t i = 0; i < len; ++i) {
+        printByte(p[i]);
+    }
+}
+void printIPAddress(uint8_t* p)
+{
+    pc.printf("%d", p[0]);
+    pc.putc('.');
+    pc.printf("%d", p[1]);
+    pc.putc('.');
+    pc.printf("%d", p[2]);
+    pc.putc('.');
+    pc.printf("%d", p[3]);
+}
+
+void printHex(uint8_t* p, uint32_t len)
+{
+    uint32_t i = 0;
+    while (i < len) {
+        if ((i & 0xf) == 0) {
+            pc.puts("\r\n");
+            printByte(i >> 4);
+            pc.puts(": ");
+        }
+        printByte(*p++);
+        i++;
+    }
+    pc.puts("\r\n");
+}
+
+uint8_t iSDIO_establish(uint32_t sequenceId)
+{
+    pc.puts("Establish command: \r\n");
+    memset(buffer, 0, 512);
+    uint8_t* p = buffer;
+    p = put_command_header(p, 1, 0);
+    p = put_command_info_header(p, 0x03, sequenceId, 3);
+    p = put_str_arg(p, (const uint8_t*)name_as_host);
+    p = put_str_arg(p, (const uint8_t*)password_ap);
+    p = put_u8_arg(p, 0x06);
+    put_command_header(buffer, 1, (p - buffer));
+    printHex(buffer, (p - buffer));
+    return sd.writeExtDataPort(1, 1, 0x000, buffer) ? true : false;
+}
+
+uint8_t iSDIO_connect(
+    uint32_t sequenceId,
+    const char* ssid,
+    const char* networkKey
+)
+{
+    pc.puts("Connect command: \r\n");
+    memset(buffer, 0, 512);
+    uint8_t* p = buffer;
+    p = put_command_header(p, 1, 0);
+    p = put_command_info_header(p, 0x02, sequenceId, 2);
+    p = put_str_arg(p, (const uint8_t*)ssid);
+    p = put_str_arg(p, (const uint8_t*)networkKey);
+    put_command_header(buffer, 1, (p - buffer));
+    printHex(buffer, (p - buffer));
+    return sd.writeExtDataPort(1, 1, 0x000, buffer) ? true : false;
+}
+
+uint8_t iSDIO_disconnect(uint32_t sequenceId)
+{
+    pc.puts("Disconnect command: \r\n");
+    memset(buffer, 0, 512);
+    uint8_t* p = buffer;
+    p = put_command_header(p, 1, 0);
+    p = put_command_info_header(p, 0x07, sequenceId, 0);
+    put_command_header(buffer, 1, (p - buffer));
+    printHex(buffer, (p - buffer));
+    return sd.writeExtDataPort(1, 1, 0x000, buffer) ? true : false;
+}
+
+uint8_t iSDIO_waitResponse(uint32_t sequenceId)
+{
+    pc.puts("Waiting response ");
+    uint8_t prev = 0xFF;
+    for (int i = 0; i < 20; ++i) {
+        memset(buffer, 0, 0x14);
+
+        // Read command response status.
+        if (!sd.readExtMemory(1, 1, 0x440, 0x14, buffer)) {
+            return false;
+        }
+        uint8_t resp = get_u8(buffer + 8);
+        if (sequenceId == get_u32(buffer + 4)) {
+            if (prev != resp) {
+                switch (resp) {
+                    case 0x00:
+                        pc.puts("  Initial");
+                        break;
+                    case 0x01:
+                        pc.puts("  Command Processing");
+                        break;
+                    case 0x02:
+                        pc.puts("  Command Rejected");
+                        return false;
+                    case 0x03:
+                        pc.puts("  Process Succeeded");
+                        return true;
+                    case 0x04:
+                        pc.puts("  Process Terminated");
+                        return false;
+                    default:
+                        pc.puts("  Process Failed ");
+                        return false;
+                }
+                prev = resp;
+            }
+        }
+        pc.putc('.');
+        wait(1.0);
+    }
+    return false;
+}
+
+uint8_t iSDIO_scan(uint32_t sequenceId)
+{
+    pc.puts("Scan: \r\n");
+    memset(buffer, 0, 512);
+    uint8_t* p = buffer;
+    p = put_command_header(p, 1, 0);
+    p = put_command_info_header(p, 0x01, sequenceId, 0);
+    put_command_header(buffer, 1, (p - buffer));
+    printHex(buffer, (p - buffer));
+    return sd.writeExtDataPort(1, 1, 0x000, buffer) ? true : false;
+}
+
+uint8_t iSDIO_showScanResult(void)
+{
+    // Try to output some wifi info.
+    if (!sd.readExtDataPort(1, 1, 0x200, buffer)) {
+        pc.puts("Scan result: False\r\n");
+        return false;
+    }
+    uint8_t num = get_u8(buffer + 24);
+    pc.puts("\r\nScan result:Number of APs: ");
+    pc.printf("%u\r\n",num);
+    uint8_t* p = buffer + 28;
+    for (int i = 0; i < num; i++) {
+        pc.putc(' ');
+        pc.printf("%s",(const char*)p);
+        pc.puts(", ");
+        printBytes(p + 32, 6);
+        pc.puts(", ");
+        pc.printf("%u",get_u8(p + 38));
+        pc.puts(", ");
+        switch (get_u8(p + 39)) {
+            case 0 :
+                pc.puts("NoSec");
+                break;
+            case 1 :
+                pc.puts("WEP");
+                break;
+            case 2 :
+                pc.puts("WPA");
+                break;
+            case 3 :
+                pc.puts("WPA2");
+                break;
+            default :
+                pc.puts("error");
+                break;
+        }
+        pc.puts("\r\n");
+        p += 44;
+    }
+    return true;
+}
+
+uint8_t iSDIO_status(void)
+{
+    pc.puts("Read iSDIO Status Register\r\n");
+    // Read iSDIO Status Register (E7 1.10 2.2.2.1)
+    memset(buffer, 0, 0x200);
+    if (!sd.readExtMemory(1, 1, 0x400, 0x200, buffer)) {
+        pc.puts("Cannot read Ext Memory\r\n");
+        return false;
+    }
+#if 1
+    uint16_t j = 0;
+    pc.puts("HEX 0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f\r\n 0 ");
+    for (int i = 0; i < 0x200; i++) {
+        pc.printf("%2x ", buffer[i]);
+        if ((i & 0xf) == 0xf) {
+            if (i == 0x1ff) {
+                pc.puts("\r\n");
+            } else {
+                pc.printf("\r\n%2x ", ++j);
+            }
+        }
+    }
+#endif
+    // Show values in the common status area.
+    pc.puts("\r\n == iSDIO Status Registers == ");
+    pc.puts("\r\n [0400h] Command Write Status: ");
+    if (buffer[0x000] & 0x01) pc.puts("CWU ");
+    if (buffer[0x000] & 0x02) pc.puts("CWA ");
+    pc.puts("\r\n [0420h] iSDIO Status: ");
+    if (buffer[0x020] & 0x01) pc.puts("CRU ");
+    if (buffer[0x020] & 0x02) pc.puts("ESU ");
+    if (buffer[0x020] & 0x04) pc.puts("MCU ");
+    if (buffer[0x020] & 0x08) pc.puts("ASU ");
+    pc.puts("\r\n [0422h] iSDIO Int Enable: ");
+    if (buffer[0x022] & 0x01) pc.puts("CRU_ENA ");
+    if (buffer[0x022] & 0x02) pc.puts("ESU_ENA ");
+    if (buffer[0x022] & 0x04) pc.puts("MCU_ENA ");
+    if (buffer[0x022] & 0x08) pc.puts("ASU_ENA ");
+    pc.puts("\r\n [0424h] Error Status: ");
+    if (buffer[0x024] & 0x01) pc.puts("CRE ");
+    if (buffer[0x024] & 0x02) pc.puts("CWE ");
+    if (buffer[0x024] & 0x04) pc.puts("RRE ");
+    if (buffer[0x024] & 0x08) pc.puts("APE ");
+    pc.puts("\r\n [0426h] Memory Status: ");
+    if (buffer[0x026] & 0x01) pc.puts("MEX ");
+    if (buffer[0x026] & 0x02) pc.puts("FAT ");
+    for (int i = 0; i < 8; ++i) {
+        uint8_t addr = 0x40 + i * 0x14;
+        pc.puts("\r\n [04");
+        printByte(addr);
+        pc.puts("h] Command Response Status #");
+        pc.printf("%d", i + 1);
+        pc.puts(": ");
+        if (buffer[addr] & 0x01) {
+            pc.puts("id = ");
+            pc.printf("%d", get_u16(buffer + addr + 2));
+            pc.puts(", sequence id = ");
+            pc.printf("%d", get_u32(buffer + addr + 4));
+            pc.puts(", status = ");
+            switch (buffer[addr + 8]) {
+                case 0x00:
+                    pc.puts("Initial");
+                    break;
+                case 0x01:
+                    pc.puts("Command Processing");
+                    break;
+                case 0x02:
+                    pc.puts("Command Rejected");
+                    break;
+                case 0x03:
+                    pc.puts("Process Succeeded");
+                    break;
+                case 0x04:
+                    pc.puts("Process Terminated");
+                    break;
+                default:
+                    pc.puts("Process Failed ");
+                    pc.printf("0x%x", buffer[addr + 8]);
+                    break;
+            }
+        } else {
+            pc.puts("Not registered");
+        }
+    }
+    // Show values in the application status area.
+    pc.puts("\r\n == Wireless LAN Status Registers ==");
+    pc.puts("\r\n [0500h] DLNA Status: ");
+    if (buffer[0x100] & 0x01) pc.puts("ULR ");
+    if (buffer[0x100] & 0x02) pc.puts("DLU ");
+    if (buffer[0x100] & 0x04) pc.puts("CBR ");
+    if (buffer[0x100] & 0x08) pc.puts("CDR ");
+    pc.puts("\r\n [0501h] P2P Status: ");
+    if (buffer[0x101] & 0x01) pc.puts("ILU ");
+    if (buffer[0x101] & 0x02) pc.puts("FLU ");
+    pc.puts("\r\n [0502h] PTP Status: ");
+    if (buffer[0x102] & 0x01) pc.puts("RPO ");
+    if (buffer[0x102] & 0x02) pc.puts("RPD ");
+    if (buffer[0x102] & 0x04) pc.puts("RPC ");
+    if (buffer[0x102] & 0x08) pc.puts("CPI ");
+    if (buffer[0x102] & 0x10) pc.puts("DPI ");
+    if (buffer[0x102] & 0x20) pc.puts("CIL ");
+    pc.puts("\r\n [0504h] Application: ");
+    pc.printf("0x%x", buffer[0x104]);
+    pc.puts("\r\n [0506h] WLAN: ");
+    if ((buffer[0x106] & 0x01) == 0x00) pc.puts("No Scan, ");
+    if ((buffer[0x106] & 0x01) == 0x01) pc.puts("Scanning, ");
+    if ((buffer[0x106] & 0x06) == 0x00) pc.puts("No WPS, ");
+    if ((buffer[0x106] & 0x06) == 0x02) pc.puts("WPS with PIN, ");
+    if ((buffer[0x106] & 0x06) == 0x04) pc.puts("WPS with PBC, ");
+    if ((buffer[0x106] & 0x08) == 0x00) pc.puts("Group Client, ");
+    if ((buffer[0x106] & 0x08) == 0x08) pc.puts("Group Owner ");
+    if ((buffer[0x106] & 0x10) == 0x00) pc.puts("STA, ");
+    if ((buffer[0x106] & 0x10) == 0x10) pc.puts("AP, ");
+    if ((buffer[0x106] & 0x60) == 0x00) pc.puts("Initial, ");
+    if ((buffer[0x106] & 0x60) == 0x20) pc.puts("Infrastructure, ");
+    if ((buffer[0x106] & 0x60) == 0x40) pc.puts("Wi-Fi Direct, ");
+    if ((buffer[0x106] & 0x80) == 0x00) pc.puts("No Connection, ");
+    if ((buffer[0x106] & 0x80) == 0x80) pc.puts("Connected, ");
+    pc.puts("\r\n [0508h] SSID: ");
+    for (int i = 0; i < 32 && buffer[0x108 + i] != 0; ++i) {
+        pc.printf("%c", (char)buffer[0x108 + i]);
+    }
+    pc.puts("\r\n [0528h] Encryption Mode: ");
+    switch (buffer[0x128]) {
+        case 0 :
+            pc.puts("Open System and no encryption");
+            break;
+        case 1 :
+            pc.puts("Open System and WEP");
+            break;
+        case 2 :
+            pc.puts("Shared Key and WEP");
+            break;
+        case 3 :
+            pc.puts("WPA-PSK and TKIP");
+            break;
+        case 4 :
+            pc.puts("WPA-PSK and AES");
+            break;
+        case 5 :
+            pc.puts("WPA2-PSK and TKIP");
+            break;
+        case 6 :
+            pc.puts("WPA2-PSK and AES");
+            break;
+        default:
+            pc.puts("Unknown");
+    }
+    pc.puts("\r\n [0529h] Signal Strength: ");
+    pc.printf("%d", buffer[0x129]);
+    pc.puts("\r\n [052Ah] Channel: ");
+    if (buffer[0x12A] == 0) pc.puts("No connection");
+    else pc.printf("%d", buffer[0x12A]);
+    pc.puts("\r\n [0530h] MAC Address: ");
+    printBytes(buffer + 0x130, 6);
+    pc.puts("\r\n [0540h] ID: ");
+    for (int i = 0; i < 16 && buffer[0x140 + i] != 0; ++i) {
+        pc.printf("%c", (char)buffer[0x140 + i]);
+    }
+    pc.puts("\r\n [0550h] IP Address: ");
+    printIPAddress(buffer + 0x150);
+    pc.puts("\r\n [0554h] Subnet Mask: ");
+    printIPAddress(buffer + 0x154);
+    pc.puts("\r\n [0558h] Default Gateway: ");
+    printIPAddress(buffer + 0x158);
+    pc.puts("\r\n [055Ch] Preferred DNS Server: ");
+    printIPAddress(buffer + 0x15C);
+    pc.puts("\r\n [0560h] Alternate DNS Server: ");
+    printIPAddress(buffer + 0x160);
+    pc.puts("\r\n [0564h] Proxy Server: ");
+    if ((buffer[0x164] & 0x01) == 0x00) pc.puts("Disabled");
+    if ((buffer[0x164] & 0x01) == 0x01) pc.puts("Enabled");
+    pc.puts("\r\n [0570h] Date: ");
+    pc.printf("%d", buffer[0x171] + 1980);
+    pc.putc('-');
+    pc.printf("%d", buffer[0x170] >> 4);
+    pc.putc('-');
+    pc.printf("%d", buffer[0x170] & 0xF);
+    pc.puts("\r\n [0572h] Time: ");
+    pc.printf("%d", buffer[0x173] >> 3);
+    pc.putc(':');
+    pc.printf("%d", buffer[0x172] << 3 | buffer[0x170] >> 3);
+    pc.putc(':');
+    pc.printf("%d", (buffer[0x172] & 0x1F) * 2);
+    pc.puts("\r\n [0574h] HTTP Status: ");
+    pc.printf("%d", buffer[0x174] & 0xEF);
+    if ((buffer[0x174] & 0x80) == 0x00) pc.puts(" (No Processing)");
+    if ((buffer[0x174] & 0x80) == 0x80) pc.puts(" (Processing)");
+    pc.puts("\r\n [0575h] Power Save Management: ");
+    if ((buffer[0x175] & 0x01) == 0x00) pc.puts("Power Save Mode Off");
+    if ((buffer[0x175] & 0x01) == 0x01) pc.puts("Power Save Mode On");
+    pc.puts("\r\n [0576h] File System Management: ");
+    if ((buffer[0x176] & 0x01) == 0x00) {
+        pc.puts("FS Information may be modified");
+    }
+    if ((buffer[0x176] & 0x01) == 0x01) {
+        pc.puts("FS Information shall not be modified");
+    }
+    pc.puts("\r\n");
+    return true;
+}
+
+//------------------------------------------------------------------------------
+// General monitor functions
+static void v_next(char *ptr)
+{
+    switch (*ptr++) {
+        case 'o' :
+            if (*ptr == 'l') {
+                *ptr = 's';
+                file_inf(ptr);  // fs [<path>] - Show volume status
+            }
+            break;
+        default:
+            pc.puts( "?\r\n" );
+    }
+}
+
+static void d_next(char *ptr)
+{
+    switch (*ptr++) {
+        case 'i' :
+            if (*ptr == 'r') {
+                *ptr = 'l';
+                file_inf(ptr);  // fl [<path>] - Directory listing
+            }
+            break;
+        default:
+            pc.puts( "?\r\n" );
+    }
+}
+
+static void c_next(char *ptr)
+{
+    switch (*ptr++) {
+        case 'o' :
+            if ((*ptr == 'p') && (*(ptr + 1) == 'y')) {
+                ptr++;
+                *ptr = 'x';
+                file_inf(ptr);  // fx <src_name> <dst_name> - Copy file
+            }
+            break;
+        case 'd' :
+            *ptr = 'g';
+            file_inf(ptr);  // fg Change directory
+            break;
+        default:
+            pc.puts( "?\r\n" );
+    }
+}
+
+static void m_next(char *ptr)
+{
+    switch (*ptr++) {
+        case 'k' :
+            if ((*ptr == 'd') && (*(ptr + 1) == 'i') && (*(ptr + 2) == 'r')) {
+                ptr += 2;
+                *ptr = 'k';
+                file_inf(ptr);  // fk <name> - Create a directory
+            }
+            break;
+        default:
+            pc.puts("?\r\n");
+    }
+}
+
+static void r_next(char *ptr)
+{
+    switch (*ptr++) {
+        case 'e' :
+            // fn <old_name> <new_name> - Change file/dir name
+            if (*ptr == 'n') {
+                file_inf(ptr);
+            }
+            break;
+        default:
+            pc.puts("?\r\n");
+    }
+}
+
+static void t_next(char *ptr)
+{
+    switch (*ptr++) {
+        case ' ' :
+        case 0x0d:
+            chk_and_set_time(ptr);
+        case 'y' :
+            if ((*ptr == 'p') && (*(ptr + 1) == 'e')) {
+                ptr++;
+                *ptr = '&';
+                file_inf(ptr);
+            }
+            break;
+        default:
+            pc.puts("?\r\n");
+    }
+}
+
+static FRESULT scan_files(
+    char* path      /* Pointer to the path name working buffer */
+)
+{
+    FATFS_DIR  dirs;
+    FRESULT res;
+    BYTE i;
+    char *fn;
+
+    if ((res = f_opendir(&dirs, path)) == FR_OK) {
+        i = strlen(path);
+        pc.printf("path: %s, n=%u\r\n", path, i);
+        while (((res = f_readdir(&dirs, &Finfo)) == FR_OK) && Finfo.fname[0]) {
+            if (_FS_RPATH && Finfo.fname[0] == '.') {
+                continue;
+            }
+            fn = *Finfo.lfname ? Finfo.lfname : Finfo.fname;
+            if (Finfo.fattrib & AM_DIR) {
+                AccDirs++;
+                *(path+i) = '/';
+                strcpy(path+i+1, fn);
+                res = scan_files(path);
+                *(path+i) = '\0';
+                if (res != FR_OK) break;
+            } else {
+                pc.printf("%s/%s\r\n", path, fn);
+                AccFiles++;
+                AccSize += Finfo.fsize;
+            }
+        }
+    }
+    return res;
+}
+
+static void put_rc(FRESULT rc)
+{
+    const char *str =
+        "OK\0" "DISK_ERR\0" "INT_ERR\0" "NOT_READY\0" "NO_FILE\0" "NO_PATH\0"
+        "INVALID_NAME\0" "DENIED\0" "EXIST\0" "INVALID_OBJECT\0"
+        "WRITE_PROTECTED\0" "INVALID_DRIVE\0" "NOT_ENABLED\0"
+        "NO_FILE_SYSTEM\0" "MKFS_ABORTED\0" "TIMEOUT\0"
+        "LOCKED\0" "NOT_ENOUGH_CORE\0" "TOO_MANY_OPEN_FILES\0";
+    for (uint32_t i = 0; i != rc && *str; i++ ) {
+        while ( *str++ ) { ;}
+    }
+    pc.printf( "rc=%u FR_%s\r\n", (UINT)rc, str );
+}
+
+static void file_inf(char *ptr)
+{
+    DDWORD pf;
+    long  p1, p2, p3;
+    CHAR   *ptr2;
+    BYTE   f_res;
+    UINT   s1, s2, cnt, blen = sizeof Buff;
+    FATFS  *fs;
+    static const BYTE ft[] = {0, 12, 16, 32};
+    BYTE res;
+    DWORD ofs = 0;
+    uint32_t tim;
+
+    switch (*ptr++) {
+        case '&' :
+            DEBUG_LINE;
+            while (*ptr == ' ') ptr++;
+            /* Open a file */
+            f_res = f_open(&File1, ptr, FA_READ);
+            if ( f_res ) {
+                put_rc((FRESULT)f_res);
+                break;
+            }
+            DEBUG_LINE;
+            /* Read all lines and display it */
+            while(true) {
+                f_res = f_read(&File1, (TCHAR*)Buff, blen, &cnt);
+                if ( f_res ) {
+                    put_rc((FRESULT)f_res);
+                    break;
+                }
+                for (s1 = 0; s1 < cnt; s1++) {
+                    pc.putc(Buff[s1]);
+                }
+                if (cnt != blen) {
+                    break;
+                }
+            }
+            DEBUG_LINE;
+            /* Close the file */
+            f_close(&File1);
+            break;
+        case 'i' :  /* fi [<opt>]- Initialize logical drive */
+            if ( !xatoi(&ptr, &p1) ) {
+                break;
+            }
+            if (!xatoi(&ptr, &p2)) p2 = 0;
+            put_rc(f_mount(&Fatfs[p1], (const TCHAR*)p1, 0));
+            break;
+        case 's' :  /* fs [<path>] - Show volume status */
+            f_res = f_getfree( ptr, (DWORD*)&p2, &fs );
+            if ( f_res ) {
+                put_rc((FRESULT)f_res);
+                break;
+            }
+            pc.printf
+            (
+                "\rFAT type = FAT%u\r\nBytes/Cluster"
+                " = %lu\r\nNumber of FATs = %u\r\n"
+                "Root DIR entries = %u\r\n"
+                "Sectors/FAT = %lu\r\n"
+                "Number of clusters = %lu\r\n"
+                "FAT start (lba) = %lu\r\n"
+                "DIR start (lba,clustor) = %lu\r\n"
+                "Data start (lba) = %lu\r\n",
+                ft[fs->fs_type & 3], (DWORD)fs->csize * 512, fs->n_fats,
+                fs->n_rootdir, fs->fsize, (DWORD)fs->n_fatent - 2,
+                fs->fatbase, fs->dirbase, fs->database
+            );
+            AccSize = AccFiles = AccDirs = 0;
+            break;
+        case 'l' :  /* fl [<path>] - Directory listing */
+            while ( *ptr == ' ' ) {
+                ptr++;
+            }
+            f_res = f_opendir( Dirx, ptr );
+            if ( f_res ) {
+                put_rc( (FRESULT)f_res );
+                break;
+            }
+            pf = 0;
+            p1 = s1 = s2 = 0;
+            for(;;) {
+                f_res = f_readdir( Dirx, &Finfo );
+                if ( (f_res != FR_OK) || !Finfo.fname[0] ) {
+                    break;
+                }
+                if ( Finfo.fattrib & AM_DIR ) {
+                    s2++;
+                } else {
+                    s1++;
+                    pf += Finfo.fsize;
+                }
+                pc.printf(
+                    "%c%c%c%c%c %u/%02u/%02u %02u:%02u %9lu  %-12s  %s\r\n",
+                    (Finfo.fattrib & AM_DIR) ? 'D' : '-',
+                    (Finfo.fattrib & AM_RDO) ? 'R' : '-',
+                    (Finfo.fattrib & AM_HID) ? 'H' : '-',
+                    (Finfo.fattrib & AM_SYS) ? 'S' : '-',
+                    (Finfo.fattrib & AM_ARC) ? 'A' : '-',
+                    (Finfo.fdate >> 9) + 1980, (Finfo.fdate >> 5) & 15,
+                    Finfo.fdate & 31,
+                    (Finfo.ftime >> 11), (Finfo.ftime >> 5) & 63,
+                    Finfo.fsize, Finfo.fname,
+                    Lfname );
+            }
+            p1 = pf%100;
+            pc.printf(
+                "%4u file(s),%10lu%02lu bytes total\r\n%4u Dir(s)",
+                s1, (DWORD)(pf/100), p1, s2
+            );
+            if ( f_getfree(ptr, (DWORD *)&p1, &fs) == FR_OK ) {
+                pc.printf( ",   %10lu bytes free\r\n", p1 * fs->csize * 512 );
+            } else {
+                put_rc( (FRESULT)f_res );
+            }
+            break;
+        case 'o' :  /* fo <mode> <file> - Open a file */
+            if (!xatoi(&ptr, &p1)) break;
+            while (*ptr == ' ') ptr++;
+            put_rc(f_open(&File1, ptr, (BYTE)p1));
+            break;
+        case 'c' :  /* fc - Close a file */
+            put_rc(f_close(&File1));
+            break;
+        case 'e' :  /* fe - Seek file pointer */
+            if (!xatoi(&ptr, &p1)) break;
+            res = f_lseek(&File1, p1);
+            put_rc((FRESULT)res);
+            if (res == FR_OK)
+                pc.printf("fptr=%lu(0x%lX)\r\n", File1.fptr, File1.fptr);
+            break;
+        case 'd' :  /* fd <len> - read and dump file from current fp */
+            if (!xatoi(&ptr, &p1)) break;
+            ofs = File1.fptr;
+            while (p1) {
+                if ((UINT)p1 >= 16) {
+                    cnt = 16;
+                    p1 -= 16;
+                } else                {
+                    cnt = p1;
+                    p1 = 0;
+                }
+                res = f_read(&File1, Buff, cnt, &cnt);
+                if (res != FR_OK) {
+                    put_rc((FRESULT)res);
+                    break;
+                }
+                if (!cnt) break;
+                put_dump(Buff, ofs, cnt, DW_CHAR);
+                ofs += 16;
+            }
+            break;
+        case 'r' :  /* fr <len> - read file */
+            if (!xatoi(&ptr, &p1)) break;
+            p2 = 0;
+            t.reset();
+            t.start();
+            while (p1) {
+                if ((UINT)p1 >= blen) {
+                    cnt = blen;
+                    p1 -= blen;
+                } else {
+                    cnt = p1;
+                    p1 = 0;
+                }
+                res = f_read(&File1, Buff, cnt, &s2);
+                if (res != FR_OK) {
+                    put_rc((FRESULT)res);
+                    break;
+                }
+                p2 += s2;
+                if (cnt != s2) break;
+            }
+            tim = t.read_ms();
+            pc.printf("%lu bytes read with %lu kB/sec.\r\n",
+                      p2, tim ? (p2 / tim) : 0);
+            break;
+        case 'w' :  /* fw <len> <val> - write file */
+            if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2)) break;
+            memset(Buff, (BYTE)p2, blen);
+            p2 = 0;
+            t.reset();
+            t.start();
+            while (p1) {
+                if ((UINT)p1 >= blen) {
+                    cnt = blen;
+                    p1 -= blen;
+                } else {
+                    cnt = p1;
+                    p1 = 0;
+                }
+                res = f_write(&File1, Buff, cnt, &s2);
+                if (res != FR_OK) {
+                    put_rc((FRESULT)res);
+                    break;
+                }
+                p2 += s2;
+                if (cnt != s2) break;
+            }
+            tim = t.read_ms();
+            pc.printf("%lu bytes written with %lu kB/sec.\r\n",
+                      p2, tim ? (p2 / tim) : 0);
+            break;
+        case 'n' :  /* fn <org.name> <new.name> - Change name of an object */
+            while (*ptr == ' ') ptr++;
+            ptr2 = strchr(ptr, ' ');
+            if (!ptr2) break;
+            *ptr2++ = 0;
+            while (*ptr2 == ' ') ptr2++;
+            put_rc(f_rename(ptr, ptr2));
+            break;
+        case 'u' :  /* fu <name> - Unlink an object */
+            while (*ptr == ' ') ptr++;
+            put_rc(f_unlink(ptr));
+            break;
+        case 'v' :  /* fv - Truncate file */
+            put_rc(f_truncate(&File1));
+            break;
+        case 'k' :  /* fk <name> - Create a directory */
+            while (*ptr == ' ') ptr++;
+            put_rc(f_mkdir(ptr));
+            break;
+#if FILCPY_NOTUSE == 0
+        case 'x' : /* fx <src_name> <dst_name> - Copy file */
+            while ( *ptr == ' ' ) {
+                ptr++;
+            }
+            ptr2 = strchr( ptr, ' ' );
+            if ( !ptr2 ) {
+                break;
+            }
+            *ptr2++ = 0;
+            while ( *ptr2 == ' ' ) {
+                ptr2++;
+            }
+            f_res = f_open( &File1, ptr, FA_OPEN_EXISTING | FA_READ );
+            pc.printf("Opening %s \r\n", ptr);
+            if ( f_res ) {
+                put_rc( (FRESULT)f_res );
+                break;
+            }
+            f_res = f_open( &File2, ptr2, FA_CREATE_ALWAYS | FA_WRITE );
+            pc.printf(" Creating %s \r\n", ptr2);
+            if ( f_res ) {
+                put_rc( (FRESULT)f_res );
+                f_close( &File1 );
+                break;
+            }
+            pc.printf("Copying file...");
+            p1 = 0;
+            for ( ;; ) {
+                f_res = f_read( &File1, Buff, blen, &s1 );
+                if ( f_res || s1 == 0 ) {
+                    break;   /* error or eof */
+                }
+                f_res = f_write( &File2, Buff, s1, &s2 );
+                p1 += s2;
+                if ( f_res || s2 < s1 ) {
+                    break;   /* error or disk full */
+                }
+            }
+            f_close( &File1 );
+            f_close( &File2 );
+            crlf();
+            break;
+#endif
+#if _FS_RPATH
+        case 'g' :  /* fg <path> - Change current directory */
+            while (*ptr == ' ') ptr++;
+            put_rc(f_chdir(ptr));
+            break;
+#endif
+    }
+}
+
+void put_dump (
+    void* buff,             /* Pointer to the array to be dumped */
+    unsigned long addr,     /* Heading address value */
+    int len,                /* Number of items to be dumped */
+    int width               /* Size of the items (DW_CHAR, DW_SHORT, DW_LONG) */
+)
+{
+    int i;
+    unsigned char *bp;
+    unsigned short *sp;
+    unsigned long *lp;
+
+    pc.printf( "%08lx ", addr );      /* address */
+    switch ( width )  {
+        case DW_CHAR:
+            bp = (unsigned char *)buff;
+            for ( i = 0; i < len; i++ ) {       /* Hexdecimal dump */
+                pc.printf( " %02x", bp[i] );
+            }
+            pc.putc(' ');
+            for ( i = 0; i < len; i++ ) {       /* ASCII dump */
+                pc.putc( (bp[i] >= ' ' && bp[i] <= '~') ? bp[i] : '.' );
+            }
+            break;
+        case DW_SHORT:
+            sp = (unsigned short *)buff;
+            do {                            /* Hexdecimal dump */
+                pc.printf( " %04x", *sp++ );
+            } while ( --len );
+            break;
+        case DW_LONG:
+            lp = (unsigned long *)buff;
+            do {                            /* Hexdecimal dump */
+                pc.printf( " %08lx", *lp++ );
+            } while ( --len );
+            break;
+    }
+    pc.puts( "\r\n" );
+}
+
+// RTC related subroutines
+void chk_and_set_time(char *ptr)
+{
+    char buf[64];
+
+    long p1;
+    struct tm t;
+    time_t seconds;
+
+    if (xatoi(&ptr, &p1)) {
+        t.tm_year       = (uint8_t)p1 + 100;
+        pc.printf("Year:%ld ",p1);
+        xatoi( &ptr, &p1 );
+        t.tm_mon        = (uint8_t)p1 - 1;
+        pc.printf("Month:%ld ",p1);
+        xatoi( &ptr, &p1 );
+        t.tm_mday       = (uint8_t)p1;
+        pc.printf("Day:%ld ",p1);
+        xatoi( &ptr, &p1 );
+        t.tm_hour       = (uint8_t)p1;
+        pc.printf("Hour:%ld ",p1);
+        xatoi( &ptr, &p1 );
+        t.tm_min        = (uint8_t)p1;
+        pc.printf("Min:%ld ",p1);
+        xatoi( &ptr, &p1 );
+        t.tm_sec        = (uint8_t)p1;
+        pc.printf("Sec: %ld \r\n",p1);
+        seconds = mktime(&t);
+        set_time(seconds);
+    } else {
+        seconds = time(NULL);
+    }
+    strftime(buf, 50, " %B %d,'%y, %H:%M:%S\r\n", localtime(&seconds));
+    pc.printf("[Time] %s", buf);
+}
+
+//  Get key input data
+void get_line (char *buff, int len)
+{
+    char c;
+    int idx = 0;
+
+    for (;;) {
+        c = pc.getc();
+        //    Added by Kenji Arai / JH1PJL   May 9th, 2010
+        if (c == '\r') {
+            buff[idx++] = c;
+            break;
+        }
+        if ((c == '\b') && idx) {
+            idx--;
+            pc.putc(c);
+            pc.putc(' ');
+            pc.putc(c);
+        }
+        if (((uint8_t)c >= ' ') && (idx < len - 1)) {
+            buff[idx++] = c;
+            pc.putc(c);
+        }
+    }
+    buff[idx] = 0;
+    pc.puts("\r\n");
+}
+
+/*  Outpur LF & CR */
+void crlf( void )
+{
+    pc.printf( "\r\n" );
+}
+
+/*  Check key input */
+unsigned int check_hit_key (void)
+{
+    return ( pc.readable() );
+}
+
+//------------------------------------------------------------------------------
+// Get a value of the string
+//------------------------------------------------------------------------------
+/*  "123 -5   0x3ff 0b1111 0377  w "
+        ^                           1st call returns 123 and next ptr
+           ^                        2nd call returns -5 and next ptr
+                   ^                3rd call returns 1023 and next ptr
+                          ^         4th call returns 15 and next ptr
+                               ^    5th call returns 255 and next ptr
+                                  ^ 6th call fails and returns 0
+*/
+int xatoi (         /* 0:Failed, 1:Successful */
+    char **str,     /* Pointer to pointer to the string */
+    long *res       /* Pointer to the valiable to store the value */
+)
+{
+    unsigned long val;
+    unsigned char c, r, s = 0;
+
+    *res = 0;
+    while ( (c = **str) == ' ' ) {
+        (*str)++;   /* Skip leading spaces */
+    }
+    if ( c == '-' ) {       /* negative? */
+        s = 1;
+        c = *(++(*str));
+    }
+    if ( c == '0' ) {
+        c = *(++(*str));
+        switch (c) {
+            case 'x':       /* hexdecimal */
+                r = 16;
+                c = *(++(*str));
+                break;
+            case 'b':       /* binary */
+                r = 2;
+                c = *(++(*str));
+                break;
+            default:
+                if ( c <= ' ' ) return 1;   /* single zero */
+                if ( c < '0' || c > '9' ) return 0; /* invalid char */
+                r = 8;      /* octal */
+        }
+    } else {
+        if ( c < '0' || c > '9' ) return 0; /* EOL or invalid char */
+        r = 10;         /* decimal */
+    }
+    val = 0;
+    while ( c > ' ' ) {
+        if ( c >= 'a' ) {
+            c -= 0x20;
+        }
+        c -= '0';
+        if ( c >= 17 ) {
+            c -= 7;
+            if ( c <= 9 ) {
+                return 0;   /* invalid char */
+            }
+        }
+        if ( c >= r ) {
+            return 0;   /* invalid char for current radix */
+        }
+        val = val * r + c;
+        c = *(++(*str));
+    }
+    if (s) val = 0 - val;           /* apply sign if needed */
+    *res = val;
+    return 1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FlashAir_monitor/mon.h	Wed Aug 28 22:48:37 2019 +0000
@@ -0,0 +1,87 @@
+/*
+ * mbed Application program for the mbed
+ *  FlashAir Check program /monitor part
+ *
+ * Copyright (c) 2015,'19 Kenji Arai / JH1PJL
+ *  http://www.page.sannet.ne.jp/kenjia/index.html
+ *  https://os.mbed.com/users/kenjiArai/
+ *      Created:    May        5th, 2015
+ *      Revised:    August    27th, 2019
+ */
+
+/*
+ *---------------- REFERENCE ---------------------------------------------------
+ * Original Source Information
+ * 1) FatFs sample program
+ *      ChaN FatFs  http://elm-chan.org/
+ *          http://elm-chan.org/fsw/ff/00index_j.html
+ * 2) FlashAir Arduino sample program
+ *      FlashAir Developers site
+ *          https://flashair-developers.com/ja/documents/tutorials/arduino/
+ * 3) "mbed+FlashAirで直ツイート!"
+ *      by ban4jp - ( https://developer.mbed.org/users/ban4jp/ )
+ *          https://developer.mbed.org/users/ban4jp/notebook
+ *                                          /ja-direct-tweet-for-flashair/
+ *          https://developer.mbed.org/users/ban4jp/code/FlashAir_Twitter/
+ */
+ 
+//  Definition -----------------------------------------------------------------
+#define DW_CHAR         sizeof(char)
+#define DW_SHORT        sizeof(short)
+#define DW_LONG         sizeof(long)
+
+/* These types must be 16-bit, 32-bit or larger integer */
+typedef int             INT;
+typedef unsigned int    UINT;
+
+/* These types must be 8-bit integer */
+typedef char            CHAR;
+typedef unsigned char   UCHAR;
+typedef unsigned char   BYTE;
+
+/* These types must be 16-bit integer */
+typedef short           SHORT;
+typedef unsigned short  USHORT;
+typedef unsigned short  WORD;
+typedef unsigned short  WCHAR;
+
+/* These types must be 32-bit integer */
+typedef long            LONG;
+typedef unsigned long   ULONG;
+typedef unsigned long   DWORD;
+typedef unsigned long long  DDWORD;
+
+//  Function prototypes --------------------------------------------------------
+static void v_next(char *ptr);
+static void d_next(char *ptr);
+static void c_next(char *ptr);
+static void m_next(char *ptr);
+static void r_next(char *ptr);
+static void t_next(char *ptr);
+static void isdio_mon(char *ptr);
+static void ap_mon(char *ptr);
+static void sta_mon(char *ptr);
+
+static void crlf(void);
+static FRESULT scan_files(char* path);
+static void put_rc(FRESULT rc);
+static void file_inf(char *ptr);
+static void get_line(char *buff, int len);
+static void put_dump(void* buff, unsigned long addr, int len, int width);
+static void chk_and_set_time(char *ptr);
+static int xatoi(char **str, long *res);
+
+// iSDIO
+static void isdio_help_massage(void);
+void printByte(uint8_t value);
+void printBytes(uint8_t* p, uint32_t len);
+void printIPAddress(uint8_t* p);
+void printHex(uint8_t* p, uint32_t len);
+uint8_t iSDIO_establish(uint32_t sequenceId);
+uint8_t iSDIO_connect(uint32_t sequenceId,
+                      const char* ssid, const char* networkKey);
+uint8_t iSDIO_disconnect(uint32_t sequenceId);
+uint8_t iSDIO_waitResponse(uint32_t sequenceId);
+uint8_t iSDIO_scan(uint32_t sequenceId);
+uint8_t iSDIO_showScanResult(void);
+uint8_t iSDIO_status(void);
--- a/SDFileSystem.lib	Tue Jul 16 20:04:48 2019 +0000
+++ b/SDFileSystem.lib	Wed Aug 28 22:48:37 2019 +0000
@@ -1,1 +1,1 @@
-https://os.mbed.com/users/mbed_crane_elec/code/SDFileSystem/#97d2cf36b1c2
+https://os.mbed.com/users/kenjiArai/code/SDFileSystem/#624b059495aa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/check_revision.cpp	Wed Aug 28 22:48:37 2019 +0000
@@ -0,0 +1,21 @@
+/*
+ * Check Mbed revision
+ *
+ * Copyright (c) 2019 Kenji Arai / JH1PJL
+ *  http://www.page.sannet.ne.jp/kenjia/index.html
+ *  https://os.mbed.com/users/kenjiArai/
+ *      Created:    July      17th, 2019
+ *      Revised:    August    28th, 2019
+ */
+
+#include "mbed.h"
+
+//    RUN ONLY ON mbed-os5.13.4
+//      https://github.com/ARMmbed/mbed-os/releases/tag/mbed-os-5.13.4
+#if (MBED_MAJOR_VERSION == 5) &&\
+    (MBED_MINOR_VERSION == 13) &&\
+    (MBED_PATCH_VERSION == 4)
+#else
+    //#warning "Please use Mbed-os5.13.4"
+    #error "Please use Mbed-os5.13.4"
+#endif
\ No newline at end of file
--- a/main.cpp	Tue Jul 16 20:04:48 2019 +0000
+++ b/main.cpp	Wed Aug 28 22:48:37 2019 +0000
@@ -1,111 +1,50 @@
-/* FlashAir iSDIO sample
- * Copyright (C) 2018 by Junichi SHIBA, PIAX Inc.
+/*
+ * Mbed Application program
+ *  FlashAir control program
  *
- * This file is a FlashAir iSDIO sample program code
- *  Released under the BSD 2-Clause license.
- *  http://flashair-developers.com/documents/license.html
+ * Copyright (c) 2018,'19 Kenji Arai / JH1PJL
+ *  http://www.page.sannet.ne.jp/kenjia/index.html
+ *  https://os.mbed.com/users/kenjiArai/
+ *      Created:    April      4th, 2018
+ *      Revised:    August    28th, 2019
  */
+
+/*
+ * FlashAir:
+ *  https://flashair-developers.com/ja/
+ *
+ * Reference program:
+ *  https://os.mbed.com/users/mbed_crane_elec/code/FlashAir_iSDIO_sample_OS5_/
+ *  https://os.mbed.com/users/ban4jp/code/FlashAir_Twitter/
+ *
+ * Tested board on Nucleo-F446RE
+ */
+
+//  Include --------------------------------------------------------------------
 #include "mbed.h"
 #include "FlashAir_iSDIO.h"
 
-//#define USE_CONSOLE
+//  Definition -----------------------------------------------------------------
+
+//  Constructor ----------------------------------------------------------------
+Serial pc(USBTX, USBRX, 115200);
+Serial console(A0, A1); // TX, RX
+//               mosi(CMD), miso(DAT0), sclk(CLK), cs(DAT3)
+FlashAir_iSDIO sd(D11,             D12,       D13, D10, "sd", &console);
 
-#if defined(TARGET_LPC11U24)
-FlashAir_iSDIO sd(p11, p12, p13, p14, "sd"); // MOSI, MISO, SCLK, SSEL
-#elif defined(TARGET_LPC1114)
-FlashAir_iSDIO sd(p11, p12, p13, p14, "sd"); // MOSI, MISO, SCLK, SSEL
-#elif defined(TARGET_LPC1549)
-FlashAir_iSDIO sd(D11, D12, D13, D10, "sd"); // MOSI, MISO, SCLK, SSEL
-#elif defined(TARGET_NUCLEO_L073RZ) // TOYBOARD
-Serial console(PA_9, PA_10); // TX, RX
-FlashAir_iSDIO sd(PB_15, PB_14, PB_13, PB_12, "sd", &console); // mosi(CMD), miso(DAT0), sclk(CLK), cs(DAT3)
-DigitalOut ledB(PB_11, 1); // B
-DigitalOut ledG(PB_10, 1); // G
-DigitalOut ledR(PA_15, 1); // R
-DigitalOut SD_VEN(PC_4, 0); // SD initialy off
-DigitalIn SD_CD(PC_1); // SD_CD
-#elif defined(TARGET_LPC11U35_401) // Airio-Base
-//#elif defined(TARGET_MCU_LPC11U35_501)
-Serial console(P0_19, P0_18); // TX, RX
-//Serial pc(USBTX, USBRX);
-FlashAir_iSDIO sd(P0_21, P0_22, P1_15, P0_17, "sd", &console); // mosi(CMD), miso(DAT0), sclk(CLK), cs(DAT3)
-DigitalOut ledB(P0_7, 1);
-DigitalOut ledG(P0_7, 1);
-DigitalOut ledR(P0_7, 1);
-DigitalOut SD_VEN(P1_16);
-DigitalIn SD_CD(P1_19);
-#else
-#error
-#endif
+//  RAM ------------------------------------------------------------------------
+
+//  ROM / Constant data --------------------------------------------------------
 
+//  Function prototypes --------------------------------------------------------
+extern void mon (void);
 
-//**************************************************
-
+//------------------------------------------------------------------------------
+//  Control Program
+//------------------------------------------------------------------------------
 int main()
 {
-    uint32_t sequenceId ;
-    ledG=0; ledB=0;
-            
-#ifdef USE_CONSOLE
-    console.printf("start FlashAir iSDIO sample\n");
-#endif
-    
-    wait(1.0);
-    // supply power to SD card
-    SD_VEN = 1;
-    wait(5.0);
-    
-    if (SD_CD) {
-#ifdef USE_CONSOLE
-        console.printf("SD: Not dected\n");
-#endif
-    } else {
-#ifdef USE_CONSOLE
-        console.printf("SD: Detected\n");
-#endif
+    while(true) {
+        mon();
     }
-
-    // Initialize card
-    FILE *fp = fopen("/sd/isdio.txt", "w");
-    fclose(fp);
-
-    wait(15.0);
-    ledG=1; ledB=1; ledR=0;
-    
-    // disconnect 
-    // 1. get sequenceID
-    // 2. issue disconnect command
-    // 3. wait response 
-    sequenceId = sd.getNextSequenceId();
-    sd.wlan_disconnect(sequenceId);
-    sd.waitResponse(sequenceId);
-    wait(5.0);
-
-    ledB = 0;
-
-    // establish
-    // 1. get sequenceID
-    // 2. issue establish command
-    // 3. wait resoonse        
-    sequenceId = sd.getNextSequenceId();
-    sd.wlan_establish(sequenceId, (uint8_t*)"isdiotest", (uint8_t*)"12345678", FlashAir_iSDIO::ENCMODE_WPA2PSK_AES);
-    wait(5.0);
-    ledG = 0;    
-
-    // shared mem
-    // 1. prepare test data
-    // 2. write data to shared mem area
-    // 3. read back and check
-    #define TESTDATA 0xdeadbeaf
-    uint32_t testdata = TESTDATA;
-    uint8_t data[sizeof(testdata)];
-    memcpy(data, &testdata, sizeof(data));
-    sd.write_shared_mem(0x0, data, sizeof(data));
-    memset(data, 0x0, sizeof(data));
-    sd.read_shared_mem(0x0, data, sizeof(data));
-
-    ledG=1; ledB=1; ledR=1;
-
-    for(;;);
-    
 }
--- a/mbed-os.lib	Tue Jul 16 20:04:48 2019 +0000
+++ b/mbed-os.lib	Wed Aug 28 22:48:37 2019 +0000
@@ -1,1 +1,1 @@
-https://github.com/ARMmbed/mbed-os/#5941d1718339116cd12914238ec331c84da3d08f
+https://github.com/ARMmbed/mbed-os/#1bf6b20df9d3cd5f29f001ffc6f0d0fcbbb96118
--- a/mbed_app.json	Tue Jul 16 20:04:48 2019 +0000
+++ b/mbed_app.json	Wed Aug 28 22:48:37 2019 +0000
@@ -2,6 +2,9 @@
     "requires": ["bare-metal"],
     "target_overrides": {
         "*": {
+            "target.features_add":["LWIP"],
+            "target.components_add": ["SD"],
+            "target.features_add":["STORAGE"],
             "platform.stack-stats-enabled": true,
             "platform.heap-stats-enabled": true,
             "platform.cpu-stats-enabled": true,
--- a/tests/README.md	Tue Jul 16 20:04:48 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-# Testing examples
-
-Examples are tested using tool [htrun](https://github.com/ARMmbed/mbed-os-tools/tree/master/packages/mbed-host-tests) and templated print log. 
-
-To run the test, use following command after you build the example:
-```
-mbedhtrun -d D: -p COM4 -m K64F -f .\BUILD\K64F\GCC_ARM\blinky.bin --compare-log tests\blinky.log
-```
-
-
-More details about `htrun` are [here](https://github.com/ARMmbed/mbed-os-tools/tree/master/packages/mbed-host-tests#testing-mbed-os-examples).
-
--- a/tests/blinky.log	Tue Jul 16 20:04:48 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-=============================== SYSTEM INFO  ================================
-Mbed OS Version:
-CPU ID: 0x[0-9a-fA-F]+
-Compiler ID: \d+
-Compiler Version:
-================= CPU STATS =================
-Idle: \d+% Usage: \d+%
-================ HEAP STATS =================
-Current heap: \d+
-Max heap size: \d+
-================ THREAD STATS ===============
-ID: 0x[0-9a-fA-F]+
-Name: main
-State: \d+
-Priority: \d+
-Stack Size: \d+
-Stack Space: \d+
-ID: 0x[0-9a-fA-F]+
-Name: rtx_idle
-State: \d+
-Priority: \d+
-Stack Size: \d+
-Stack Space: \d+
-ID: 0x[0-9a-fA-F]+
-Name: rtx_timer
-State: \d+
-Priority: \d+
-Stack Size: \d+
-Stack Space: \d+