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

📄 usb.c

📁 ertfs文件系统里面既有完整ucos程序
💻 C
📖 第 1 页 / 共 4 页
字号:
	}
	/*we do this stuff for all tx_0 events **************************/
}


/**********************************************************************/
/* This subroutine handles TX events for FIFO1 (endpoint 1)           */
/**********************************************************************/
unsigned rlen;
extern unsigned short rbuf[256];

void tx_1(void)
{
	U32 Pointer,i;
	txstat=read_usb(TXS1);              /*get transmitter status  */
	/*if a transmission has completed successfully, update the data */
	/*toggle and queue up a dummy packet ****************************/
	if (txstat & TX_DONE)
	{
		FLUSHTX1;                       /*flush the FIFO(first of all)*/
		
		if(txstat & ACK_STAT)           /*ACK received:           */
		{
			/* 
			 * this DATAIN is ONLY for read operation in fact!!
			 * because other DATAIN operations are all less than 64 bytes
			 * and cannot enter thsi tx_1 isr
			 * so we need not other FSMstate
			 */
			if(BOTFSMstate == FSM4BOT_DATAIN)
			{
				if(BOTXfer_wResidue == 0)
				{
            		/* set FSM state to IDLE */
            		BOTFSMstate = BOTFSM_IDLE;
            		
            		/* handle CSW procedure */
            		TPBulk_CSWHandler();
				}
				else
				{
					/* send 64 byte data to the tx1 FIFO */
					for(i=0; i<64; i++)
	    				write_usb(TXD1,((INT8 *)BOTXfer_pData)[i]);       

	    			BOTXfer_pData += 64;
					BOTXfer_wResidue -= 64;
					
					//Uart_Printf("%d\n", rlen);	
	    			//	Uart_Printf("rlen = %d LBA_W32 = %d BOTXfer_pData = %x BOTXfer_wResidue = %x\n",
	    			//	             rlen, LBA_W32, (int)BOTXfer_pData, BOTXfer_wResidue);
	    			
	    			/* enable TX, choose PID, and flip the data toggle */
	    			TXEN1_PID;
	    		}		
	    	}
			else
			{
			}
		}
	}
	else
	{
	}
}

void tx_2(void)
{}

void tx_3(void)
{}

