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

📄 bot_driver.c

📁 This software package contains the USB framework core developped by ATMEL, as well as a Mass stora
💻 C
📖 第 1 页 / 共 3 页
字号:
    pBot->sCommandState.bState = 0;
    pBot->sCommandState.bCase = 0;
    pBot->sCommandState.dLength = 0;
    pBot->sCommandState.sTransfer.bSemaphore = 0;

    // LUNs
    pBot->pLun = pLun;
    pBot->bMaxLun = (unsigned char) (bNumLun - 1);

    // Reset BOT driver
    BOT_Reset(pBot);

    // Init the USB driver
    USB_Init(pUsb);
}

//------------------------------------------------------------------------------
//! \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 BOT_RequestHandler(S_bot *pBot)
{
    const S_usb *pUsb = pBot->sClass.pUsb;
    S_usb_request *pSetup = USB_GetSetup(pUsb);

    TRACE_DEBUG_M("NewReq ");

    // Handle requests
    switch (pSetup->bRequest) {
    //---------------------
    case USB_CLEAR_FEATURE:
    //---------------------
        TRACE_DEBUG_M("ClrFeat ");

        switch (pSetup->wValue) {

        //---------------------
        case USB_ENDPOINT_HALT:
        //---------------------
            TRACE_DEBUG_M("Hlt ");

            // Do not clear the endpoint halt status if the device is waiting
            // for a reset recovery sequence
            if (!pBot->isWaitResetRecovery) {

                // Forward the request to the standard handler
                STD_RequestHandler(&(pBot->sClass));
            }
            else {

                TRACE_DEBUG_M("No ");
            }

            USB_SendZLP0(pUsb, 0, 0);
            break;

        //------
        default:
        //------
            // Forward the request to the standard handler
            STD_RequestHandler(&(pBot->sClass));
        }
        break;

    //-------------------
    case MSD_GET_MAX_LUN:
    //-------------------
        TRACE_DEBUG_M("gMaxLun ");

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

            USB_Write(pUsb, 0, &(pBot->bMaxLun), 1, 0, 0);
        }
        else {

            TRACE_WARNING("W: BOT_RequestHandler: GetMaxLUN(%d,%d,%d)\n\r",
                          pSetup->wValue, pSetup->wIndex, pSetup->wLength);
            USB_Stall(pUsb, 0);
        }
        break;

    //-----------------------
    case MSD_BULK_ONLY_RESET:
    //-----------------------
        TRACE_DEBUG_M("Rst ");

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

            // Reset the MSD driver
            BOT_Reset(pBot);
            USB_SendZLP0(pUsb, 0, 0);
        }
        else {

            TRACE_WARNING("W: BOT_RequestHandler: Reset(%d,%d,%d)\n\r",
                          pSetup->wValue, pSetup->wIndex, pSetup->wLength);
            USB_Stall(pUsb, 0);
        }
        break;

    //------
    default:
    //------
        // Forward request to standard handler
        STD_RequestHandler(&(pBot->sClass));

        break;
    }

#if !defined(TR_DEBUG_L)
    TRACE_DEBUG_M("\n\r");
#endif
}

