⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msddriver.c

📁 Atmel的AT91SAM7x256芯片的usb存储的源程序
💻 C
📖 第 1 页 / 共 2 页
字号:

            csw->dCSWDataResidue += commandState->length;

            // STALL the endpoint waiting for data
            if ((cbw->bmCBWFlags & MSD_CBW_DEVICE_TO_HOST) == 0) {

                // Stall the OUT endpoint : host to device
                USBD_Halt(MSDDriverDescriptors_BULKOUT);
                trace_LOG(trace_INFO, "StaOUT ");
            }
            else {

                // Stall the IN endpoint : device to host
                USBD_Halt(MSDDriverDescriptors_BULKIN);
                trace_LOG(trace_INFO, "StaIN ");
            }
        }

        // Reset command state
        commandState->state = 0;
    }

    return isCommandComplete;
}

//------------------------------------------------------------------------------
//! \brief  Resets the state of the BOT driver
//! \param  pBot Pointer to a S_bot instance
//! \see    S_bot
//------------------------------------------------------------------------------
void MSDDriver_Reset()
{
    trace_LOG(trace_INFO, "MSDReset ");

    msdDriver.state = MSDDriver_STATE_READ_CBW;
    msdDriver.waitResetRecovery = 0;
    msdDriver.commandState.state = 0;
}

//------------------------------------------------------------------------------
//         Callback re-implementation
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Invoked when a new SETUP request is received from the host. Forwards the
/// request to the Mass Storage device driver handler function.
/// \param request  Pointer to a USBGenericRequest instance.
//------------------------------------------------------------------------------
void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
{
    MSDDriver_RequestHandler(request);
}

//------------------------------------------------------------------------------
/// Invoked when the configuration of the device changes. Resets the mass
/// storage driver.
//------------------------------------------------------------------------------
void USBDDriverCallbacks_ConfigurationChanged(unsigned char cfgnum)
{
    if (cfgnum > 0) {

        MSDDriver_Reset();
    }
}

//------------------------------------------------------------------------------
//      Exported functions
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//! \brief  Initializes a BOT driver and the associated USB driver.
//! \param  pBot    Pointer to a S_bot instance
//! \param  pUsb    USB driver to use
//! \param  lun    Pointer to a list of LUNs
//! \param  numLuns Number of LUN in list
//! \see    S_bot
//! \see    S_usb
//------------------------------------------------------------------------------
void MSDDriver_Initialize(MSDLun *luns, unsigned char numLuns)
{
    trace_LOG(trace_INFO, "I: MSD init\n\r");

    // Command state initialization
    msdDriver.commandState.state = 0;
    msdDriver.commandState.postprocess = 0;
    msdDriver.commandState.length = 0;
    msdDriver.commandState.transfer.semaphore = 0;

    // LUNs
    msdDriver.luns = luns;
    msdDriver.maxLun = (unsigned char) (numLuns - 1);

    // Reset BOT driver
    MSDDriver_Reset();

    // Init the USB driver
    USBDDriver_Initialize(&usbdDriver, &msdDriverDescriptors, 0);
    USBD_Init();
}

