This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

LPC2468 USB-MSD ChanFs FAT32

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

Parents
  • 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/.../

    V.Nagarajan

Reply
  • 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/.../

    V.Nagarajan

Children
  • 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