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. */