diff --git a/demos/host/host_os_none/host_os_none.uvopt b/demos/host/host_os_none/host_os_none.uvopt index 905eb692a..1c5f0b565 100644 --- a/demos/host/host_os_none/host_os_none.uvopt +++ b/demos/host/host_os_none/host_os_none.uvopt @@ -135,7 +135,7 @@ 0 DLGUARM - (106=-1,-1,-1,-1,0)(107=-1,-1,-1,-1,0) + 0 @@ -158,24 +158,7 @@ -O975 -S0 -C0 -FO7 -FD10000000 -FC800 -FN2 -FF0LPC18xx43xx_512_BA -FS01A000000 -FL080000 -FF1LPC18xx43xx_512_BB -FS11B000000 -FL180000) - - - 0 - 0 - 269 - 1 -
0
- 0 - 0 - 0 - 0 - 0 - 0 - C:\Users\hathach\Dropbox\tinyusb\workspace\tinyusb\demos\host\src\cli.c - - -
-
+ 0 @@ -387,24 +370,7 @@ -O975 -S0 -C0 -FO7 -FD10000000 -FC800 -FN2 -FF0LPC18xx43xx_512_BA -FS01A000000 -FL080000 -FF1LPC18xx43xx_512_BB -FS11B000000 -FL180000) - - - 0 - 0 - 269 - 1 -
0
- 0 - 0 - 0 - 0 - 0 - 0 - C:\Users\hathach\Dropbox\tinyusb\workspace\tinyusb\demos\host\src\cli.c - - -
-
+ 0 @@ -458,10 +424,10 @@ 1 0 0 - 1 + 0 0 - 195 - 200 + 1 + 1 0 ..\src\main.c main.c @@ -476,7 +442,7 @@ 0 0 0 - 94 + 125 145 0 ..\src\cdc_serial_app.c @@ -492,7 +458,7 @@ 0 0 0 - 136 + 167 180 0 ..\src\keyboard_app.c @@ -508,7 +474,7 @@ 0 44 0 - 120 + 121 127 0 ..\src\mouse_app.c @@ -538,10 +504,10 @@ 1 0 0 - 1 + 0 0 - 111 - 125 + 1 + 1 0 ..\src\msc_app.c msc_app.c @@ -554,10 +520,10 @@ 1 0 0 - 24 + 27 0 - 1 - 11 + 355 + 367 0 ..\src\cli.c cli.c @@ -596,7 +562,7 @@ 0 0 0 - 139 + 140 142 0 ..\..\bsp\boards\embedded_artists\board_ea4357.c @@ -612,7 +578,7 @@ 0 6 0 - 95 + 125 135 0 ..\..\bsp\boards\printf_retarget.c @@ -748,7 +714,7 @@ 0 0 0 - 25 + 56 76 0 ..\..\..\tinyusb\tusb.c @@ -812,7 +778,7 @@ 0 0 0 - 483 + 491 501 0 ..\..\..\tinyusb\host\usbh.c @@ -826,10 +792,10 @@ 1 0 0 - 0 + 38 0 - 602 - 605 + 479 + 484 0 ..\..\..\tinyusb\host\ehci\ehci.c ehci.c @@ -986,10 +952,10 @@ 1 0 0 - 0 + 1 0 - 1 - 1 + 110 + 118 0 ..\..\..\tinyusb\class\msc_host.c msc_host.c @@ -1012,7 +978,7 @@ 0 0 0 - 548 + 549 553 0 ..\..\bsp\lpc43xx\CMSIS_LPC43xx_DriverLib\src\lpc43xx_uart.c @@ -1114,10 +1080,10 @@ 2 0 0 - 0 + 26 0 - 140 - 158 + 145 + 154 0 ..\..\bsp\lpc43xx\startup_keil\startup_LPC43xx.s startup_LPC43xx.s @@ -1138,10 +1104,10 @@ 1 0 0 - 46 + 45 0 - 17 - 30 + 1 + 10 0 ..\..\..\vendor\fatfs\diskio.c diskio.c diff --git a/demos/host/src/cli.c b/demos/host/src/cli.c index 3236ae5a0..737369768 100644 --- a/demos/host/src/cli.c +++ b/demos/host/src/cli.c @@ -57,26 +57,39 @@ typedef enum { CLI_ERROR_NONE = 0, CLI_ERROR_INVALID_PARA, CLI_ERROR_INVALID_PATH, + CLI_ERROR_FILE_EXISTED, CLI_ERROR_FAILED }cli_error_t; +static char const * const cli_error_message[] = +{ + [CLI_ERROR_NONE ] = 0, + [CLI_ERROR_INVALID_PARA ] = "Invalid parameter(s)", + [CLI_ERROR_INVALID_PATH ] = "No such file or directory", + [CLI_ERROR_FILE_EXISTED ] = "file or directory already exists", + [CLI_ERROR_FAILED ] = "failed to execute" +}; + //--------------------------------------------------------------------+ // CLI Database definition //--------------------------------------------------------------------+ // command, function, description #define CLI_COMMAND_TABLE(ENTRY) \ - ENTRY(unknown , cli_cmd_unknown , NULL) \ - ENTRY(help , cli_cmd_help , NULL) \ - ENTRY(ls , cli_cmd_list , "list items in current directory") \ - ENTRY(cd , cli_cmd_changedir, "change current directory") \ - ENTRY(cat , cli_cmd_cat , "display contents of a text file") \ + ENTRY(unknown , cli_cmd_unknown , NULL ) \ + ENTRY(help , cli_cmd_help , NULL ) \ + ENTRY(cls , cli_cmd_clear , "Clear the screen." ) \ + ENTRY(ls , cli_cmd_list , "List information about the FILEs (the current directory by default).") \ + ENTRY(cd , cli_cmd_changedir, "change the current directory." ) \ + ENTRY(cat , cli_cmd_cat , "display contents of a text file." ) \ + ENTRY(cp , cli_cmd_copy , "Copies one or more files to another location." ) \ + ENTRY(mkdir , cli_cmd_mkdir , "Create a DIRECTORY, if it does not already exist." ) \ //--------------------------------------------------------------------+ // Expands the function to have the standard function signature //--------------------------------------------------------------------+ #define CLI_PROTOTYPE_EXPAND(command, function, description) \ - cli_error_t function(char const *); + cli_error_t function(char *); CLI_COMMAND_TABLE(CLI_PROTOTYPE_EXPAND); @@ -116,38 +129,38 @@ char const* const cli_description_tbl[] = #define CMD_LOOKUP_EXPAND(command, function, description)\ [CLI_CMDTYPE_##command] = function,\ -typedef cli_error_t (* const cli_cmdfunc_t)(char const *); +typedef cli_error_t (* const cli_cmdfunc_t)(char *); static cli_cmdfunc_t cli_command_tbl[] = { CLI_COMMAND_TABLE(CMD_LOOKUP_EXPAND) }; - - -static char const * const cli_error_message[] = -{ - [CLI_ERROR_NONE ] = 0, - [CLI_ERROR_INVALID_PARA ] = "Invalid parameter(s)", - [CLI_ERROR_INVALID_PATH ] = "No such file or directory", - [CLI_ERROR_FAILED ] = "failed to execute" -}; - //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ - static char cli_buffer[CLI_MAX_BUFFER]; - uint8_t fileread_buffer[CLI_FILE_READ_BUFFER] TUSB_CFG_ATTR_USBRAM; - +static char volume_label[20]; //--------------------------------------------------------------------+ // IMPLEMENTATION //--------------------------------------------------------------------+ +// NOTES: prompt re-use cli_buffer --> should not be called when cli_buffer has contents +void cli_command_prompt(void) +{ + f_getcwd(cli_buffer, CLI_MAX_BUFFER); + printf("\n%s %c%s\n$ ", + (volume_label[0] !=0) ? volume_label : "No Label", + 'E'+cli_buffer[0]-'0', + cli_buffer+1); + + memclr_(cli_buffer, CLI_MAX_BUFFER); +} void cli_init(void) { memclr_(cli_buffer, CLI_MAX_BUFFER); + f_getlabel(NULL, volume_label, NULL); } void cli_poll(char ch) @@ -192,11 +205,7 @@ void cli_poll(char ch) if (CLI_ERROR_NONE != error) puts(cli_error_message[error]); // error message output if any //------------- print out current path -------------// - f_getcwd(cli_buffer, CLI_MAX_BUFFER); - printf("\nMSC %c%s\n$ ", - 'E'+cli_buffer[0]-'0', - cli_buffer+1); - memclr_(cli_buffer, CLI_MAX_BUFFER); + cli_command_prompt(); } else if (ch=='\t') // \t may be used for auto-complete later { @@ -207,7 +216,7 @@ void cli_poll(char ch) //--------------------------------------------------------------------+ // UNKNOWN Command //--------------------------------------------------------------------+ -cli_error_t cli_cmd_unknown(char const * para) +cli_error_t cli_cmd_unknown(char * para) { puts("unknown command, please type \"help\" for list of supported commands"); return CLI_ERROR_NONE; @@ -216,7 +225,7 @@ cli_error_t cli_cmd_unknown(char const * para) //--------------------------------------------------------------------+ // HELP command //--------------------------------------------------------------------+ -cli_error_t cli_cmd_help(char const * para) +cli_error_t cli_cmd_help(char * para) { puts("current supported commands are:"); for(cli_cmdtype_t cmd_id = CLI_CMDTYPE_help+1; cmd_id < CLI_CMDTYPE_COUNT; cmd_id++) @@ -227,10 +236,18 @@ cli_error_t cli_cmd_help(char const * para) return CLI_ERROR_NONE; } +//--------------------------------------------------------------------+ +// Clear Screen Command +//--------------------------------------------------------------------+ +cli_error_t cli_cmd_clear(char* p_para) +{ + printf(ANSI_ERASE_SCREEN(2)); +} + //--------------------------------------------------------------------+ // LS Command //--------------------------------------------------------------------+ -cli_error_t cli_cmd_list(const char * p_para) +cli_error_t cli_cmd_list(char * p_para) { if ( strlen(p_para) == 0 ) // list current directory { @@ -253,7 +270,7 @@ cli_error_t cli_cmd_list(const char * p_para) printf("/%s", p_name); }else { - printf("%-50s%d KB", p_name, dir_entry.fsize / 1000); + printf("%-40s%d KB", p_name, dir_entry.fsize / 1000); } putchar('\n'); } @@ -271,7 +288,7 @@ cli_error_t cli_cmd_list(const char * p_para) //--------------------------------------------------------------------+ // CD Command //--------------------------------------------------------------------+ -cli_error_t cli_cmd_changedir(const char * p_para) +cli_error_t cli_cmd_changedir(char * p_para) { if ( strlen(p_para) == 0 ) return CLI_ERROR_INVALID_PARA; @@ -286,7 +303,7 @@ cli_error_t cli_cmd_changedir(const char * p_para) //--------------------------------------------------------------------+ // CAT Command //--------------------------------------------------------------------+ -cli_error_t cli_cmd_cat(const char *p_para) +cli_error_t cli_cmd_cat(char *p_para) { if ( strlen(p_para) == 0 ) return CLI_ERROR_INVALID_PARA; @@ -325,4 +342,57 @@ cli_error_t cli_cmd_cat(const char *p_para) return CLI_ERROR_NONE; } +//--------------------------------------------------------------------+ +// Make Directory command +//--------------------------------------------------------------------+ +//--------------------------------------------------------------------+ +// COPY command +//--------------------------------------------------------------------+ +cli_error_t cli_cmd_copy(char *p_para) +{ + char* p_space = strchr(p_para, ' '); + if ( p_space == NULL ) return CLI_ERROR_INVALID_PARA; + + *p_space = 0; // replace space by NULL-character + char* p_dest = p_space+1; + + if ( strlen(p_dest) == 0 ) return CLI_ERROR_INVALID_PARA; + + //------------- Check Existence of source & dest file -------------// + cli_error_t error = CLI_ERROR_NONE; + FIL src_file, dest_file; + + if ( FR_OK != f_open(&src_file , p_para, FA_READ) ) return CLI_ERROR_INVALID_PATH; + switch ( f_open(&dest_file, p_dest, FA_WRITE | FA_CREATE_NEW) ) + { + case FR_EXIST: + error = CLI_ERROR_FILE_EXISTED; + break;\ + + case FR_OK: + while(1) + { + uint32_t bytes_read = 0; + uint32_t bytes_write = 0; + FRESULT res; + + res = f_read(&src_file, fileread_buffer, CLI_FILE_READ_BUFFER, &bytes_read); /* Read a chunk of src file */ + if ( (res != FR_OK) || (bytes_read == 0) ) break; /* error or eof */ + + res = f_write(&dest_file, fileread_buffer, bytes_read, &bytes_write); /* Write it to the dst file */ + if ( (res != FR_OK) || (bytes_write < bytes_read) ) break; /* error or disk full */ + } + + f_close(&dest_file); + break; + + default: + error = CLI_ERROR_FAILED; + break; + } + + f_close(&src_file); + + return error; +} #endif diff --git a/demos/host/src/main.c b/demos/host/src/main.c index d6c7e43e4..6f33cc49c 100644 --- a/demos/host/src/main.c +++ b/demos/host/src/main.c @@ -125,8 +125,6 @@ int main(void) tusb_init(); - cli_init(); - //------------- application task init -------------// (void) osal_task_create( OSAL_TASK_REF(led_blinking_task) ); diff --git a/demos/host/src/msc_app.c b/demos/host/src/msc_app.c index 3971d7557..2cbe8466d 100644 --- a/demos/host/src/msc_app.c +++ b/demos/host/src/msc_app.c @@ -89,24 +89,23 @@ void tusbh_msc_mounted_cb(uint8_t dev_addr) if ( disk_is_ready(0) ) { - if ( f_mount(0, &fatfs[dev_addr-1]) != FR_OK ) + if ( f_mount(0, &fatfs[dev_addr-1]) != FR_OK ) // TODO multiple volume { puts("mount failed"); return; } - char volume_label[20] = {0}; - f_getlabel(NULL, volume_label, NULL); - printf("Label: %s\n\n", volume_label); - f_chdrive(dev_addr-1); // change to newly mounted drive f_chdir("/"); // root as current dir - printf("MSC %c:/\n$ ", 'E'+dev_addr-1); + + cli_init(); + cli_command_prompt(); } } void tusbh_msc_unmounted_isr(uint8_t dev_addr) { + // unmount disk disk_state = STA_NOINIT; puts("--"); } diff --git a/tests/lpc18xx_43xx/test/host/msc/msch_callback.h b/tests/lpc18xx_43xx/test/host/msc/msch_callback.h index b91db23fe..3c75a1c3f 100644 --- a/tests/lpc18xx_43xx/test/host/msc/msch_callback.h +++ b/tests/lpc18xx_43xx/test/host/msc/msch_callback.h @@ -54,7 +54,7 @@ void tusbh_msc_mounted_cb(uint8_t dev_addr); void tusbh_msc_unmounted_isr(uint8_t dev_addr); -void tusbh_msc_isr(uint8_t dev_addr, tusb_event_t event); +void tusbh_msc_isr(uint8_t dev_addr, tusb_event_t event, uint32_t xferred_bytes); #ifdef __cplusplus diff --git a/tinyusb/class/msc.h b/tinyusb/class/msc.h index 5ca1db6bd..f4adbbbea 100644 --- a/tinyusb/class/msc.h +++ b/tinyusb/class/msc.h @@ -119,6 +119,15 @@ STATIC_ASSERT(sizeof(msc_cmd_status_wrapper_t) == 13, "size is not correct"); //--------------------------------------------------------------------+ // SCSI Primary Command (SPC-4) //--------------------------------------------------------------------+ +typedef ATTR_PACKED_STRUCT(struct) { + uint8_t cmd_code; + uint8_t lun; + uint8_t reserved[3]; + uint8_t control; +} scsi_test_unit_ready_t; + +STATIC_ASSERT(sizeof(scsi_test_unit_ready_t) == 6, "size is not correct"); + typedef ATTR_PACKED_STRUCT(struct) { uint8_t cmd_code; uint8_t reserved1; diff --git a/tinyusb/class/msc_host.c b/tinyusb/class/msc_host.c index 673cfc9e0..25518a757 100644 --- a/tinyusb/class/msc_host.c +++ b/tinyusb/class/msc_host.c @@ -116,8 +116,19 @@ static inline void msc_cbw_add_signature(msc_cmd_block_wrapper_t *p_cbw, uint8_t static tusb_error_t msch_command_xfer(msch_interface_t * p_msch, void* p_buffer) ATTR_WARN_UNUSED_RESULT; static tusb_error_t msch_command_xfer(msch_interface_t * p_msch, void* p_buffer) { - ASSERT_STATUS( hcd_pipe_xfer(p_msch->bulk_out, &p_msch->cbw, sizeof(msc_cmd_block_wrapper_t), false) ); - ASSERT_STATUS( hcd_pipe_queue_xfer(p_msch->bulk_in , p_buffer, p_msch->cbw.xfer_bytes) ); + if ( NULL != p_buffer) + { // there is data phase + if (p_msch->cbw.flags & TUSB_DIR_DEV_TO_HOST_MASK) + { + ASSERT_STATUS( hcd_pipe_xfer(p_msch->bulk_out, &p_msch->cbw, sizeof(msc_cmd_block_wrapper_t), false) ); + ASSERT_STATUS( hcd_pipe_queue_xfer(p_msch->bulk_in , p_buffer, p_msch->cbw.xfer_bytes) ); + }else + { + ASSERT_STATUS( hcd_pipe_queue_xfer(p_msch->bulk_out, &p_msch->cbw, sizeof(msc_cmd_block_wrapper_t)) ); + ASSERT_STATUS( hcd_pipe_xfer(p_msch->bulk_out , p_buffer, p_msch->cbw.xfer_bytes, false) ); + } + } + ASSERT_STATUS( hcd_pipe_xfer(p_msch->bulk_in , &p_msch->csw, sizeof(msc_cmd_status_wrapper_t), true) ); return TUSB_ERROR_NONE; @@ -198,6 +209,33 @@ tusb_error_t tusbh_msc_request_sense(uint8_t dev_addr, uint8_t lun, uint8_t *p_d return TUSB_ERROR_NONE; } +tusb_error_t tusbh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, msc_cmd_status_wrapper_t * p_csw) +{ + msch_interface_t* p_msch = &msch_data[dev_addr-1]; + + //------------- Command Block Wrapper -------------// + msc_cbw_add_signature(&p_msch->cbw, lun); + + p_msch->cbw.xfer_bytes = 0; // Number of bytes + p_msch->cbw.flags = TUSB_DIR_HOST_TO_DEV; + p_msch->cbw.cmd_len = sizeof(scsi_test_unit_ready_t); + + //------------- SCSI command -------------// + scsi_test_unit_ready_t cmd_test_unit_ready = + { + .cmd_code = SCSI_CMD_TEST_UNIT_READY, + .lun = lun // according to wiki + }; + + memcpy(p_msch->cbw.command, &cmd_test_unit_ready, p_msch->cbw.cmd_len); + + // TODO MSCH refractor test uinit ready + ASSERT_STATUS( hcd_pipe_xfer(p_msch->bulk_out, &p_msch->cbw, sizeof(msc_cmd_block_wrapper_t), false) ); + ASSERT_STATUS( hcd_pipe_xfer(p_msch->bulk_in , p_csw, sizeof(msc_cmd_status_wrapper_t), true) ); + + return TUSB_ERROR_NONE; +} + tusb_error_t tusbh_msc_read10(uint8_t dev_addr, uint8_t lun, void * p_buffer, uint32_t lba, uint16_t block_count) { msch_interface_t* p_msch = &msch_data[dev_addr-1]; @@ -232,7 +270,7 @@ tusb_error_t tusbh_msc_write10(uint8_t dev_addr, uint8_t lun, void * p_buffer, u msc_cbw_add_signature(&p_msch->cbw, lun); p_msch->cbw.xfer_bytes = p_msch->block_size*block_count; // Number of bytes - p_msch->cbw.flags = TUSB_DIR_DEV_TO_HOST_MASK; + p_msch->cbw.flags = TUSB_DIR_HOST_TO_DEV; p_msch->cbw.cmd_len = sizeof(scsi_write10_t); //------------- SCSI command -------------// @@ -355,6 +393,8 @@ tusb_error_t msch_open_subtask(uint8_t dev_addr, tusb_descriptor_interface_t con msch_data[dev_addr-1].last_lba = __be2le( ((scsi_read_capacity10_data_t*)msch_buffer)->last_lba ); msch_data[dev_addr-1].block_size = (uint16_t) __be2le( ((scsi_read_capacity10_data_t*)msch_buffer)->block_size ); + osal_semaphore_wait(msch_sem_hdl, SCSI_XFER_TIMEOUT, &error); + msch_data[dev_addr-1].is_initialized = true; tusbh_msc_mounted_cb(dev_addr); diff --git a/tinyusb/class/msc_host.h b/tinyusb/class/msc_host.h index df2f6d833..b51b9f515 100644 --- a/tinyusb/class/msc_host.h +++ b/tinyusb/class/msc_host.h @@ -67,8 +67,8 @@ tusb_error_t tusbh_msc_get_capacity(uint8_t dev_addr, uint32_t* p_last_lba, uint tusb_error_t tusbh_msc_read10 (uint8_t dev_addr, uint8_t lun, void * p_buffer, uint32_t lba, uint16_t block_count) ATTR_WARN_UNUSED_RESULT; tusb_error_t tusbh_msc_write10(uint8_t dev_addr, uint8_t lun, void * p_buffer, uint32_t lba, uint16_t block_count) ATTR_WARN_UNUSED_RESULT; tusb_error_t tusbh_msc_request_sense(uint8_t dev_addr, uint8_t lun, uint8_t *p_data) ATTR_WARN_UNUSED_RESULT; +tusb_error_t tusbh_msc_test_unit_ready(uint8_t dev_addr, uint8_t lun, msc_cmd_status_wrapper_t * p_csw) ATTR_WARN_UNUSED_RESULT; // TODO to be refractor -//tusb_error_t tusbh_msc_test_unit_ready(uint8_t dev_addr) ATTR_WARN_UNUSED_RESULT; //tusb_error_t tusbh_msc_inquiry(uint8_t dev_addr, scsi_inquiry_data_t * p_inquiry_data) ATTR_WARN_UNUSED_RESULT; //tusb_error_t tusbh_msc_read_capacity10(uint8_t dev_addr, scsi_read_capacity10_t * p_buffer) ATTR_WARN_UNUSED_RESULT; diff --git a/vendor/fatfs/diskio.c b/vendor/fatfs/diskio.c index 17b7d5447..58e590775 100644 --- a/vendor/fatfs/diskio.c +++ b/vendor/fatfs/diskio.c @@ -56,6 +56,19 @@ //--------------------------------------------------------------------+ // IMPLEMENTATION //--------------------------------------------------------------------+ +static tusb_error_t wait_for_io_complete(uint8_t usb_addr) +{ + #if TUSB_CFG_OS == TUSB_OS_NONE + while ( tusbh_msc_status(usb_addr) == TUSB_INTERFACE_STATUS_BUSY ) + { + // timeout here + } + return tusbh_msc_status(usb_addr) == TUSB_INTERFACE_STATUS_READY ? RES_OK : RES_ERROR; +#else + #error semaphore instead of blocking +#endif + +} //pdrv Specifies the physical drive number. DSTATUS disk_initialize ( BYTE pdrv ) @@ -80,51 +93,113 @@ DSTATUS disk_status (BYTE pdrv) DRESULT disk_read (BYTE pdrv, BYTE*buff, DWORD sector, BYTE count) { uint8_t usb_addr = pdrv+1; - tusbh_msc_read10(usb_addr, 0, buff, sector, count); + + if ( TUSB_ERROR_NONE != tusbh_msc_read10(usb_addr, 0, buff, sector, count) ) return RES_ERROR; -#if TUSB_CFG_OS == TUSB_OS_NONE - while ( tusbh_msc_status(usb_addr) == TUSB_INTERFACE_STATUS_BUSY ) - { - // timeout here - } - return tusbh_msc_status(usb_addr) == TUSB_INTERFACE_STATUS_READY ? RES_OK : RES_ERROR; -#else - #error semaphore instead of blocking -#endif - - return RES_ERROR; + return wait_for_io_complete(usb_addr); } DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, BYTE count) { + uint8_t usb_addr = pdrv+1; + if ( TUSB_ERROR_NONE != tusbh_msc_write10(usb_addr, 0, buff, sector, count) ) return RES_ERROR; + + return wait_for_io_complete(usb_addr); } +/* [IN] Drive number */ +/* [IN] Control command code */ +/* [I/O] Parameter and data buffer */ +msc_cmd_status_wrapper_t temp_csw TUSB_CFG_ATTR_USBRAM; // TODO MSCH test unit ready refractor DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff) { + if (cmd != CTRL_SYNC) return RES_ERROR; + uint8_t usb_addr = pdrv+1; + + do { + memclr_(&temp_csw, sizeof(msc_cmd_status_wrapper_t)); + + if ( TUSB_ERROR_NONE != tusbh_msc_test_unit_ready(usb_addr, 0, &temp_csw) ) return RES_ERROR; + wait_for_io_complete(usb_addr); + + } while( temp_csw.status != 0 ); // wait unitl unit is ready + + return RES_OK; } -//DWORD get_fattime (void) -//{ -// union { -// struct { -// DWORD second : 5; -// DWORD minute : 6; -// DWORD hour : 5; -// DWORD day_in_month : 5; -// DWORD month : 4; -// DWORD year : 7; -// }; -// -// DWORD value -// } timestamp = -// { -// .year = (2013-1980), -// .month = 10, -// .day_in_month = 21, -// }; -//} +static inline uint8_t month2number(char* p_ch) ATTR_PURE ATTR_ALWAYS_INLINE; +static inline uint8_t month2number(char* p_ch) +{ + uint8_t const * const month_str[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + + for(uint8_t i=0; i<12; i++) + { + if ( strncmp(p_ch, month_str[i], 3) == 0 ) return i+1; + } + + return 1; +} + +static inline uint8_t c2i(char ch) ATTR_CONST ATTR_ALWAYS_INLINE; +static inline uint8_t c2i(char ch) +{ + return ch - '0'; +} + +DWORD get_fattime (void) +{ + union { + struct { + DWORD second : 5; + DWORD minute : 6; + DWORD hour : 5; + DWORD day_in_month : 5; + DWORD month : 4; + DWORD year : 7; + }; + + DWORD value; + } timestamp; + + //------------- Date is compiled date-------------// + char compile_date[] = __DATE__; // eg. "Sep 26 2013" + char* p_ch; + + p_ch = strtok (compile_date, " "); + timestamp.month = month2number(p_ch); + + p_ch = strtok (NULL, " "); + timestamp.day_in_month = 10*c2i(p_ch[0])+ c2i(p_ch[1]); + + p_ch = strtok (NULL, " "); + timestamp.year = 1000*c2i(p_ch[0]) + 100*c2i(p_ch[1]) + 10*c2i(p_ch[2]) + c2i(p_ch[3]) - 1980; + + //------------- Time each time this function call --> sec ++ -------------// + static uint8_t sec = 0; + static uint8_t min = 0; + static uint8_t hour = 0; + + if (++sec >= 60) + { + sec = 0; + if (++min >= 60) + { + min = 0; + if (++hour >= 24) + { + hour = 0; // assume demo wont call this function more than 24*60*60 times + } + } + } + + timestamp.hour = hour; + timestamp.minute = min; + timestamp.second = sec; + + return timestamp.value; +} #endif diff --git a/vendor/fatfs/ffconf.h b/vendor/fatfs/ffconf.h index c490ca8ea..2ba90f251 100644 --- a/vendor/fatfs/ffconf.h +++ b/vendor/fatfs/ffconf.h @@ -20,7 +20,7 @@ / data transfer. This reduces memory consumption 512 bytes each file object. */ -#define _FS_READONLY 1 /* 0:Read/Write or 1:Read only */ +#define _FS_READONLY 0 /* 0:Read/Write or 1:Read only */ /* Setting _FS_READONLY to 1 defines read only configuration. This removes / writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename, / f_truncate and useless f_getfree. */