Example #1
0
/*!
    \brief      handle USB device class request
    \param[in]  pudev: pointer to USB device instance
    \param[in]  req: pointer to USB device class request
    \param[out] none
    \retval     USB device operation status
*/
static usbd_status_enum  usbd_device_class_request (usb_core_handle_struct *pudev, usb_device_req_struct *req)
{
    usbd_status_enum ret = USBD_OK;

    switch (pudev->dev.status) {
        case USB_STATUS_CONFIGURED:
            if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) {
                ret = (usbd_status_enum)(pudev->dev.class_req_handler(pudev, req));

                if ((0U == req->wLength) && (USBD_OK == ret)) {
                    /* no data stage */
                    usbd_ctlstatus_tx(pudev);
                }
            } else {
                usbd_enum_error(pudev, req);
            }
            break;

        default:
            usbd_enum_error(pudev, req);
            break;
    }

    return ret;
}
Example #2
0
/*!
    \brief      handle USB Get_Descriptor request
    \param[in]  pudev: pointer to USB device instance
    \param[in]  req: pointer to USB device request
    \param[out] none
    \retval     none
*/
static void  usbd_getdescriptor (usb_core_handle_struct *pudev, usb_device_req_struct *req)
{
    if (USB_REQTYPE_DEVICE == (req->bmRequestType & USB_REQTYPE_MASK)) {
        uint8_t desc_index = (uint8_t)(req->wValue >> 8U);

        if (desc_index <= 0x03U) {
            uint16_t len;
            uint8_t *pbuf;

            /* call corresponding descriptor get function */
            pbuf = standard_descriptor_get[desc_index - 1U](pudev, (uint8_t)(req->wValue) & 0xFFU, &len);

            if ((0U != len) && (0U != req->wLength)) {
                len = USB_MIN(len, req->wLength);

                if ((1U == desc_index) && (64U == req->wLength)) {
                    len = 8U;
                }

                usbd_ctltx(pudev, pbuf, len);
            }
        } else {
            usbd_enum_error(pudev, req);
        }
    } else if (USB_REQTYPE_INTERFACE == (req->bmRequestType & USB_REQTYPE_MASK)) {
Example #3
0
/*!
    \brief      handle USB Set_Address request
    \param[in]  pudev: pointer to USB device instance
    \param[in]  req: pointer to USB device request
    \param[out] none
    \retval     none
*/
static void  usbd_setaddress (usb_core_handle_struct *pudev, usb_device_req_struct *req)
{
    uint8_t DevAddr;

    if ((0U == req->wIndex) && (0U == req->wLength)) {
        DevAddr = (uint8_t)(req->wValue) & 0x7FU;

        if (USB_STATUS_CONFIGURED == pudev->dev.status) {
            usbd_enum_error(pudev, req);
        } else {
            USB_SET_DEVADDR((uint32_t)DevAddr);

            usbd_ctlstatus_tx(pudev);

            if (0U != DevAddr) {
                pudev->dev.status = USB_STATUS_ADDRESSED;
            } else {
                pudev->dev.status = USB_STATUS_DEFAULT;
            }
        }
    } else {
        usbd_enum_error(pudev, req);
    }
}
Example #4
0
/*!
    \brief      handle data stage
    \param[in]  pudev: pointer to USB device instance
    \param[in]  rx_tx: data transfer direction:
      \arg        USBD_TX
      \arg        USBD_RX
    \param[in]  ep_id: endpoint identifier
    \param[out] none
    \retval     USB device operation status
*/
usbd_status_enum  iap_data_handler (void *pudev, usbd_dir_enum rx_tx, uint8_t ep_id)
{
    if((USBD_TX == rx_tx) && ((IAP_IN_EP & 0x7F) == ep_id)) {
        return USBD_OK;
    } else if ((USBD_RX == rx_tx) && (IAP_OUT_EP == ep_id)) {
        switch (report_buf[0]) {
        case 0x01:
            switch(report_buf[1]) {
            case IAP_DNLOAD:
                iap_req_dnload(pudev);
                break;
            case IAP_ERASE:
                iap_req_erase(pudev);
                break;
            case IAP_OPTION_BYTE:
                iap_req_optionbyte(pudev);
                break;
            case IAP_LEAVE:
                iap_req_leave(pudev);
                break;
            case IAP_GETBIN_ADDRESS:
                iap_address_send(pudev);
                break;
            default:
                usbd_enum_error(pudev, NULL);
                return USBD_FAIL;
            }
            break;
        default:
            break;
        }

        usbd_ep_rx(pudev, IAP_OUT_EP, report_buf, IAP_OUT_PACKET);

        return USBD_OK;
    }

    return USBD_FAIL;
}
Example #5
0
/*!
    \brief      handle the HID class-specific requests
    \param[in]  pudev: pointer to USB device instance
    \param[in]  req: device class-specific request
    \param[out] none
    \retval     USB device operation status
*/
usbd_status_enum iap_req_handler (void *pudev, usb_device_req_struct *req)
{
    uint16_t len = 0;
    uint8_t *pbuf = NULL;
    uint8_t USBD_CUSTOMHID_Report_LENGTH = 0;

    switch (req->bmRequestType & USB_REQ_MASK) {
    case USB_CLASS_REQ:
        switch (req->bRequest) {
        case GET_REPORT:
            /* no use for this driver */
            break;
        case GET_IDLE:
            usbd_ep_tx (pudev, EP0_IN, (uint8_t *)&usbd_customhid_idlestate, 1);
            break;
        case GET_PROTOCOL:
            usbd_ep_tx (pudev, EP0_IN, (uint8_t *)&usbd_customhid_protocol, 1);
            break;
        case SET_REPORT:
            flag = 1;
            usbd_customhid_report_id = (uint8_t)(req->wValue);
            USBD_CUSTOMHID_Report_LENGTH = (uint8_t)(req->wLength);
            usbd_ep_rx (pudev, EP0_OUT, report_buf, USBD_CUSTOMHID_Report_LENGTH);
            break;
        case SET_IDLE:
            usbd_customhid_idlestate = (uint8_t)(req->wValue >> 8);
            break;
        case SET_PROTOCOL:
            usbd_customhid_protocol = (uint8_t)(req->wValue);
            break;
        default:
            usbd_enum_error (pudev, req);
            return USBD_FAIL; 
            }
            break;
    case USB_STANDARD_REQ:
        /* standard device request */
        switch(req->bRequest) {
        case USBREQ_GET_DESCRIPTOR:
            switch(req->wValue >> 8) {
            case HID_REPORT_DESCTYPE:
                len = MIN(IAP_REPORT_DESC_SIZE, req->wLength);
                pbuf = (uint8_t *)iap_report_descriptor;
                break;
            case HID_DESCTYPE:
                len = MIN(IAP_CONFIG_DESC_SIZE, req->wLength);
                pbuf = (uint8_t *)(&(configuration_descriptor.HID_VendorHID));
                break;
            default:
                break;
            }
            usbd_ep_tx (pudev, EP0_IN, pbuf, len);
            break;
        case USBREQ_GET_INTERFACE:
            usbd_ep_tx (pudev, EP0_IN, (uint8_t *)&usbd_customhid_altset, 1);
            break;
        case USBREQ_SET_INTERFACE:
            usbd_customhid_altset = (uint8_t)(req->wValue);
            break;
        default:
            break;
        }
        break;
    }

    return USBD_OK;
}
Example #6
0
/*!
    \brief      handle USB Set_Feature request
    \param[in]  pudev: pointer to USB device instance
    \param[in]  req: pointer to USB device request
    \param[out] none
    \retval     none
*/
static void  usbd_setfeature (usb_core_handle_struct *pudev, usb_device_req_struct *req)
{
    uint8_t ep_addr = 0U;
    __IO uint32_t DctlrStatus;

    switch (req->bmRequestType & USB_REQ_MASK) {
        case USB_REQTYPE_DEVICE:
            switch (pudev->dev.status) {
                case USB_STATUS_ADDRESSED:
                case USB_STATUS_CONFIGURED:
                    if (USB_FEATURE_REMOTE_WAKEUP == req->wValue) {
                        pudev->dev.remote_wakeup = 1U;
                        pudev->dev.class_req_handler(pudev, req);

                        usbd_ctlstatus_tx(pudev);
                    } else if ((req->wValue == USB_FEATURE_TEST_MODE) && 
                                (0U == (req->wIndex & 0xFFU))) {
                        DctlrStatus = USB_DCTL;

                        usbd_ctlstatus_tx(pudev);
                    } else {
                        /* no operation */
                    }
                    break;
                default:
                    break;
            }
            break;
        case USB_REQTYPE_INTERFACE:
            switch (pudev->dev.status) {
                case USB_STATUS_ADDRESSED:
                    usbd_enum_error(pudev, req);
                    break;
                case USB_STATUS_CONFIGURED:
                    if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) {
                        /* no operation */
                    } else {
                        usbd_enum_error(pudev, req);
                    }
                    break;
                default:
                    break;
            }
            break;
        case USB_REQTYPE_ENDPOINT:
            switch (pudev->dev.status) {
                case USB_STATUS_ADDRESSED:
                    if (IS_NOT_EP0(ep_addr)) {
                        usbd_ep_stall(pudev, ep_addr);
                    }
                    break;
                case USB_STATUS_CONFIGURED:
                    if (USB_FEATURE_ENDP_HALT == req->wValue) {
                        if (IS_NOT_EP0(ep_addr)) {
                            usbd_ep_stall(pudev, ep_addr);
                        }
                    }
                    pudev->dev.class_req_handler(pudev, req);

                    usbd_ctlstatus_tx(pudev);
                    break;
                default:
                    break;
            }
            break;
        default:
            usbd_enum_error(pudev, req);
            break;
    }
}
Example #7
0
/*!
    \brief      handle USB Clear_Feature request
    \param[in]  pudev: pointer to USB device instance
    \param[in]  req: USB device request
    \param[out] none
    \retval     none
*/
static void  usbd_clrfeature (usb_core_handle_struct *pudev, usb_device_req_struct *req)
{
    uint8_t ep_addr = 0U;

    switch (req->bmRequestType & USB_REQTYPE_MASK) {
        case USB_REQTYPE_DEVICE:
            switch (pudev->dev.status) {
                case USB_STATUS_ADDRESSED:
                case USB_STATUS_CONFIGURED:
                    if (USB_FEATURE_REMOTE_WAKEUP == req->wValue) {
                        pudev->dev.remote_wakeup = 0U;
                        pudev->dev.class_req_handler(pudev, req);

                        usbd_ctlstatus_tx(pudev);
                    }
                    break;

                default:
                    usbd_enum_error(pudev, req);
                    break;
            }
            break;
        case USB_REQTYPE_INTERFACE:
            switch (pudev->dev.status) {
                case USB_STATUS_ADDRESSED:
                    usbd_enum_error(pudev, req);
                    break;
                case USB_STATUS_CONFIGURED:
                    if (LOWBYTE(req->wIndex) <= USBD_ITF_MAX_NUM) {
                        /* no operation */
                    } else {
                        usbd_enum_error(pudev, req);
                    }
                    break;
                default:
                    break;
            }
            break;
        case USB_REQTYPE_ENDPOINT:
            ep_addr = LOWBYTE(req->wIndex);

            switch (pudev->dev.status) {
                case USB_STATUS_ADDRESSED:
                    if (IS_NOT_EP0(ep_addr)) {
                        usbd_ep_stall(pudev, ep_addr);
                    }
                    break;
                case USB_STATUS_CONFIGURED:
                    if (USB_FEATURE_ENDP_HALT == req->wValue) {
                        if (IS_NOT_EP0(ep_addr)) {
                            usbd_ep_clear_stall(pudev, ep_addr);

                            pudev->dev.class_req_handler(pudev, req);
                        }
                    }
                    usbd_ctlstatus_tx(pudev);
                    break;
                default:
                    break;
            }
            break;
        default:
            usbd_enum_error(pudev, req);
            break;
    }
}