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

📄 usbdrv.c

📁 杭州立宇泰豪华型44B0开发板
💻 C
📖 第 1 页 / 共 4 页
字号:
/*<<<-------------------------------------------------------------------------
 * File Contents:
 *	usb.c - USB related functions
 *
 *  Project: USB Demo firmware
 *  Author : Yan Nosovitsky
 *  Date   : Oct 2001
 *----------------------------------------------------------------------->>>*/
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include "..\Target\44b.h"
#include "..\Target\44blib.h"
#include "Usbdrv.h"
#include "Usb_reg.h"


/*=====================================================================
 *					USB Driver Definitions
 *=====================================================================*/
extern Device_buffers_t device_buffers;//a union
extern void _disable_(void);
extern void _enable_(void);
extern byte code_loaded;

endpoint_t DMA_ep;//endpoint_t is an enum for EP0~EP7

endpoint_status_t tx0_ep_stat; //endpoint_status_t is a struct for endpoint's status
endpoint_status_t tx1_ep_stat, tx2_ep_stat;
endpoint_status_t rx1_ep_stat, rx2_ep_stat;
endpoint_status_t tx3_ep_stat;
State bulkState;
file_status_t FileStat;
byte 		buffer[2*1024];
byte 		*readPtr = buffer;
byte 		*writePtr = buffer;

endpoint_status_t *endpoint_stat[] = //pointer array
{
	&tx0_ep_stat,	
	&tx1_ep_stat,
	&rx1_ep_stat,
	&tx2_ep_stat,
	&rx2_ep_stat,
	&tx3_ep_stat, 
	NULL  
};



void endpoint_status_init(void) {

	int i;

	for(i=0;i<NUM_OF_ENDPOINTS;i++) {
		if (endpoint_stat[i] != NULL) {
			endpoint_stat[i]->FIFO_status = EMPTY;
			if (i==0)
				/*----------------
				* control endpoint
				*-----------------*/
				endpoint_stat[i]->toggle_bit = 0x01;
			else 
				/*----------------------
				* tx & rx data endpoints
				*-----------------------*/
				endpoint_stat[i]->toggle_bit = 0x00;
		}
	}
}

const int usbn9604_tx_endpoint_addr[] =//save the address of EPx TXDx register (0,1,3,5)
{
	TXD0,	/* Endpoint 0 *///register name
	TXD1,	/* Endpoint 1 */
	0xFF,
	TXD2,	/* Endpoint 3 */
	0xFF,
	TXD3,	/* Endpoint 5 */
	0xFF
};

const int usbn9604_rx_endpoint_addr[] =
{
	RXD0,	/* Endpoint 0 */
	0xFF,
	RXD1,	/* Endpoint 2 */
	0xFF,
	RXD2,	/* Endpoint 4 */
	0xFF,
	RXD3	/* Endpoint 6 */
};

const int fifo_sizes[] = 
{
	EP0_FIFO_SIZE,			/* control tx0, rx0 *///=8
	TX_BULK_EP_FIFO_SIZE, 	/* bulk tx *///=64
	RX_BULK_EP_FIFO_SIZE, 	/* bulk rx */
	TX_ISO_EP_FIFO_SIZE,  	/* ISO tx  *///=64
	RX_ISO_EP_FIFO_SIZE,  	/* ISO rx  */
	TX_INTR_EP_FIFO_SIZE, 	/* interrupt tx *///=1
	RX_INTR_EP_FIFO_SIZE  	/* interrupt rx */
};

const int endpoint_to_fifo[] =//the set-bit content for register
{
	TX_FIFO0, /* endpoint0 TX/RX FIFO0 */
	TX_FIFO1, /* endpoint1 */
	RX_FIFO1, /* endpoint2 */
	TX_FIFO2, /* endpoint3 */
	RX_FIFO2, /* endpoint4 */
	TX_FIFO3, /* endpoint5 */
	RX_FIFO3  /* endpoint6 */
};
/*=============================================================================
 *						Data Buffer Definitions
 *=============================================================================*/

control_buffer_t control_send_buffer;//control_buffer_t: include byte array and length(uint)
control_buffer_t control_receive_buffer;

