static void start_dma_transfer(td243fc_rev2_softc_t *sc, jint_t ep_n, juint32_t size) { td243fc_rev2_ep_t *ep = &sc->ep[ep_n]; jbool_t is_in = EP_IS_IN(ep_n); juint32_t xybuf_size = ep->buf_size; WRITE4(TD243FC_DMA_EP_SYSTEM_MEM_ADDR_REG((jint_t)(ep_n / 2), is_in), ep->req ? (juint32_t)ep->req->buffer.dma_addr : (juint32_t)sc->dma_buf.dma_addr); if (ep->req) xybuf_size = MIN(xybuf_size, ep->req->buffer.buffer_size); else xybuf_size = MIN(xybuf_size, sc->dma_buf.buffer_size); TOGGLE_IF_SET(TD243FC_XFILLED_STATUS_REG, TD243FC_EP_BIT_INDEX(ep_n)); TOGGLE_IF_SET(TD243FC_YFILLED_STATUS_REG, TD243FC_EP_BIT_INDEX(ep_n)); TOGGLE_IF_SET(TD243FC_XBUF_INT_STATUS_REG, TD243FC_EP_BIT_INDEX(ep_n)); TOGGLE_IF_SET(TD243FC_YBUF_INT_STATUS_REG, TD243FC_EP_BIT_INDEX(ep_n)); WRITE4(TD243FC_EPN_PACKET_CONTROL_REG((jint_t)(ep_n / 2), is_in), BFSET4(TD243FC_BUFFERSIZE, xybuf_size - 1) | BFSET4(TD243FC_TTLBTECNT, size)); SET4(TD243FC_DMA_EP_ENABLE_REG, TD243FC_EP_BIT_INDEX(ep_n)); if (sc->add_to_list) sc->ep_ready |= TD243FC_EP_BIT_INDEX(ep_n); else WRITE4(TD243FC_EP_READY_REG, TD243FC_EP_BIT_INDEX(ep_n)); }
/* Disable an endpoint */ static jresult_t dcd_disable_ep(jdevice_t dev, pipe_desc_t *pipe) { td243fc_rev2_softc_t *sc = (td243fc_rev2_softc_t *)j_device_get_softc(dev); jint_t ep_n = (jint_t)(pipe->dcd_handle); td243fc_rev2_ep_t *ep = NULL; jbool_t is_in = FALSE; KASSERT(pipe, ("Pipe is NULL\n")); KASSERT(pipe->dcd_handle, ("Pipe was not allocated\n")); /* HSU Addition */ ep = &sc->ep[ep_n]; /* First set value in ep, only then try to ASSERT on ep->pipe */ KASSERT(ep->pipe, ("Pipe was not enabled\n")); /* End of HSU Addition */ is_in = EP_IS_IN(ep_n); DBG_I(DSLAVE_DCD, ("DCD: dcd_disable_ep pipe=%p, buf_size=%d\n", pipe, ep->buf_size)); WRITE4(TD243FC_EPN_CONFIG_CONTROL_REG(ep_n/2, is_in), 0); pipe->status = PIPE_DISABLED; td243fc_mem_free(sc, ep->buf_size * 2); ep->pipe = NULL; return 0; }
int usb_dc_ep_write(const u8_t ep, const u8_t *const data, const u32_t data_len, u32_t * const ret_bytes) { struct usb_dc_stm32_ep_state *ep_state = usb_dc_stm32_get_ep_state(ep); HAL_StatusTypeDef status; u32_t len = data_len; int ret = 0; LOG_DBG("ep 0x%02x, len %u", ep, data_len); if (!ep_state || !EP_IS_IN(ep)) { LOG_ERR("invalid ep 0x%02x", ep); return -EINVAL; } ret = k_sem_take(&ep_state->write_sem, K_NO_WAIT); if (ret) { LOG_ERR("Unable to get write lock (%d)", ret); return -EAGAIN; } if (!k_is_in_isr()) { irq_disable(DT_USB_IRQ); } if (ep == EP0_IN && len > USB_MAX_CTRL_MPS) { len = USB_MAX_CTRL_MPS; } status = HAL_PCD_EP_Transmit(&usb_dc_stm32_state.pcd, ep, (void *)data, len); if (status != HAL_OK) { LOG_ERR("HAL_PCD_EP_Transmit failed(0x%02x), %d", ep, (int)status); k_sem_give(&ep_state->write_sem); ret = -EIO; } if (!ret && ep == EP0_IN && len > 0) { /* Wait for an empty package as from the host. * This also flushes the TX FIFO to the host. */ usb_dc_ep_start_read(ep, NULL, 0); } if (!k_is_in_isr()) { irq_enable(DT_USB_IRQ); } if (ret_bytes) { *ret_bytes = len; } return ret; }
static void start_zero_packet(td243fc_rev2_softc_t *sc, jint_t ep_n) { if (EP_IS_IN(ep_n)) { TOGGLE_IF_NOT_SET(TD243FC_XFILLED_STATUS_REG, TD243FC_EP_BIT_INDEX(ep_n)); } if (sc->add_to_list) sc->ep_ready |= TD243FC_EP_BIT_INDEX(ep_n); else WRITE4(TD243FC_EP_READY_REG, TD243FC_EP_BIT_INDEX(ep_n)); }
static void handle_epn(td243fc_rev2_softc_t *sc, jint_t ep_n) { td243fc_rev2_ep_t *ep = &sc->ep[ep_n]; request_t *req = ep->req; jbool_t is_in = EP_IS_IN(ep_n); DBG_V(DSLAVE_DCD, ("DCD: handle_epn_out_req %d\n", ep_n)); /* Canceled requests handled in abort */ if (req->status == REQUEST_CANCELLED) return; req->bytes_transferred = req->transfer_size - BFGET4(TD243FC_TTLBTECNT, READ4(TD243FC_EPN_PACKET_CONTROL_REG(ep_n/2, is_in))); req_finish(sc, ep_n, req, REQUEST_COMPLETED); }
/* Flag: 0/1-Clear/Set */ static jresult_t dcd_stall_ep(jdevice_t dev, pipe_desc_t *pipe, jbool_t flag) { td243fc_rev2_softc_t *sc = (td243fc_rev2_softc_t *)j_device_get_softc(dev); DBG_V(DSLAVE_DCD, ("DCD: dcd_stall_ep, addr=%02x\n", pipe?pipe->address:0)); if (pipe) { jint_t ep_n = (jint_t)(pipe->dcd_handle); jbool_t is_in = EP_IS_IN(ep_n); ep_n /= 2; KASSERT(pipe->dcd_handle, ("Pipe was not allocated\n")); if (flag) { SET4(TD243FC_EPN_CONFIG_CONTROL_REG(ep_n, is_in), TD243FC_STL); pipe->status = PIPE_STALLLED; } else { TOGGLE_IF_SET(TD243FC_EP_TOGGLE_REG, TD243FC_EP_BIT(ep_n, is_in)); if (pipe->status == PIPE_STALLLED) { CLEAR4(TD243FC_EPN_CONFIG_CONTROL_REG(ep_n, is_in), TD243FC_STL); pipe->status = PIPE_ENABLED; start_next_transfer(sc, (jint_t)(pipe->dcd_handle)); } } } else { if (flag) SET4(TD243FC_EPN_CONFIG_CONTROL_REG(0, 1), TD243FC_STL); else CLEAR4(TD243FC_EPN_CONFIG_CONTROL_REG(0, 1), TD243FC_STL); } return 0; }
/* Enable an endpoint for operation */ static jresult_t dcd_enable_ep(jdevice_t dev, pipe_desc_t *pipe) { td243fc_rev2_softc_t *sc = (td243fc_rev2_softc_t *)j_device_get_softc(dev); jint_t ep_n = (jint_t)(pipe->dcd_handle); td243fc_rev2_ep_t *ep = &sc->ep[ep_n]; jresult_t rc; juint_t type = 0; jbool_t is_in = EP_IS_IN(ep_n); KASSERT(pipe->dcd_handle, ("Pipe was not allocated\n")); KASSERT(!ep->pipe, ("Pipe already enabled\n")); switch (pipe->type) { case PIPE_BULK: type = TD243FC_BULK_EP; break; case PIPE_INTR: type = TD243FC_INTR_EP; break; case PIPE_ISOC: type = TD243FC_ISOC_EP; break; default: rc = JEINVAL; goto Exit; } ep->pipe = pipe; /* alloc buffer */ rc = td243fc_mem_alloc(sc, ep->buf_size, &ep->xaddr); KASSERT(!rc, ("Can't allocate pipe(%p) xbuffer, size=%d\n", pipe, ep->buf_size)); rc = td243fc_mem_alloc(sc, ep->buf_size, &ep->yaddr); KASSERT(!rc, ("Can't allocate pipe(%p) ybuffer, size=%d\n", pipe, ep->buf_size)); DBG_I(DSLAVE_DCD, ("DCD: dcd_enable_ep pipe=%p, buf_size=%d, " "max_packet=%d XY(%04x,%04x)\n", pipe, ep->buf_size, pipe->max_pkt_size_full, ep->xaddr, ep->yaddr)); /* Clear TOGGLE */ TOGGLE_IF_SET(TD243FC_EP_TOGGLE_REG, TD243FC_EP_BIT_INDEX(ep_n)); /* Init ep control registers */ WRITE4(TD243FC_EPN_CONFIG_CONTROL_REG(ep_n/2, is_in), BFSET4(TD243FC_FORMAT, type) | BFSET4(TD243FC_MAXPKTSIZ, pipe->max_pkt_size_full)); WRITE4(TD243FC_EPN_XY_BUFFER_ADDRESS_REG(ep_n/2, is_in), BFSET4(TD243FC_XBSA, TD243FC_GET_IADDR(sc->ep[ep_n].xaddr)) | BFSET4(TD243FC_YBSA, TD243FC_GET_IADDR(sc->ep[ep_n].yaddr))); ENABLE_EP(ep_n/2, is_in); pipe->status = PIPE_ENABLED; Exit: return rc; }