add scsi write10 & test unit ready

done copy command
implement get_fattime using __DATE__ and number of calls
This commit is contained in:
hathach
2013-09-26 14:37:40 +07:00
parent 4bdede53eb
commit 9d60db0f9f
10 changed files with 300 additions and 143 deletions

139
vendor/fatfs/diskio.c vendored
View File

@@ -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