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

📄 usb.c

📁 USBN9603的DEMO程序
💻 C
📖 第 1 页 / 共 3 页
字号:

const USB_vendor_device_desc_t usb_vendor_dev_desc =
{
    sizeof(USB_vendor_device_desc_t),
    USB_DEVICE_DESCRIPTOR,
	0x0
    
};


/*=================================================================*
 *					String Descriptors 							   *
 *=================================================================*/

/*-------------------
* String descriptors 
*------------------*/
const struct {
    byte	bLength;
    byte	bDescriptorType;
    word	bstring;
} langid_str_desc = {sizeof(langid_str_desc), STRING_DESCRIPTOR, ENGLISH_US};

const struct {
    byte	bLength;
    byte	bDescriptorType;
    char	bstring[sizeof(MANUFACTURER_STR)];
} manufacturer_str_desc = {sizeof(manufacturer_str_desc), STRING_DESCRIPTOR, MANUFACTURER_STR};

const struct {
    byte	bLength;
    byte	bDescriptorType;
    char	bstring[sizeof(PRODUCT_STR)];
} product_str_desc = {sizeof(product_str_desc), STRING_DESCRIPTOR, PRODUCT_STR};

const struct {
    byte	bLength;
    byte	bDescriptorType;
    char	bstring[sizeof(VERSION_STR)];
} version_str_desc = {sizeof(version_str_desc), STRING_DESCRIPTOR, VERSION_STR};


/*------------------------------------------------------
* List of all string descriptors, Be sure that the order
* of the list is the same as String_index_t enum 
*------------------------------------------------------*/
const USB_string_desc_t *string_descs[] = {
    (USB_string_desc_t*)&langid_str_desc,
    (USB_string_desc_t*)&manufacturer_str_desc,
    (USB_string_desc_t*)&product_str_desc,
    (USB_string_desc_t*)&version_str_desc
};


void build_string_desc(USB_string_desc_t* dsc, byte* dsc_buff) 
{
	int i;	
	byte* dsc_buff_p;

	dsc_buff[0] = dsc->bLength;
	dsc_buff[1] = dsc->bDescriptorType;

	/*-------------------------------
	* make the string UNICODE encoded
	* each char is two bytes long
	*-------------------------------*/
	dsc_buff_p = (byte *)(dsc_buff+2);
	for(i=0;i<dsc->bLength; i++) 
	{
		*dsc_buff_p++ = dsc->bstring[i];
		*dsc_buff_p++ = 0x00;
	}

}


/*=================================================================*
 *					Standard device request handlers			   *
 *=================================================================*/


/*-------------------------------------------------------
* requests' sequence is according to USB 1.1 spec values 
*-------------------------------------------------------*/
const USB_req_handler_t usb_std_device_req[] =
{
    usb_dev_get_status,
    usb_dev_clear_feature,
    USB_req_reserved,
    usb_dev_set_feature,
    USB_req_reserved,
    usb_dev_set_address,
    usb_std_dev_get_descriptor,
    usb_std_dev_set_descriptor,
    usb_dev_get_config,
    usb_dev_set_config,
    usb_dev_get_interface,
    usb_dev_set_interface,
    usb_dev_sync_frame,
    USB_req_reserved,
    USB_req_reserved,
    USB_req_reserved
};
/*=================================================================*
 *					Vendor device request handlers				   *
 *=================================================================*/

const USB_req_handler_t usb_vendor_device_req[] =
{
	Gen_Parser,
    Bulk_Parser,
    Interrupt_Parser,
    Iso_Parser,
};


/*============================================================================
 *	
 *				Standard USB device request handlers
 *
 *============================================================================*/
