Exemplo n.º 1
0
//-----------------------------------------------------------------------------
/// Return halted status
/// \return stallCASE bitmap, case of the stall condition
///         (bit: MSDD_CASE_STALL_OUT or MSDD_CASE_STALL_IN)
//-----------------------------------------------------------------------------
unsigned int MSDD_IsHalted(void)
{
    unsigned int stallCASE = 0;
    if (USBD_IsHalted(MSDDriverDescriptors_BULKOUT)) {

        stallCASE |= MSDD_CASE_STALL_OUT;
    }
    if (USBD_IsHalted(MSDDriverDescriptors_BULKIN)) {

        stallCASE |= MSDD_CASE_STALL_IN;
    }
    return stallCASE;
}
Exemplo n.º 2
0
//------------------------------------------------------------------------------
/// Sends the current status of an endpoints to the USB host.
/// \param bEndpoint  Endpoint number.
//------------------------------------------------------------------------------
static void GetEndpointStatus(unsigned char bEndpoint)
{
    unsigned short data = 0;

    // Check if the endpoint exists
    if (bEndpoint > BOARD_USB_NUMENDPOINTS) {

        USBD_Stall(0);
    }
    else {

        // Check if the endpoint if currently halted
        if (USBD_IsHalted(bEndpoint)) {

            data = 1;
        }
        
        // Send the endpoint status
        USBD_Write(0, &data, 2, 0, 0);
    }
}
Exemplo n.º 3
0
/**
 * Handles HID-specific SETUP request sent by the host.
 * \param request Pointer to a USBGenericRequest instance
 */
void HIDDTransferDriver_RequestHandler(const USBGenericRequest *request)
{
    HIDDTransferDriver *pDrv = &hiddTransferDriver;
    HIDDFunction *pHidd = &pDrv->hidFunction;

    TRACE_INFO("NewReq ");

    /* Check if this is a standard request */
    if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) {

        /* This is a standard request */
        switch (USBGenericRequest_GetRequest(request)) {

        case USBGenericRequest_GETDESCRIPTOR:
            /* Check if this is a HID descriptor, otherwise forward it to
               the standard driver */
            if (!HIDDTransferDriver_GetDescriptor(
                    USBGetDescriptorRequest_GetDescriptorType(request),
                    USBGenericRequest_GetLength(request))) {

                USBDDriver_RequestHandler(pHidd->pUsbd,
                                          request);
            }
            return; /* Handled, no need to do others */

        case USBGenericRequest_CLEARFEATURE:

            /* Check which is the requested feature */
            switch (USBFeatureRequest_GetFeatureSelector(request)) {
                case USBFeatureRequest_ENDPOINTHALT:
                {   uint8_t ep =
                        USBGenericRequest_GetEndpointNumber(request);
                        if (USBD_IsHalted(ep)) {
                            /* Unhalt endpoint restart OUT EP
                             */
                            USBD_Unhalt(ep);
                            if (ep == pHidd->bPipeOUT) {
                                HIDDFunction_StartPollingOutputs(pHidd);
                            }
                        }
                        /* and send a zero-length packet */
                        USBD_Write(0, 0, 0, 0, 0);
                    return; /* Handled, no need to do others */
                }
            }
            break;

        }
    }
    /* We use different buffer for SetReport */
    else if (USBGenericRequest_GetType(request) == USBGenericRequest_CLASS) {

        switch (USBGenericRequest_GetRequest(request)) {

        case HIDGenericRequest_SETREPORT:
            {
                uint16_t length = USBGenericRequest_GetLength(request);
                uint8_t  type = HIDReportRequest_GetReportType(request);
                if (type == HIDReportRequest_OUTPUT) {
                    if (length > HIDDTransferDriver_REPORTSIZE)
                        length = HIDDTransferDriver_REPORTSIZE;
                    USBD_Read(0,
                              pDrv->iReportBuf,
                              length,
                              HIDDTransferDriver_ReportReceived,
                              0); /* No argument to the callback function */
                }
                else {

                    USBD_Stall(0);
                }
            }
            return; /* Handled, no need do others */
        }
    }
    

    /* Process HID requests */
    if (USBRC_SUCCESS == HIDDFunction_RequestHandler(pHidd,
                                                     request)) {
        return;
    }
    else
        USBDDriver_RequestHandler(pHidd->pUsbd, request);
}
Exemplo n.º 4
0
/**
 * 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;
    #if 1
        status = USBD_Read(commandState->pipeOUT,
                           cbw,
                           MSD_CBW_SIZE,
                           (TransferCallback) MSDDriver_Callback,
                           (void *) transfer);
    #else
        status = MSDD_Read(cbw,
                           MSD_CBW_SIZE,
                           (TransferCallback) MSDDriver_Callback,
                           (void *) transfer);
    #endif

        /* 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------------------------------\n\r");

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

                TRACE_INFO("MSDD_StateMachine: EP 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 (len %d)\n\r",
                    (int)transfer->transferred);

                /* 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);
                USBD_Halt(commandState->pipeIN);
                USBD_Halt(commandState->pipeOUT);

                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);
                USBD_Halt(commandState->pipeIN);
                USBD_Halt(commandState->pipeOUT);

                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 */
                if (MSDD_PostProcessCommand(pMsdDriver)) {

                    TRACE_INFO_WP("WaitHALT ");
                    pMsdDriver->state = MSDD_STATE_WAIT_HALT;
                }
                else {

                    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 */
      #if 1
        status = USBD_Write(commandState->pipeIN,
                            csw,
                            MSD_CSW_SIZE,
                            (TransferCallback) MSDDriver_Callback,
                            (void *) transfer);
      #else
        status = MSDD_Write(csw,
                            MSD_CSW_SIZE,
                            (TransferCallback) MSDDriver_Callback,
                            (void *) transfer);
      #endif

        /* 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: EP 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;

    /*---------------------- */
    case MSDD_STATE_WAIT_HALT:
    /*---------------------- */
        //if (MSDD_IsHalted() == 0) {
        if (!USBD_IsHalted(commandState->pipeIN)) {

            pMsdDriver->state = MSDD_STATE_SEND_CSW;
        }
        break;
    }
}