SD-Card Control Program / Using Micro-SD / based on SDCardTest Program (http://mbed.org/users/simon/programs/SDCardTest/gpdz4x/)
Dependencies: mbed SDFileSystem
Please refer following my Notebook page.
/users/kenjiArai/notebook/sd-card-control-new/#
Revision 2:1397a54382ec, committed 2018-04-07
- Comitter:
- kenjiArai
- Date:
- Sat Apr 07 01:29:41 2018 +0000
- Parent:
- 1:484feaf2da84
- Child:
- 3:2134d3cb4e8e
- Commit message:
- combined latest library and new main program
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FatFs_Mon/mon.cpp Sat Apr 07 01:29:41 2018 +0000 @@ -0,0 +1,1228 @@ +/* + * mbed Application program for the mbed + * FatFs Check program / monitor part + * + * Copyright (c) 2015,'18 Kenji Arai / JH1PJL + * http://www.page.sannet.ne.jp/kenjia/index.html + * https://os.mbed.com/users/kenjiArai/ + * Created: May 5th, 2015 + * Revised: June 14th, 2015 + * Revised: April 7th, 2018 + */ + +/* + *---------------- REFERENCE --------------------------------------------------- + * Original Source Information + * FatFs sample program + * ChaN FatFs http://elm-chan.org/ + * http://elm-chan.org/fsw/ff/00index_e.html + */ +/*----------------------------------------------------------------------*/ +/* FAT file system sample project for FatFs (C)ChaN, 2016 */ +/*----------------------------------------------------------------------*/ + +// Include -------------------------------------------------------------------- +#include "mbed.h" +#if (MBED_MAJOR_VERSION == 2) +#include "SDFileSystem.h" +#elif (MBED_MAJOR_VERSION == 5) +#include "FATFileSystem.h" +#endif +#include "ff.h" +#include "ffconf.h" +#include "diskio.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 + +// Com +#if 1 +#define BAUD(x) pc.baud(x) +#define GETC(x) pc.getc(x) +#define PUTC(x) pc.putc(x) +#define PUTS(x) pc.puts(x) +#define PRINTF(...) pc.printf(__VA_ARGS__) +#define READABLE(x) pc.readable(x) +#else +#define BAUD(x) {;} +#define GETC(x) {;} +#define PUTC(x) {;} +#define PRINTF(...) {;} +#define READABLE(x) {;} +#endif + +#define UTC_JST_OFFSET (32400) // +9 hours + +// from ffconf.h +#define _VOLUMES 1 +#define FF_USE_LFN 0 + +#if !defined(FF_FS_RPATH) +#define FF_FS_RPATH 0 +#endif + +#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; +/* by Kenji Arai / JH1PJL September 10th, 2012 */ +typedef unsigned long long DDWORD; + +// RAM ------------------------------------------------------------------------ +BYTE Buff[4096]; +char Linebuf[128]; // Console input buffer +FATFS Fatfs[_VOLUMES]; // File system object for each logical drive +FIL File1, File2; // File objects +FATFS_DIR* Dirx; +FILINFO Finfo; +#if FF_USE_LFN +//inside of FILINFO +char Lfname[512]; +#endif +DWORD AccSize; // Work register for fs command +WORD AccFiles, AccDirs; + +// ROM / Constant data -------------------------------------------------------- +char *const monmsg0 = "Start monitor program for FatFs File System\r\n"; +char *const monmsg1 = " <Please press any key to start the monitor>"; + +static const char HelpMsg0[] = + "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" + "x extend commands mode\r\n" + "q Return to main\r\n" + "t Show current time or Adjust time\r\n" + " e.g. t 18 3 28 14 48 20 -> 2018-03-28 14:48:20\r\n" + "? Help/You know the command\r\n" + "\r\n"; + +static const char HelpMsg1[] = + "[File system controls]\r\n" + " fi <ld#> [<mount>]- Force initialized the volume\r\n" + " fs [<path>] - Show volume status\r\n" + " fl [<path>] - Show a directory\r\n" + " fo <mode> <file> - Open a file\r\n" + " <mode> Read=1, Write=2\r\n" + " fc - Close the file\r\n" + " fe <ofs> - Move fp in normal seek\r\n" + " fd <len> - Read and dump the file\r\n" + " fr <len> - Read the file\r\n" + " fw <len> <val> - Write to the file\r\n" + " fn <org.name> <new.name> - Rename an object\r\n" + " fu <name> - Unlink an object\r\n" + " fv - Truncate the file at current fp\r\n" + " fk <name> - Create a directory\r\n" + " fa <atrr> <mask> <object name> - Change attribute of an object\r\n" + " ft <year> <month> <day> <hour> <min> <sec> <name>" + " - Change timestamp of an object\r\n" + " fx <src.file> <dst.file> - Copy a file\r\n" + " fg <path> - Change current directory\r\n" + " fq - Show current directory\r\n" + " fb <name> - Set volume label\r\n" + " fm <ld#> <type> <csize> - Create file system\r\n" + " fz [<len>] - Change/Show R/W length for fr/fw/fx command\r\n" + "[Disk contorls]\r\n" + " di <pd#> - Initialize disk\r\n" + " dd [<pd#> <lba>] - Dump a secrtor\r\n" + " ds <pd#> - Show disk status\r\n" + "[Buffer controls]\r\n" + " bd <ofs> - Dump working buffer\r\n" + " be <ofs> [<data>] ... - Edit working buffer\r\n" + " br <pd#> <lba> [<count>] - Read disk into working buffer\r\n" + " bw <pd#> <lba> [<count>] - Write working buffer into disk\r\n" + " bf <val> - Fill working buffer\r\n" + "[Misc commands]\r\n" + " q Return\r\n" + " ? Help\r\n" + "\r\n"; + +// Function prototypes -------------------------------------------------------- +#if (MBED_MAJOR_VERSION == 2) +extern SDFileSystem fs; +#elif (MBED_MAJOR_VERSION == 5) +extern HeapBlockDevice bd; +extern FATFileSystem fs; +#endif + +static void extended_mon( char *ptr ); +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 memory_inf(char *ptr); +static void disk_inf(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 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 ); + +void get_line (char *buff, int len); + +// Object --------------------------------------------------------------------- +extern Serial pc; +Timer t; + +//------------------------------------------------------------------------------ +// Control Program +//------------------------------------------------------------------------------ +// Monitor program for File control +void mon () +{ + char *ptr; + + Dirx = new FATFS_DIR; + /* Open Uart to communicate with Host PC */ + PUTS(monmsg0); + PUTS(monmsg1); + crlf(); +#if FF_USE_LFN + // no needs because FILINFO structure is changed + Finfo.lfname = Lfname; + Finfo.lfsize = sizeof Lfname; +#endif + for (;;) { + DEBUG_LINE + PUTC('>'); + ptr = Linebuf; + get_line( ptr, sizeof(Linebuf) ); + switch ( *ptr++ ) { + // 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; + case 't' : + t_next(ptr); + break; + case 'x' : + extended_mon(ptr); + break; + // Help + case '?' : + PUTS(HelpMsg0); + break; + // Exit monitor (return to main()) + case 'q' : + PUTS("Return to main\r\n"); + return; + // Not a command + default: + 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 extended_mon( char *ptr ) +{ + PUTS(HelpMsg1); + while(true) { + PUTS("e>"); + ptr = Linebuf; + get_line( ptr, sizeof(Linebuf) ); + switch ( *ptr++ ) { + case 'f' : + DEBUG_LINE; + file_inf(ptr); + break; + case 'd' : + DEBUG_LINE; + disk_inf(ptr); + break; + case 'm' : + DEBUG_LINE; + memory_inf(ptr); + break; + case '?' : + DEBUG_LINE; + PUTS(HelpMsg1); + break; + case 'q' : + DEBUG_LINE; + return; + default: + PUTS( "?\r\n" ); + } + } +} + +//------------------------------------------------------------------------------ +// 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: + 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: + 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); // fx <src_name> <dst_name> - Copy file + break; + default: + 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: + PUTS("?\r\n"); + } +} + +static void r_next(char *ptr) +{ + switch (*ptr++) { + case 'e' : + if (*ptr == 'n') { + // fn <old_name> <new_name> - Change file/dir name + file_inf(ptr); + } + break; + default: + 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: + 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); + PRINTF("path: %s, n=%u\r\n", path, i); + while (((res = f_readdir(&dirs, &Finfo)) == FR_OK) && Finfo.fname[0]) { + if (FF_FS_RPATH && Finfo.fname[0] == '.') { + continue; + } +#if FF_USE_LFN + //fn = *Finfo.lfname ? Finfo.lfname : Finfo.fname; + if (Finfo.altname[0] == 0) { + fn = Finfo.fname; + } else { + fn = Finfo.altname; + } +#else + fn = Finfo.fname; +#endif + 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 { + 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"; + int i; + + for ( i = 0; i != rc && *str; i++ ) { + while ( *str++ ) { + ; + } + } + PRINTF( "rc=%u FR_%s\r\n", (UINT)rc, str ); +} + +static void file_inf(char *ptr) +{ + 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++) { + 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; + } + 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++; + res = f_opendir(Dirx, ptr); + if (res) { + put_rc((FRESULT)res); + break; + } + 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; + } + PRINTF("%c%c%c%c%c %u/%02u/%02u %02u:%02u %9lu %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); + } +#if 0 // f_getfree cannnot count under Dir, subdirectory area + PRINTF("%4u File(s),%10lu bytes total\r\n%4u Dir(s)", s1, p1, s2); + res = f_getfree(ptr, (DWORD*)&p1, &fs); + if (res == FR_OK) + PRINTF(", %10lu bytes free\r\n", p1 * fs->csize * 512); + else + put_rc((FRESULT)res); +#else + PRINTF("%4u File(s) = %10lu bytes total, %4u Dir(s)\r\n", + s1, p1, s2); +#endif + 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)); +#if 0 + put_rc(f_open(&File1, "savedata.txt", 1)); + PRINTF("Open savedata.txt as read mode\r\n"); +#endif + 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) + 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(); + 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(); + 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 0 + case 'a' : /* fa <atrr> <mask> <name> - Change attribute of an object */ + if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2)) break; + while (*ptr == ' ') ptr++; + put_rc(f_chmod(ptr, p1, p2)); + break; +#endif +#if 0 + /* ft <year> <month> <day> <hour> <min> <sec> <name> + - Change timestamp of an object */ + case 't' : + if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) { + break; + } + Finfo.fdate = ((p1 - 1980) << 9) | ((p2 & 15) << 5) | (p3 & 31); + if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) { + break; + } + Finfo.ftime = + ((p1 & 31) << 11) | ((p2 & 63) << 5) | ((p3 >> 1) & 31); + put_rc(f_utime(ptr, &Finfo)); + break; +#endif +#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 ); + 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 ); + PRINTF(" Creating %s \r\n", ptr2); + if ( f_res ) { + put_rc( (FRESULT)f_res ); + f_close( &File1 ); + break; + } + 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 0 + case 'x' : /* fx <src.name> <dst.name> - Copy a file */ + while (*ptr == ' ') ptr++; + ptr2 = strchr(ptr, ' '); + if (!ptr2) break; + *ptr2++ = 0; + while (*ptr2 == ' ') ptr2++; + PRINTF("Opening \"%s\"", ptr); + res = f_open(&File1, ptr, FA_OPEN_EXISTING | FA_READ); + PUTS("\r\n"); + if (res) { + put_rc((FRESULT)res); + break; + } + PRINTF("Creating \"%s\"", ptr2); + res = f_open(&File1, ptr2, FA_CREATE_ALWAYS | FA_WRITE); + PUTS("\r\n"); + if (res) { + put_rc((FRESULT)res); + f_close(&File1); + break; + } + PRINTF("Copying file..."); + t.reset(); + t.start(); + p1 = 0; + for (;;) { + res = f_read(&File1, Buff, blen, &s1); + if (res || s1 == 0) break; /* error or eof */ + res = f_write(&File2, Buff, s1, &s2); + p1 += s2; + if (res || s2 < s1) break; /* error or disk full */ + } + tim = t.read_ms(); + PRINTF("\r\n%lu bytes copied with %lu kB/sec.\r\n", + p1, tim ? (p1 / tim) : 0); + f_close(&File1); + f_close(&File2); + break; +#endif +#if FF_FS_RPATH + case 'g' : /* fg <path> - Change current directory */ + while (*ptr == ' ') ptr++; + put_rc(f_chdir(ptr)); + break; +#if FF_FS_RPATH >= 2 + case 'q' : /* fq - Show current dir path */ + res = f_getcwd(Linebuf, sizeof Linebuf); + if (res) + put_rc(res); + else + PRINTF("%s\r\n", Linebuf); + break; +#endif +#endif +#if FF_USE_LABEL + case 'b' : /* fb <name> - Set volume label */ + while (*ptr == ' ') ptr++; + put_rc(f_setlabel(ptr)); + break; +#endif /* FF_USE_LABEL */ +#if FF_USE_MKFS + case 'm' : /* fm <type> <csize> - Create file system */ + if (!xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) break; + PRINTF("The volume will be formatted. Are you sure? (Y/n)="); + get_line(Linebuf, sizeof Linebuf); + if (Linebuf[0] == 'Y') + put_rc(f_mkfs("", (BYTE)p2, (DWORD)p3, Buff, sizeof Buff)); + break; +#endif /* FF_USE_MKFS */ + /* fz [<size>] - Change/Show R/W length for fr/fw/fx command */ + case 'z' : + if (xatoi(&ptr, &p1) && p1 >= 1 && p1 <= (long)sizeof Buff) + blen = p1; + PRINTF("blen=%u\r\n", blen); + break; + } +} + +static void memory_inf(char *ptr) +{ + long p1, p2, p3; + + switch (*ptr++) { + case 'd' : /* md[b|h|w] <address> [<count>] - Dump memory */ + switch (*ptr++) { + case 'w': + p3 = DW_LONG; + break; + case 'h': + p3 = DW_SHORT; + break; + default: + p3 = DW_CHAR; + } + if (!xatoi(&ptr, &p1)) break; + if (!xatoi(&ptr, &p2)) p2 = 128 / p3; + for (ptr = (char*)p1; p2 >= 16 / p3; ptr += 16, p2 -= 16 / p3) + put_dump(ptr, (DWORD)ptr, 16 / p3, p3); + if (p2) put_dump((BYTE*)ptr, (UINT)ptr, p2, p3); + break; + case 'f' : /* mf <address> <value> <count> - Fill memory */ + if (!xatoi(&ptr, &p1) || !xatoi(&ptr, &p2) || !xatoi(&ptr, &p3)) { + break; + } + while (p3--) { + *(BYTE*)p1 = (BYTE)p2; + p1++; + } + break; + case 'e' : /* me[b|h|w] <address> [<value> ...] - Edit memory */ + switch (*ptr++) { /* Get data width */ + case 'w': + p3 = DW_LONG; + break; + case 'h': + p3 = DW_SHORT; + break; + default: + p3 = DW_CHAR; + } + if (!xatoi(&ptr, &p1)) break; /* Get start address */ + if (xatoi(&ptr, &p2)) { /* 2nd parameter is given (direct mode) */ + do { + switch (p3) { + case DW_LONG: + *(DWORD*)p1 = (DWORD)p2; + break; + case DW_SHORT: + *(WORD*)p1 = (WORD)p2; + break; + default: + *(BYTE*)p1 = (BYTE)p2; + } + p1 += p3; + } while (xatoi(&ptr, &p2)); /* Get next value */ + break; + } + for (;;) { /* 2nd parameter is not given (interactive mode) */ + switch (p3) { + case DW_LONG: + PRINTF("%08X 0x%08X-", p1, *(DWORD*)p1); + break; + case DW_SHORT: + PRINTF("%08X 0x%04X-", p1, *(WORD*)p1); + break; + default: + PRINTF("%08X 0x%02X-", p1, *(BYTE*)p1); + } + ptr = Linebuf; + get_line(ptr, sizeof Linebuf); + if (*ptr == '.') break; + if ((BYTE)*ptr >= ' ') { + if (!xatoi(&ptr, &p2)) continue; + switch (p3) { + case DW_LONG: + *(DWORD*)p1 = (DWORD)p2; + break; + case DW_SHORT: + *(WORD*)p1 = (WORD)p2; + break; + default: + *(BYTE*)p1 = (BYTE)p2; + } + } + p1 += p3; + } + } +} + +static void disk_inf(char *ptr) +{ + long p1, p2; + UINT s1; + BYTE res, b, drv = 0; + DWORD ofs = 0, sect = 0, blk[2]; + + switch (*ptr++) { + case 'd' : /* dd [<pd#> <sect>] - Dump secrtor */ + if (!xatoi(&ptr, &p1)) { + p1 = drv; + p2 = sect; + } else { + if (!xatoi(&ptr, &p2)) break; + } + drv = (BYTE)p1; + sect = p2; + res = disk_read(drv, Buff, sect, 1); + if (res) { + PRINTF("rc=%d\r\n", (WORD)res); + break; + } + PRINTF("PD#:%u LBA:%lu\r\n", drv, sect++); + for (ptr=(char*)Buff, ofs = 0; ofs < 0x200; ptr += 16, ofs += 16) + put_dump((BYTE*)ptr, ofs, 16, DW_CHAR); + break; + + case 'i' : /* di <pd#> - Initialize disk */ + if (!xatoi(&ptr, &p1)) break; + PRINTF("rc=%d\r\n", (WORD)disk_initialize((BYTE)p1)); + break; + + case 's' : /* ds <pd#> - Show disk status */ + if (!xatoi(&ptr, &p1)) break; + if (disk_ioctl((BYTE)p1, GET_SECTOR_COUNT, &p2) == RES_OK) { + PRINTF("Drive size: %lu sectors\r\n", p2); + } + if (disk_ioctl((BYTE)p1, GET_BLOCK_SIZE, &p2) == RES_OK) { + PRINTF("Block size: %lu sectors\r\n", p2); + } + if (disk_ioctl((BYTE)p1, MMC_GET_TYPE, &b) == RES_OK) { + PRINTF("Media type: %u\r\n", b); + } + if (disk_ioctl((BYTE)p1, MMC_GET_CSD, Buff) == RES_OK) { + PUTS("CSD:\r\n"); + put_dump(Buff, 0, 16, DW_CHAR); + } + if (disk_ioctl((BYTE)p1, MMC_GET_CID, Buff) == RES_OK) { + PUTS("CID:\r\n"); + put_dump(Buff, 0, 16, DW_CHAR); + } + if (disk_ioctl((BYTE)p1, MMC_GET_OCR, Buff) == RES_OK) { + PUTS("OCR:\r\n"); + put_dump(Buff, 0, 4, DW_CHAR); + } + if (disk_ioctl((BYTE)p1, MMC_GET_SDSTAT, Buff) == RES_OK) { + PUTS("SD Status:\r\n"); + for (s1 = 0; s1 < 64; s1 += 16) { + put_dump(Buff+s1, s1, 16, DW_CHAR); + } + } + break; + + case 'c' : /* Disk ioctl */ + switch (*ptr++) { + case 's' : /* dcs <pd#> - CTRL_SYNC */ + if (!xatoi(&ptr, &p1)) break; + PRINTF("rc=%d\r\n", disk_ioctl((BYTE)p1, CTRL_SYNC, 0)); + break; + case 'e' : /* dce <pd#> <s.lba> <e.lba> - CTRL_TRIM */ + if (!xatoi(&ptr, &p1) || + !xatoi(&ptr, (long*)&blk[0]) || + !xatoi(&ptr, (long*)&blk[1])) { + break; + } + PRINTF("rc=%d\r\n", disk_ioctl((BYTE)p1, CTRL_TRIM, blk)); + break; + } + } +} + +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; + + PRINTF( "%08lx ", addr ); /* address */ + switch ( width ) { + case DW_CHAR: + bp = (unsigned char *)buff; + for ( i = 0; i < len; i++ ) { /* Hexdecimal dump */ + PRINTF( " %02x", bp[i] ); + } + PUTC(' '); + for ( i = 0; i < len; i++ ) { /* ASCII dump */ + PUTC( (bp[i] >= ' ' && bp[i] <= '~') ? bp[i] : '.' ); + } + break; + case DW_SHORT: + sp = (unsigned short *)buff; + do { /* Hexdecimal dump */ + PRINTF( " %04x", *sp++ ); + } while ( --len ); + break; + case DW_LONG: + lp = (unsigned long *)buff; + do { /* Hexdecimal dump */ + PRINTF( " %08lx", *lp++ ); + } while ( --len ); + break; + } + 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:%d ",p1); + xatoi( &ptr, &p1 ); + t.tm_mon = (uint8_t)p1 - 1; + pc.printf("Month:%d ",p1); + xatoi( &ptr, &p1 ); + t.tm_mday = (uint8_t)p1; + pc.printf("Day:%d ",p1); + xatoi( &ptr, &p1 ); + t.tm_hour = (uint8_t)p1; + pc.printf("Hour:%d ",p1); + xatoi( &ptr, &p1 ); + t.tm_min = (uint8_t)p1; + pc.printf("Min:%d ",p1); + xatoi( &ptr, &p1 ); + t.tm_sec = (uint8_t)p1; + pc.printf("Sec: %d \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 = GETC(); + // Added by Kenji Arai / JH1PJL May 9th, 2010 + if (c == '\r') { + buff[idx++] = c; + break; + } + if ((c == '\b') && idx) { + idx--; + PUTC(c); + PUTC(' '); + PUTC(c); + } + if (((uint8_t)c >= ' ') && (idx < len - 1)) { + buff[idx++] = c; + PUTC(c); + } + } + buff[idx] = 0; + PUTS("\r\n"); +} + +/* Outpur LF & CR */ +void crlf( void ) +{ + PRINTF( "\r\n" ); +} + +/* Check key input */ +unsigned int check_hit_key (void) +{ + return ( 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/FatFs_Mon/mon.h Sat Apr 07 01:29:41 2018 +0000 @@ -0,0 +1,15 @@ +/* + * mbed Application program for the mbed + * FatFs Check program /monitor part + * + * Copyright (c) 2015,'18 Kenji Arai / JH1PJL + * http://www.page.sannet.ne.jp/kenjia/index.html + * https://os.mbed.com/users/kenjiArai/ + * Created: May 5th, 2015 + * Revised: June 14th, 2015 + * Revised: April 7th, 2018 + */ + +// Function prototypes -------------------------------------------------------- +void mon(void); +uint32_t get_disk_freespace(void);
--- a/SDFileSystem.lib Fri Oct 03 10:43:29 2014 +0000 +++ b/SDFileSystem.lib Sat Apr 07 01:29:41 2018 +0000 @@ -1,1 +1,1 @@ -http://developer.mbed.org/users/mbed_official/code/SDFileSystem/#7b35d1709458 +https://os.mbed.com/users/kenjiArai/code/SDFileSystem/#5df189cc1d54
--- a/TextLCD.lib Fri Oct 03 10:43:29 2014 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/kenjiArai/code/TextLCD/#986538f94abe
--- a/main.cpp Fri Oct 03 10:43:29 2014 +0000 +++ b/main.cpp Sat Apr 07 01:29:41 2018 +0000 @@ -1,203 +1,116 @@ -/* - * mbed Application program - * SD-Card Control Program - * - * Copyright (c) 2010-2014 Kenji Arai / JH1PJL - * http://www.page.sannet.ne.jp/kenjia/index.html - * http://mbed.org/users/kenjiArai/ - * March 28th, 2010 Started - * April 3rd, 2010 - * October 3rd, 2014 use latest lib. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, - * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE - * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -//------------------------------------------------------------------------------------------------- -// Function -// 5 channeles ADC data records into a file which is located in SD-Card -// If USE_LCD = 1, data shows on a Text LCD -// If USE_RTC = 1, time stamp also writes in the file -// Connection -// Analog input PIN 15,16,17,19,20 -// LCD PIN 22,21,8,7,6,5 -// -> CAUTION!! pin assignment is different -// with " http://mbed.org/projects/cookbook/wiki/TextLCD " -// RTC PIN 3 needs to connect 3V Battery -// -> Please refer my program " RTC_w_COM" for time adjustment -// at " http://mbed.org/users/kenjiArai/programs/RTC_w_COM/5yi9a/ " -//------------------------------------------------------------------------------------------------- - -// Include --------------------------------------------------------------------------------------- -#include "mbed.h" -#include "TextLCD.h" -#include "SDFileSystem.h" - -// Definition ------------------------------------------------------------------------------------ -#define DEBUG 1 // 1= Shows progress on PC via USB ( virtual COM line) -#define USE_LCD 1 // 1= Display the data on LCD -#define USE_RTC 1 // 1= Use RTC (need 3V supply and time adjustment before use) - -#define NO_OF_SAMPLE 100 // Total recording length -> unit=sec -#define TIM_INTVL 10 // Insert time stamp in the file every ?? sec - -// Object ---------------------------------------------------------------------------------------- -DigitalOut myled(LED1); // Indicate the sampling period -#if USE_LCD -TextLCD lcd(p22, p21, p8, p7, p6, p5, TextLCD::LCD40x2); // rs, e, d4-d7 -#endif -AnalogIn ain_G_X(p15); // G Sensor -AnalogIn ain_G_Y(p16); // G Sensor -AnalogIn ain_G_Z(p17); // G Sensor -AnalogIn ain_BAT(p19); // Battery Volt -AnalogIn ain_TEMP(p20); // Temperature Sensor -SDFileSystem sd(p11, p12, p13, p14, "sd"); // do,di,clk,cs -#if DEBUG -Serial pc(USBTX, USBRX); -#endif - -// RAM ------------------------------------------------------------------------------------------- - -// ROM / Constant data --------------------------------------------------------------------------- - -// Function prototypes --------------------------------------------------------------------------- - -//------------------------------------------------------------------------------------------------- -// Control Program -//------------------------------------------------------------------------------------------------- -int main() -{ - char buf[40]; // data buffer for text - int count; // count for number of record - float x,y,z,b,t; // Analog data -#if USE_RTC - time_t seconds, old_sec; // RTC data based on seconds - int i; -#endif - - // Open the file -#if USE_RTC - seconds = time(NULL); - seconds %= 100000000; // Adjust 8 charcters file name - sprintf(buf,"/sd/%d.txt",seconds); // File name is defined based on time from 1970/1/1 - FILE *fp = fopen(buf, "w"); // Open "out.txt" on the local file system for writing -#if DEBUG - printf("\r\n %s \r\n", buf); // File name on the screen - printf(" use RTC\r\n"); -#endif -#else - FILE *fp = fopen("/sd/out.txt", "w");// Open "out.txt" on the local file system for writing -#if DEBUG - printf("\r\n /sd/out.txt\r\n"); // File name on the screen - printf(" Not use RTC\r\n"); -#endif -#endif - if(fp == NULL) { - // File not open and stop -#if USE_LCD - lcd.printf(" Could not open file for write\n"); -#endif -#if DEBUG - printf( "\r\n Could not open file for write\r\n"); -#endif - while(1) ; - } - // Success file access - fprintf(fp, "This is a test program for logging /by JH1PJL\r\n"); -#if DEBUG - printf( "This is a test program for logging /by JH1PJL\r\n"); - printf("\r\nStart sampling\r\n"); -#endif -#if USE_LCD - lcd.cls(); -#endif - - count = 0; // Initialze counter -#if USE_RTC - seconds = time(NULL); // Put time stamp in the file - old_sec = seconds; - strftime(buf,40, "Time:%I:%M:%S %p, %Y/%m/%d\r\n", localtime(&seconds)); - fprintf(fp,buf); -#if DEBUG - printf(" %s \r\n", buf); -#endif -#endif - while(1) { - // check time interval (1sec) -#if USE_RTC - myled = 1; - wait(0.5); - myled = 0; - while ((seconds = time(NULL)) == old_sec) ; // Wait 1 sec for loop - old_sec = seconds; -#else - myled = 1; - wait(0.5); - myled = 0; - wait(0.5); -#endif - // Get analog data from each port - x=ain_G_X.read(); - y=ain_G_Y.read(); - z=ain_G_Z.read(); - b=ain_BAT.read(); - t=ain_TEMP.read(); - // Write data into the file - sprintf(buf, "G-Sen, %f, %f, %f \r\n", x, y, z); - fprintf(fp,buf); -#if USE_LCD - lcd.locate(0, 0); // 1st line top - lcd.printf(buf); -#endif -#if DEBUG - printf(" %s", buf); -#endif - sprintf(buf, "VB, %f, T, %f \r\n", b, t); - fprintf(fp,buf); -#if USE_LCD - lcd.locate(0, 1); // 2nd line top - lcd.printf(buf); -#endif -#if DEBUG - printf(" %s", buf); -#endif - // if reach to expected data number then finsh - if (++count > NO_OF_SAMPLE) { - break; - } - // Set time satmp -#if USE_RTC - i = count / TIM_INTVL; - if (count == i * TIM_INTVL) { - //seconds = time(NULL); // this line is wrong! BUG - strftime(buf,40, "Time:%I:%M:%S %p, %Y/%m/%d\r\n", localtime(&seconds)); - fprintf(fp, buf); -#if DEBUG - printf(" %s", buf); -#endif - } -#endif -#if DEBUG - printf("Sampling #%d/end=%d\r\n", count, NO_OF_SAMPLE); -#endif - } - // Set time satmp -#if USE_RTC - sprintf(buf,"Sampling numbers: %d\r\n", count-1); - fprintf(fp, buf); - seconds = time(NULL); - strftime(buf,40, "Time:%I:%M:%S %p, %Y/%m/%d\r\n", localtime(&seconds)); - fprintf(fp, buf); -#if DEBUG - printf(" %s", buf); -#endif -#endif - fclose(fp); - // for debug -#if DEBUG - printf("\r\nFinished sampling\r\n"); -#endif -} +/* + * Mbed Application program + * SD Card file control function with FatFs on Mbed-os5 or os2 + * + * Copyright (c) 2018 Kenji Arai / JH1PJL + * http://www.page.sannet.ne.jp/kenjia/index.html + * https://os.mbed.com/users/kenjiArai/ + * Created: April 4th, 2018 + * Revised: April 7th, 2018 + */ + +// Include -------------------------------------------------------------------- +#include "mbed.h" +#if (MBED_MAJOR_VERSION == 2) +#include "SDFileSystem.h" +#elif (MBED_MAJOR_VERSION == 5) +#include "SDBlockDevice.h" +#include "FATFileSystem.h" +#endif +#include "mon.h" +#include <stdlib.h> + +// Definition ----------------------------------------------------------------- +#define USER_SW_ON 0 + +// Constructor ---------------------------------------------------------------- +//DigitalOut led(LED1); // same as D13 (equal to SPI CLK) STM Nucleo +DigitalIn user_sw(USER_BUTTON); +Serial pc(USBTX, USBRX, 115200); +#if (MBED_MAJOR_VERSION == 2) +SDFileSystem sd(D11, D12, D13, D10, "fs"); // do,di,clk,cs +#elif (MBED_MAJOR_VERSION == 5) +SDBlockDevice sd(D11, D12, D13, D10, 8000000); +FATFileSystem fs("fs"); +#endif + +// RAM ------------------------------------------------------------------------ + +// ROM / Constant data -------------------------------------------------------- +char *const opening_msg0 = "microSD Card test program"; +#if (MBED_MAJOR_VERSION == 2) +char *const opening_msg1 = " -> run on Mbed Classic\r\n"; +#elif (MBED_MAJOR_VERSION == 5) +char *const opening_msg1 = " -> run on Mbed OS-5\r\n"; +#endif + +// Function prototypes -------------------------------------------------------- + +//------------------------------------------------------------------------------ +// Control Program +//------------------------------------------------------------------------------ +int main() +{ + time_t seconds; + uint32_t data0 = 10000U; + uint32_t data1 = 20000U; + uint32_t data2 = 30000U; + uint32_t data3 = 40000U; + uint32_t data4 = 50000U; + uint32_t data5 = 60000U; + + if (user_sw == USER_SW_ON) { + mon(); + } + //pc.printf("line:%d\r\n", __LINE__); +#if (MBED_MAJOR_VERSION == 5) + /* Init SD CARD reader */ + sd.init(); + fs.mount(&sd); +#endif + FILE* fp = fopen("/fs/mydata.txt", "a"); + if (fp != 0) { + pc.printf("%s%s", opening_msg0, opening_msg1); + fprintf(fp,"%s%s", opening_msg0, opening_msg1); + } else { + pc.printf("ERROR\r\n"); + } + fclose(fp); + while (pc.readable()) { + char c = pc.getc(); // dummy read + } + while (true) { + uint32_t size = get_disk_freespace(); + pc.printf("free %u ", size); + fp = fopen("/fs/mydata.txt", "a"); + if(fp != 0) { + char tmp[64]; + seconds = time(NULL); + strftime(tmp, 64, "DATE %H:%M:%S,%Y/%m/%d,", localtime(&seconds)); + pc.printf(tmp); + fprintf(fp, "%s", tmp); + pc.printf("%08d;%08d;%08d;%08d;%08d;%08d\r\n", + ++data0, ++data1, ++data2, ++data3, ++data4, ++data5); + fprintf(fp, "%08d;%08d;%08d;%08d;%08d;%08d\r\n", + data0, data1, data2, data3, data4, data5); + } else { + pc.printf("ERROR\r\n"); + } + fclose(fp); +#if (MBED_MAJOR_VERSION == 2) + wait(0.1f); +#elif (MBED_MAJOR_VERSION == 5) + Thread::wait(100); +#endif + if (user_sw == USER_SW_ON) { + break; + } + if (pc.readable()) { + mon(); + } + } + while(true) { + mon(); + NVIC_SystemReset(); + } +}
--- a/mbed.bld Fri Oct 03 10:43:29 2014 +0000 +++ b/mbed.bld Sat Apr 07 01:29:41 2018 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/552587b429a1 \ No newline at end of file +https://os.mbed.com/users/mbed_official/code/mbed/builds/994bdf8177cb \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/org_main.cpp Sat Apr 07 01:29:41 2018 +0000 @@ -0,0 +1,205 @@ +#if 0 +/* + * mbed Application program + * SD-Card Control Program + * + * Copyright (c) 2010-2014 Kenji Arai / JH1PJL + * http://www.page.sannet.ne.jp/kenjia/index.html + * http://mbed.org/users/kenjiArai/ + * March 28th, 2010 Started + * April 3rd, 2010 + * October 3rd, 2014 use latest lib. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +//------------------------------------------------------------------------------------------------- +// Function +// 5 channeles ADC data records into a file which is located in SD-Card +// If USE_LCD = 1, data shows on a Text LCD +// If USE_RTC = 1, time stamp also writes in the file +// Connection +// Analog input PIN 15,16,17,19,20 +// LCD PIN 22,21,8,7,6,5 +// -> CAUTION!! pin assignment is different +// with " http://mbed.org/projects/cookbook/wiki/TextLCD " +// RTC PIN 3 needs to connect 3V Battery +// -> Please refer my program " RTC_w_COM" for time adjustment +// at " http://mbed.org/users/kenjiArai/programs/RTC_w_COM/5yi9a/ " +//------------------------------------------------------------------------------------------------- + +// Include --------------------------------------------------------------------------------------- +#include "mbed.h" +#include "TextLCD.h" +#include "SDFileSystem.h" + +// Definition ------------------------------------------------------------------------------------ +#define DEBUG 1 // 1= Shows progress on PC via USB ( virtual COM line) +#define USE_LCD 1 // 1= Display the data on LCD +#define USE_RTC 1 // 1= Use RTC (need 3V supply and time adjustment before use) + +#define NO_OF_SAMPLE 100 // Total recording length -> unit=sec +#define TIM_INTVL 10 // Insert time stamp in the file every ?? sec + +// Object ---------------------------------------------------------------------------------------- +DigitalOut myled(LED1); // Indicate the sampling period +#if USE_LCD +TextLCD lcd(p22, p21, p8, p7, p6, p5, TextLCD::LCD40x2); // rs, e, d4-d7 +#endif +AnalogIn ain_G_X(p15); // G Sensor +AnalogIn ain_G_Y(p16); // G Sensor +AnalogIn ain_G_Z(p17); // G Sensor +AnalogIn ain_BAT(p19); // Battery Volt +AnalogIn ain_TEMP(p20); // Temperature Sensor +SDFileSystem sd(p11, p12, p13, p14, "sd"); // do,di,clk,cs +#if DEBUG +Serial pc(USBTX, USBRX); +#endif + +// RAM ------------------------------------------------------------------------------------------- + +// ROM / Constant data --------------------------------------------------------------------------- + +// Function prototypes --------------------------------------------------------------------------- + +//------------------------------------------------------------------------------------------------- +// Control Program +//------------------------------------------------------------------------------------------------- +int main() +{ + char buf[40]; // data buffer for text + int count; // count for number of record + float x,y,z,b,t; // Analog data +#if USE_RTC + time_t seconds, old_sec; // RTC data based on seconds + int i; +#endif + + // Open the file +#if USE_RTC + seconds = time(NULL); + seconds %= 100000000; // Adjust 8 charcters file name + sprintf(buf,"/sd/%d.txt",seconds); // File name is defined based on time from 1970/1/1 + FILE *fp = fopen(buf, "w"); // Open "out.txt" on the local file system for writing +#if DEBUG + printf("\r\n %s \r\n", buf); // File name on the screen + printf(" use RTC\r\n"); +#endif +#else + FILE *fp = fopen("/sd/out.txt", "w");// Open "out.txt" on the local file system for writing +#if DEBUG + printf("\r\n /sd/out.txt\r\n"); // File name on the screen + printf(" Not use RTC\r\n"); +#endif +#endif + if(fp == NULL) { + // File not open and stop +#if USE_LCD + lcd.printf(" Could not open file for write\n"); +#endif +#if DEBUG + printf( "\r\n Could not open file for write\r\n"); +#endif + while(1) ; + } + // Success file access + fprintf(fp, "This is a test program for logging /by JH1PJL\r\n"); +#if DEBUG + printf( "This is a test program for logging /by JH1PJL\r\n"); + printf("\r\nStart sampling\r\n"); +#endif +#if USE_LCD + lcd.cls(); +#endif + + count = 0; // Initialze counter +#if USE_RTC + seconds = time(NULL); // Put time stamp in the file + old_sec = seconds; + strftime(buf,40, "Time:%I:%M:%S %p, %Y/%m/%d\r\n", localtime(&seconds)); + fprintf(fp,buf); +#if DEBUG + printf(" %s \r\n", buf); +#endif +#endif + while(1) { + // check time interval (1sec) +#if USE_RTC + myled = 1; + wait(0.5); + myled = 0; + while ((seconds = time(NULL)) == old_sec) ; // Wait 1 sec for loop + old_sec = seconds; +#else + myled = 1; + wait(0.5); + myled = 0; + wait(0.5); +#endif + // Get analog data from each port + x=ain_G_X.read(); + y=ain_G_Y.read(); + z=ain_G_Z.read(); + b=ain_BAT.read(); + t=ain_TEMP.read(); + // Write data into the file + sprintf(buf, "G-Sen, %f, %f, %f \r\n", x, y, z); + fprintf(fp,buf); +#if USE_LCD + lcd.locate(0, 0); // 1st line top + lcd.printf(buf); +#endif +#if DEBUG + printf(" %s", buf); +#endif + sprintf(buf, "VB, %f, T, %f \r\n", b, t); + fprintf(fp,buf); +#if USE_LCD + lcd.locate(0, 1); // 2nd line top + lcd.printf(buf); +#endif +#if DEBUG + printf(" %s", buf); +#endif + // if reach to expected data number then finsh + if (++count > NO_OF_SAMPLE) { + break; + } + // Set time satmp +#if USE_RTC + i = count / TIM_INTVL; + if (count == i * TIM_INTVL) { + //seconds = time(NULL); // this line is wrong! BUG + strftime(buf,40, "Time:%I:%M:%S %p, %Y/%m/%d\r\n", localtime(&seconds)); + fprintf(fp, buf); +#if DEBUG + printf(" %s", buf); +#endif + } +#endif +#if DEBUG + printf("Sampling #%d/end=%d\r\n", count, NO_OF_SAMPLE); +#endif + } + // Set time satmp +#if USE_RTC + sprintf(buf,"Sampling numbers: %d\r\n", count-1); + fprintf(fp, buf); + seconds = time(NULL); + strftime(buf,40, "Time:%I:%M:%S %p, %Y/%m/%d\r\n", localtime(&seconds)); + fprintf(fp, buf); +#if DEBUG + printf(" %s", buf); +#endif +#endif + fclose(fp); + // for debug +#if DEBUG + printf("\r\nFinished sampling\r\n"); +#endif +} +#endif