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

📄 msddstatemachine.c

📁 Include startup files and peripherial devices Code for Atmel ARM7 development
💻 C
📖 第 1 页 / 共 2 页
字号:
        TRACE_WARNING(
            "MSDD_ProcessCommand: Requested LUN does not exist\n\r");
        status = MSDD_STATUS_ERROR;
    }
    else {

        // Process command
        if (pMsdDriver->maxLun > 0) {

            TRACE_INFO_WP("LUN%d ", cbw->bCBWLUN);
        }

        status = SBC_ProcessCommand(lun, commandState);
    }

    // Check command result code
    if (status == MSDD_STATUS_PARAMETER) {

        TRACE_WARNING(
            "MSDD_ProcessCommand: Unknown command 0x%02X\n\r",
            cbw->pCommand[0]);

        // Update sense data
        SBC_UpdateSenseData(&(lun->requestSenseData),
                            SBC_SENSE_KEY_ILLEGAL_REQUEST,
                            SBC_ASC_INVALID_FIELD_IN_CDB,
                            0);

        // Result codes
        csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
        isCommandComplete = 1;

        // stall the request, IN or OUT
        if (((cbw->bmCBWFlags & MSD_CBW_DEVICE_TO_HOST) == 0)
            && (cbw->dCBWDataTransferLength > 0)) {

            // Stall the OUT endpoint : host to device
            MSDD_Halt(MSDD_CASE_STALL_OUT);
            TRACE_INFO_WP("StaOUT ");
        }
        else {

            // Stall the IN endpoint : device to host
            MSDD_Halt(MSDD_CASE_STALL_IN);
            TRACE_INFO_WP("StaIN ");
        }
    }
    else if (status == MSDD_STATUS_ERROR) {

        TRACE_WARNING("MSD_ProcessCommand: Command failed\n\r");

        // Update sense data
// TODO (jjoannic#1#): Change code
        SBC_UpdateSenseData(&(lun->requestSenseData),
                            SBC_SENSE_KEY_MEDIUM_ERROR,
                            SBC_ASC_INVALID_FIELD_IN_CDB,
                            0);

        // Result codes
        csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
        isCommandComplete = 1;
    }
    else {

        // Update sense data
        SBC_UpdateSenseData(&(lun->requestSenseData),
                            SBC_SENSE_KEY_NO_SENSE,
                            0,
                            0);

        // Is command complete ?
        if (status == MSDD_STATUS_SUCCESS) {

            isCommandComplete = 1;
        }
    }

    // Check if command has been completed
    if (isCommandComplete) {

        TRACE_INFO_WP("Cplt ");

        // Adjust data residue
        if (commandState->length != 0) {

            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
                MSDD_Halt(MSDD_CASE_STALL_OUT);
                TRACE_INFO_WP("StaOUT ");
            }
            else {

                // Stall the IN endpoint : device to host
                MSDD_Halt(MSDD_CASE_STALL_IN);
                TRACE_INFO_WP("StaIN ");
            }
        }

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

    return isCommandComplete;
}

//-----------------------------------------------------------------------------
/// State machine for the MSD %device driver
/// \param  pMsdDriver Pointer to a MSDDriver instance
//-----------------------------------------------------------------------------
void MSDD_StateMachine(MSDDriver * pMsdDriver)
{
    MSDCommandState *commandState = &(pMsdDriver->commandState);
    MSCbw           *cbw = &(commandState->cbw);
    MSCsw           *csw = &(commandState->csw);
    MSDTransfer     *transfer = &(commandState->transfer);
    unsigned char   status;

    // Identify current driver state
    switch (pMsdDriver->state) {
    //----------------------
    case MSDD_STATE_READ_CBW:
    //----------------------
        // Start the CBW read operation
        transfer->semaphore = 0;
        status = MSDD_Read(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
            pMsdDriver->state = MSDD_STATE_WAIT_CBW;
        }
        break;

    //----------------------
    case MSDD_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_INFO_WP("------------------------------\n\r");

                // Process received command
                pMsdDriver->state = MSDD_STATE_PROCESS_CBW;
            }
            else if (transfer->status == USBD_STATUS_RESET) {

                TRACE_INFO("MSDD_StateMachine: Endpoint resetted\n\r");
                pMsdDriver->state = MSDD_STATE_READ_CBW;
            }
            else {

                TRACE_WARNING(
                    "MSDD_StateMachine: Failed to read CBW\n\r");
                pMsdDriver->state = MSDD_STATE_READ_CBW;
            }
        }
        break;

    //-------------------------
    case MSDD_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_WARNING(
                    "MSDD_StateMachine: Invalid CBW (Bad Length)\n\r");

                // Wait for a reset recovery
                pMsdDriver->waitResetRecovery = 1;

                // Halt the Bulk-IN and Bulk-OUT pipes
                MSDD_Halt(MSDD_CASE_STALL_OUT | MSDD_CASE_STALL_IN);

                csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
                pMsdDriver->state = MSDD_STATE_READ_CBW;

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

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

                // Wait for a reset recovery
                pMsdDriver->waitResetRecovery = 1;

                // Halt the Bulk-IN and Bulk-OUT pipes
                MSDD_Halt(MSDD_CASE_STALL_OUT | MSDD_CASE_STALL_IN);

                csw->bCSWStatus = MSD_CSW_COMMAND_FAILED;
                pMsdDriver->state = MSDD_STATE_READ_CBW;
            }
            else {

                // Pre-process command
                MSDD_PreProcessCommand(pMsdDriver);
            }
        }

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

            if (MSDD_ProcessCommand(pMsdDriver)) {

                // Post-process command if it is finished
                MSDD_PostProcessCommand(pMsdDriver);
                pMsdDriver->state = MSDD_STATE_SEND_CSW;
            }
            TRACE_INFO_WP("\n\r");
        }

        break;

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

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

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

            TRACE_INFO_WP("SendCSW ");

            // Wait for end of transfer
            pMsdDriver->state = MSDD_STATE_WAIT_CSW;
        }
        break;

    //----------------------
    case MSDD_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_INFO("MSDD_StateMachine: Endpoint resetted\n\r");
            }
            else if (transfer->status == USBD_STATUS_ABORTED) {

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

                TRACE_INFO_WP("ok");
            }

            // Read new CBW
            pMsdDriver->state = MSDD_STATE_READ_CBW;
        }
        break;
    }
}

⌨️ 快捷键说明

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