![](/media/cache/profiles/f0fcf351df4eb6786e9bb6fc4e2dee02.jpg.50x50_q85.jpg)
Test program for FlashAir with iSDIO
Dependencies: FlashAir_iSDIO SDFileSystem
FlashAir_monitor/mon.cpp
- Committer:
- kenjiArai
- Date:
- 2019-08-28
- Revision:
- 3:fc1908567f3b
File content as of revision 3:fc1908567f3b:
/* * 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; }