/** * This function completes the request for the 'BULK' EP. If there are * additional requests for the EP in the queue they will be started. */ static void complete_ep( int ep_num,int is_in ) { deptsiz_data_t deptsiz; pcd_struct_t *pcd = &this_pcd[ep_num]; dwc_ep_t *ep = &g_dwc_eps[ep_num]; if (is_in) { pcd->xfer_len = ep->xfer_count;//////////////// deptsiz.d32 = dwc_read_reg32(DWC_REG_IN_EP_TSIZE(ep_num)); if (deptsiz.b.xfersize == 0 && deptsiz.b.pktcnt == 0 && ep->xfer_count == ep->xfer_len) { ep->start_xfer_buff = 0; ep->xfer_buff = 0; ep->xfer_len = 0; } } else {/* OUT Transfer */ deptsiz.d32 = dwc_read_reg32(DWC_REG_OUT_EP_TSIZE(ep_num)); pcd->xfer_len = ep->xfer_count; ep->start_xfer_buff = 0; ep->xfer_buff = 0; ep->xfer_len = 0; } do_bulk_complete(pcd); }
/** * This function configures EP0 to receive SETUP packets. * * @todo NGS: Update the comments from the HW FS. * * -# Program the following fields in the endpoint specific registers * for Control OUT EP 0, in order to receive a setup packet * - DOEPTSIZ0.Packet Count = 3 (To receive up to 3 back to back * setup packets) * - DOEPTSIZE0.Transfer Size = 24 Bytes (To receive up to 3 back * to back setup packets) * - In DMA mode, DOEPDMA0 Register with a memory address to * store any setup packets received * */ static void ep0_out_start(void) { deptsiz0_data_t doeptsize0 = { 0}; depctl_data_t doepctl = { 0 }; doeptsize0.b.supcnt = 3; doeptsize0.b.pktcnt = 1; doeptsize0.b.xfersize = 8*3; DBG("ep0_out_start()\n"); dwc_write_reg32( DWC_REG_OUT_EP_TSIZE(0),doeptsize0.d32 ); // EP enable doepctl.d32 = dwc_read_reg32(DWC_REG_OUT_EP_REG(0)); doepctl.b.epena = 1; doepctl.d32 = 0x80008000; dwc_write_reg32(DWC_REG_OUT_EP_REG(0),doepctl.d32); flush_cpu_cache(); }
static void pcd_setup( pcd_struct_t *_pcd ) { struct usb_ctrlrequest ctrl = _pcd->setup_pkt.req; dwc_ep_t *ep0 = &g_dwc_eps[0]; deptsiz0_data_t doeptsize0 = { 0}; if(_pcd->request_enable == 0) return; // _pcd->setup_pkt.d32[0] = 0; // _pcd->setup_pkt.d32[1] = 0; unsigned short status = 0; _pcd->request_enable = 0; doeptsize0.d32 = dwc_read_reg32( DWC_REG_OUT_EP_TSIZE(0)); if (ctrl.bRequestType & USB_DIR_IN) { ep0->is_in = 1; _pcd->ep0state = EP0_IN_DATA_PHASE; } else { ep0->is_in = 0; _pcd->ep0state = EP0_OUT_DATA_PHASE; } if ((ctrl.bRequestType & USB_TYPE_MASK) != USB_TYPE_STANDARD) { /* handle non-standard (class/vendor) requests in the gadget driver */ //do_gadget_setup(_pcd, &ctrl ); DBG("Vendor requset\n"); do_vendor_request(_pcd, &ctrl ); dwc_otg_ep_req_start(_pcd,0); return; } /** @todo NGS: Handle bad setup packet? */ switch (ctrl.bRequest) { case USB_REQ_GET_STATUS: switch (ctrl.bRequestType & USB_RECIP_MASK) { case USB_RECIP_DEVICE: status = 0x1; /* Self powered */ status |= 0;//_pcd->remote_wakeup_enable << 1; break; } _pcd->buf = (char *)&status; _pcd->length = 2; dwc_otg_ep_req_start(_pcd,0); break; #if 0 case USB_RECIP_INTERFACE: *status = 0; break; case USB_RECIP_ENDPOINT: ep = get_ep_by_addr(_pcd, ctrl.wIndex); if ( ep == 0 || ctrl.wLength > 2) { ep0_do_stall(_pcd, -EOPNOTSUPP); return; } /** @todo check for EP stall */ *status = ep->stopped; break; } _pcd->ep0_pending = 1; ep0->dwc_ep.start_xfer_buff = (uint8_t *)status; ep0->dwc_ep.xfer_buff = (uint8_t *)status; ep0->dwc_ep.dma_addr = _pcd->status_buf_dma_handle; ep0->dwc_ep.xfer_len = 2; ep0->dwc_ep.xfer_count = 0; ep0->dwc_ep.total_len = ep0->dwc_ep.xfer_len; dwc_otg_ep0_start_transfer( GET_CORE_IF(_pcd), &ep0->dwc_ep ); break; case USB_REQ_CLEAR_FEATURE: do_clear_feature( _pcd ); break; case USB_REQ_SET_FEATURE: do_set_feature( _pcd ); break; #endif case USB_REQ_SET_ADDRESS: if (ctrl.bRequestType == USB_RECIP_DEVICE) { dcfg_data_t dcfg = { 0 }; //DBG("Set address: %d\n",ctrl.wValue); dcfg.b.devaddr = ctrl.wValue; dwc_modify_reg32(DWC_REG_DCFG,0, dcfg.d32); do_setup_in_status_phase( _pcd ); return; } break; case USB_REQ_SET_INTERFACE: case USB_REQ_SET_CONFIGURATION: _pcd->request_config = 1; /* Configuration changed */ // do_gadget_setup(_pcd, &ctrl ); // break; default: /* Call the Gadget Driver's setup functions */ do_gadget_setup(_pcd, &ctrl ); dwc_otg_ep_req_start(_pcd,0); break; }