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

📄 usbdrv.c

📁 USBN9603的DEMO程序
💻 C
📖 第 1 页 / 共 2 页
字号:
				CLEAR_STALL_EP0;
				request_length = min(fifo_sizes[ep_num], RX_EP_COUNTER(ep_num));
				/*-------------------------
				* Receive request from hub 
				*-------------------------*/
				for(i=0; i<request_length; i++) 
					request_buffer[i] = EP_FIFO_READ(ENDPOINT_0);

				control_receive_buffer.data = (byte *)request_buffer;
				control_receive_buffer.bytes_counter = request_length;

				FLUSH_TXEP(ENDPOINT_0);	
				FLUSH_RXEP(ENDPOINT_0);
				USB_device_req_handler();

			}
			/*------------------------------------------------------------
			* OUT packet of Status stage in control read/write sequence 
			*----------------------------------------------------------*/
			else 
			{
				/*--------------------
				* Re-enable receiving 
				*-------------------*/
				FLUSHTX0;
				FLUSHRX0;
				ENABLE_RX(ENDPOINT_0);
				clear_control_buffer(&control_send_buffer);
			}
			break;
		case RX_FIFO1: 
			/*-------------------
			* endpoint 2 bulk OUT
			*-------------------*/
			ep_num = ENDPOINT_2;

			rxstat = EP_RXSTATUS(ep_num);
			if (rxstat & RX_ERR) 
			{	
				/*-------------------
				* receive media error
				*--------------------*/
				FLUSH_RXEP(ep_num);
				ENABLE_RX(ep_num);
				break;
			}
			Toggle = endpoint_stat[ep_num]->toggle_bit;
			Toggle <<= 5;
			if ((rxstat & RX_LAST) && ((rxstat & RX_TOGL) ==  Toggle ))
			{	
				/*-------------------------
				* received data is correct
				*-------------------------*/
				endpoint_stat[ep_num]->toggle_bit = endpoint_stat[ep_num]->toggle_bit ? 0 : 1;
				send_event(EVT_USB_BULK_RX);
			}
			else 
			{
				/*--------------------------------
				* response to the toggle bit error
				* response to the receive error	
				*--------------------------------*/	
				FLUSH_RXEP(ep_num);
				ENABLE_RX(ep_num);

			}
			break;		
		case RX_FIFO2: 
			/*----------------
			 * endpoint 4 
			 * isochronous OUT
			 *----------------*/
			rxstat = EP_RXSTATUS(ENDPOINT_4);
			if ((rxstat & RX_ERR) &&!(rxstat & RX_LAST))
			{
				/*-------------------
				* receive media error
				*--------------------*/
				FLUSH_RXEP(ENDPOINT_4);
				ENABLE_RX(ENDPOINT_4);
				break;
			}
			/*-------------------------
			* received data is correct
			*-------------------------*/			
			send_event(EVT_USB_ISO_RX);
			break;
		case RX_FIFO3:
			break;
		case RX_OVRN0:
			break;
		case RX_OVRN1:
			break;
		case RX_OVRN2:
			break;
		case RX_OVRN3:
			break;
		default:
			/*------------------------------
			* No event with this event mask 
			*------------------------------*/
			break;
	}
	rx_event &= ~evnt_mask;
	evnt_mask = evnt_mask << 1;
	}
}

/*=====================================================================
 *			Usb module external interface implementations
 *=====================================================================*/