//------------------------------------------------------------------------------
//! \brief  State machine for the BOT driver
//! \param  pBot Pointer to a S_bot instance
//------------------------------------------------------------------------------
void BOT_StateMachine(S_bot *pBot)
{
    const S_usb         *pUsb = pBot->sClass.pUsb;
    S_bot_command_state *pCommandState = &(pBot->sCommandState);
    S_msd_cbw           *pCbw = &(pCommandState->sCbw);
    S_msd_csw           *pCsw = &(pCommandState->sCsw);
    S_bot_transfer      *pTransfer = &(pCommandState->sTransfer);
    unsigned char       bStatus;

    // Identify current driver state
    switch (pBot->bState) {
    //----------------------
    case BOT_STATE_READ_CBW:
    //----------------------
        // Start the CBW read operation
        pTransfer->bSemaphore = 0;
        bStatus = USB_Read(pUsb,
                           BOT_EPT_BULK_OUT,
                           pCbw,
                           MSD_CBW_SIZE,
                           (Callback_f) BOT_Callback,
                           (void *) pTransfer);

        // Check operation result code
        if (bStatus == USB_STATUS_SUCCESS) {

            // If the command was successful, wait for transfer
            pBot->bState = BOT_STATE_WAIT_CBW;
        }
        break;

    //----------------------
    case BOT_STATE_WAIT_CBW:
    //----------------------
        // Check transfer semaphore
        if (pTransfer->bSemaphore > 0) {

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

            // Check if transfer was successful
            if (pTransfer->bStatus == USB_STATUS_SUCCESS) {

#if !defined(TR_DEBUG_L)
                TRACE_DEBUG_M("\n\r");
#endif

                TRACE_DEBUG_M("------------------------------\n\r");

                // Process received command
                pBot->bState = BOT_STATE_PROCESS_CBW;
            }
            else if (pTransfer->bStatus == USB_STATUS_RESET) {

                TRACE_INFO("I: BOT_StateMachine: Endpoint resetted\n\r");
                pBot->bState = BOT_STATE_READ_CBW;
            }
            else {

                TRACE_WARNING("W: BOT_StateMachine: Failed to read CBW\n\r");
                pBot->bState = BOT_STATE_READ_CBW;
            }
        }
        break;

    //-------------------------
    case BOT_STATE_PROCESS_CBW:
    //-------------------------
        // Check if this is a new command
        if (pCommandState->bState == 0) {

            // Copy the CBW tag
            pCsw->dCSWTag = pCbw->dCBWTag;

            // Check that the CBW is 31 bytes long
            if ((pTransfer->dBytesTransferred != MSD_CBW_SIZE) ||
                (pTransfer->dBytesRemaining != 0)) {

                TRACE_WARNING("W: BOT_StateMachine: Invalid CBW (too short or too long)\n\r");

                // Wait for a reset recovery
                pBot->isWaitResetRecovery = true;

                // Halt the Bulk-IN and Bulk-OUT pipes
                USB_Halt(pUsb, BOT_EPT_BULK_OUT, USB_SET_FEATURE);
                USB_Halt(pUsb, BOT_EPT_BULK_IN, USB_SET_FEATURE);

                pCsw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
                pBot->bState = BOT_STATE_READ_CBW;
            }
            // Check the CBW Signature
            else if (pCbw->dCBWSignature != MSD_CBW_SIGNATURE) {

                TRACE_WARNING("W: MSD_BOTStateMachine: Invalid CBW (Bad signature)\n\r");

                // Wait for a reset recovery
                pBot->isWaitResetRecovery = true;

                // Halt the Bulk-IN and Bulk-OUT pipes
                USB_Halt(pUsb, BOT_EPT_BULK_OUT, USB_SET_FEATURE);
                USB_Halt(pUsb, BOT_EPT_BULK_IN, USB_SET_FEATURE);

                pCsw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
                pBot->bState = BOT_STATE_READ_CBW;
            }
            else {

                // Pre-process command
                BOT_PreProcessCommand(pBot);
            }
        }

        // Process command
        if (pCsw->bCSWStatus == BOT_STATUS_SUCCESS) {

            if (BOT_ProcessCommand(pBot)) {

                // Post-process command if it is finished
                BOT_PostProcessCommand(pBot);
                pBot->bState = BOT_STATE_SEND_CSW;
            }
            TRACE_DEBUG_M("\n\r");
        }

        break;

    //----------------------
    case BOT_STATE_SEND_CSW:
    //----------------------
        // Set signature
        pCsw->dCSWSignature = MSD_CSW_SIGNATURE;

        // Start the CSW write operation
        bStatus = USB_Write(pUsb,
                            BOT_EPT_BULK_IN,
                            pCsw,
                            MSD_CSW_SIZE,
                            (Callback_f) BOT_Callback,
                            (void *) pTransfer);

        // Check operation result code
        if (bStatus == USB_STATUS_SUCCESS) {

            TRACE_DEBUG_M("SendCSW ");

            // Wait for end of transfer
            pBot->bState = BOT_STATE_WAIT_CSW;
        }
        break;

    //----------------------
    case BOT_STATE_WAIT_CSW:
    //----------------------
        // Check transfer semaphore
        if (pTransfer->bSemaphore > 0) {

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

            // Check if transfer was successful
            if (bStatus == USB_STATUS_RESET) {

                TRACE_INFO("I: BOT_StateMachine: Endpoint resetted\n\r");
            }
            else if (bStatus == USB_STATUS_ABORTED) {

                TRACE_WARNING("W: BOT_StateMachine: Failed to send CSW\n\r");
            }
            else {

                TRACE_DEBUG_M("ok");
            }

            // Read new CBW
            pBot->bState = BOT_STATE_READ_CBW;
        }
        break;
    }
}

⌨️ 快捷键说明

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