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

📄 udc.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 2 页
字号:
/********************** BEGIN LICENSE BLOCK ************************************ * * JZ4740  mobile_tv  Project  V1.0.0 * INGENIC CONFIDENTIAL--NOT FOR DISTRIBUTION IN SOURCE CODE FORM * Copyright (c) Ingenic Semiconductor Co. Ltd 2005. All rights reserved. *  * This file, and the files included with this file, is distributed and made  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.  *  * http://www.ingenic.cn  * ********************** END LICENSE BLOCK ************************************** * *  Author:  <dsqiu@ingenic.cn>  <jgao@ingenic.cn>  * *  Create:   2008-06-26, by dsqiu *             *  Maintain: 2008-06-26, by jgao *             * ******************************************************************************* */#include <ucos_ii.h>#include <jz4740.h>#include <bsp.h>#include "usb.h"#include "udc.h"#include "udcbus.h"#include "threadprio.h"#ifdef USE_MIDWARE#include "midware.h"#endif#define EP1_INTR_BIT 2#define EP_FIFO_NOEMPTY 2#define GPIO_UDC_DETE GPIO_UDC_DETE_PIN#define IRQ_GPIO_UDC_DETE (IRQ_GPIO_0 + GPIO_UDC_DETE)#define MAX_CABLE_DETE  3#define CABLE_DETE_TIME  500                //wait time in ms#define CABLE_CONNECTED          0#define CABLE_DISCONNECT         1#define DEBUGMSG 0#if DEBUGMSG#define dprintf printf#else#undef  dprintf#define dprintf(x...)#endif#define IS_CACHE(x) (x < 0xa0000000)#ifdef USE_MIDWAREvolatile static MIDSRC udcsrc;volatile static MIDSRCDTA res;volatile static u32 udcid;volatile static u32 cable_stat;volatile static u32 protocool_stat;static u8 err;#endiftypedef struct{	unsigned char ep;	unsigned char state;	unsigned short fifosize;		unsigned int curlen;	unsigned int totallen;	unsigned int data_addr;	unsigned int fifo_addr;}EPSTATE,*PEPSTATE;#define CPU_READ     0#define CPU_WRITE     1#define DMA_READ     2#define DMA_WRITE     3#define WRITE_FINISH  4#define READ_FINISH  5#define TXFIFOEP0 USB_FIFO_EP0EPSTATE epstat[3] = {	{0x00, 0,0,0,0,0,TXFIFOEP0 + 0},	{0x81, 0,0,0,0,0,TXFIFOEP0 + 4},	{0x01, 0,0,0,0,0,TXFIFOEP0 + 4}};#define GetEpState(x) (&epstat[x])static OS_EVENT *udcEvent;u8 USB_Version;volatile static unsigned char udc_irq_type = 0;//void (*tx_done)(void) = NULL;#define UDC_TASK_PRIO	UDC_THREAD_PRIO  //7#define UDC_TASK_STK_SIZE	1024 * 2static OS_STK udcTaskStack[UDC_TASK_STK_SIZE];#define PHYADDR(x) (x & 0x1fffffff)static void dma_receieve_data(PEPSTATE pep){	unsigned int size;	size = pep->totallen - (pep->totallen % pep->fifosize);	if(IS_CACHE(pep->data_addr))		dma_cache_wback_inv(pep->data_addr, pep->totallen);	//IntrOutMask = 0x0;			jz_writel(USB_REG_ADDR2,PHYADDR(pep->data_addr));	jz_writel(USB_REG_COUNT2,size);	jz_writel(USB_REG_CNTL2,0x001d);	jz_writeb(USB_REG_INDEX,1);		usb_setw(USB_REG_OUTCSR,0xa000);	//printf("dma receive %x\n",size);    	pep->curlen = size;		}static void dma_send_data(PEPSTATE pep){	  unsigned int size;	  	  size = pep->totallen - (pep->totallen % pep->fifosize);	  	  if(IS_CACHE(pep->data_addr))		  dma_cache_wback_inv(pep->data_addr, size);	  jz_writel(USB_REG_ADDR1,PHYADDR(pep->data_addr));	  jz_writel(USB_REG_COUNT1,size);//fifosize[ep]);	  jz_writel(USB_REG_CNTL1,0x001f);	  jz_writeb(USB_REG_INDEX, 1);	  usb_setw(USB_REG_INCSR,0x9400);	  	  //printf("dma send %x\n",size);	  pep->curlen = size;}static inline void dma_send_data_Finish(){	jz_writel(USB_REG_CNTL1,0x0);	jz_writeb(USB_REG_INDEX,1);	usb_clearw(USB_REG_INCSR,0x9400);	}static void dma_receieve_data_finish(){	dprintf("\n Disable DMA!");		jz_writel(USB_REG_CNTL2,0x0);	jz_writeb(USB_REG_INDEX,1);	usb_clearw(USB_REG_OUTCSR,0xa000);}void disable_device(unsigned int handle);static void udc_reset(unsigned int handle){//	PUDC_BUS pBus = (PUDC_BUS) handle;	u8 byte;	PEPSTATE pep;		//data init		//ep0state = USB_EP0_IDLE;//	IntrOutMask = 0x2;	// __cpm_stop_udc();	/* Enable the USB PHY */	//REG_CPM_SCR |= CPM_SCR_USBPHY_ENABLE;	/* Disable interrupts */	jz_writew(USB_REG_INTRINE,0);	jz_writew(USB_REG_INTROUTE, 0);	jz_writeb(USB_REG_INTRUSBE, 0);	jz_writeb(USB_REG_FADDR,0);//jz_writeb(USB_REG_POWER,0x60);   //High speed	jz_writeb(USB_REG_INDEX,0);	jz_writeb(USB_REG_CSR0,0xc0);	jz_writeb(USB_REG_INDEX,1);	jz_writew(USB_REG_INCSR,0x2048);	jz_writew(USB_REG_INMAXP,512);		jz_writeb(USB_REG_INDEX,1);	jz_writew(USB_REG_OUTCSR,0x0090);	jz_writew(USB_REG_OUTMAXP,512);	byte = jz_readb(USB_REG_POWER);	dprintf("REG_POWER: %02x\r\n",byte);	epstat[0].fifosize = 64;		if(epstat[1].state != WRITE_FINISH)		jz_readw(USB_REG_INTRIN);	if(epstat[2].state != READ_FINISH)		jz_readw(USB_REG_INTROUT);		epstat[0].state = 0;	epstat[1].state = WRITE_FINISH;	epstat[2].state = READ_FINISH;	epstat[0].curlen = 0;	epstat[1].curlen = 0;	epstat[2].curlen = 0;	epstat[0].totallen = 0;	epstat[1].totallen = 0;	epstat[2].totallen = 0;		if ((byte & 0x10)==0) 	{		jz_writeb(USB_REG_INDEX,1);		jz_writew(USB_REG_INMAXP,64);		jz_writew(USB_REG_INCSR,0x2048);		jz_writeb(USB_REG_INDEX,1);		jz_writew(USB_REG_OUTMAXP,64);		jz_writew(USB_REG_OUTCSR,0x0090);		USB_Version=USB_FS;		//fifosize[1]=64;      		epstat[1].fifosize = 64;		epstat[2].fifosize = 64;		printf("usb1.1\n");			}	else	{		jz_writeb(USB_REG_INDEX,1);		jz_writew(USB_REG_INMAXP,512);		jz_writew(USB_REG_INCSR,0x2048);		jz_writeb(USB_REG_INDEX,1);		jz_writew(USB_REG_OUTMAXP,512);		jz_writew(USB_REG_OUTCSR,0x0090);		USB_Version=USB_HS;		epstat[1].fifosize = 512;		epstat[2].fifosize = 512;		printf("usb2.0\n");			}//DMA USE	jz_writel(USB_REG_CNTL1,0);		jz_writel(USB_REG_ADDR1,0);	jz_writel(USB_REG_COUNT1,0);//fifosize[ep]);	jz_writel(USB_REG_CNTL2,0);	jz_writel(USB_REG_ADDR2,0);	jz_writel(USB_REG_COUNT2,0);//fifosize[ep]);	jz_readb(USB_REG_INTR); // clear dma interrupt	jz_writew(USB_REG_INTRINE,0x1);   //enable ep0 intr	jz_writeb(USB_REG_INTRUSBE,0x6);//	disable_device();	}static void udc_read_fifo(PEPSTATE pep, int size){	unsigned int *ptr = (unsigned int *)(pep->data_addr + pep->curlen);	unsigned int fifo = pep->fifo_addr;	unsigned char *c;	int s = size / 4;	unsigned int x;	if(((unsigned int )ptr & 3) == 0)	{		while(s--)			*ptr++ = REG32(fifo);				}	else	{		while(s--)		{			x = REG32(fifo);			*ptr++ = (x >> 0)& 0x0ff;			*ptr++ = (x >> 8)  & 0x0ff;			*ptr++ = (x >> 16) & 0x0ff;			*ptr++ = (x >> 24) & 0xff;		}	}		s = size & 3;	c = (unsigned char *)ptr;	while(s--)		*c++ = REG8(fifo);	pep->curlen += size;		#if 0	c = (unsigned char *)(pep->data_addr + pep->curlen - size);	dprintf("recv:(%d)", size);	for (s=0;s<size;s++) {		if (s % 16 == 0)			dprintf("\n");		dprintf(" %02x", *(c+s));	}	dprintf("\n");#endif}static void udc_write_fifo(PEPSTATE pep, int size){	unsigned int *d = (unsigned int *)(pep->data_addr + pep->curlen);	unsigned int fifo = pep->fifo_addr;	u8 *c;	int s, q;#if 0	unsigned char *ptr =(unsigned char *)d;		dprintf("send:fifo(%x) = (%d)",fifo, size);	for (s=0;s<size;s++) {		if (s % 16 == 0)			dprintf("\n");		dprintf(" %02x", ptr[s]);	}	dprintf("\n");#endif		if (size > 0) {		s = size >> 2;		while (s--)			REG32(fifo) = *d++;		q = size & 3;		if (q) {			c = (u8 *)d;			while (q--)				REG8(fifo) = *c++;		}	} 	pep->curlen += size;}void ep0_handler(unsigned int handle){    PEPSTATE pep = GetEpState(0);	unsigned char byCSR0;/* Read CSR0 */	jz_writeb(USB_REG_INDEX, 0);	byCSR0 = jz_readb(USB_REG_CSR0);   //	printf("EP0 CSR = %x\n",byCSR0);    if(byCSR0 == 0)		return;	/* Check for SentStall    if sendtall is set ,clear the sendstall bit*/	if (byCSR0 & USB_CSR0_SENTSTALL) 	{		jz_writeb(USB_REG_CSR0, (byCSR0 & ~USB_CSR0_SENDSTALL));		pep->state = CPU_READ;				printf("\nSentstall!");		return;	}/* Check for SetupEnd */	if (byCSR0 & USB_CSR0_SETUPEND) 	{		jz_writeb(USB_REG_CSR0, (byCSR0 | USB_CSR0_SVDSETUPEND));		pep->state = CPU_READ;		printf("\nSetupend!");		//return;	}/* Call relevant routines for endpoint 0 state */	if (pep->state == CPU_READ) 	{		if (byCSR0 & USB_CSR0_OUTPKTRDY)   //There are datas in fifo		{            USB_DeviceRequest dreq;			            *(unsigned int *) &dreq =  REG32(pep->fifo_addr);			*(unsigned int *) ((unsigned int)&dreq + 4)=  REG32(pep->fifo_addr);								dprintf("\nbmRequestType:%02x\nbRequest:%02x\n"					"wValue:%04x\nwIndex:%04x\n"					"wLength:%04x\n",					dreq.bmRequestType,					dreq.bRequest,					dreq.wValue,					dreq.wIndex,					dreq.wLength);			if ( dreq.bRequest == SET_CONFIGURATION )				protocool_stat = CABLE_CONNECTED;			if ( dreq.bRequest == SET_ADDRESS || dreq.bRequest == SET_CONFIGURATION || dreq.bRequest == CLEAR_FEATURE )				usb_setb(USB_REG_CSR0, 0x40 | USB_CSR0_DATAEND);//clear OUTRD bit and DATAEND			else				usb_setb(USB_REG_CSR0, 0x40);//clear OUTRD bit			BusNotify(handle,UDC_SETUP_PKG_FINISH,(unsigned char *)&dreq,8);		}		else 		{			dprintf("0:R DATA\n");					}			}		if (pep->state == CPU_WRITE) 	{		int sendsize;		sendsize = pep->totallen - pep->curlen;//		printf("send size = %d\r\n",sendsize);				if (sendsize < 64) 		{			udc_write_fifo(pep,sendsize);			pep->curlen = pep->totallen;			usb_setb(USB_REG_CSR0, USB_CSR0_INPKTRDY | USB_CSR0_DATAEND);			pep->state = CPU_READ;					} else 		{			if(sendsize)			{				udc_write_fifo(pep, 64);				usb_setb(USB_REG_CSR0, USB_CSR0_INPKTRDY);				pep->curlen += 64;							}else				pep->state = CPU_READ;					}	}//	printf("pep state = %d %d\r\n",CPU_WRITE,pep->state);	return;}void ep_in_handler(unsigned int handle,PEPSTATE pep){	unsigned int size;   		//fifo = fifoaddr[EP];	size = pep->totallen - pep->curlen;//	printf("pep->totallen = %d size = %d \n",pep->totallen,size);	if(size == 0)	{				pep->state = WRITE_FINISH;		usb_clearw(USB_REG_INTRINE,EP1_INTR_BIT);  // close ep1 in intr		BusNotify(handle,UDC_PROTAL_SEND_FINISH,(unsigned char *)pep->data_addr,pep->curlen);//		printf("Send finish \n");		return;			}		if(size < pep->fifosize)	{		udc_write_fifo(pep,size);	}else		udc_write_fifo(pep,pep->fifosize);	usb_setb(USB_REG_INCSR, USB_INCSR_INPKTRDY);	}void ep_out_handler(unsigned int handle,PEPSTATE pep){    unsigned int size;		jz_writeb(USB_REG_INDEX, 1);	size = jz_readw(USB_REG_OUTCOUNT);	 	udc_read_fifo(pep, size);	usb_clearb(USB_REG_OUTCSR,USB_OUTCSR_OUTPKTRDY);	pep->state = CPU_READ;	dprintf("EPOUT: totallen = %d curlen = %d",pep->totallen,pep->curlen);		if(pep->totallen == pep->curlen)	{		pep->state = READ_FINISH;		usb_clearw(USB_REG_INTROUTE,EP1_INTR_BIT);		BusNotify(handle,UDC_PROTAL_RECEIVE_FINISH,			  (unsigned char *)pep->data_addr,pep->curlen);					}		//	USB_HandleUFICmd();	dprintf("\nEPOUT_handle return!");}static int check_gpio(u32 pin){	int i ,j  = 0,k = 0;	for ( i = 0 ; i < 10 ; i ++ )	{		OSTimeDly(1);		if (__gpio_get_pin(pin))			j ++;		else k ++;	}		if ( j >= k ) return 1;	else return 0;}void udc_intrb_handler(unsigned int handle,unsigned char val){	unsigned char byte;		if (val & USB_INTR_RESET) 	{		printf("UDC reset intrupt!\r\n");  		if ( protocool_stat == CABLE_DISCONNECT && 		     cable_stat == CABLE_CONNECTED )		{			printf("USB cable insert! \n");			cable_stat = CABLE_CONNECTED;			udcsrc.Src = SRC_UDC;			udcsrc.Event = EVENT_USB_IN;			OSQPost(udcsrc.CurEvent1 , (void *)&udcid);			OSSemPost(udcsrc.CurEvent);			if ( res.Val == 1 )  //|| res.Val == 0xffff) //up layer said yes!			{//				protocool_stat = CABLE_CONNECTED;//				BusNotify((unsigned int)pBus,stat,0,0);				;			}			else           //up layer said no!			{				protocool_stat = CABLE_DISCONNECT;				//jz_writeb(USB_REG_POWER,0x00);   //High speed					disable_device(0);				printf("As power cable insert! \n");				return;							}		}		udc_reset(handle);				byte = jz_readb(USB_REG_POWER);		//dprintf("REG_POWER: %02x\r\n",byte);		if ((byte&0x10) ==0 ) 		{			BusNotify(handle,UDC_FULLSPEED,0,0);		}else			BusNotify(handle,UDC_HIGHSPEED,0,0);		// enable USB Suspend interrupt				byte = jz_readb(USB_REG_INTRUSBE);		jz_writeb(USB_REG_INTRUSBE,byte | USB_INTR_SUSPEND);      		BusNotify(handle,UDC_RESET,0,0);			}	if(val & USB_INTR_SUSPEND)	{		BusNotify(handle,UDC_SUSPEND,0,0);				byte = jz_readb(USB_REG_INTRUSBE);		jz_writeb(USB_REG_INTRUSBE,(byte & (~USB_INTR_SUSPEND) & 7));		printf("udc suspend %x\n",byte);#ifdef USE_MIDWARE		if ( protocool_stat == CABLE_CONNECTED )		{			printf("USB uninstall ! %d \n",protocool_stat);			udcsrc.Src = SRC_UDC;			udcsrc.Event = EVENT_UNINSTALL;			protocool_stat = CABLE_DISCONNECT;

⌨️ 快捷键说明

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