Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 1:7a568319eeb7, committed 2020-04-30
- Comitter:
- kenjiArai
- Date:
- Thu Apr 30 23:43:35 2020 +0000
- Parent:
- 0:c6dea1f647f6
- Commit message:
- function test USBMSD(as external strage for PC USB) and USBSerial
Changed in this revision
--- a/0_USB_Serial/main.cpp Mon Jan 06 10:56:13 2020 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,19 +0,0 @@ - -//#define EXAMPLE_0_SERIAL -#ifdef EXAMPLE_0_SERIAL - -#include "mbed.h" -#include "USBSerial.h" - -Serial pc(USBTX, USBRX, 115200); -USBSerial usb_serial; - -int main(void){ - uint32_t num = 0; - while(true) { - usb_serial.printf("I am a USB virtual serial port: %d\r\n", num++); - pc.printf("I am a ST-Link virtual serial port: %d\r\n", num + 10000); - } -} - -#endif // EXAMPLE_0_SERIAL
--- a/1_USB_Storage_RW_microSD/main.cpp Mon Jan 06 10:56:13 2020 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -/* - * Mbed Application program - * SD Card & USB on Mbed-os5 - * - * Copyright (c) 2019,'20 Kenji Arai / JH1PJL - * http://www.page.sannet.ne.jp/kenjia/index.html - * https://os.mbed.com/users/kenjiArai/ - * Created: December 31st, 2019 - * Revised: January 6th, 2020 - */ - -//#define EXAMPLE_1_MSD -#ifdef EXAMPLE_1_MSD - -// Include -------------------------------------------------------------------- -#include "mbed.h" -#include "USBMSD.h" -#include "SDBlockDevice.h" -#include "FATFileSystem.h" - -// Definition ----------------------------------------------------------------- - -// Constructor ---------------------------------------------------------------- -Serial pc(USBTX, USBRX, 115200); -SDBlockDevice sd(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS, 12000000); -USBMSD usb(&sd); - -// RAM ------------------------------------------------------------------------ - -// ROM / Constant data -------------------------------------------------------- - -// Function prototypes -------------------------------------------------------- - -//------------------------------------------------------------------------------ -// Control Program -//------------------------------------------------------------------------------ -int main() { - pc.printf("Wait for a while and check "); - pc.printf("if it is recognized as a drive on your PC.\r\n"); - while(true) { - usb.process(); - } -} - -#endif // EXAMPLE_1_MSD \ No newline at end of file
--- a/2_USB_Mouse/main.cpp Mon Jan 06 10:56:13 2020 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -//#define EXAMPLE_2_MOUSE -#ifdef EXAMPLE_2_MOUSE - -#include "mbed.h" -#include "USBMouse.h" - -USBMouse mouse; - -int main() { - int16_t x = 0; - int16_t y = 0; - int32_t radius = 10; - int32_t angle = 0; - - while (true) { - //will cause mouse to move in a circle - x = cos((double)angle*3.14/180.0)*radius; - y = sin((double)angle*3.14/180.0)*radius; - - //will move mouse x, y away from its previous position on the screen - mouse.move(x, y); - angle += 3; - ThisThread::sleep_for(1); - } -} - -#endif // EXAMPLE_2_MOUSE
--- a/3_USB_Keyboard/main.cpp Mon Jan 06 10:56:13 2020 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,17 +0,0 @@ -//#define EXAMPLE_3_KEYBOARD -#ifdef EXAMPLE_3_KEYBOARD - -#include "mbed.h" -#include "USBKeyboard.h" - -USBKeyboard key; - -int main(void) -{ - while (true) { - key.printf("Mbed USBDevice -- Keyboard on mbed-os5.15.0\r\n"); - ThisThread::sleep_for(1000); - } -} - -#endif // EXAMPLE_3_KEYBOARD
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FatFs_Mon/mon.cpp Thu Apr 30 23:43:35 2020 +0000 @@ -0,0 +1,1247 @@ +/* + * mbed Application program for the mbed + * FatFs Check program / monitor part + * + * Copyright (c) 2015,'18,'19,'20 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 + * Revised: April 29th, 2020 + */ + +/* + *---------------- 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 "USBSerial.h" +#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 +# if 1 +# define BAUD(x) {;} +# define GETC(x) usb_ser->getc(x) +# define PUTC(x) usb_ser->putc(x) +# define PUTS(x) usb_ser->puts(x) +# define PRINTF(...) usb_ser->printf(__VA_ARGS__) +# define READABLE(x) usb_ser->readable(x) +# else +# 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) +# endif +#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 + +#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; +DWORD AccSize; // Work register for fs command +WORD AccFiles, AccDirs; + +// ROM / Constant data -------------------------------------------------------- +const char *const monmsg0 = "Start monitor program for FatFs File System\r\n"; +const 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 20 4 29 10 11 12 -> April 29,'20, 10:11:12\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 USBSerial *usb_ser; +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(); + 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' : + // so many bugs in extended monitor + //extended_mon(ptr); + PRINTF("Not support!\r\n"); + 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; + } +} + +uint32_t get_data_file_size(const char *const file_name) +{ + BYTE res; + //const char *file_name ="acc_data.txt"; + + if (Dirx == NULL){ + Dirx = new FATFS_DIR; + } + char p = NULL; + res = f_opendir(Dirx, &p); + if (res) { + put_rc((FRESULT)res); + return 0; + } + for(;;) { + res = f_readdir(Dirx, &Finfo); + if ((res != FR_OK) || !Finfo.fname[0]) break; + if (strcmp(Finfo.fname, file_name) == 0){ + return Finfo.fsize; + } + } + 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; + } + fn = 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 { + 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-", (unsigned int)p1, *(unsigned int*)p1); + break; + case DW_SHORT: + PRINTF("%08X 0x%04X-", (unsigned int)p1, *(WORD*)p1); + break; + default: + PRINTF("%08X 0x%02X-", (unsigned int)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; + PRINTF("Year:%ld ",p1); + xatoi( &ptr, &p1 ); + t.tm_mon = (uint8_t)p1 - 1; + PRINTF("Month:%ld ",p1); + xatoi( &ptr, &p1 ); + t.tm_mday = (uint8_t)p1; + PRINTF("Day:%ld ",p1); + xatoi( &ptr, &p1 ); + t.tm_hour = (uint8_t)p1; + PRINTF("Hour:%ld ",p1); + xatoi( &ptr, &p1 ); + t.tm_min = (uint8_t)p1; + PRINTF("Min:%ld ",p1); + xatoi( &ptr, &p1 ); + t.tm_sec = (uint8_t)p1; + 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)); + 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 Thu Apr 30 23:43:35 2020 +0000 @@ -0,0 +1,16 @@ +/* + * mbed Application program for the mbed + * FatFs Check program /monitor part + * + * Copyright (c) 2015,'18,'19,'20 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 29th, 2020 + */ + +// Function prototypes -------------------------------------------------------- +void mon(void); +uint32_t get_disk_freespace(void); +uint32_t get_data_file_size(const char *const file_name);
--- a/check_revision.cpp Mon Jan 06 10:56:13 2020 +0000 +++ b/check_revision.cpp Thu Apr 30 23:43:35 2020 +0000 @@ -1,21 +1,25 @@ /* * Check Mbed revision * - * Copyright (c) 2019 Kenji Arai / JH1PJL - * http://www.page.sannet.ne.jp/kenjia/index.html + * Copyright (c) 2019,'20 Kenji Arai / JH1PJL + * http://www7b.biglobe.ne.jp/~kenjia/ * https://os.mbed.com/users/kenjiArai/ * Created: July 17th, 2019 - * Revised: December 24th, 2019 + * Revised: April 28th, 2020 */ #include "mbed.h" - -// RUN ONLY ON mbed-os5.15.0 -// https://github.com/ARMmbed/mbed-os/releases/tag/mbed-os-5.15.0 + +// RUN ONLY ON mbed-os-5.15.2 +// https://github.com/ARMmbed/mbed-os/releases/tag/mbed-os-5.15.2 #if (MBED_MAJOR_VERSION == 5) &&\ (MBED_MINOR_VERSION == 15) &&\ - (MBED_PATCH_VERSION == 0) + (MBED_PATCH_VERSION == 2) +#elif (MBED_MAJOR_VERSION == 5) &&\ + (MBED_MINOR_VERSION == 15) &&\ + (MBED_PATCH_VERSION == 1) + // use mbed-os-5.15.2 but mbed_version.h has 5.15.1 value #else - //#warning "Please use Mbed-os5.15.0" - #error "Please use Mbed-os5.15.0" + //#warning "Please use mbed-os-5.15.2" + #error "Please use mbed-os-5.15.2" #endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main_another_way.cpp Thu Apr 30 23:43:35 2020 +0000 @@ -0,0 +1,183 @@ +/* + * Mbed Application program + * SD Card via USB on Mbed-os5 + * + * Copyright (c) 2019,'20 Kenji Arai / JH1PJL + * http://www.page.sannet.ne.jp/kenjia/index.html + * https://os.mbed.com/users/kenjiArai/ + * Created: December 31st, 2019 + * Revised: May 1st, 2020 + */ + +/* + * Tested on: + * Nucleo-F446RE + * FRDM-K64F --> does NOT work!! + * nRF52840-DK --> does NOT work!! + * PC: Windows10 64bit + Tera Term + */ + +#if 0 + +// Include -------------------------------------------------------------------- +#include "mbed.h" +#include "USBMSD.h" +#include "USBSerial.h" +#include "SDBlockDevice.h" +#include "FATFileSystem.h" +#include "mon.h" + +// Definition ----------------------------------------------------------------- + +// Constructor ---------------------------------------------------------------- +#if defined(TARGET_K64F) +DigitalIn disconnect_sw(BUTTON2); +SDBlockDevice sd(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS, 20000000); +#warning "This program does NOT work!!" +#elif defined(TARGET_STM32F4) +DigitalIn disconnect_sw(USER_BUTTON); +SDBlockDevice sd(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS, 20000000); +#elif defined(TARGET_MCU_NRF52840) +#warning "This program does NOT work!!" +DigitalIn disconnect_sw(BUTTON1); +SDBlockDevice sd(D11, D12, D13, D10); +#endif +Serial pc(USBTX, USBRX, 115200); +FATFileSystem *fs = NULL; +USBMSD *usb_msd = NULL; +USBSerial *usb_ser = NULL; + +// RAM ------------------------------------------------------------------------ + +// ROM / Constant data -------------------------------------------------------- +const char *const opening_msg0 = "microSD Card test program"; +const char *const opening_msg1 = " -> run on Mbed OS-5 multi-thread mode\r\n"; + +// Function prototypes -------------------------------------------------------- +template <typename ... Args> +void printf_usb(const char *format, Args const & ... args); +char usb_ser_readable(void); +char usb_ser_get_c(void); +void usb_ser_put_c(char c); + +//------------------------------------------------------------------------------ +// Control Program +//------------------------------------------------------------------------------ +int main() +{ + char buf[128]; + uint32_t step = 0; + + usb_ser = new USBSerial; + printf_usb( + "\r\n\r\nConnect the USB which is embedded on F446 CPU to your PC\r\n" + ); + printf_usb("-----STEP%d------> Start\r\n", step++); + while(true) { + printf_usb("Please see your new strage using the Explorer\r\n"); + printf_usb("-----STEP%d------> Create USB MSD\r\n", step++); + printf_usb( + "If you want to disconnect the strage, please enter usr button\r\n" + ); + ThisThread::sleep_for(100); + // we cannot use both MSD & Serial simultaneously!! + delete usb_ser; + // Start MSD + usb_msd = new USBMSD(&sd); + while(true) { + usb_msd->process(); + if (disconnect_sw == 0) { + break; + } + } + // Terminate MSD + usb_msd->disconnect(); + delete usb_msd; + // Restart Serial + usb_ser = new USBSerial; + printf("line:%d\r\n", __LINE__); + printf_usb("You cannot see F446 SD strage!\r\n Now open SD strage\r\n"); + printf_usb("-----STEP%d------> Disconnect USB MSD\r\n", step++); + // Init SD CARD reader + sd.init(); + fs = new FATFileSystem("fs"); + fs->mount(&sd); + printf_usb("-----STEP%d------> Create microSD file system\r\n", step++); + // Get date & time + time_t seconds = time(NULL); + strftime(buf, 64, "DATE %H:%M:%S,%Y/%m/%d\r\n", localtime(&seconds)); + // write data into SD + FILE* fp = fopen("/fs/mydata.txt", "a"); + if (fp != 0) { + usb_ser->printf("%s%s", opening_msg0, opening_msg1); + fprintf(fp,"%s%s", opening_msg0, opening_msg1); + usb_ser->printf("%s", buf); // buf = date & time + fprintf(fp, "%s", buf); + fflush(fp); + fclose(fp); + } else { + printf_usb("ERROR\r\n"); + } + printf_usb("-----STEP%d------> Start file monitor\r\n", step++); + // goto monitor program to set date & time and so on + mon(); + fs->remove("fs"); + fs->unmount(); + printf_usb("-----STEP%d------> Terminate microSD\r\n", step++); + while(true) { + printf_usb("-----STEP%d------> Waiting restart\r\n", step); + printf_usb("If you want to connect again, please enter 'y'\r\n>> "); + while (usb_ser_readable() == 0) { + ThisThread::sleep_for(100); + } + char c = usb_ser_get_c(); + printf_usb("%c\r\n", c); + if (c == 'y') { + break; + } + } + step = 1; + } +} + +template <typename ... Args> +void printf_usb(const char *format, Args const & ... args) +{ + if (usb_ser == NULL) { + return; + } else { + pc.printf(format, args ...); + if (usb_ser->connected() == true) { + usb_ser->printf(format, args ...); + } + } +} + +char usb_ser_readable() +{ + if (usb_ser == NULL) { + return 0; + } else { + return usb_ser->readable(); + } +} + +char usb_ser_get_c() +{ + if (usb_ser == NULL) { + return ' '; + } else { + return usb_ser->getc(); + } +} + +void usb_ser_put_c(char c) +{ + if (usb_ser == NULL) { + return; + } else { + usb_ser->putc(c); + } +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main_best.cpp Thu Apr 30 23:43:35 2020 +0000 @@ -0,0 +1,206 @@ +/* + * Mbed Application program + * SD Card via USB on Mbed-os5 + * + * Copyright (c) 2019,'20 Kenji Arai / JH1PJL + * http://www.page.sannet.ne.jp/kenjia/index.html + * https://os.mbed.com/users/kenjiArai/ + * Created: December 31st, 2019 + * Revised: May 1st, 2020 + */ + +/* + * Tested on: + * Nucleo-F446RE + * FRDM-K64F + * nRF52840-DK --> does NOT work!! + * PC: Windows10 64bit + Tera Term + */ + +#if 1 + +// Include -------------------------------------------------------------------- +#include "mbed.h" +#include "USBMSD.h" +#include "USBSerial.h" +#include "SDBlockDevice.h" +#include "FATFileSystem.h" +#include "mon.h" + +// Definition ----------------------------------------------------------------- + +// Constructor ---------------------------------------------------------------- +#if defined(TARGET_K64F) +DigitalIn disconnect_sw(BUTTON2); +SDBlockDevice sd(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS, 20000000); +#elif defined(TARGET_STM32F4) +DigitalIn disconnect_sw(USER_BUTTON); +SDBlockDevice sd(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS, 20000000); +#elif defined(TARGET_MCU_NRF52840) +#warning "This program does NOT work!!" +DigitalIn disconnect_sw(BUTTON1); +SDBlockDevice sd(D11, D12, D13, D10); +#endif +Serial pc(USBTX, USBRX, 115200); +FATFileSystem *fs = NULL; +USBMSD *usb_msd = NULL; +USBSerial *usb_ser = NULL; + +// RAM ------------------------------------------------------------------------ +bool stop_flag = false; +bool run_flag = false; +bool connected_flag = false; + +// ROM / Constant data -------------------------------------------------------- +const char *const opening_msg0 = "microSD Card test program"; +const char *const opening_msg1 = " -> run on Mbed OS-5 multi-thread mode\r\n"; + +// Function prototypes -------------------------------------------------------- +static void tsk_msd(void const *args); +template <typename ... Args> +void printf_usb(const char *format, Args const & ... args); +char usb_ser_readable(void); +char usb_ser_get_c(void); +void usb_ser_put_c(char c); + +//------------------------------------------------------------------------------ +// Control Program +//------------------------------------------------------------------------------ +osThreadDef(tsk_msd, osPriorityNormal,2048); + +int main() +{ + char buf[128]; + uint32_t step = 0; + + usb_ser = new USBSerial; + printf_usb( + "\r\n\r\nConnect the USB which is embedded on F446 CPU to your PC\r\n" + ); + printf_usb("-----STEP%d------> Start\r\n", step++); + while(true) { + printf_usb("Please see your new strage using the Explorer\r\n"); + printf_usb("-----STEP%d------> Create USB MSD\r\n", step++); + printf_usb( + "If you want to disconnect the strage, please enter usr button\r\n" + ); + ThisThread::sleep_for(100); + // we cannot use both MSD & Serial simultaneously!! + delete usb_ser; + osThreadId id = osThreadCreate(osThread(tsk_msd), NULL); + while(true) { + if (disconnect_sw == 0) { break;} + //if (stop_flag == true) { break;} + } + stop_flag = true; + while (run_flag == true) { + ThisThread::sleep_for(100); + } + // Terminate MSD + osThreadTerminate(id); + pc.printf("line:%d\r\n", __LINE__); + // Restart Serial + usb_ser = new USBSerial; + printf("line:%d\r\n", __LINE__); + printf_usb("You cannot see F446 SD strage!\r\n Now open SD strage\r\n"); + printf_usb("-----STEP%d------> Disconnect USB MSD\r\n", step++); + // Init SD CARD reader + sd.init(); + fs = new FATFileSystem("fs"); + fs->mount(&sd); + printf_usb("-----STEP%d------> Create microSD file system\r\n", step++); + // Get date & time + time_t seconds = time(NULL); + strftime(buf, 64, "DATE %H:%M:%S,%Y/%m/%d\r\n", localtime(&seconds)); + // write data into SD + FILE* fp = fopen("/fs/mydata.txt", "a"); + if (fp != 0) { + usb_ser->printf("%s%s", opening_msg0, opening_msg1); + fprintf(fp,"%s%s", opening_msg0, opening_msg1); + usb_ser->printf("%s", buf); // buf = date & time + fprintf(fp, "%s", buf); + fflush(fp); + fclose(fp); + } else { + printf_usb("ERROR\r\n"); + } + printf_usb("-----STEP%d------> Start file monitor\r\n", step++); + mon(); + fs->remove("fs"); + fs->unmount(); + printf_usb("-----STEP%d------> Terminate microSD\r\n", step++); + while(true) { + printf_usb("-----STEP%d------> Waiting restart\r\n", step); + printf_usb("If you want to connect again, please enter 'y'\r\n>> "); + while (usb_ser_readable() == 0) { + ThisThread::sleep_for(100); + } + char c = usb_ser_get_c(); + printf_usb("%c\r\n", c); + if (c == 'y') { + stop_flag = false; + break; + } + } + step = 1; + } +} + +void tsk_msd(void const *args) +{ + usb_msd = new USBMSD(&sd); + while(true) { + if (stop_flag == false) { + run_flag = true; + usb_msd->process(); + //if (usb_msd->media_removed() == true) { + //stop_flag = true; + //} + } else { + usb_msd->disconnect(); + run_flag = false; + } + } +} + +template <typename ... Args> +void printf_usb(const char *format, Args const & ... args) +{ + if (usb_ser == NULL) { + return; + } else { + pc.printf(format, args ...); + if (usb_ser->connected() == true) { + usb_ser->printf(format, args ...); + } + } +} + +char usb_ser_readable() +{ + if (usb_ser == NULL) { + return 0; + } else { + return usb_ser->readable(); + } +} + +char usb_ser_get_c() +{ + if (usb_ser == NULL) { + return ' '; + } else { + return usb_ser->getc(); + } +} + +void usb_ser_put_c(char c) +{ + if (usb_ser == NULL) { + return; + } else { + usb_ser->putc(c); + } +} + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main_not_so_good.cpp Thu Apr 30 23:43:35 2020 +0000 @@ -0,0 +1,209 @@ +/* + * Mbed Application program + * SD Card via USB on Mbed-os5 + * + * Copyright (c) 2019,'20 Kenji Arai / JH1PJL + * http://www.page.sannet.ne.jp/kenjia/index.html + * https://os.mbed.com/users/kenjiArai/ + * Created: December 31st, 2019 + * Revised: May 1st, 2020 + */ + +/* + * Tested on: + * Nucleo-F446RE + * FRDM-K64F --> does NOT work!! + * nRF52840-DK --> does NOT work!! + * PC: Windows10 64bit + Tera Term + */ + +#if 0 + +// Include -------------------------------------------------------------------- +#include "mbed.h" +#include "USBMSD.h" +#include "USBSerial.h" +#include "SDBlockDevice.h" +#include "FATFileSystem.h" +#include "mon.h" + +// Definition ----------------------------------------------------------------- + +// Constructor ---------------------------------------------------------------- +#if defined(TARGET_K64F) +DigitalIn disconnect_sw(BUTTON2); +SDBlockDevice sd(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS, 20000000); +#warning "This program does NOT work!!" +#elif defined(TARGET_STM32F4) +DigitalIn disconnect_sw(USER_BUTTON); +SDBlockDevice sd(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS, 20000000); +#elif defined(TARGET_MCU_NRF52840) +#warning "This program does NOT work!!" +DigitalIn disconnect_sw(BUTTON1); +SDBlockDevice sd(D11, D12, D13, D10); +#endif +Serial pc(USBTX, USBRX, 115200); +FATFileSystem *fs = NULL; +USBMSD *usb_msd = NULL; +USBSerial *usb_ser = NULL; + +// RAM ------------------------------------------------------------------------ +Semaphore media_remove_event(0, 1); +static volatile bool msd_process_done = false; + +// ROM / Constant data -------------------------------------------------------- +const char *const opening_msg0 = "microSD Card test program"; +const char *const opening_msg1 = " -> run on Mbed OS-5 multi-thread mode\r\n"; + +// Function prototypes -------------------------------------------------------- +void msd_process(USBMSD *msd); +void run_processing(Semaphore *sem); +template <typename ... Args> +void printf_usb(const char *format, Args const & ... args); +char usb_ser_readable(void); +char usb_ser_get_c(void); +void usb_ser_put_c(char c); + +//------------------------------------------------------------------------------ +// Control Program +//------------------------------------------------------------------------------ +int main() +{ + char buf[128]; + uint32_t step = 0; + + usb_ser = new USBSerial; + printf_usb( + "\r\n\r\nConnect the USB which is embedded on F446 CPU to your PC\r\n" + ); + printf_usb("-----STEP%d------> Start\r\n", step++); + while(true) { + printf_usb("Please see your new strage using the Explorer\r\n"); + printf_usb("-----STEP%d------> Create USB MSD\r\n", step++); + printf_usb( + "If you want to disconnect the strage, please enter usr button\r\n" + ); + ThisThread::sleep_for(100); + // we cannot use both MSD & Serial simultaneously!! + delete usb_ser; + + Thread msd_thread(osPriorityHigh); + usb_msd = new USBMSD(&sd); + msd_thread.start(callback(msd_process, usb_msd)); + while(true) { + media_remove_event.try_acquire_for(1000); + if (disconnect_sw == 0) { + break; + } + } + + // Terminate MSD + msd_process_done = true; + ThisThread::sleep_for(100); + delete usb_msd; + // Restart Serial + usb_ser = new USBSerial; + printf("line:%d\r\n", __LINE__); + printf_usb("You cannot see F446 SD strage!\r\n Now open SD strage\r\n"); + printf_usb("-----STEP%d------> Disconnect USB MSD\r\n", step++); + // Init SD CARD reader + sd.init(); + fs = new FATFileSystem("fs"); + fs->mount(&sd); + printf_usb("-----STEP%d------> Create microSD file system\r\n", step++); + // Get date & time + time_t seconds = time(NULL); + strftime(buf, 64, "DATE %H:%M:%S,%Y/%m/%d\r\n", localtime(&seconds)); + // write data into SD + FILE* fp = fopen("/fs/mydata.txt", "a"); + if (fp != 0) { + usb_ser->printf("%s%s", opening_msg0, opening_msg1); + fprintf(fp,"%s%s", opening_msg0, opening_msg1); + usb_ser->printf("%s", buf); // buf = date & time + fprintf(fp, "%s", buf); + fflush(fp); + fclose(fp); + } else { + printf_usb("ERROR\r\n"); + } + printf_usb("-----STEP%d------> Start file monitor\r\n", step++); + mon(); + fs->remove("fs"); + fs->unmount(); + printf_usb("-----STEP%d------> Terminate microSD\r\n", step++); + while(true) { + printf_usb("-----STEP%d------> Waiting restart\r\n", step); + printf_usb("If you want to connect again, please enter 'y'\r\n>> "); + while (usb_ser_readable() == 0) { + ThisThread::sleep_for(100); + } + char c = usb_ser_get_c(); + printf_usb("%c\r\n", c); + if (c == 'y') { + break; + } + } + step = 1; + } +} + +void run_processing(Semaphore *sem) +{ + sem->release(); +} + +void msd_process(USBMSD *msd) +{ + printf("line:%d\r\n", __LINE__); + usb_msd->connect(); + Semaphore proc; + msd->attach(callback(run_processing, &proc)); + printf("line:%d\r\n", __LINE__); + while (!msd_process_done) { + proc.try_acquire_for(100); + msd->process(); + } + msd->attach(NULL); +} + +template <typename ... Args> +void printf_usb(const char *format, Args const & ... args) +{ + if (usb_ser == NULL) { + return; + } else { + pc.printf(format, args ...); + if (usb_ser->connected() == true) { + usb_ser->printf(format, args ...); + } + } +} + +char usb_ser_readable() +{ + if (usb_ser == NULL) { + return 0; + } else { + return usb_ser->readable(); + } +} + +char usb_ser_get_c() +{ + if (usb_ser == NULL) { + return ' '; + } else { + return usb_ser->getc(); + } +} + +void usb_ser_put_c(char c) +{ + if (usb_ser == NULL) { + return; + } else { + usb_ser->putc(c); + } +} + +#endif
--- a/mbed-os.lib Mon Jan 06 10:56:13 2020 +0000 +++ b/mbed-os.lib Thu Apr 30 23:43:35 2020 +0000 @@ -1,1 +1,1 @@ -https://github.com/ARMmbed/mbed-os/#64853b354fa188bfe8dbd51e78771213c7ed37f7 +https://github.com/ARMmbed/mbed-os/#565ab149819481224ab43f878c3921b14b11d180
--- a/mbed_app.json Mon Jan 06 10:56:13 2020 +0000 +++ b/mbed_app.json Thu Apr 30 23:43:35 2020 +0000 @@ -9,6 +9,16 @@ "*": { "target.components_add": ["SD"], "target.device_has_add": ["USBDEVICE"] + }, + "NRF52840_DK": { + "target.extra_labels_add": ["SOFTDEVICE_NONE"], + "target.extra_labels_remove": ["BLE", "SOFTDEVICE_COMMON", "SOFTDEVICE_S140_FULL", "NORDIC_SOFTDEVICE"], + "target.features_add": ["STORAGE"], + "target.components_add": ["SD"], + "sd.SPI_MOSI": "D11", + "sd.SPI_MISO": "D12", + "sd.SPI_CLK" : "D13", + "sd.SPI_CS" : "D10" } } }
--- a/select_example.cpp Mon Jan 06 10:56:13 2020 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * STM32F4xx USB Device example programs - * - * Copyright (c) 2020 Kenji Arai / JH1PJL - * http://www.page.sannet.ne.jp/kenjia/index.html - * https://os.mbed.com/users/kenjiArai/ - * Created: January 4th, 2020 - * Revised: January 6th, 2020 - */ - - -/* - You can select several examples as followings. - 0. 0_USB_Serial - Send & Receive data strings via USB port to Host PC - 1. 1_USB_Storage_RW_microSD - Access microSD drive via USB port from Host PC - 2. 2_USB_Mouse - Mouse control for Host PC - 3. 3_USB_Keyboard - Keyboard control for Host PC - */ -#define EXAMPLE_NUMBER 2 // select 0 or 3 - -//----------------- You don't need any modification ---------------------------- -#if EXAMPLE_NUMBER == 0 - #define EXAMPLE_0_SERIAL - #ifdef EXAMPLE_0_SERIAL - #include "0_USB_Serial/main.cpp" - #warning "Select 0_USB_Serial" - #endif -#elif EXAMPLE_NUMBER == 1 - #define EXAMPLE_1_MSD - #ifdef EXAMPLE_1_MSD - #include "1_USB_Storage_RW_microSD/main.cpp" - #warning "Select 1_USB_Storage_RW_microSD" - #endif -#elif EXAMPLE_NUMBER == 2 - #define EXAMPLE_2_MOUSE - #ifdef EXAMPLE_2_MOUSE - #include "2_USB_Mouse/main.cpp" - #warning "Select 2_USB_Mouse" - #endif -#elif EXAMPLE_NUMBER == 3 - #define EXAMPLE_3_KEYBOARD - #ifdef EXAMPLE_3_KEYBOARD - #include "3_USB_Keyboard/main.cpp" - #warning "Select 3_USB_Keyboard" - #endif -#else - #error " Please set 0 to 3 number for EXAMPLE_NUMBER!!" -#endif