/*----------------------------------------------------------------------------------------------
*	Prototype
*		void USB_Transmit_Data (int data_size, BYTE* data_ptr, endpoint_t ep_num)
*
*	Parameters
*		data_size - size of data (in bytes) to be sent
*		data_ptr  - pointer to data to be sent
*		ep_num	  - number of transmit endpoint
*
*	Returns
*		Number of byes that was write to the fifo
*
*	Description
*		Fill corresponding endpoint with the new data. The data size to be written to the FIFO
*		is the minimum between requested size and FIFO size.
-------------------------------------------------------------------------------------------------*/

 byte USB_Transmit_Data (int data_size, BYTE* data_ptr, endpoint_t ep_num) 
 {
	byte i;
	byte size;
	

	_disable_();
	FLUSH_TXEP(ep_num);

	/*-------------------------------------------------
	* assure that data size is no more then fifo length
	*--------------------------------------------------*/
	size = min(data_size, fifo_sizes[ep_num]); 

	/*-------------------------------------------
	* Now data size is no more than the fifo length,
	* transfer the data directly to the fifo
	*--------------------------------------------*/
	USBADDR = usbn9604_tx_endpoint_addr[ep_num];
	for (i=0;i<size;i++) 
		/*-----------------------------------
		 * transfer data directly to the fifo
		 * address updating is not needed
		 *-----------------------------------*/
		USBDATA = data_ptr[i];

	/*---------------------------
	 * enable  data transmittion 
	 *---------------------------*/
	usbn9604_tx_enable(ep_num);

	_enable_();
	
	return size;
}


/*----------------------------------------------------------------------------------------------
*	Prototype
*		void USB_Receive_Data (BYTE* data_ptr, endpoint_t ep_num)
*
*	Parameters
*		data_ptr  - pointer to the local buffer
*		ep_num	  - number of receive endpoint
*
*	Returns
*		Number of byes that was read from the FIFO.
*
*	Description
*		Read whole corresponding endpoint to the local buffer. 
-------------------------------------------------------------------------------------------------*/

byte USB_Receive_Data (byte* data_ptr,endpoint_t ep_num) 
{
	byte bytes_count;
	byte bytes_sum = 0;
	int i;

	_disable_();	

	/*-------------------------------------------
	* Read data from the fifo until it's empty
	*-------------------------------------------*/
	do 
	{
		/*-----------------------------------------
		* Read count of bytes presently in the FIFO
		*-----------------------------------------*/
		bytes_count =  RX_EP_COUNTER(ep_num);
		/*---------------------------------------
		* update address register in the Voyager
		* with address of Receive Data register
		*---------------------------------------*/
		USBADDR = usbn9604_rx_endpoint_addr[ep_num];	
		for(i=0;i<bytes_count;i++) 
		{
			/*-----------------------------------
			 * read data directly from the fifo
			 * address updating is not needed
			*-----------------------------------*/
			*(data_ptr ++) = USBDATA; 			
		}
		bytes_sum += bytes_count;
	}
	/*-----------------------------------------------------
	* If the FIFO containes more than 15 bytes, a value 15 is 
	* reported in the counter. Therefore continue reading from the
	* fifo until the counter is less then 15.
	*------------------------------------------------------*/
	while (bytes_count == 0xf); 
	
	/*----------------------------------------------
	* Flush the fifo and re-enable receive operation
	*-----------------------------------------------*/
	FLUSH_RXEP(ep_num);
	ENABLE_RX(ep_num);

	_enable_();
	return bytes_sum;
}




/*=====================================================================
 *			Usb module services implementations
 *=====================================================================*/

/*----------------------------------------------------------------------------------------------
*	Prototype
*		void send_control_data(byte *data_ptr, int data_size)
*
*	Parameters
*		data_ptr - pointer to the data buffer to be send
*		data_size - data buffer size
*
*	Returns
*		None
*
*	Description
*		Sends data through the control pipe
-------------------------------------------------------------------------------------------------*/
 
void send_control_data(byte *data_ptr, int data_size)
{

	FLUSHTX0;
	control_send_buffer.data = data_ptr;
	control_send_buffer.bytes_counter = data_size;
	fill_control_fifo();
	usbn9604_tx_enable(ENDPOINT_0);

}

/*-------------------------------------------------------------
*	Prototype
*		void zero_length_data_response(endpoint_t ep_num)
*
*	Parameters
*		ep_num - endpoint number
*
*	Returns
*		None
*
*	Description
*		Generates zero length data packet
----------------------------------------------------------------*/