//------------------------------------------------------------------------------
//! \brief  Handler for incoming SETUP requests on default Control endpoint 0.
//!
//!         Standard requests are forwarded to the STD_RequestHandler method.
//! \param  pBot Pointer to a S_bot instance
//------------------------------------------------------------------------------
void MSDDriver_RequestHandler(const USBGenericRequest *request)
{
    trace_LOG(trace_INFO, "NewReq ");

    // Handle requests
    switch (USBGenericRequest_GetRequest(request)) {
    //---------------------
    case USBGenericRequest_CLEARFEATURE:
    //---------------------
        trace_LOG(trace_INFO, "ClrFeat ");

        switch (USBFeatureRequest_GetFeatureSelector(request)) {

        //---------------------
        case USBFeatureRequest_ENDPOINTHALT:
        //---------------------
            trace_LOG(trace_INFO, "Hlt ");

            // Do not clear the endpoint halt status if the device is waiting
            // for a reset recovery sequence
            if (!msdDriver.waitResetRecovery) {

                // Forward the request to the standard handler
                USBDDriver_RequestHandler(&usbdDriver, request);
            }
            else {

                trace_LOG(trace_INFO, "No ");
            }

            USBD_Write(0, 0, 0, 0, 0);
            break;

        //------
        default:
        //------
            // Forward the request to the standard handler
            USBDDriver_RequestHandler(&usbdDriver, request);
        }
        break;

    //-------------------
    case MSD_GET_MAX_LUN:
    //-------------------
        trace_LOG(trace_INFO, "gMaxLun ");

        // Check request parameters
        if ((request->wValue == 0)
            && (request->wIndex == 0)
            && (request->wLength == 1)) {

            USBD_Write(0, &(msdDriver.maxLun), 1, 0, 0);

        }
        else {

            trace_LOG(trace_WARNING, "W: MSDDriver_RequestHandler: GetMaxLUN(%d,%d,%d)\n\r",
                          request->wValue, request->wIndex, request->wLength);
            USBD_Stall(0);
        }
        break;

    //-----------------------
    case MSD_BULK_ONLY_RESET:
    //-----------------------
        trace_LOG(trace_INFO, "Rst ");

        // Check parameters
        if ((request->wValue == 0)
            && (request->wIndex == 0)
            && (request->wLength == 0)) {

            // Reset the MSD driver
            MSDDriver_Reset();
            USBD_Write(0, 0, 0, 0, 0);
        }
        else {

            trace_LOG(trace_WARNING, "W: MSDDriver_RequestHandler: Reset(%d,%d,%d)\n\r",
                          request->wValue, request->wIndex, request->wLength);
            USBD_Stall(0);
        }
        break;

    //------
    default:
    //------
        // Forward request to standard handler
        USBDDriver_RequestHandler(&usbdDriver, request);

        break;
    }
}