byte request_buffer[EP0_FIFO_SIZE];

void clear_control_buffer(control_buffer_t* control_buff) {

	control_buff->data = NULL;
	control_buff->bytes_counter = 0;
}
/*=====================================================================
 *					USB Driver Implementations
 *=====================================================================*/
/*----------------------------------------------------------------------------------------------
*	Prototype
*		void usb_node_handler()
*
*	Parameters
*		None
*
*	Returns
*		None
*
*	Description
*		 USB interrupt handler.
----------------------------------------------------------------------------------------------*/

//#pragma interrupt(usb_node_handler)//#pragma: can be ignored by other compiler

void __irq usb_node_handler(void){
	byte usbn_event;
	//PCDOUT &= 0x0;
	_disable_();	
	//Uart_Printf("\nenter interrupt");
	/*-------------------
	* Clear the interrupt 
	*-------------------*/
	//ICU_clear_int(USB_NODE_INT);
	
	while(usbn_event = read_usb(MAEV))
	{
		if (usbn_event & RX_EV)
			USBN9604_rx_event_handler();//received OUT command
		if (usbn_event & ALT) 
			USBN9604_alt_event_handler();
		if (usbn_event & TX_EV) 	
			USBN9604_tx_event_handler();//complete transmit a packet
		if (usbn_event & NAK)          //NAK: device is busy
		{
			if (read_usb(NAKEV) & 0x10)//FIFO0 for OUT token
			{/*----------
			  * NAK OUT
			  *---------*/
				FLUSHTX0;
				FLUSHRX0;
				/*------------------
				* re enable receving
				*-------------------*/
				DISABLE_TX(ENDPOINT_0);
				ENABLE_RX(ENDPOINT_0);
			}
		}
	}
	_enable_(); 
}

/*----------------------------------------------------------------------------------------------
*	Prototype
*		void USBN9602_tx_event_handler()
*
*	Parameters
*		None
*
*	Returns
*		None
*
*	Description
*		TX event handler
----------------------------------------------------------------------------------------------*/

/*__inline*/ void USBN9604_tx_event_handler(void)
{
	volatile byte tx_event = TX_EVENTS;//read_usb(TXEV)

	byte evnt_mask = 1;
	byte txstat;
    
	while(tx_event)//transmission done or underrun 
	{
		switch(tx_event & evnt_mask)//FIFO0 Tx 
		{
			case TX_FIFO0:
				
				/*-----------
				* endpoint 0
				* zero tx endpoint
				*-----------*/
				txstat = EP_TXSTATUS(ENDPOINT_0);//read_usb(TXS of EP0);
				if (txstat & ACK_STAT)           //ACK_STAT:the ACK has received for the packet previously sent. 
				{
				  
				  /*--------------------------------------
				  * previous data packet from current 
				  * ep was received successfully by host
				  *-------------------------------------*/
					endpoint_stat[ENDPOINT_0]->FIFO_status = EMPTY;
					if (control_send_buffer.bytes_counter > 0) 
					{
					    //Uart_Printf("\nbb");
						/*-------------------------------------
						* there is additional data to be sent
						*------------------------------------*/
						fill_control_fifo();
						usbn9604_tx_enable(ENDPOINT_0);
					}
					else if (device_buffers.zero_data == 1) 
					{ 
					    /*-------------------
						* zero data required
						*-------------------*/
						device_buffers.zero_data = 0;
						FLUSH_TXEP(ENDPOINT_0);
						usbn9604_tx_enable(ENDPOINT_0);
					}
					else 
					{
					    //Uart_Printf("\nsn");
						FLUSH_TXEP(ENDPOINT_0);
						ENABLE_RX(ENDPOINT_0);	
					}
				}
				else
					//Uart_Printf("\nno");
					/*-------------------
					* there is no ACK
					* Re-enable receiving 
					*--------------------*/
					ENABLE_RX(ENDPOINT_0);	
				break;
			case TX_FIFO1://a data packet completed transmission in response to an IN token 
				/*----------------
				* endpoint 1
				* bulk tx endpoint
				*----------------*/
				txstat = EP_TXSTATUS(ENDPOINT_1);
				if (txstat & ACK_STAT)
				{	
					/*-----------------------------------------------------------------------
					 * previous data packet from current ep was received successfully by host
					 *-----------------------------------------------------------------------*/
					FLUSHTX1;
					BulkTransmitEvent();
				}                               
				else  
					/*------------------------------------
					* there is no ACK
					* retransmit the previous data packet
					*------------------------------------*/
					usbn9604_tx_retransmit_enable(ENDPOINT_1); 	
				break;
			case TX_FIFO2: 
				/*-----------------------
				* endpoint 3
				* isochronous tx endpoint
				*-----------------------*
				txstat = EP_TXSTATUS(ENDPOINT_3);
	//			PCDOUT &= ~0x2;
	//			PCDOUT |=  0x2;
				if (txstat & ACK_STAT)
				{	
					*-----------------------------------------
					* Data was sent in response to an IN token
					*-----------------------------------------*
					FLUSHTX2;
					send_event(EVT_USB_ISO_TX);
				}
				else 
				{
					*------------------------
					* ISO frame was discarded
					* Do nothing
					*------------------------*
				}*/
				break;
			case TX_FIFO3:
				/*-----------------------
				* endpoint 5
				* interrupt tx endpoint
				*-----------------------*
				txstat = EP_TXSTATUS(ENDPOINT_5);
				if (txstat & ACK_STAT)
				{	
					*-----------------------------------------------------------------------
					 * previous data packet from current ep was received successfully by host
					 *-----------------------------------------------------------------------*
					 FLUSHTX3;
				}
				else 
					*------------------------------------
					* there is no ACK
					* retransmit the previous data packet
					*------------------------------------*
					usbn9604_tx_retransmit_enable(ENDPOINT_5);*/
				break;		
			case TX_UDRN0:
			case TX_UDRN1:
			case TX_UDRN2:
			case TX_UDRN3:
				break;
			default:
				/*-------------------------------
				*  No event with this event mask 
				*-------------------------------*/
				break;
		}
		tx_event &= ~evnt_mask;
		evnt_mask = evnt_mask << 1;
	}
}


