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

📄 dwc_otg_cil.c

📁 host usb 主设备程序 支持sd卡 mouse keyboard 的最单单的驱动程序 gcc编译
💻 C
📖 第 1 页 / 共 5 页
字号:
			for (i = 1; i < _core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {				txfifosize.b.depth = params->dev_tx_fifo_size[i];				DWC_DEBUGPL(DBG_CIL, "initial dptxfsiz_dieptxf[%d]=%08x\n", i,					    dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]));				dwc_write_reg32(&global_regs->dptxfsiz_dieptxf[i - 1],						txfifosize.d32);				DWC_DEBUGPL(DBG_CIL, "new dptxfsiz_dieptxf[%d]=%08x\n", i,					    dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i - 1]));				txfifosize.b.startaddr += txfifosize.b.depth;			}		}	}	/* Flush the FIFOs */	dwc_otg_flush_tx_fifo(_core_if, 0x10);	/* all Tx FIFOs */	dwc_otg_flush_rx_fifo(_core_if);	/* Flush the Learning Queue. */	resetctl.b.intknqflsh = 1;	dwc_write_reg32(&_core_if->core_global_regs->grstctl, resetctl.d32);	/* Clear all pending Device Interrupts */	dwc_write_reg32(&dev_if->dev_global_regs->diepmsk, 0);	dwc_write_reg32(&dev_if->dev_global_regs->doepmsk, 0);	dwc_write_reg32(&dev_if->dev_global_regs->daint, 0xFFFFFFFF);	dwc_write_reg32(&dev_if->dev_global_regs->daintmsk, 0);	for (i = 0; i <= dev_if->num_in_eps; i++) {		depctl_data_t depctl;		depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);		if (depctl.b.epena) {			depctl.d32 = 0;			depctl.b.epdis = 1;			depctl.b.snak = 1;		} else {			depctl.d32 = 0;		}		dwc_write_reg32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);		dwc_write_reg32(&dev_if->in_ep_regs[i]->dieptsiz, 0);		dwc_write_reg32(&dev_if->in_ep_regs[i]->diepdma, 0);		dwc_write_reg32(&dev_if->in_ep_regs[i]->diepint, 0xFF);	}	for (i = 0; i <= dev_if->num_out_eps; i++) {		depctl_data_t depctl;		depctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[i]->doepctl);		if (depctl.b.epena) {			depctl.d32 = 0;			depctl.b.epdis = 1;			depctl.b.snak = 1;		} else {			depctl.d32 = 0;		}		dwc_write_reg32(&dev_if->out_ep_regs[i]->doepctl, depctl.d32);		dwc_write_reg32(&dev_if->out_ep_regs[i]->doeptsiz, 0);		dwc_write_reg32(&dev_if->out_ep_regs[i]->doepdma, 0);		dwc_write_reg32(&dev_if->out_ep_regs[i]->doepint, 0xFF);	}	if (_core_if->en_multiple_tx_fifo && _core_if->dma_enable) {		dev_if->non_iso_tx_thr_en = _core_if->core_params->thr_ctl & 0x1;		dev_if->iso_tx_thr_en = (_core_if->core_params->thr_ctl >> 1) & 0x1;		dev_if->rx_thr_en = (_core_if->core_params->thr_ctl >> 2) & 0x1;		dev_if->rx_thr_length = _core_if->core_params->rx_thr_length;		dev_if->tx_thr_length = _core_if->core_params->tx_thr_length;		dev_if->setup_desc_index = 0;		dthrctl.d32 = 0;		dthrctl.b.non_iso_thr_en = dev_if->non_iso_tx_thr_en;		dthrctl.b.iso_thr_en = dev_if->iso_tx_thr_en;		dthrctl.b.tx_thr_len = dev_if->tx_thr_length;		dthrctl.b.rx_thr_en = dev_if->rx_thr_en;		dthrctl.b.rx_thr_len = dev_if->rx_thr_length;		dwc_write_reg32(&dev_if->dev_global_regs->dtknqr3_dthrctl, dthrctl.d32);		DWC_DEBUGPL(DBG_CIL,			    "Non ISO Tx Thr - %d\nISO Tx Thr - %d\nRx Thr - %d\nTx Thr Len - %d\nRx Thr Len - %d\n",			    dthrctl.b.non_iso_thr_en, dthrctl.b.iso_thr_en, dthrctl.b.rx_thr_en,			    dthrctl.b.tx_thr_len, dthrctl.b.rx_thr_len);	}	dwc_otg_enable_device_interrupts(_core_if);	{		diepmsk_data_t msk = {.d32 = 0 };		msk.b.txfifoundrn = 1;		dwc_modify_reg32(&dev_if->dev_global_regs->diepmsk, msk.d32, msk.d32);	}}/** * This function enables the Host mode interrupts. * * @param _core_if Programming view of DWC_otg controller */void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t * _core_if){	dwc_otg_core_global_regs_t *global_regs = _core_if->core_global_regs;	gintmsk_data_t intr_mask = {.d32 = 0 };	DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);	/* Disable all interrupts. */	dwc_write_reg32(&global_regs->gintmsk, 0);	/* Clear any pending interrupts. */	dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);	/* Enable the common interrupts */	dwc_otg_enable_common_interrupts(_core_if);	/*	 * Enable host mode interrupts without disturbing common	 * interrupts.	 */	intr_mask.b.sofintr = 1;	intr_mask.b.portintr = 1;	intr_mask.b.hcintr = 1;	dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);}/** * This function disables the Host Mode interrupts. * * @param _core_if Programming view of DWC_otg controller */void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t * _core_if){	dwc_otg_core_global_regs_t *global_regs = _core_if->core_global_regs;	gintmsk_data_t intr_mask = {.d32 = 0 };	DWC_DEBUGPL(DBG_CILV, "%s()\n", __func__);	/*	 * Disable host mode interrupts without disturbing common	 * interrupts.	 */	intr_mask.b.sofintr = 1;	intr_mask.b.portintr = 1;	intr_mask.b.hcintr = 1;	intr_mask.b.ptxfempty = 1;	intr_mask.b.nptxfempty = 1;	dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);}/** * This function initializes the DWC_otg controller registers for * host mode. * * This function flushes the Tx and Rx FIFOs and it flushes any entries in the * request queues. Host channels are reset to ensure that they are ready for * performing transfers. * * @param _core_if Programming view of DWC_otg controller * */void dwc_otg_core_host_init(dwc_otg_core_if_t * _core_if){	dwc_otg_core_global_regs_t *global_regs = _core_if->core_global_regs;	dwc_otg_host_if_t *host_if = _core_if->host_if;	dwc_otg_core_params_t *params = _core_if->core_params;	hprt0_data_t hprt0 = {.d32 = 0 };	fifosize_data_t nptxfifosize;	fifosize_data_t ptxfifosize;	int i;	hcchar_data_t hcchar;	hcfg_data_t hcfg;	dwc_otg_hc_regs_t *hc_regs;	int num_channels;	gotgctl_data_t gotgctl = {.d32 = 0 };	DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, _core_if);	/* Restart the Phy Clock */	dwc_write_reg32(_core_if->pcgcctl, 0);	/* Initialize Host Configuration Register */	init_fslspclksel(_core_if);	if (_core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {		hcfg.d32 = dwc_read_reg32(&host_if->host_global_regs->hcfg);		hcfg.b.fslssupp = 1;		dwc_write_reg32(&host_if->host_global_regs->hcfg, hcfg.d32);	}	/* Configure data FIFO sizes */	if (_core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {		DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n", _core_if->total_fifo_size);		DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n", params->host_rx_fifo_size);		DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n", params->host_nperio_tx_fifo_size);		DWC_DEBUGPL(DBG_CIL, "P Tx FIFO Size=%d\n", params->host_perio_tx_fifo_size);		/* Rx FIFO */		DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",			    dwc_read_reg32(&global_regs->grxfsiz));		dwc_write_reg32(&global_regs->grxfsiz, params->host_rx_fifo_size);		DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n", dwc_read_reg32(&global_regs->grxfsiz));		/* Non-periodic Tx FIFO */		DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",			    dwc_read_reg32(&global_regs->gnptxfsiz));		nptxfifosize.b.depth = params->host_nperio_tx_fifo_size;		nptxfifosize.b.startaddr = params->host_rx_fifo_size;		dwc_write_reg32(&global_regs->gnptxfsiz, nptxfifosize.d32);		DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",			    dwc_read_reg32(&global_regs->gnptxfsiz));		/* Periodic Tx FIFO */		DWC_DEBUGPL(DBG_CIL, "initial hptxfsiz=%08x\n",			    dwc_read_reg32(&global_regs->hptxfsiz));		ptxfifosize.b.depth = params->host_perio_tx_fifo_size;		ptxfifosize.b.startaddr = nptxfifosize.b.startaddr + nptxfifosize.b.depth;		dwc_write_reg32(&global_regs->hptxfsiz, ptxfifosize.d32);		DWC_DEBUGPL(DBG_CIL, "new hptxfsiz=%08x\n", dwc_read_reg32(&global_regs->hptxfsiz));	}	/* Clear Host Set HNP Enable in the OTG Control Register */	gotgctl.b.hstsethnpen = 1;	dwc_modify_reg32(&global_regs->gotgctl, gotgctl.d32, 0);	/* Make sure the FIFOs are flushed. */	dwc_otg_flush_tx_fifo(_core_if, 0x10 /* all Tx FIFOs */ );	dwc_otg_flush_rx_fifo(_core_if);	/* Flush out any leftover queued requests. */	num_channels = _core_if->core_params->host_channels;	for (i = 0; i < num_channels; i++) {		hc_regs = _core_if->host_if->hc_regs[i];		hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);		hcchar.b.chen = 0;		hcchar.b.chdis = 1;		hcchar.b.epdir = 0;		dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);	}	/* Halt all channels to put them into a known state. */	for (i = 0; i < num_channels; i++) {		int count = 0;		hc_regs = _core_if->host_if->hc_regs[i];		hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);		hcchar.b.chen = 1;		hcchar.b.chdis = 1;		hcchar.b.epdir = 0;		dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);		DWC_DEBUGPL(DBG_HCDV, "%s: Halt channel %d\n", __func__, i);		do {			hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);			if (++count > 1000) {				DWC_ERROR("%s: Unable to clear halt on channel %d\n", __func__, i);				break;			}		}		while (hcchar.b.chen);	}	/* Turn on the vbus power. */	DWC_PRINT("Init: Port Power? op_state=%d\n", _core_if->op_state);	if (_core_if->op_state == A_HOST) {		hprt0.d32 = dwc_otg_read_hprt0(_core_if);		DWC_PRINT("Init: Power Port (%d)\n", hprt0.b.prtpwr);		if (hprt0.b.prtpwr == 0) {			hprt0.b.prtpwr = 1;			dwc_write_reg32(host_if->hprt0, hprt0.d32);		}	}	dwc_otg_enable_host_interrupts(_core_if);}/** * Prepares a host channel for transferring packets to/from a specific * endpoint. The HCCHARn register is set up with the characteristics specified * in _hc. Host channel interrupts that may need to be serviced while this * transfer is in progress are enabled. * * @param _core_if Programming view of DWC_otg controller * @param _hc Information needed to initialize the host channel */void dwc_otg_hc_init(dwc_otg_core_if_t * _core_if, dwc_hc_t * _hc){	uint32_t intr_enable;	hcintmsk_data_t hc_intr_mask;	gintmsk_data_t gintmsk = {.d32 = 0 };	hcchar_data_t hcchar;	hcsplt_data_t hcsplt;	uint8_t hc_num = _hc->hc_num;	dwc_otg_host_if_t *host_if = _core_if->host_if;	dwc_otg_hc_regs_t *hc_regs = host_if->hc_regs[hc_num];	/* Clear old interrupt conditions for this host channel. */	hc_intr_mask.d32 = 0xFFFFFFFF;	hc_intr_mask.b.reserved = 0;	dwc_write_reg32(&hc_regs->hcint, hc_intr_mask.d32);	/* Enable channel interrupts required for this transfer. */	hc_intr_mask.d32 = 0;	hc_intr_mask.b.chhltd = 1;	if (_core_if->dma_enable) {		hc_intr_mask.b.ahberr = 1;		if (_hc->error_state && !_hc->do_split && _hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {			hc_intr_mask.b.ack = 1;			if (_hc->ep_is_in) {				hc_intr_mask.b.datatglerr = 1;				if (_hc->ep_type != DWC_OTG_EP_TYPE_INTR) {					hc_intr_mask.b.nak = 1;				}			}		}	} else {		switch (_hc->ep_type) {		case DWC_OTG_EP_TYPE_CONTROL:		case DWC_OTG_EP_TYPE_BULK:			hc_intr_mask.b.xfercompl = 1;			hc_intr_mask.b.stall = 1;			hc_intr_mask.b.xacterr = 1;			hc_intr_mask.b.datatglerr = 1;			if (_hc->ep_is_in) {				hc_intr_mask.b.bblerr = 1;			} else {				hc_intr_mask.b.nak = 1;				hc_intr_mask.b.nyet = 1;				if (_hc->do_ping) {					hc_intr_mask.b.ack = 1;				}			}			if (_hc->do_split) {				hc_intr_mask.b.nak = 1;				if (_hc->complete_split) {					hc_intr_mask.b.nyet = 1;				} else {					hc_intr_mask.b.ack = 1;				}			}			if (_hc->error_state) {				hc_intr_mask.b.ack = 1;			}			break;		case DWC_OTG_EP_TYPE_INTR:			hc_intr_mask.b.xfercompl = 1;			hc_intr_mask.b.nak = 1;			hc_intr_mask.b.stall = 1;			hc_intr_mask.b.xacterr = 1;			hc_intr_mask.b.datatglerr = 1;			hc_intr_mask.b.frmovrun = 1;			if (_hc->ep_is_in) {				hc_intr_mask.b.bblerr = 1;			}			if (_hc->error_state) {				hc_intr_mask.b.ack = 1;			}			if (_hc->do_split) {				if (_hc->complete_split) {					hc_intr_mask.b.nyet = 1;				} else {					hc_intr_mask.b.ack = 1;				}			}			break;		case DWC_OTG_EP_TYPE_ISOC:			hc_intr_mask.b.xfercompl = 1;			hc_intr_mask.b.frmovrun = 1;			hc_intr_mask.b.ack = 1;			if (_hc->ep_is_in) {				hc_intr_mask.b.xacterr = 1;				hc_intr_mask.b.bblerr = 1;			}			break;		}	}	dwc_write_reg32(&hc_regs->hcintmsk, hc_intr_mask.d32);	/* Enable the top level host channel interrupt. */	intr_enable = (1 << hc_num);	dwc_modify_reg32(&host_if->host_global_regs->haintmsk, 0, intr_enable);	/* Make sure host channel interrupts are enabled. */	gintmsk.b.hcintr = 1;	dwc_modify_reg32(&_core_if->core_global_regs->gintmsk, 0, gintmsk.d32);	/*	 * Program the HCCHARn register with the endpoint characteristics for	 * the current transfer.	 */	hcchar.d32 = 0;	hcchar.b.devaddr = _hc->dev_addr;	hcchar.b.epnum = _hc->ep_num;	hcchar.b.epdir = _hc->ep_is_in;

⌨️ 快捷键说明

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