//------------------------------------------------------------------------------
//! \brief  State machine for the BOT driver
//! \param  pBot Pointer to a S_bot instance
//------------------------------------------------------------------------------
void MSDDriver_StateMachine(void)
{
    MSDCommandState *commandState = &(msdDriver.commandState);
    MSCbw           *cbw = &(commandState->cbw);
    MSCsw           *csw = &(commandState->csw);
    MSDTransfer      *transfer = &(commandState->transfer);
    unsigned char       status;

    // Identify current driver state
    switch (msdDriver.state) {
    //----------------------
    case MSDDriver_STATE_READ_CBW:
    //----------------------
        // Start the CBW read operation
        transfer->semaphore = 0;
        status = USBD_Read(MSDDriverDescriptors_BULKOUT,
                           cbw,
                           MSD_CBW_SIZE,
                           (TransferCallback) MSDDriver_Callback,
                           (void *) transfer);

        // Check operation result code
        if (status == USBD_STATUS_SUCCESS) {

            // If the command was successful, wait for transfer
            msdDriver.state = MSDDriver_STATE_WAIT_CBW;
        }
        break;

    //----------------------
    case MSDDriver_STATE_WAIT_CBW:
    //----------------------
        // Check transfer semaphore
        if (transfer->semaphore > 0) {

            // Take semaphore and terminate transfer
            transfer->semaphore--;

            // Check if transfer was successful
            if (transfer->status == USBD_STATUS_SUCCESS) {

                trace_LOG(trace_INFO, "------------------------------\n\r");

                // Process received command
                msdDriver.state = MSDDriver_STATE_PROCESS_CBW;
            }
            else if (transfer->status == USBD_STATUS_RESET) {

                trace_LOG(trace_INFO, "I: MSDDriver_StateMachine: Endpoint resetted\n\r");
                msdDriver.state = MSDDriver_STATE_READ_CBW;
            }
            else {

                trace_LOG(trace_WARNING, "W: MSDDriver_StateMachine: Failed to read CBW\n\r");
                msdDriver.state = MSDDriver_STATE_READ_CBW;
            }
        }
        break;

    //-------------------------
    case MSDDriver_STATE_PROCESS_CBW:
    //-------------------------
        // Check if this is a new command
        if (commandState->state == 0) {

            // Copy the CBW tag
            csw->dCSWTag = cbw->dCBWTag;

            // Check that the CBW is 31 bytes long
            if ((transfer->transferred != MSD_CBW_SIZE) ||
                (transfer->remaining != 0)) {

                trace_LOG(trace_WARNING, "W: MSDDriver_StateMachine: Invalid CBW (too short or too long)\n\r");

                // Wait for a reset recovery
                msdDriver.waitResetRecovery = 1;

                // Halt the Bulk-IN and Bulk-OUT pipes
                USBD_Halt(MSDDriverDescriptors_BULKOUT);
                USBD_Halt(MSDDriverDescriptors_BULKIN);

                csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
                msdDriver.state = MSDDriver_STATE_READ_CBW;

            }
            // Check the CBW Signature
            else if (cbw->dCBWSignature != MSD_CBW_SIGNATURE) {

                trace_LOG(trace_WARNING, "W: MSD_BOTStateMachine: Invalid CBW (Bad signature)\n\r");

                // Wait for a reset recovery
                msdDriver.waitResetRecovery = 1;

                // Halt the Bulk-IN and Bulk-OUT pipes
                USBD_Halt(MSDDriverDescriptors_BULKOUT);
                USBD_Halt(MSDDriverDescriptors_BULKIN);

                csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
                msdDriver.state = MSDDriver_STATE_READ_CBW;
            }
            else {

                // Pre-process command
                MSDDriver_PreProcessCommand();
            }
        }

        // Process command
        if (csw->bCSWStatus == MSDDriver_STATUS_SUCCESS) {

            if (MSDDriver_ProcessCommand()) {

                // Post-process command if it is finished
                MSDDriver_PostProcessCommand();
                msdDriver.state = MSDDriver_STATE_SEND_CSW;
            }
            trace_LOG(trace_INFO, "\n\r");
        }

        break;

    //----------------------
    case MSDDriver_STATE_SEND_CSW:
    //----------------------
        // Set signature
        csw->dCSWSignature = MSD_CSW_SIGNATURE;

        // Start the CSW write operation
        status = USBD_Write(MSDDriverDescriptors_BULKIN,
                            csw,
                            MSD_CSW_SIZE,
                            (TransferCallback) MSDDriver_Callback,
                            (void *) transfer);

        // Check operation result code
        if (status == USBD_STATUS_SUCCESS) {

            trace_LOG(trace_INFO, "SendCSW ");

            // Wait for end of transfer
            msdDriver.state = MSDDriver_STATE_WAIT_CSW;
        }
        break;

    //----------------------
    case MSDDriver_STATE_WAIT_CSW:
    //----------------------
        // Check transfer semaphore
        if (transfer->semaphore > 0) {

            // Take semaphore and terminate transfer
            transfer->semaphore--;

            // Check if transfer was successful
            if (transfer->status == USBD_STATUS_RESET) {

                trace_LOG(trace_INFO, "MSDDriver_StateMachine: Endpoint resetted\n\r");
            }
            else if (transfer->status == USBD_STATUS_ABORTED) {

                trace_LOG(trace_WARNING, "W: MSDDriver_StateMachine: Failed to send CSW\n\r");
            }
            else {

                trace_LOG(trace_INFO, "ok");
            }

            // Read new CBW
            msdDriver.state = MSDDriver_STATE_READ_CBW;
        }
        break;
    }
}

//------------------------------------------------------------------------------
/// Starts a remote wake-up sequence if the host has explicitely enabled it
/// by sending the appropriate SET_FEATURE request.
//------------------------------------------------------------------------------
void MSDDriver_RemoteWakeUp(void)
{
    // Remote wake-up has been enabled
    if (USBDDriver_IsRemoteWakeUpEnabled(&usbdDriver)) {

        USBD_RemoteWakeUp();
    }
    // Remote wake-up NOT enabled
    else {

        trace_LOG(trace_WARNING, "-W- MSDDriver_RemoteWakeUp: Host has not enabled remote wake-up\n\r");
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -