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

📄 usbdrv.c

📁 杭州立宇泰的ARMSYS开发系统的USB例子
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "..\include\all.h"

//#include "..\loopback\parser.h"
//#include "..\loopback\command_api.h"




#define BPTG \
__asm__("push $1,r0"); \
__asm__("movw $0,r0"); \
__asm__("lpr sp,carl"); \
__asm__("lpr r0,carh"); \
__asm__("movw $0xc1,r0"); \
__asm__("lpr r0,dcr"); \
__asm__("pop $1, r0"); 

/*=====================================================================
 *					USB Driver Definitions
 *=====================================================================*/
extern Device_buffers_t device_buffers;

endpoint_status_t tx0_ep_stat;
endpoint_status_t tx1_ep_stat, tx2_ep_stat;
endpoint_status_t rx1_ep_stat, rx2_ep_stat;
endpoint_status_t tx3_ep_stat; 

endpoint_status_t *endpoint_stat[] =
{
	&tx0_ep_stat,	//rx0, tx0
	&tx1_ep_stat,
	&rx1_ep_stat,
	&tx2_ep_stat,
	&rx2_ep_stat,
	&tx3_ep_stat, //IN interrupt
	NULL  //interrupt

};

volatile byte direct_send_active;
volatile byte wating_rx_data;

