Beispiel #1
0
static int __usb_read_fifo(void *buffer, unsigned int buffer_size)
{
    u32 old_ep_idx = 0;
    u32 fifo = 0;
	u32 transfered = 0;
    u32 left = 0;
    u32 this_len;

	old_ep_idx = USBC_GetActiveEp(sunxi_udc_source.usbc_hd);
	USBC_SelectActiveEp(sunxi_udc_source.usbc_hd, SUNXI_USB_BULK_OUT_EP_INDEX);			//选择当前EP

	fifo = USBC_SelectFIFO(sunxi_udc_source.usbc_hd, SUNXI_USB_BULK_OUT_EP_INDEX);		//选择fifo

	left = buffer_size;

	if(left)
	{
		while(left)
		{
			if(USBC_Dev_IsReadDataReady(sunxi_udc_source.usbc_hd, USBC_EP_TYPE_RX))
			{
				this_len = USBC_ReadLenFromFifo(sunxi_udc_source.usbc_hd, USBC_EP_TYPE_RX);
				this_len = USBC_ReadPacket(sunxi_udc_source.usbc_hd, fifo, this_len, buffer + transfered);

				transfered += this_len;
	        	left -= this_len;

	        	__usb_readcomplete(sunxi_udc_source.usbc_hd, USBC_EP_TYPE_RX, 1);		//返回状态
			}
		}
		USBC_INT_ClearEpPending(sunxi_udc_source.usbc_hd, USBC_EP_TYPE_RX, SUNXI_USB_BULK_OUT_EP_INDEX);
	}
	else
	{
		if(USBC_Dev_IsReadDataReady(sunxi_udc_source.usbc_hd, USBC_EP_TYPE_RX))
		{
			this_len = USBC_ReadLenFromFifo(sunxi_udc_source.usbc_hd, USBC_EP_TYPE_RX);
			this_len = USBC_ReadPacket(sunxi_udc_source.usbc_hd, fifo, this_len, buffer);

			transfered = this_len;
			__usb_readcomplete(sunxi_udc_source.usbc_hd, USBC_EP_TYPE_RX, 1);		//返回状态
		}
		else
		{
			sunxi_usb_dbg("sunxi usb rxdata not ready\n");
		}
	}

	USBC_SelectActiveEp(sunxi_udc_source.usbc_hd, old_ep_idx);

	sunxi_usb_dbg("read bytes 0x%x\n", transfered);

	return transfered;
}
/*
*******************************************************************************
*                     ReadDataStatusComplete
*
* Description:
*    void
*
* Parameters:
*    void
*
* Return value:
*    void
*
* note:
*    void
*
*******************************************************************************
*/
static void ReadDataStatusComplete(__hdle hUSB, u32 ep_type, u32 complete)
{
	USBC_Dev_ReadDataStatus(hUSB, ep_type, complete);

    udelay(2);

    if(ep_type == USBC_EP_TYPE_EP0){
        /* clear data end */
        if(complete){
            USBC_Dev_Ctrl_ClearSetupEnd(hUSB);
        }

        /* clear irq */
        USBC_INT_ClearEpPending(hUSB, USBC_EP_TYPE_TX, 0);
    }

	return;
}
Beispiel #3
0
/*
*******************************************************************************
*                     __usb_readcomplete
*
* Description:
*    void
*
* Parameters:
*    void
*
* Return value:
*    void
*
* note:
*    void
*
*******************************************************************************
*/
static void __usb_readcomplete(__hdle hUSB, u32 ep_type, u32 complete)
{
	USBC_Dev_ReadDataStatus(hUSB, ep_type, complete);

    if(ep_type == USBC_EP_TYPE_EP0)
    {
        /* clear data end */
        if(complete)
        {
            USBC_Dev_Ctrl_ClearSetupEnd(hUSB);
        }

        /* clear irq */
        USBC_INT_ClearEpPending(hUSB, USBC_EP_TYPE_TX, SUNXI_USB_CTRL_EP_INDEX);
    }

	return;
}
/*
*******************************************************************************
*                     WriteDataStatusComplete
*
* Description:
*    void
*
* Parameters:
*    void
*
* Return value:
*    void
*
* note:
*    void
*
*******************************************************************************
*/
static void WriteDataStatusComplete(__hdle hUSB, u32 ep_type, u32 complete)
{
	USBC_Dev_WriteDataStatus(hUSB, ep_type, complete);

    /* wait for tx packet sent out */
	while(USBC_Dev_IsWriteDataReady(hUSB, ep_type)){
        udelay(1);
    }

    if(ep_type == USBC_EP_TYPE_EP0){
        /* clear data end */
        if(complete){
            USBC_Dev_Ctrl_ClearSetupEnd(hUSB);
        }

        /* clear irq */
        USBC_INT_ClearEpPending(hUSB, USBC_EP_TYPE_TX, 0);
    }

	return;
}
Beispiel #5
0
/*
*******************************************************************************
*                     __usb_writecomplete
*
* Description:
*    void
*
* Parameters:
*    void
*
* Return value:
*    void
*
* note:
*    void
*
*******************************************************************************
*/
static void __usb_writecomplete(__hdle hUSB, u32 ep_type, u32 complete)
{
	USBC_Dev_WriteDataStatus(hUSB, ep_type, complete);

	/* wait for tx packet sent out */
	while(USBC_Dev_IsWriteDataReady(hUSB, ep_type));

	if(ep_type == USBC_EP_TYPE_EP0)
    {
        /* clear data end */
        if(complete)
        {
            USBC_Dev_Ctrl_ClearSetupEnd(hUSB);
        }

        /* clear irq */
        USBC_INT_ClearEpPending(hUSB, USBC_EP_TYPE_TX, SUNXI_USB_CTRL_EP_INDEX);
    }

	return;
}
Beispiel #6
0
/*
************************************************************************************************************
*
*                                             function
*
*    name          :
*
*    parmeters     :
*
*    return        :
*
*    note          :
*
*
************************************************************************************************************
*/
void sunxi_usb_irq(void *data)
{
	u8 misc_irq = 0;
	u16 tx_irq = 0;
	u16 rx_irq = 0;
    u32 old_ep_idx  = 0;

    /* Save index */
	old_ep_idx = USBC_GetActiveEp(sunxi_udc_source.usbc_hd);

    /* Read status registers */
	misc_irq = USBC_INT_MiscPending(sunxi_udc_source.usbc_hd);
	tx_irq  = USBC_INT_EpPending(sunxi_udc_source.usbc_hd, USBC_EP_TYPE_TX);
	rx_irq  = USBC_INT_EpPending(sunxi_udc_source.usbc_hd, USBC_EP_TYPE_RX);

	/* RESET */
	if(misc_irq & USBC_INTUSB_RESET)
	{
	    sunxi_usb_dbg("IRQ: reset\n");

	    USBC_INT_ClearMiscPending(sunxi_udc_source.usbc_hd, USBC_INTUSB_RESET);
        __usb_clear_all_irq();

        USBC_SelectActiveEp(sunxi_udc_source.usbc_hd, 0);
		USBC_Dev_SetAddress_default(sunxi_udc_source.usbc_hd);

		sunxi_udc_source.address = 0;					//default value
		sunxi_udc_source.speed = USB_SPEED_HIGH;		//default value

		sunxi_dma_stop(sunxi_udc_source.dma_recv_channal);
		sunxi_dma_stop(sunxi_udc_source.dma_send_channal);

		sunxi_ubuf.rx_ready_for_data = 0;
		sunxi_udev_active->state_reset();

		return ;
    }

	/* RESUME 暂时不处理,仅仅清理中断*/
	if (misc_irq & USBC_INTUSB_RESUME)
	{
		sunxi_usb_dbg("IRQ: resume\n");
		/* clear interrupt */
		USBC_INT_ClearMiscPending(sunxi_udc_source.usbc_hd, USBC_INTUSB_RESUME);
	}

	/* SUSPEND */
	if (misc_irq & USBC_INTUSB_SUSPEND)
	{
		sunxi_usb_dbg("IRQ: suspend\n");
		/* clear interrupt */
		USBC_INT_ClearMiscPending(sunxi_udc_source.usbc_hd, USBC_INTUSB_SUSPEND);
	}

    /* DISCONNECT */
    if(misc_irq & USBC_INTUSB_DISCONNECT)
    {
        sunxi_usb_dbg("IRQ: disconnect\n");

		USBC_INT_ClearMiscPending(sunxi_udc_source.usbc_hd, USBC_INTUSB_DISCONNECT);

        return ;
	}
#if 0
	/* SOF */
	if(misc_irq & USBC_INTUSB_SOF)
	{
	    sunxi_usb_dbg("IRQ: SOF\n");

		USBC_INT_ClearMiscPending(sunxi_udc_source.usbc_hd, USBC_INTUSB_SOF);
	}
#endif
	/* ep0 */
	if (tx_irq & (1 << SUNXI_USB_CTRL_EP_INDEX) )
	{
		sunxi_usb_dbg("IRQ: EP0\n");

		USBC_INT_ClearEpPending(sunxi_udc_source.usbc_hd, USBC_EP_TYPE_TX, SUNXI_USB_CTRL_EP_INDEX);
		//中断内完成ep0处理
		ep0_recv_op();
    }

	/* tx endpoint data transfers */
	if (tx_irq & (1 << SUNXI_USB_BULK_IN_EP_INDEX))
	{
		sunxi_usb_dbg("tx irq occur\n");
		/* Clear the interrupt bit by setting it to 1 */
		USBC_INT_ClearEpPending(sunxi_udc_source.usbc_hd, USBC_EP_TYPE_TX, SUNXI_USB_BULK_IN_EP_INDEX);

		eptx_send_op();
	}
	/* rx endpoint data transfers */
	if (rx_irq & (1 << SUNXI_USB_BULK_OUT_EP_INDEX))
	{
		sunxi_usb_dbg("rx irq occur\n");
		/* Clear the interrupt bit by setting it to 1 */
		USBC_INT_ClearEpPending(sunxi_udc_source.usbc_hd, USBC_EP_TYPE_RX, SUNXI_USB_BULK_OUT_EP_INDEX);

		eprx_recv_op();
	}

    USBC_SelectActiveEp(sunxi_udc_source.usbc_hd, old_ep_idx);

    return ;
}