void zero_length_data_response(endpoint_t ep_num)
{

	FLUSH_TXEP(ep_num);
//	FLUSH_RXEP(ep_num);
	usbn9604_tx_enable(ep_num);
}

/*------------------------------------------------------------------------------
*	Prototype
*		void fill_control_fifo()
*
*	Parameters
*		None
*
*	Returns
*		None
*
*	Description
*		 Transfers data from the control buffer to zero endpoint control fifo.
----------------------------------------------------------------------------*/

void fill_control_fifo()
{
	byte *data_ptr = control_send_buffer.data;

	/*-----------------------------------
	* number of bytes actually to be sent
	*-----------------------------------*/
	int count = min(control_send_buffer.bytes_counter, EP0_FIFO_SIZE);

	FLUSH_RXEP(ENDPOINT_0);
	FLUSH_TXEP(ENDPOINT_0);

	/*----------------------------------
	* update control buffer parameters
	*----------------------------------*/
	control_send_buffer.data += count;
	control_send_buffer.bytes_counter -= count;	


	while(count--) 
		EP_FIFO_WRITE(ENDPOINT_0, *data_ptr++);


}

/*------------------------------------------------------------------------------
*	Prototype
*		void usbn9604_tx_enable(int ep_num) 
*
*	Parameters
*		ep_num - endpoin number
*
*	Returns
*		None
*
*	Description
*		  Enable tx endpoint transmission
----------------------------------------------------------------------------*/

void usbn9604_tx_enable(int ep_num) 
{

	byte Toggle = endpoint_stat[ep_num]->toggle_bit;
	/*-------------------------------------------
	 * update toggle bit of appropriate endpoint
	 *-------------------------------------------*/
	endpoint_stat[ep_num]->toggle_bit = !endpoint_stat[ep_num]->toggle_bit;
	Toggle = Toggle << 2;

	switch (ep_num){
		case ENDPOINT_0:
			write_usb(EP_TXC(ep_num), Toggle|TX_EN);
			write_usb(EP_RXC(ENDPOINT_0), 0x0);
			break;
		case ENDPOINT_1:
		case ENDPOINT_5: 
			write_usb(EP_TXC(ep_num), Toggle|TX_LAST|TX_EN);
			break;
		case ENDPOINT_3: /* isochronous */
			write_usb(EP_TXC(ep_num), Toggle|TX_LAST|IGN_ISOMSK|TX_EN);
			break;
		}

}

/*------------------------------------------------------------------------------
*	Prototype
*		void usbn9604_tx_retransmit_enable(int ep_num) 
*
*	Parameters
*		ep_num - endpoin number
*
*	Returns
*		None
*
*	Description
*		 Enable tx data retransmission
----------------------------------------------------------------------------*/

void usbn9604_tx_retransmit_enable(int ep_num) 
{
	/*------------------------------
	 * use previous toggle bit value
	 *------------------------------*/
	byte Toggle = endpoint_stat[ep_num]->toggle_bit;
	Toggle = Toggle << 2; 

	if (ep_num == ENDPOINT_0)
		/*-------------------------------------------------
		 * there is no retransmission from the endpoint zero
		 *------------------------------------------------*/
		return;
	else 
		write_usb(EP_TXC(ep_num), Toggle|TX_LAST|TX_EN|RFF);
}


/*----------------------------------------------------------------------------------------------
*	Prototype
*		void USB_init_dma(endpoint_t endPoint)
*
*	Parameters
*		endPoint - Number of Endpoint for DMA support
*
*	Returns
*		None
*
*	Description
*		This is a sample code for dma initialization. This function should be called before starting
*       DMA operation.
----------------------------------------------------------------------------------------------*/
extern USB_endpoint_desc_t *usb_dev_endpoints[];

