示例#1
0
/**
 * This function handles the Rx Status Queue Level Interrupt, which
 * indicates that there is a least one packet in the Rx FIFO.  The
 * packets are moved from the FIFO to memory, where they will be
 * processed when the Endpoint Interrupt Register indicates Transfer
 * Complete or SETUP Phase Done.
 *
 * Repeat the following until the Rx Status Queue is empty:
 *   -#	Read the Receive Status Pop Register (GRXSTSP) to get Packet
 *     	info
 *   -#	If Receive FIFO is empty then skip to step Clear the interrupt
 *     	and exit
 *   -#	If SETUP Packet call dwc_otg_read_setup_packet to copy the
 *   	SETUP data to the buffer
 *   -#	If OUT Data Packet call dwc_otg_read_packet to copy the data
 *     	to the destination buffer
 */
int32_t dwc_otg_pcd_handle_rx_status_q_level_intr(void)
{
    gintmsk_data_t gintmask = { 0 };
    device_grxsts_data_t status;
    gintsts_data_t gintsts;
    dwc_ep_t *ep;


    DBG("dwc_otg_pcd_handle_rx_status_q_level_intr()\n");
    /* Disable the Rx Status Queue Level interrupt */
    gintmask.b.rxstsqlvl= 1;
    dwc_modify_reg32( DWC_REG_GINTMSK, gintmask.d32, 0);

    /* Get the Status from the top of the FIFO */
    status.d32 = dwc_read_reg32( DWC_REG_GRXSTSP);

    //DBG("rx status: ep%d, pktsts: %d\n",status.b.epnum,status.b.pktsts);

    /* Get pointer to EP structure */
    ep = &g_dwc_eps[status.b.epnum];

    switch (status.b.pktsts)
    {
        case DWC_DSTS_GOUT_NAK:
            DBG( "Global OUT NAK\n");
            break;

        case DWC_STS_DATA_UPDT:
            DBG( "OUT Data Packet\n");
            {
                if (status.b.bcnt && ep->xfer_buff)
                {
                    /** @todo NGS Check for buffer overflow? */
                    dwc_otg_read_packet( ep->xfer_buff,status.b.bcnt);
                    ep->xfer_count += status.b.bcnt;
                    ep->xfer_buff += status.b.bcnt;

                    if (!status.b.epnum)
                    {
                        /*const char* p = ep->xfer_buff - status.b.bcnt;*/
                        this_pcd[0].cmdtype.out_complete = 1;
                        /*
                         *if(!strcmp("power", p) || !strcmp("low_power", p)){
                         *    printf("%s, bcnt %d, cnt %d, %d\n", p, status.b.bcnt, ep->xfer_count, this_pcd.cmdtype.in_complete);
                         *}
                         */
                    }
                }
            }
            break;

        case DWC_STS_XFER_COMP:
            DBG("OUT Complete\n");
            break;

        case DWC_DSTS_SETUP_COMP:
            DBG("SETUP Complete\n");
            break;

        case DWC_DSTS_SETUP_UPDT:
            DBG("SETUP update\n");
            {
                static int _is_first_setup_out_in_cmd = 1;

                dwc_otg_read_setup_packet( this_pcd[0].setup_pkt.d32);
                this_pcd[0].request_enable = 1;
                ep->xfer_count += status.b.bcnt;

                DBG("set %d, %d\n", status.b.bcnt, ep->xfer_count);
                if (_is_first_setup_out_in_cmd) //first tplcmd/bulkcmd that in sequence 'setup + out + in'
                {
                    struct usb_ctrlrequest request = this_pcd[0].setup_pkt.req;
                    if ( USB_TYPE_VENDOR == (request.bRequestType & USB_TYPE_MASK) )
                    {
                        unsigned bRequest = request.bRequest;

                        if ((AM_REQ_WR_LARGE_MEM == bRequest) || (AM_REQ_RD_LARGE_MEM == bRequest)
                                ||(AM_REQ_TPL_CMD == bRequest) || (AM_REQ_TPL_STAT == bRequest)
                                || (AM_REQ_DOWNLOAD == bRequest) || (AM_REQ_BULKCMD == bRequest))
                        {
                            __udelay(20);//delay for first command that consisted of consecutive 'ep0 out', i.e. 'setup + out + in'
                            _is_first_setup_out_in_cmd = 0;
                        }
                    }
                }
            }
        break;

        default:
            //DBG( "Invalid Packet Status (0x%0x)\n", status.b.pktsts);
            break;

    }

    /* Enable the Rx Status Queue Level interrupt */
    dwc_modify_reg32( DWC_REG_GINTMSK, 0, gintmask.d32);
    /* Clear interrupt */
    gintsts.d32 = 0;
    gintsts.b.rxstsqlvl = 1;
    dwc_write_reg32 ( DWC_REG_GINTSTS, gintsts.d32);

    return 1;
}
示例#2
0
/**
 * This function handles the Rx Status Queue Level Interrupt, which
 * indicates that there is a least one packet in the Rx FIFO.  The
 * packets are moved from the FIFO to memory, where they will be
 * processed when the Endpoint Interrupt Register indicates Transfer
 * Complete or SETUP Phase Done.
 *
 * Repeat the following until the Rx Status Queue is empty:
 *   -#	Read the Receive Status Pop Register (GRXSTSP) to get Packet
 *     	info
 *   -#	If Receive FIFO is empty then skip to step Clear the interrupt
 *     	and exit
 *   -#	If SETUP Packet call dwc_otg_read_setup_packet to copy the
 *   	SETUP data to the buffer
 *   -#	If OUT Data Packet call dwc_otg_read_packet to copy the data
 *     	to the destination buffer
 */