/*******************************************************************
*****                USB ALT(alternate)事件处理程序             *****
*******************************************************************/
void usb_alt(void)
{
	evnt = read_usb(ALTEV);				/*读入Alternate Event Register*/
										/*判断为何种ALT事件           */
    
	if(evnt & RESET_A)                  /*reset event             */
	{
		write_usb(NFSR,RST_ST);			/*enter reset state       */
		write_usb(FAR,AD_EN+0);			/*set default address     */
		write_usb(EPC0, 0x00);          /*enable EP0 only         */
		FLUSHTX0;						/*flush TX0 and disable   */
		write_usb(RXC0,RX_EN);          /*enable the receiver     */

		/*adjusting ints is nec. here in case we were in suspend    */
		write_usb(ALTMSK,NORMAL_ALTMSK);/*adjust interrupts       */
		write_usb(NFSR,OPR_ST);         /*go operational          */
	}

	else if(evnt & RESUME_A)            /*resume  event           */
	{
		write_usb(ALTMSK,NORMAL_ALTMSK);/*adjust interrupts       */
		write_usb(NFSR,OPR_ST);         /*go operational          */
	}

	else if((evnt & SD3)&&(suscntr==0)) /*suspend event           */
	{
		write_usb(ALTMSK,RESUME_A+RESET_A);/*adj interrupts          */
		write_usb(NFSR,SUS_ST);         /*enter suspend state     */
		deep_sleep();                   /*reduce power cons.      */
		suscntr=SUSPND_TO;              /*start suspend cntr(flag prevent suspend again)*/
	}

	else                                /*spurious alt. event!    */
	{
	}
}
/**********************************************************************/
/* This subroutine handles OUT NAK events for FIFO0 (endpoint 0)      */
/**********************************************************************/
void onak0(void)
{
	/*important note:  even after servicing a NAK, another NAK      */
	/*interrupt may occur if another 'OUT' or 'IN' packet comes in  */
	/*during our NAK service.                                       */

	/*if we're currently doing something that requires multiple 'IN'*/
	/*transactions, 'OUT' requests will get NAKs because the FIFO is*/
	/*busy with the TX data.  Since the 'OUT' here means a premature*/
	/*end to the previous transfer, just flush the FIFO, disable the*/
	/*transmitter, and re-enable the receiver.                      */
	if (TSTBIT(status,READSTA) || TSTBIT(status,GETDESC))/*multi-pkt status stage? */
	{
		if( TSTBIT(status,READSTA) )	/*exit multi-packet mode  */
			CLR_READSTA;
		if( TSTBIT(status,GETDESC) )
			CLR_GETDESC;
                              
		FLUSHTX0;                         /*flush TX0 and disable   */
		write_usb(RXC0,RX_EN);            /*re-enable the receiver  */
	}
	/*we do this stuff for all onak0 events **************************/
}
/**********************************************************************/
/* This subroutine handles OUT NAK events for FIFO1 (endpoint 2)      */
/**********************************************************************/
void onak1(void)
{}
/**********************************************************************/
/* This subroutine handles OUT NAK events for FIFO2 (endpoint 4)      */
/**********************************************************************/
void onak2(void)
{}
/**********************************************************************/
/* This subroutine handles OUT NAK events for FIFO3 (endpoint 6)      */
/**********************************************************************/
void onak3(void)
{}
/**********************************************************************/
/* This subroutine handles INP NAK events for FIFO0 (endpoint 0)      */
/**********************************************************************/
void inak0(void)
{}
/**********************************************************************/
/* This subroutine handles INP NAK events for FIFO1 (endpoint 1)      */
/**********************************************************************/
void inak1(void)
{}
/**********************************************************************/
/* This subroutine handles INP NAK events for FIFO02(endpoint 3)      */
/**********************************************************************/
void inak2(void)
{}
/**********************************************************************/
/* This subroutine handles INP NAK events for FIFO3 (endpoint 5)      */
/**********************************************************************/
void inak3(void)
{}
/*******************************************************************
*****                    USBN9603的中断服务程序                  *****
*******************************************************************/
void __irq usb_isr(void) /*USBN9603的中断输出接在8051的INT0*/
{
	/*clear interrupt source IN 41100*/
rI_ISPC = BIT_EINT0;
	evnt = read_usb(MAEV);	/*读入Main Event Register,以判断何种中断事件*/
	
	if (evnt & RX_EV)		/*如果为接收事件*/
	{
		evnt=read_usb(RXEV);            /*check the RX events     */

		if		(evnt&RXFIFO0)
			rx_0();  /*endpoint 0              */
		else if	(evnt&RXFIFO1) 
			rx_1();  /*endpoint 2              */
		else if	(evnt&RXFIFO2)
			rx_2();  /*endpoint 4(not use)     */
		else if (evnt&RXFIFO3)
			rx_3();  /*endpoint 6(not use)     */
		else                            /*some other RX event     */
		{}
	}

	else if (evnt & TX_EV)	/*如果为发送事件*/
	{
		evnt=read_usb(TXEV);            /*check the TX events     */
		if      (evnt&TXFIFO0)
			tx_0();  /*endpoint 0              */
		else if (evnt&TXFIFO1)
			tx_1();  /*endpoint 1              */
		else if (evnt&TXFIFO2)
			tx_2();  /*endpoint 3(not use)     */
		else if (evnt&TXFIFO3)
			tx_3();  /*endpoint 5(not use)     */
		else                            /*some other TX event     */
		{}
	}

	else if (evnt & ALT) usb_alt();     /*如果为ALT事件*/
        
	/*NAKs can come so fast and furious (especially with OHCI hosts)*/
	/*that they MUST have a lower priority than the other events. If*/
	/*they did not, the other events could get starved out.         */
	else if (evnt & NAK)
	{
		evnt=read_usb(NAKEV);           /*如果为NAK*/
		if      (evnt&NAK_O0) onak0();  /*endpoint 0              */
		else if (evnt&NAK_O1) onak1();  /*endpoint 2(not use)     */
		else if (evnt&NAK_O2) onak2();  /*endpoint 4(not use)     */
		else if (evnt&NAK_O3) onak3();	/*endpoint 6(not use)     */
		else if (evnt&NAK_I0) inak0();  /*endpoint 0(not use)     */
		else if (evnt&NAK_I1) inak1();  /*endpoint 1(not use)     */
		else if (evnt&NAK_I2) inak2();  /*endpoint 2(not use)     */
		else if (evnt&NAK_I3) inak3();  /*endpoint 5              */
		else                            /*some other NAK event    */
		{
		}
	}

	else                                /*如果为其它的未能识别的事件*/
	{
	}

	/*由于USBN9603 的中断为电平触发型,而有些MCU的中断触发为边沿型   */
	/*为了使程序有更好的移植性,先禁止USBN9603中断输出,然后再使能它  */
	/*从而得到下一次中断产生时的触发边沿。                          */
	evnt=read_usb(MAMSK);               /*保存原来的中断设置    */
	write_usb(MAMSK,0);                 /*禁止USBN9603的中断输出*/
	write_usb(MAMSK,evnt);              /*恢复原来的中断设置    */
	evnt=0;	/*clear the evnt flag*/
}
/*******************************************************************
*****                       初始化USBN9603                      *****
*******************************************************************/
void init_usb(void)
{
	
	/*toss out any previous state ***********************************/
  	CLR_MLTIPKT;/*exit multi-packet mode  */
  	usb_cfg	=0;

	/*对USBN9603进行一次软件复位*/
	write_usb(MCNTRL,SRST);	/*写 0x01 到 MCNTRL*/
	/*INTOC(1-0)=00	:禁止中断输出      */
	/*NAT=0			:禁止被USB总线检测 */
	/*VEG=0			:禁止内部3.3V稳压  */
	/*SRST=1		:进行软件复位      */

	/*等待软件复位完成*/
	while(read_usb(MCNTRL)&0x01==0x00)
	{
		usb_cfg=0;
	}
	
	evnt=read_usb(RID);		/*读取USBN9603的版本识别号*/
	/*该数值因为0x02,由此可判断USBN9603是否被正确地挂在总线上*/
	if(evnt==0x02)
	{
		Uart_Printf("\n*                USBN9603 is found!                                     *");
		Uart_Printf("\n*                USB interface is active now!                           *");
		Uart_Printf("\n*-----------------------------------------------------------------------*");
	}
	else
		Uart_Printf("\nUSBN9603 is not found!Pls check your hardware!");
	
	write_usb(MCNTRL,VGE+INT_L_O); /*写0x04+0x40=0x44 到 MCNTRL(该句能否省略?)*/
	/*INTOC(1-0)=01	:中断为低电平有效输出*/
	/*VEG=0			:使能内部3.3V稳压   */

	/*设置USBN9603的时钟输出*/
	write_usb(CCONF,CLKDIV);	/*输出时钟频率为4MHZ */
	/* CLKDIV=5=0x0101=11,so frequency=48MHz/(CLKDIV+1)=4MHZ*/

	/*set default address, enable EP0 only **************************/
	write_usb(FAR,AD_EN+0);		/*FAR is "Function Address Register"*/
	/*write 0x80+0x00=0x80 to FAR*/
	/*AD_EN=1		:Address Enable. When set to 1, bits AD6-0 are used in address comparison.*/
	/*               When cleared, the device does not respond to any token on the USB bus.   */
	/*采用寻址方式访问端点*/

	write_usb(EPC0,0x00);	/*设置端点0的寻址地址*/

	/* 设置USBN9603的中断屏蔽位 */
	write_usb(NAKMSK,NAK_O0);                          /*NAK evnts*/
	/*NAK_O0=0x10*/
	/*当EndPoint0收到OUT token时,MAEV中的NAK位将被置位*/
//	write_usb(TXMSK,TXFIFO0);      
	write_usb(TXMSK,TXFIFO0+TXFIFO1+TXFIFO2+TXFIFO3);                  /*TX events*/
	/*使能EndPoint0的发送中断*/
//	write_usb(RXMSK,RXFIFO0);       
	write_usb(RXMSK,RXFIFO0+RXFIFO1+RXFIFO2+RXFIFO3);                  /*RX events*/
	/*使能EndPoint0的接收中断*/

	write_usb(ALTMSK,NORMAL_ALTMSK);
	/*NORMAL_ALTMSK=SD3+RESET_A*/
	/*使能Reset和SD3中断*/
	/*SD3	:Suspend Detect 3 mS. This bit is set after 3 mS of IDLE is detected */
	/*       on the upstream port, indicating that the device should be          */
	/*       suspended. The suspend occurs under firmware control by writing     */
	/*       the suspend value to the Node Functional State (NF-SR) register.    */
	/*       This bit is cleared when the register is read.                      */
	/*RESET	:This bit is set when 2.5 mS of SEO is detected on the upstream port.*/
	/*       In response, the functional state should be reset (NFS in the NFSR  */
	/*       register is set to RESET), where it must remain for at least 100 mS.*/
	/*       The functional state can then return to Op-erational state. This bit*/
	/*       is cleared when the register is read.                               */

	write_usb(MAMSK,(INTR_E+RX_EV+NAK+TX_EV+ALT));
	/*向MAMSK写入INTR_E=0x80(master interrupt enable)*/
	/*        和RX_EV=0x40(receive event)           */
	/*        和NAK=0x10(NAK event)                 */
	/*        和TX_EV=0x04(transmit event)          */
	/*        和ALT=0x02(alternate event)           */
	
	/*enable the receiver and go operational ************************/
	FLUSHTX0;							/*置TX0为Idle,并清除其FIFO的读写指针*/
	
	write_usb(RXC0,RX_EN);              /*使能 RX0接收 */

	write_usb(NFSR,OPR_ST);				/*将OPR_ST=0x02写到NFSR中,置USBN9603为Operational State*/

	write_usb(MCNTRL,VGE+INT_L_O+NAT);	/*允许USB总线检测到USBN9603的接入*/
//	LED1=0;
}

⌨️ 快捷键说明

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