void USB_init_dma(endpoint_t endPoint)
{
	byte  dmaControl = 0; /* value of DMA control register */
	DMA_ep = endPoint;
	
	/*-------------------------------
	*   update DMA source field 
	*-------------------------------*/
	dmaControl = ((endPoint - 1)&3);  
	
	/*----------------------------------
	*  update DMA Toggle bit if needeed
	*-----------------------------------*/
	if  (IS_EP_ISO(endPoint))
	{ 
		/*----------------------
		* Isochronous endpoint.
		*-----------------------*/
		if (IS_EP_IN(endPoint))
			 /*------------------------------------------------
			 * Transmit endpoint
			 * It seems that in this mode ISO Mask should 
			 * better be ignored.
			 *-----------------------------------------------*/	
			write_usb(EP_TXC(endPoint), IGN_ISOMSK);		 
		else
			 /*------------------------------------------------
			 * Receive endpoint
			 * It seems that in this mode toggle compare should 
			 * better be disabled.
			 *-----------------------------------------------*/
			dmaControl |= IGNRXTGL;
	}		
	else
	{
		/*----------------------------------
		*  update DMA Toggle bit if needeed
		*-----------------------------------*/
		if (endpoint_stat[endPoint]->toggle_bit)
			dmaControl |= DMA_DTGL;
	}
	
	
	/*------------------------------
	* write to DMA control register
	*------------------------------*/
	write_usb(DMACNTRL,dmaControl);
	
	/*--------------------------------
	* clear all dma events to be sure
	*--------------------------------*/
	write_usb(DMAEV,0x00);		
	/*-------------------------------------
	* do automatic error handling if needed
	*------------------------------------*/
	write_usb(DMAERR,0x88);	
	
	/*-------------------------
	* enable DMA interrupts
	*-----------------------*/
	write_usb(DMAMSK,(DMA_DCNT|DMA_DSIZ|DMA_DERR |DMA_DSHLT ));	
	
	/*-----------------------------------------------
	* enable DMA Request interrupt for DMA emulation
	*------------------------------------------------*/
//	ICU_UNMASK_INT(DRQ_INT);	
}

/*----------------------------------------------------------------------------------------------
*	Prototype
*		void USB_start_dma(byte DCOUNT)
*
*	Parameters
*		DCOUNT - (Number of packets to transfer) 
*
*	Returns
*		None
*
*	Description
*		This sample code for strat dma process. Call this function each time DMA fills/empties a page.
*		Note, after calling this function you must set endpoint Enable bit of respective endpoint
*		using  ENABLE_EP(endpoint number) macro.
*		Before starting DMA process, disable interrupt of respective endpoint using 
*       DISABLE_TX_INTS(TX_FIFO[number of FIFO]) for transfer operations or
*		DISABLE_RX_INTS(RX_FIFO[number of FIFO]) for receive operations
----------------------------------------------------------------------------------------------*/
void USB_start_dma(int DCOUNT)
{
	byte  dmaControl = 0; /* value of DMA control register */
	/*-----------------------------------
	* write number of packets to transfer 
	* to DMA count register
	*----------------------------------*/
	write_usb(DMACNT,(DCOUNT -1));
	
	/*----------------------------------------------
	* Set Atomatic DMA Mode and enable DMA operation
	*------------------------------------------------*/
	dmaControl = read_usb(DMACNTRL);
	dmaControl |= (DMA_ADMA | DMA_DEN);
	write_usb(DMACNTRL,dmaControl);
	
}

/*----------------------------------------------------
* For test use
*----------------------------------------------------*/
#pragma interrupt(usb_drq_handler)
void usb_drq_handler(void)
{
//	ICU_clear_int(DRQ_INT);

	_disable_();
    ICU_MASK_INT(DRQ_INT);
	PFDOUT = (PFDOUT & 0x7f);
	while (ICU_STATUS_INT(DRQ_INT))
		 USBDATA = 0x14;
	PFDOUT = (PFDOUT | 0x80);
	ICU_UNMASK_INT(DRQ_INT);
	_enable_(); 
}

⌨️ 快捷键说明

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