Dear All
i have a problem with modified version of USB hostlite with Mr Chans FS SFAT32.
DRESULT disk_ioctl(BYTE drv, /* Physical drive number (0..) */ BYTE ctrl, /* Control code */ void *buff /* Buffer to send/receive control data */ ) { DRESULT res; int result; (void) result; //The FatFs module uses only device independent commands described below. Any device dependent function is not used. //Command Description //CTRL_SYNC Make sure that the disk drive has finished pending write process. When the disk I/O module has a write back cache, flush the dirty sector immediately. This command is not required in read-only configuration. //GET_SECTOR_SIZE Returns sector size of the drive into the WORD variable pointed by Buffer. This command is not required in single sector size configuration, _MAX_SS is 512. //GET_SECTOR_COUNT Returns total sectors on the drive into the DWORD variable pointed by Buffer. This command is used by only f_mkfs function to determine the volume size to be created. //GET_BLOCK_SIZE Returns erase block size of the flash memory in unit of sector into the DWORD variable pointed by Buffer. This command is used by only f_mkfs function and it attempts to align data area to the erase block boundary. The allowable value is 1 to 32768 in power of 2. Return 1 if the erase block size is unknown or disk devices. if ( drv != 0) return RES_PARERR; if (usb_status & STA_NOINIT) return RES_NOTRDY; res = RES_OK; switch(ctrl) { case CTRL_SYNC: // TODO break; case GET_SECTOR_SIZE: *(WORD*)buff = blkSize; break; case GET_SECTOR_COUNT: *(DWORD*)buff = numBlks; break; case GET_BLOCK_SIZE: *(DWORD*)buff = 1; break; default: res = RES_PARERR; break; } return res; }
This function CTRL_SYNC case is flushing the last f_write call, since it is empty.
Someboby could help me?
V.Nagarajan
Hi Tsuneo
I use latest revision of FATfs/ Jan 15,'14 R0.10a
WriteUSBHost() used in one Task only called apptask and one USB host port with MSD only right now.
There is no return error anywhere.
Here is the basic codes of USB Host
i use event(USBP1_WDH) to indicate end of Write back done head interrupt.
int OpenUSBHost(unsigned char port) { unsigned char status; status = OK; if(port == 0) { if(enum_status & 0x1) { if (os_evt_wait_or(USBP1_RHSC_DIS, 0) == OS_R_EVT) { if(usbhost[port].class == MASS_STORAGE_CLASS) { f_mount(NULL, "", 0); } usbhost[port].class = 0; enum_status &= ~0x1; usb_status = STA_NOINIT; status = USB_PORT_DISCONNECT; } } else if (Host_EnumDev(port) == OK ) { if(usbhost[port].class == MASS_STORAGE_CLASS) { status = USB_ENUM_FAIL; if ( (MS_Init(&blkSize, &numBlks, inquiryResult) == OK) && (f_mount(&Fatfs[0],"", 0) == OK)) { enum_status |= 0x1; usb_status &= ~STA_NOINIT; status = OK; } } else { enum_status |= 0x1; } os_evt_wait_or(USBP1_RHSC_DIS, 0); //clear old events } else status = USB_ENUM_FAIL; } else { if(enum_status & 0x2) { if (os_evt_wait_or(USBP2_RHSC_DIS, 0) == OS_R_EVT) { if(usbhost[port].class == MASS_STORAGE_CLASS) { f_mount(NULL, "", 0); } usbhost[port].class = 0; enum_status &= ~0x2; usb_status = STA_NOINIT; status = USB_PORT_DISCONNECT; } } else if ( Host_EnumDev(port) == OK ) { if(usbhost[port].class == MASS_STORAGE_CLASS) { status = USB_ENUM_FAIL; if (MS_Init(&blkSize, &numBlks, inquiryResult) == OK) { usb_status &= ~STA_NOINIT; if(f_mount(&Fatfs[0], "", 1) == OK) { enum_status |= 0x2; status = OK; } else { usb_status = STA_NOINIT; } } } else { enum_status |= 0x2; } os_evt_wait_or(USBP2_RHSC_DIS, 0); //clear old events } else status = USB_ENUM_FAIL; } return status; } USB_INT32S Host_ProcessTD (volatile HCED *ed, volatile USB_INT32U token, volatile USB_INT08U *buffer, USB_INT32U buffer_len) { volatile USB_INT32U td_toggle, rv; if (ed == EDCtrl) { if (token == TD_SETUP) { td_toggle = TD_TOGGLE_0; } else { td_toggle = TD_TOGGLE_1; } } else { td_toggle = 0; } TDHead->Control = (TD_ROUNDING | token | TD_DELAY_INT(0) | td_toggle | TD_CC); TDTail->Control = 0; TDHead->CurrBufPtr = (USB_INT32U) buffer; TDTail->CurrBufPtr = 0; TDHead->Next = (USB_INT32U) TDTail; TDTail->Next = 0; TDHead->BufEnd = (USB_INT32U)(buffer + (buffer_len - 1)); TDTail->BufEnd = 0; ed->HeadTd = (USB_INT32U)TDHead | ((ed->HeadTd) & 0x00000002); ed->TailTd = (USB_INT32U)TDTail; ed->Next = 0; if (ed == EDCtrl) { HcControlHeadED = (USB_INT32U)ed; HcCommandStatus = HcCommandStatus | OR_CMD_STATUS_CLF; HcControl = HcControl | OR_CONTROL_CLE; } else { HcBulkHeadED = (USB_INT32U)ed; HcCommandStatus = HcCommandStatus | OR_CMD_STATUS_BLF; HcControl = HcControl | OR_CONTROL_BLE; } rv = os_evt_wait_or(USBP1_WDH, 200); if((rv == OS_R_EVT) && (os_evt_wait_or(USBP1_CC_ERR, 0) == OS_R_TMO)) return (OK); return (ERR_TD_FAIL); }
Tried to call f_sync() before f_close still no change.
elm-chan.org/.../
Hi Tsuneo.
I got it resolved by adding SCSI_SYNCHRONIZE_CACHE_10 command in CTRL_SYNC case of disk_ioctl().
Could i please have your feedback on this.
//---------------------------------------------------------------------------- USB_INT32S MS_SynchnoniseCache (void) { USB_INT32S rc; Fill_MSCommand(0, 0, 0, MS_DATA_DIR_NONE, SCSI_SYNCHRONIZE_CACHE_10, 6); rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE); if (rc == OK) { rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE); if (rc == OK) { if (TDBuffer[12] != 0) { rc = ERR_MS_CMD_FAILED; } } } return (rc); } DRESULT disk_ioctl(BYTE drv, /* Physical drive number (0..) */ BYTE ctrl, /* Control code */ void *buff /* Buffer to send/receive control data */ ) { DRESULT res; int result; (void) result; if ( drv != 0) return RES_PARERR; if (usb_status & STA_NOINIT) return RES_NOTRDY; res = RES_OK; switch(ctrl) { case CTRL_SYNC: // TODO MS_SynchnoniseCache(); break; case GET_SECTOR_SIZE: *(WORD*)buff = blkSize; break; case GET_SECTOR_COUNT: *(DWORD*)buff = numBlks; break; case GET_BLOCK_SIZE: *(DWORD*)buff = 1; break; default: res = RES_PARERR; break; } return res; } void Fill_MSCommand (USB_INT32U block_number, USB_INT32U block_size, USB_INT16U num_blocks, MS_DATA_DIR direction, USB_INT08U scsi_cmd, USB_INT08U scsi_cmd_len) { USB_INT32U data_len; static USB_INT32U tag_cnt = 0; USB_INT32U cnt; for (cnt = 0; cnt < CBW_SIZE; cnt++) { TDBuffer[cnt] = 0; } switch(scsi_cmd) { case SCSI_CMD_TEST_UNIT_READY: data_len = 0; break; case SCSI_CMD_READ_CAPACITY: data_len = 8; break; case SCSI_CMD_REQUEST_SENSE: data_len = 18; break; case SCSI_CMD_INQUIRY: data_len = 36; break; default: data_len = block_size * num_blocks; break; } WriteLE32U(TDBuffer, CBW_SIGNATURE); WriteLE32U(&TDBuffer[4], tag_cnt); WriteLE32U(&TDBuffer[8], data_len); TDBuffer[12] = (direction == MS_DATA_DIR_NONE) ? 0 : direction; TDBuffer[14] = scsi_cmd_len; /* Length of the CBW */ TDBuffer[15] = scsi_cmd; if(scsi_cmd == SCSI_SYNCHRONIZE_CACHE_10) { return; } else if ((scsi_cmd == SCSI_CMD_REQUEST_SENSE) || (scsi_cmd == SCSI_CMD_INQUIRY)) { TDBuffer[19] = (USB_INT08U)data_len; } else { WriteBE32U(&TDBuffer[17], block_number); } WriteBE16U(&TDBuffer[22], num_blocks); } <\PRE> Once again thank you for pointing problem somewhere in earlier post. V.Nagarajan