Exemplo n.º 1
0
/*!
    \brief      data in stage processing
    \param[in]  pudev: pointer to USB device instance
    \param[in]  ep_id: endpoint identifier(0..7)
    \param[out] none
    \retval     USB device operation status
*/
usbd_status_enum usbd_in_transaction (usb_core_handle_struct *pudev, uint8_t endp_num)
{
    usb_ep_struct *ep;

    if (0U == endp_num) {
        ep = &pudev->dev.in_ep[0];

        if (USB_CTRL_DATA_IN == pudev->dev.ctl_status) {
            if (pudev->dev.remain_len > ep->endp_mps) {
                pudev->dev.remain_len -= ep->endp_mps;

                usbd_ep_tx (pudev, 0U, ep->xfer_buff, pudev->dev.remain_len);
                
                usbd_ep_rx (pudev, 0U, NULL, 0U);
            } else {
                /* last packet is MPS multiple, so send ZLP packet */
                if ((pudev->dev.sum_len % ep->endp_mps == 0U) &&
                     (pudev->dev.sum_len >= ep->endp_mps) &&
                      (pudev->dev.sum_len < pudev->dev.ctl_len)) {
                    usbd_ep_tx (pudev, 0U, NULL, 0U);
                    pudev->dev.ctl_len = 0U;
                        
                    usbd_ep_rx (pudev, 0U, NULL, 0U);
                } else {
                    if (USB_STATUS_CONFIGURED == pudev->dev.status) {
                        pudev->dev.class_data_handler(pudev, USB_TX, 0U);
                    }

                    usbd_ctlstatus_rx(pudev);
                }
            }
        }
    } else if (USB_STATUS_CONFIGURED == pudev->dev.status) {
        pudev->dev.class_data_handler(pudev, USB_TX, endp_num);
    } else {
        /* no operation */
    }

    return USBD_OK;
}
Exemplo n.º 2
0
/*!
    \brief      handle the IAP_ERASE request
    \param[in]  pudev: pointer to usb device instance
    \param[out] none
    \retval     none
*/
static void iap_req_erase(void *pudev)
{
    uint32_t i, addr = 0;

    /* get base address to erase */
    base_address  = report_buf[2];
    base_address |= report_buf[3] << 8;
    base_address |= report_buf[4] << 16;
    base_address |= report_buf[5] << 24;

    page_count = report_buf[6];

    /* get file length */
    file_length = report_buf[7];
    file_length |= report_buf[8] << 8;
    file_length |= report_buf[9] << 16;
    file_length |= report_buf[10] << 24;

    if (0 == (file_length % TRANSFER_SIZE)) {
        transfer_times = file_length / TRANSFER_SIZE;
    } else {
        transfer_times = file_length / TRANSFER_SIZE + 1;
    }

    /* check if the address is in protected area */
    if (IS_PROTECTED_AREA(base_address)) {
        return;
    }

    addr = base_address;

    for (i = 0; i < page_count; i ++) {
        /* call the standard flash erase-page function */
        fmc_page_erase(addr);

        addr += PAGE_SIZE;
    }

    device_status[0] = 0x02;
    device_status[1] = 0x01;

    usbd_ep_tx(pudev, IAP_IN_EP, device_status, IAP_IN_PACKET);
}
Exemplo n.º 3
0
/*!
    \brief      send iap report
    \param[in]  pudev: pointer to USB device instance
    \param[in]  report: pointer to HID report
    \param[in]  len: data length
    \param[out] none
    \retval     USB device operation status
*/
uint8_t  iap_report_send (usbd_core_handle_struct *pudev, uint8_t *report, uint16_t len)
{
    usbd_ep_tx (pudev, IAP_IN_EP, report, len);

    return USBD_OK;
}
Exemplo n.º 4
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;
}