/*----------------------------------------------------------------------------------------------
*	Prototype
*		void usb_dev_get_status(USB_request_t *req)
*
*	Parameters
*		req - pointer to struct of the received USB request
*
*	Returns
*		None
*
*	Description
*  		Handles the GET_STATUS device request from the USB host.
*
*  		The GET_STATUS device request can go to one of three recipients: the device,
*  		the current interface, or a particular endpoint.
*  		1. The device returns its self-powered status and its remote
*   	   wake-up status.
*  		2. The current interface returns, as defined in USB spec, 0.
*  		3. The selected endpoint returns its stall status.
*	
----------------------------------------------------------------------------------------------*/

void usb_dev_get_status(USB_request_t *req)
{
      
	byte ep_no = REQ_INDEX(req).endpoint.ep_num;
	
	if (DEVICE_STATE(device_status) == DEV_ATTACHED) 
	{
		STALL_EP0();
		return;
	}

	if (IS_REQ_VALUE_NOT_ZERO(req)) 
	{
		STALL_EP0();
		return;
	}
	if (REQ_LENGTH(req) != 2) 
	{
		STALL_EP0();
		return;
	}
	/*-----------------------
	* Clear all reserved bits
	*-----------------------*/
    device_buffers.status.msb.as_byte = 0;	
    switch (REQ_RECIPIENT(req)) 
	{
		case DEVICE_REQ:
			if (REQ_INDEX(req).as_bytes.lsb != 0) 
			{
				/*-------------------------------------
				 *device's behaviour is not specified
				 *------------------------------------*/
				STALL_EP0();
				return;
			}
			/*---------------------------------
			 *disable to request remote wakeup
			 *-------------------------------*/
			device_buffers.status.msb.device.wakeup = OFF;
			/*------------
			 *bus powered
			 *-----------*/
			device_buffers.status.msb.device.selfpowered = OFF; 
			break;
		case INTERFACE_REQ:
			if (REQ_INDEX(req).interface.inf_no != 0) 
			{
				/*------------------------------------
				* device's behaviour is not specified
				*------------------------------------*/
				STALL_EP0();
				return;
			}
			/*----------
			* Reserved 
			*---------*/
			device_buffers.status.msb.interface.value = 0;	
			break;
		case ENDPOINT_REQ:
			switch (ep_no) 
			{
				case ENDPOINT_0:
						device_buffers.status.msb.endpoint.stalled = (IS_EP0_STALLED)? ON : OFF;
					break;
				case ENDPOINT_1:
				case ENDPOINT_2:
				case ENDPOINT_3:
				case ENDPOINT_4:
				case ENDPOINT_5:
						device_buffers.status.msb.endpoint.stalled = (IS_EP_STALLED(ep_no))? ON : OFF;
					break;
				/*----------------------
				 * endpoints not in use
				 *---------------------*/
				case ENDPOINT_6:
				default: 
				/*--------------------
				*  undefined endpoint 
				*--------------------*/
					STALL_EP0();
					return;
			}
			break;
		case OTHER_REQ:
		default: 
		/*---------------------
		 * undefined recipient 
		 *-------------------*/
			STALL_EP0();
			return;
	}
	/*---------
	* Reserved 
	*---------*/
    device_buffers.status.lsb = 0;	
    send_control_data((byte *)&device_buffers.status, sizeof(USB_device_status_t));
}
/*----------------------------------------------------------------------------------------------
*	Prototype
*		void usb_dev_clear_feature(USB_request_t *req)
*
*	Parameters
*		req - pointer to struct of USB request
*
*	Returns
*		None
*
*	Description
*  		Handles the CLEAR_FEATURE device request from the USB host.
*
*  		The CLEAR_FEATURE device request can go to one of two recipients:
*  		the device, or a particular endpoint.
*  		1. The device returns a 0 length packet to complete the handshake with 
*     	   the host.
*  		2. The selected endpoint only respond to clear stall commands.
*		
----------------------------------------------------------------------------------------------*/
void usb_dev_clear_feature(USB_request_t *req)
{
  
	byte ep_no = REQ_INDEX(req).endpoint.ep_num;

	if (DEVICE_STATE(device_status) == DEV_ATTACHED) 
	{
		STALL_EP0();
		return;
	}
	if (REQ_LENGTH(req) != 0) 
	{
		STALL_EP0();
		return;
	}

    switch (REQ_RECIPIENT(req)) 
    {
		case DEVICE_REQ:
			/*--------------------------------
			 * wakeup feature is not supported
			 *------------------------------*/
			if (REQ_VALUE(req).feature.bSelector == DEVICE_REMOTE_WAKEUP)
			STALL_EP0();
			break;
		case INTERFACE_REQ:
			break;
		case ENDPOINT_REQ:
			/*-------------------------------------------
			 * clear stall state of appropriate endpoint
			 *-----------------------------------------*/
			if (REQ_VALUE(req).feature.bSelector != ENDPOINT_STALL ||
				ep_no >= ENDPOINT_LAST || usb_dev_endpoints[device_status.curAltSetting][ep_no] == NULL)
				STALL_EP0();
			else
			{
				(ep_no == ENDPOINT_0) ? CLEAR_STALL_EP0 : CLEAR_STALL_EP(ep_no);
				zero_length_data_response(ENDPOINT_0);
			}
			break;
		case OTHER_REQ:
		default:
			STALL_EP0();
			break;
    }
}
/*----------------------------------------------------------------------------------------------
*	Prototype
*		void usb_dev_set_feature(USB_request_t *req)
*
*	Parameters
*		req - pointer to struct of USB request
*
*	Returns
*		None
*
*	Description
*  		Handles the SET_FEATURE device request from the USB host.
*
*  		The SET_FEATURE device request can go to one of two recipients:
*  		the device, or a particular endpoint.
*  		1. The device responds to set remote wake-up commands 
*  		2. The selected endpoint responds to set stall commands.
*		
----------------------------------------------------------------------------------------------*/

void usb_dev_set_feature(USB_request_t *req)
{
    
	byte ep_no = REQ_INDEX(req).endpoint.ep_num;

	if (DEVICE_STATE(device_status) == DEV_ATTACHED) 
	{
		STALL_EP0();
		return;
	}
	if (REQ_LENGTH(req) != 0) 
	{
		STALL_EP0();
		return;
	}

    switch (REQ_RECIPIENT(req)) 
    {
		case DEVICE_REQ:
			if (REQ_VALUE(req).feature.bSelector == DEVICE_REMOTE_WAKEUP)
				/*--------------------------------
				 * remote wakeup is not supported
				 *-------------------------------*/
				STALL_EP0();
			break;
		case INTERFACE_REQ:
			break;
		case ENDPOINT_REQ:
			if (REQ_VALUE(req).feature.bSelector != ENDPOINT_STALL ||
				ep_no >= ENDPOINT_LAST || usb_dev_endpoints[device_status.curAltSetting][ep_no] == NULL)
				STALL_EP0();
			else
			{
				/*-----------------------------------------
				 * set appropriate endpoint to stall state 
				 *---------------------------------------*/
				(ep_no == ENDPOINT_0)? STALL_EP0() : STALL_EP(ep_no);
				zero_length_data_response(ENDPOINT_0);
			}
			break;
		case OTHER_REQ:
		default:
			STALL_EP0();
			break;
    }
}
/*----------------------------------------------------------------------------------------------
*	Prototype
*		void usb_dev_set_address(USB_request_t *req)
*
*	Parameters
*		req - pointer to struct of USB request
*
*	Returns
*		None
*
*	Description
*		Handles the SET_ADDRESS device request from the USB host.
----------------------------------------------------------------------------------------------*/