/*----------------------------------------------------------------------------------------------
*	Prototype
*		void USBN9604_alt_event_handler()
*
*	Parameters
*		None
*
*	Returns
*		None
*
*	Description
*		ALT event handler
----------------------------------------------------------------------------------------------*/

void USBN9604_alt_event_handler(void)
{
	volatile byte alt_event = ALT_EVENTS;//read_usb(ALTEV)
	volatile byte dma_event = 0;
	byte evnt_mask = 1;
	byte tmp = 0;
	extern void USB_dev_reset(void);

	while(alt_event) 
	{
		switch(alt_event & evnt_mask) 
		{
			case ALT_DMA: 
				Uart_Printf("\nalt1");
				/*------------
				*  DMA events 
				*------------*/
				dma_event = DMA_EVENTS ;
				/*--------------------------------
				* clear all dma events to be sure
				*--------------------------------*/
				write_usb(DMAEV,0x00);		
				switch (dma_event&0xf){
					case DMA_DSIZ:
						/*----------------------------------------------------------
						* Only for DMA receive operation 
						* It indicates that a packet has been received which is less
						* then the full length of the FIFO. This normally indicates 
						* the end of transfer.
						* ---------------------------------------------------------*/
						/*------------------
						*  update toggle bit
						*-------------------*/
						if (DMA_NTGL&dma_event)
							endpoint_stat[DMA_ep]->toggle_bit = 1;
						else
							endpoint_stat[DMA_ep]->toggle_bit = 0;

						/*------------------------
						* Insert your code here
						*------------------------*/
						break;
					case DMA_DCNT:      	  
						/*-------------------------------------
						* DMA count (DMA Count) regiser is 0
						* ADMA is stopped
						*------------------------------------*/
						/*-----------------
						* update toggle bit
						*------------------*/
						tmp = read_usb(DMACNTRL);
						if (DMA_NTGL&dma_event)
						{
							tmp |= DMA_DTGL;
							endpoint_stat[DMA_ep]->toggle_bit = 1;
						}
						else
						{

⌨️ 快捷键说明

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