Пример #1
0
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));
}
Пример #2
0
/* 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;
}
Пример #3
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;
}
Пример #4
0
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));
}
Пример #5
0
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);
}
Пример #6
0
/* 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;
}
Пример #7
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;
}