int32_t dwc_otg_pcd_handle_rx_status_q_level_intr()
{
	gintmsk_data_t gintmask = { 0 };
	device_grxsts_data_t status;
	gintsts_data_t gintsts;
	dwc_ep_t *ep;

        
        DBG("dwc_otg_pcd_handle_rx_status_q_level_intr()\n");
        /* Disable the Rx Status Queue Level interrupt */
        gintmask.b.rxstsqlvl= 1;
        dwc_modify_reg32( DWC_REG_GINTMSK, gintmask.d32, 0);

        /* Get the Status from the top of the FIFO */
        status.d32 = dwc_read_reg32( DWC_REG_GRXSTSP);

        //DBG("rx status: ep%d, pktsts: %d\n",status.b.epnum,status.b.pktsts);

        /* Get pointer to EP structure */
	if(status.b.epnum == 0)
	{
		ep = &g_dwc_eps[0];
	}		
	else
	{
		ep = &g_dwc_eps[status.b.epnum];
	}
	 
        switch (status.b.pktsts) {
        case DWC_DSTS_GOUT_NAK:
                DBG( "Global OUT NAK\n");
                break;

        case DWC_STS_DATA_UPDT:
                DBG( "OUT Data Packet\n");
                if (status.b.bcnt && ep->xfer_buff){
                        /** @todo NGS Check for buffer overflow? */
                        dwc_otg_read_packet( ep->xfer_buff,status.b.bcnt);
                        ep->xfer_count += status.b.bcnt;
                        ep->xfer_buff += status.b.bcnt;
                }
                break;

        case DWC_STS_XFER_COMP:
                DBG("OUT Complete\n");
                break;

        case DWC_DSTS_SETUP_COMP:
		   DBG("SETUP Complete\n");
                break;

        case DWC_DSTS_SETUP_UPDT:
		   DBG("SETUP update\n");
                dwc_otg_read_setup_packet( this_pcd.setup_pkt.d32);
		   this_pcd.request_enable = 1;

                ep->xfer_count += status.b.bcnt;
                break;

        default:
                //DBG( "Invalid Packet Status (0x%0x)\n", status.b.pktsts);
                break;
                
        }

        /* Enable the Rx Status Queue Level interrupt */
        dwc_modify_reg32( DWC_REG_GINTMSK, 0, gintmask.d32);
	/* Clear interrupt */
	gintsts.d32 = 0;
	gintsts.b.rxstsqlvl = 1;
	dwc_write_reg32 ( DWC_REG_GINTSTS, gintsts.d32);

        return 1;
}