void usb_dev_set_address(USB_request_t *req)
{
	
	byte address;

	if (IS_REQ_INDEX_NOT_ZERO(req)) 
	{
		/*-----------------------------------------
		 * behavior of the device is not specified
		 *---------------------------------------*/
		STALL_EP0();
		return;
	}
	
	if (REQ_LENGTH(req) != 0x0) 
	{
		/*----------------------------------------
		* behavior of the device is not specified
		*---------------------------------------*/
		STALL_EP0();
		return;
	}
	
	if (DEVICE_STATE(device_status) == DEV_CONFIGURED)
	{
		/*---------------------------------------
		 *behavior of the device is not specified
		 *--------------------------------------*/
		STALL_EP0();
		return;
	}
	
	switch (REQ_RECIPIENT(req)) 
	{
		case DEVICE_REQ:
			/*------------------------
			 * ENABLE_DEFAULT_ADDRESS;
			 *-----------------------*/
			write_usb(EPC0, read_usb(EPC0) | DEF);
			/*-------------------------------------------------------
			 * The setting of device address is delayed in order to
			 * complete successfully the Status stage of this request
			 *------------------------------------------------------*/
			address = REQ_VALUE(req).as_bytes.lsb;
			/*-----------------------
			 * set new device address
			 *----------------------*/
			write_usb(FAR, address|AD_EN);
			/*---------------------------------
			* Enable answer to the set address 
			*--------------------------------*/
			if (REQ_VALUE(req).as_bytes.lsb == 0x0)
				SET_DEVICE_STATE(device_status, DEV_ATTACHED);
			else{
				SET_DEVICE_STATE(device_status, DEV_ADDRESS);
				/*------------------
				* Set usb board leds
				*------------------*/
				SET_ID_LEDS(GET_DIP_SW1());
				SET_USB_LED();
			}
			/*---------------------------------
			* enable zero length data responce
			*---------------------------------*/
			usbn9604_tx_enable(ENDPOINT_0);
			break;
		case INTERFACE_REQ:
		case ENDPOINT_REQ:
		case OTHER_REQ:
		default:
			STALL_EP0();
			break;
    }
}
/*----------------------------------------------------------------------------------------------
*	Prototype
*		void usb_std_dev_get_descriptor(USB_request_t *req)
*
*	Parameters
*		req - pointer to struct of USB request
*
*	Returns
*		None
*
*	Description
*		Handles the standard GET_DESCRIPTOR device request from the USB host.
----------------------------------------------------------------------------------------------*/

void usb_std_dev_get_descriptor(USB_request_t *req)
{
    int desc_length = 0;
    int desc_index = REQ_VALUE(req).descriptor.bDescriptorIndex;
    byte *desc_buf = NULL;
    int max_desc_length = REQ_LENGTH(req);


	switch (REQ_RECIPIENT(req)) 
	{
		case DEVICE_REQ:
			switch (REQ_VALUE(req).descriptor.bDescriptorType) 
			{
				case DEVICE_DESCRIPTOR:
					desc_length = usb_device_desc.bLength;
					desc_buf = (byte *)&usb_device_desc;
					break;
				case CONFIG_DESCRIPTOR:
					desc_length = usb_dev_long_config_desc.usb_dev_config_desc.wTotalLength;
					desc_buf = (byte *)&usb_dev_long_config_desc;
					break;
				case STRING_DESCRIPTOR:
					/*---------------------------------------------------------------
					 * String index 0 for all languages returns an array of two-byte
					 * LANGID codes supported by the device 
					 *-------------------------------------------------------------*/
					if (desc_index < STR_LAST_INDEX && desc_index >= 0)
					 {
						/*---------------------------------------------------------
						 * If the descriptor is longer than the wLength field,
						 * only the initial bytes of the descriptor are returned.
						 * If the descriptor is shorter than the wLength field,
						 * the device indicates the end of the control transfer
						 * by sending NULL character 
						 *-----------------------------------------------------*/

						desc_length = string_descs[desc_index]->bLength;
						desc_buf = (byte *)string_descs[desc_index];
						break;
					}
					/*----------------------------------------------- 
					 * In case of the wrong string index, stall EP0 
					 *---------------------------------------------*/
				default:
					STALL_EP0();
					return;
			}
			desc_length = (desc_length < max_desc_length)? desc_length : max_desc_length;
			if (desc_length%EP0_FIFO_SIZE)
				/*-------------------------------------
				* zero lada length will not be required

⌨️ 快捷键说明

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