void endpoint_status_init() {

	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[] =
{
	TXD0,	/* Endpoint 0 */
	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
	TX_BULK_EP_FIFO_SIZE, //bulk tx1
	RX_BULK_EP_FIFO_SIZE, //bulk rx1
	TX_BULK_EP_FIFO_SIZE, //bulk tx2
	RX_BULK_EP_FIFO_SIZE, //bulk rx2
	TX_INTR_EP_FIFO_SIZE, //interrupt tx
	RX_INTR_EP_FIFO_SIZE  //interrupt rx
};

const int endpoint_to_fifo[] =
{
	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 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
 *=====================================================================*/
/*---------------------------------------------------------------------
 *              USBN9602_tx_event_handler()
 *
 *  TX event handler
 *
 *  Input:  None
 *  Output: None
 *---------------------------------------------------------------------*/

__inline__ void USBN9604_tx_event_handler(void)
{
	volatile byte tx_event = TX_EVENTS;
	byte evnt_mask = 1;
	byte txstat;
	endpoint_t ep_num;

	byte writeCount = 0;
	byte byteToWrite = 0;

	while(tx_event) {
	switch(tx_event & evnt_mask) {
		case TX_FIFO0: //endpoint 0
		//bulk tx endpoint
		ep_num = ENDPOINT_0;
		goto tx_evnt;
		case TX_FIFO1: //endpoint 1
		//bulk tx endpoint
		ep_num = ENDPOINT_1;
		goto tx_evnt;
		case TX_FIFO3: //endpoint 5
		//interrupt tx endpoint
		ep_num = ENDPOINT_5;

		tx_evnt:
		// Read the Transmit Status Register. 
		txstat = EP_TXSTATUS(ep_num);

		if (txstat & ACK_STAT) {
			//previous data packet from current ep was received successfully by host
			endpoint_stat[ep_num]->FIFO_status = EMPTY;
			switch(ep_num) {
			case ENDPOINT_0:

				if (control_send_buffer.bytes_counter > 0) 
				{
					//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 {
					FLUSH_TXEP(ENDPOINT_0);
					ENABLE_RX(ENDPOINT_0);	// Re-enable receiving 
				}
				break;
			case ENDPOINT_1:
				//keep sending data 
				FLUSHTX1;
				direct_send_active = 0;
				send_event(EVT_USB_BULK_TX);	
				break;
			default:
				break;
			}
		}
		else { //there is no ACK
			switch(ep_num) {
			case ENDPOINT_0:
				ENABLE_RX(ENDPOINT_0);	// Re-enable receiving 
				break;
			case ENDPOINT_1:
				//retransmit the previous data packet
				usbn9604_tx_retransmit_enable(ep_num); 
				break;
			case ENDPOINT_3:
				//not in use
				break;
			case ENDPOINT_5:
				break;
			default:
				break;
			}
		}
		break;
		case TX_FIFO2: //endpoint 3 not in use
		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;
	}
}


/*---------------------------------------------------------------------
 *              USBN9604_alt_event_handler()
 *
 *  ALT event handler
 *
 *  Input:  None
 *  Output: None
 *---------------------------------------------------------------------*/
void USBN9604_alt_event_handler(void)
{
	volatile byte alt_event = ALT_EVENTS;
	byte evnt_mask = 1;
	extern void USB_dev_reset(void);

	while(alt_event) {
	switch(alt_event & evnt_mask) {
		case ALT_RESET:
			CLEAR_STALL_EP0;
			GOTO_STATE(RST_ST);
			write_usb(FAR,AD_EN+0);         /*set default address     */
			write_usb(EPC0, 0x00);          /*enable EP0 only         */
			// Go Reset state 

			reset_usb();
			uja_device_reset();

			// Go operational 
			GOTO_STATE(OPR_ST);

			break;
		case ALT_SD3:
		case ALT_SD5:
			ENABLE_ALT_INTS(ALT_SD3|ALT_RESET|ALT_RESUME);	/* Enable Resume int */
			/* enter suspend state */
			GOTO_STATE(SUS_ST);			  	
			break;
		case ALT_RESUME:
			ENABLE_ALT_INTS(ALT_SD3|ALT_RESET);		/* Disabe Resume int */
			/* Enable receving */
			GOTO_STATE(OPR_ST);			  	/* Operational state */
			ENABLE_RX(ENDPOINT_0);
			break;
		case ALT_EOP:
			break;
		default:
		/* No event with this event mask */
		break;
	}
	alt_event &= ~evnt_mask;
	evnt_mask = evnt_mask << 1;
   }
}

/*---------------------------------------------------------------------
 *              USBN9604_rx_event_handler()
 *
 *  RX event handler
 *
 *  Input:  None
 *  Output: pointer to received data
 *---------------------------------------------------------------------*/
__inline__ void USBN9604_rx_event_handler(void)
{
	volatile byte rx_event = RX_EVENTS;
	byte evnt_mask = 1;
	volatile byte rxstat;
	byte Toggle, i;
	endpoint_t ep_num;
	int request_length;

	byte readCount = 0;
	byte byteToRead = 0;
	byte byteToWrite = 0;


	while(rx_event) {
	switch(rx_event & evnt_mask) {
		case RX_FIFO0: //endpoint 0
		ep_num = ENDPOINT_0;
		clear_control_buffer(&control_receive_buffer);
		/* Is this a setup packet? */
		rxstat = EP_RXSTATUS(ENDPOINT_0);
		if (rxstat & SETUP_R) {
			/* Clear STALL condition */

			//endpoint_status_init();
			endpoint_stat[0]->toggle_bit = 0x01;

			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;
//		goto rx_evnt;


//		rx_evnt:

		rxstat = EP_RXSTATUS(ep_num);
		if (rxstat & RX_ERR) {/*receive media error*/
			FLUSH_RXEP(ep_num);
			break;
		}
		Toggle = endpoint_stat[ep_num]->toggle_bit;
		Toggle <<= 5;
		if ((rxstat & RX_LAST) && ((rxstat & RX_TOGL) == Toggle))
		{	//received data is correct	
			wating_rx_data = 1;
			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 
		case RX_FIFO3: //endpoint 6 interrupt OUT 
		case RX_OVRN0:
		case RX_OVRN1:
		case RX_OVRN2:
		case RX_OVRN3:
		break;
		default:
		/* No event with this event mask */
		break;
	}
	rx_event &= ~evnt_mask;
	evnt_mask = evnt_mask << 1;
	}
}

/*=====================================================================

⌨️ 快捷键说明

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