⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dwc_otg_pcd_intr.c

📁 host usb 主设备程序 支持sd卡 mouse keyboard 的最单单的驱动程序 gcc编译
💻 C
📖 第 1 页 / 共 5 页
字号:
			iso_packet = _ep->iso_req->iso_packet_desc1;		}		dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * dwc_ep->proc_buf_num;		sts.b.bs = BS_HOST_READY;//0		sts.b.rxsts = 0;		sts.b.l = 0;		sts.b.sp = 0;		sts.b.ioc = 0;		sts.b.pid = 0;		sts.b.framenum = 0;		stsTmp.d32 = readl(&dma_desc->status);		_ep->iso_req->start_frame = stsTmp.b.framenum;		for(i = 0; i < dwc_ep->desc_cnt - dwc_ep->pkt_per_frm; i+= dwc_ep->pkt_per_frm)		{			for(j = 0; j < dwc_ep->pkt_per_frm; ++j)			{				stsTmp.d32 = readl(&dma_desc->status);				/* Write status in iso_packet_decsriptor  */				iso_packet->status = stsTmp.b.rxsts + (stsTmp.b.bs^BS_DMA_DONE);				if(iso_packet->status)				{					iso_packet->status = -ENODATA;				}				/* Received data length */				iso_packet->actual_length = dwc_ep->data_per_frame - stsTmp.b.rxbytes;				data_per_desc = ( (j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?					dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;				sts.b.rxbytes = data_per_desc;				if(stsTmp.b.bs != BS_DMA_BUSY)				{					writel((uint32_t)dma_ad, &dma_desc->buf);					writel(sts.d32, &dma_desc->status);				}				dma_desc ++;				(uint32_t)dma_ad += data_per_desc;				++iso_packet;			}		}		for(j = 0; j < dwc_ep->pkt_per_frm - 1; ++j)		{			stsTmp.d32 = readl(&dma_desc->status);			/* Write status in iso_packet_decsriptor  */			iso_packet->status = stsTmp.b.rxsts + (stsTmp.b.bs^BS_DMA_DONE);			if(iso_packet->status)			{				iso_packet->status = -ENODATA;			}			/* Received data length */			iso_packet->actual_length = dwc_ep->data_per_frame - stsTmp.b.rxbytes;			data_per_desc = ( (j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?				dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;			sts.b.rxbytes = data_per_desc;			if(stsTmp.b.bs != BS_DMA_BUSY)			{				writel((uint32_t)dma_ad, &dma_desc->buf);				writel(sts.d32, &dma_desc->status);			}			++iso_packet;			dma_desc++;			(uint32_t)dma_ad += data_per_desc;		}		sts.b.ioc = 1;		sts.b.l = dwc_ep->proc_buf_num;		stsTmp.d32 = readl(&dma_desc->status);		while(stsTmp.b.bs == BS_DMA_BUSY)		{			stsTmp.d32 = readl(&dma_desc->status);		}		data_per_desc = ( (j + 1) * dwc_ep->maxpacket > dwc_ep->data_per_frame) ?			dwc_ep->data_per_frame - j * dwc_ep->maxpacket : dwc_ep->maxpacket;		sts.b.rxbytes = data_per_desc;		writel((uint32_t)dma_ad, &dma_desc->buf);		writel(sts.d32, &dma_desc->status);		/* Write status in iso_packet_decsriptor  */		iso_packet->status = stsTmp.b.rxsts + (stsTmp.b.bs^BS_DMA_DONE);		if(iso_packet->status)		{			iso_packet->status = -ENODATA;		}		/* Received data length */		iso_packet->actual_length = dwc_ep->data_per_frame - stsTmp.b.rxbytes;		dwc_ep->proc_buf_num ^= 0x1;	}	else /** ISO IN EP */	{		iso_in_sts_data_t sts = { .d32 =0 };		iso_in_sts_data_t stsTmp = {.d32 = 0};		struct usb_gadget_iso_packet_descriptor *iso_packet;		if(dwc_ep->proc_buf_num == 0)		{			/** Buffer 0 descriptors setup */			dma_ad = dwc_ep->dma_addr0;			iso_packet = _ep->iso_req->iso_packet_desc0;		}		else		{			/** Buffer 1 descriptors setup */			dma_ad = dwc_ep->dma_addr1;			iso_packet = _ep->iso_req->iso_packet_desc1;		}		dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * dwc_ep->proc_buf_num;		sts.b.bs = BS_HOST_READY;		sts.b.txsts = 0;		sts.b.sp = 0;//(dwc_ep->data_per_frame % dwc_ep->maxpacket)? 1 : 0;		sts.b.ioc = 0;		sts.b.pid = dwc_ep->pkt_per_frm;		sts.b.framenum = dwc_ep->next_frame;		sts.b.txbytes = dwc_ep->data_per_frame;		sts.b.l = 0;		for(i = 0; i < dwc_ep->desc_cnt - 1; i++)		{			stsTmp.d32 = readl(&dma_desc->status);			/* Write status in iso packet descriptor */			iso_packet->status = stsTmp.b.txsts + (stsTmp.b.bs^BS_DMA_DONE);			if(iso_packet->status != 0)			{				iso_packet->status = -ENODATA;			}			/* Bytes has been transfered */			iso_packet->actual_length = dwc_ep->data_per_frame - stsTmp.b.txbytes;			if(stsTmp.b.bs  != BS_DMA_BUSY){				writel((uint32_t)dma_ad, &dma_desc->buf);				writel(sts.d32, &dma_desc->status);			}			dma_desc ++;			(uint32_t)dma_ad += dwc_ep->data_per_frame;			sts.b.framenum  += dwc_ep->bInterval;			++iso_packet;		}		sts.b.ioc = 1;		sts.b.l = dwc_ep->proc_buf_num;		stsTmp.d32 = readl(&dma_desc->status);		while(stsTmp.b.bs == BS_DMA_BUSY)		{			DWC_PRINT("last busy\n");			stsTmp.d32 = readl(&dma_desc->status);		}		/* Write status in iso packet descriptor ??? do be done with ERROR codes*/		iso_packet->status = stsTmp.b.txsts + (stsTmp.b.bs^BS_DMA_DONE);		if(iso_packet->status != 0)		{			iso_packet->status = -ENODATA;		}		/* Bytes has been transfered */		iso_packet->actual_length = dwc_ep->data_per_frame - stsTmp.b.txbytes;		writel((uint32_t)dma_ad, &dma_desc->buf);		writel(sts.d32, &dma_desc->status);		dwc_ep->next_frame = sts.b.framenum + dwc_ep->bInterval * 1;		dwc_ep->proc_buf_num ^= 1;	}	/** Call callback function to process data buffer */	_ep->iso_req->status = 0;/* success */	_ep->iso_req->process_buffer(&_ep->ep, _ep->iso_req);}static void dwc_otg_pcd_handle_iso_bna(dwc_otg_pcd_ep_t *_ep){	dwc_ep_t		*dwc_ep = &_ep->dwc_ep;	volatile uint32_t	*addr;	depctl_data_t		depctl = {.d32 = 0};	dwc_otg_pcd_t		*pcd = _ep->pcd;	dwc_otg_iso_dma_desc_t	*dma_desc;	dma_desc = dwc_ep->iso_desc_addr + dwc_ep->desc_cnt * (dwc_ep->proc_buf_num);	make_descriptors_host_ready(dma_desc,dwc_ep->desc_cnt,dwc_ep->is_in);	if(dwc_ep->is_in == 0){		addr = &GET_CORE_IF(pcd)->dev_if->out_ep_regs[dwc_ep->num]->doepctl;	}else{		addr = &GET_CORE_IF(pcd)->dev_if->in_ep_regs[dwc_ep->num]->diepctl;	}	depctl.b.epena = 1;	dwc_modify_reg32(addr,depctl.d32,depctl.d32);}#endif  //_EN_ISOC_/** * This function handles EP0 Control transfers. * * The state of the control tranfers are tracked in * <code>ep0state</code>. */static void handle_ep0( dwc_otg_pcd_t *_pcd ){	dwc_otg_core_if_t *core_if = GET_CORE_IF(_pcd);	dwc_otg_pcd_ep_t *ep0 = &_pcd->ep0;	desc_sts_data_t desc_sts;	deptsiz0_data_t deptsiz;	uint32_t byte_count;#ifdef DEBUG_EP0	DWC_DEBUGPL(DBG_PCDV, "%s()\n", __func__);	print_ep0_state(_pcd);#endif//	DWC_PRINT("HANDLE EP0\n");	switch (_pcd->ep0state)	{	case EP0_DISCONNECT:		break;	case EP0_IDLE:		_pcd->request_config = 0;		pcd_setup( _pcd );		break;	case EP0_IN_DATA_PHASE:#ifdef DEBUG_EP0		DWC_DEBUGPL(DBG_PCD, "DATA_IN EP%d-%s: type=%d, mps=%d\n",						ep0->dwc_ep.num, (ep0->dwc_ep.is_in ?"IN":"OUT"),						ep0->dwc_ep.type, ep0->dwc_ep.maxpacket );#endif		if (core_if->dma_enable != 0)		{			if(core_if->dma_desc_enable == 0)			{				/*				 * For EP0 we can only program 1 packet at a time so we				 * need to do the make calculations after each complete.				 * Call write_packet to make the calculations, as in				 * slave mode, and use those values to determine if we				 * can complete.				 */				dwc_otg_ep_write_packet (core_if, &ep0->dwc_ep, 1);			}			else			{				desc_sts.d32 = readl(core_if->dev_if->in_desc_addr);				byte_count = ep0->dwc_ep.xfer_len - desc_sts.b.bytes;				ep0->dwc_ep.xfer_count += byte_count;				ep0->dwc_ep.xfer_buff += byte_count;				ep0->dwc_ep.dma_addr += byte_count;			}		}		if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len)		{//			DWC_PRINT("IN CONTINUE\n");			dwc_otg_ep0_continue_transfer ( GET_CORE_IF(_pcd), &ep0->dwc_ep );			DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");		}		else if(ep0->dwc_ep.sent_zlp)		{//			DWC_PRINT("IN ZLP\n");			dwc_otg_ep0_continue_transfer ( GET_CORE_IF(_pcd), &ep0->dwc_ep );			ep0->dwc_ep.sent_zlp = 0;			DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");		}		else		{//			DWC_PRINT("IN COMPLETE\n");			ep0_complete_request( ep0 );			DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");		}		break;	case EP0_OUT_DATA_PHASE:#ifdef DEBUG_EP0		DWC_DEBUGPL(DBG_PCD, "DATA_OUT EP%d-%s: type=%d, mps=%d\n",						ep0->dwc_ep.num, (ep0->dwc_ep.is_in ?"IN":"OUT"),						ep0->dwc_ep.type, ep0->dwc_ep.maxpacket );#endif		if (core_if->dma_enable != 0)		{			byte_count = ep0->dwc_ep.maxpacket;			if(core_if->dma_desc_enable == 0)			{				deptsiz.d32 = dwc_read_reg32(&core_if->dev_if->out_ep_regs[0]->doeptsiz);				byte_count -= deptsiz.b.xfersize;			}			else			{				desc_sts.d32 = readl(core_if->dev_if->out_desc_addr);				byte_count -= desc_sts.b.bytes;			}			ep0->dwc_ep.xfer_count += byte_count;			ep0->dwc_ep.xfer_buff += byte_count;			ep0->dwc_ep.dma_addr += byte_count;		}		if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len)		{//			DWC_PRINT("OUT CONTINUE\n");			dwc_otg_ep0_continue_transfer ( GET_CORE_IF(_pcd), &ep0->dwc_ep );			DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");		}		else if(ep0->dwc_ep.sent_zlp)		{//			DWC_PRINT("OUT ZLP\n");			dwc_otg_ep0_continue_transfer ( GET_CORE_IF(_pcd), &ep0->dwc_ep );			ep0->dwc_ep.sent_zlp = 0;			DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");		}		else		{//			DWC_PRINT("OUT COMPLETE\n");			ep0_complete_request( ep0 );			DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");		}		break;	case EP0_IN_STATUS_PHASE:	case EP0_OUT_STATUS_PHASE:		DWC_DEBUGPL(DBG_PCD, "CASE: EP0_STATUS\n");						ep0_complete_request( ep0 );						_pcd->ep0state = EP0_IDLE;						ep0->stopped = 1;						ep0->dwc_ep.is_in = 0;	/* OUT for next SETUP */		/* Prepare for more SETUP Packets */		if (core_if->dma_enable)		{			ep0_out_start( core_if, _pcd );		}		else		{			int i;			depctl_data_t diepctl;			diepctl.d32 = dwc_read_reg32( &core_if->dev_if->in_ep_regs[0]->diepctl);			if (_pcd->ep0.queue_sof)			{				_pcd->ep0.queue_sof = 0;				start_next_request (&_pcd->ep0);			}			diepctl.d32 = dwc_read_reg32( &core_if->dev_if->in_ep_regs[0]->diepctl);			if (_pcd->ep0.queue_sof)			{				_pcd->ep0.queue_sof = 0;				start_next_request (&_pcd->ep0);			}			for (i=0; i < core_if->dev_if->num_in_eps; i++)			{				diepctl.d32 = dwc_read_reg32( &core_if->dev_if->in_ep_regs[i+1]->diepctl);				if (_pcd->in_ep[i].queue_sof)				{					_pcd->in_ep[i].queue_sof = 0;					start_next_request (&_pcd->in_ep[i]);				}			}		}		break;	case EP0_STALL:		DWC_ERROR("EP0 STALLed, should not get here pcd_setup()\n");		break;	}#ifdef DEBUG_EP0	print_ep0_state(_pcd);#endif}#if 0/** * This function handles EP0 Control transfers. * * The state of the control tranfers are tracked in * <code>ep0state</code>. */static void handle_ep0_descdma( dwc_otg_pcd_t *_pcd , uint32_t intr_sts){	dwc_otg_core_if_t *core_if = GET_CORE_IF(_pcd);	dwc_otg_pcd_ep_t *ep0 = &_pcd->ep0;	desc_sts_data_t desc_sts;	uint32_t byte_count;	depctl_data_t diepctl = { .d32 = 0};	depctl_data_t doepctl = { .d32 = 0};	switch(intr_sts)	{//////////////////////// CASE A /////////////////////////////////////////////	case 1:	// EP0 OUT IOC is set (case A)		switch(_pcd->ep0state)		{		case EP0_DISCONNECT:			break;		case EP0_IDLE:		case EP0_OUT_STATUS_PHASE:			// this tells "IN Token received with Tx FIFO Empty"			// Interrupt handler not to STALL EP0 IN			_pcd->ep0state = EP0_IDLE;			if(desc_sts.b.sr)			{				pcd_setup(_pcd);				if(_pcd->ep0state == EP0_IN_DATA_PHASE || _pcd->ep0state == EP0_IN_STATUS_PHASE)					init_setup_desc(core_if, _pcd);			}			else			{				init_setup_desc(core_if, _pcd);			}			break;		case EP0_IN_DATA_PHASE:		case EP0_IN_STATUS_PHASE:			// disable EP0 IN			diepctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl);			diepctl.b.epdis = 1;			diepctl.b.snak = 1;			dwc_write_reg32( &dev_if->in_ep_regs[0]->diepctl, diepctl.d32 );			// ... should be here ??? ... ///			if(desc_sts.b.sr)			{				pcd_setup(_pcd);				if(_pcd->ep0state == EP0_IN_DATA_PHASE || _pcd->ep0state == EP0_IN_STATUS_PHASE)					ep0_out_start(core_if, _pcd);			}			break;		case EP0_OUT_DATA_PHASE:			if(desc_sts.b.sr)			{				// ... linking SETUP desc pointer to this ...				pcd_setup(_pcd);				if(_pcd->ep0state == EP0_IN_DATA_PHASE || _pcd->ep0state == EP0_IN_STATUS_PHASE)					ep0_out_start(core_if, _pcd);			}			else			{				byte_count = ep0->dwc_ep.maxpacket - desc_sts.b.bytes;				ep0->dwc_ep.xfer_count += byte_count;				ep0->dwc_ep.xfer_buff += byte_count;				ep0->dwc_ep.dma_addr += byte_count;				if (ep0->dwc_ep.xfer_count < ep0->dwc_ep.total_len)				{					dwc_otg_ep0_continue_transfer ( GET_CORE_IF(_pcd), &ep0->dwc_ep );					DWC_DEBUGPL(DBG_PCD, "CONTINUE TRANSFER\n");				}				else				{					// ... EP set STALL ...					ep0_complete_request( ep0 );					ep0_out_start(core_if, _pcd);					DWC_DEBUGPL(DBG_PCD, "COMPLETE TRANSFER\n");				}			}			break;		case EP0_STALL:			DWC_ERROR("EP0 STALLed, should not get here pcd_setup()\n");			break;		}		break;//////////////////////// CASE B //////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -