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

📄 usb.c

📁 usbn9603的驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
    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				   *
 *=================================================================*/


/* requests' sequence is according to USB 1.1 spec values */
const USB_req_handler_t usb_vendor_device_req[] =
{
	Gen_Parser,
    Bulk_Parser,
    Interrupt_Parser,
    USB_req_reserved,
};


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

/*----------------------------------------------------------------------------
 *               usb_dev_get_status
 *
 *  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.
 *
 *  Input: pointer to struct of the received USB request
 *  Output: None
 *--------------------------------------------------------------------------*/
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;
	}

    device_buffers.status.msb.as_byte = 0;	/* Clear all reserved bits */
    switch (REQ_RECIPIENT(req)) {
	case DEVICE_REQ:
		if (REQ_INDEX(req).as_bytes.lsb != 0) 
		{
			//device's behaviour is not specified
		    STALL_EP0;
		    return;
		}
	    device_buffers.status.msb.device.wakeup = OFF;/*disable to request remote wakeup*/
	    device_buffers.status.msb.device.selfpowered = OFF; /*bus powered*/
	    break;
	case INTERFACE_REQ:
		if (REQ_INDEX(req).interface.inf_no != 0) {
			//device's behaviour is not specified
		    STALL_EP0;
		    return;
		}
	    device_buffers.status.msb.interface.value = 0;	/* Reserved */
	    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_5:
	    	    device_buffers.status.msb.endpoint.stalled = (IS_EP_STALLED(ep_no))? ON : OFF;
		    break;
		//endpoints not in use
		case ENDPOINT_3:
		case ENDPOINT_4:
		case ENDPOINT_6:
		default: /* undefined endpoint */
		    STALL_EP0;
		    return;
	    }
	    break;
	case OTHER_REQ:
	default: /* undefined recipient */
	    STALL_EP0;
	    return;
    }
    device_buffers.status.lsb = 0;	/* Reserved */
    send_control_data((byte *)&device_buffers.status, sizeof(USB_device_status_t));
}

/*----------------------------------------------------------------------------
 *               usb_dev_clear_feature
 *
 *  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.
 *
 *  Input: pointer to struct of USB request
 *  Output: None
 *--------------------------------------------------------------------------*/
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)
		goto cs_stall;
		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 || uja_dev_endpoints[ep_no] == NULL)
			goto cs_stall;
	    (ep_no == ENDPOINT_0) ? CLEAR_STALL_EP0 : CLEAR_STALL_EP(ep_no);
	    break;
	case OTHER_REQ:
	default:
	    cs_stall:
	    STALL_EP0;
	    break;
    }
}

/*----------------------------------------------------------------------------
 *               usb_dev_set_feature
 *
 *  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.
 *
 *  Input: pointer to struct of USB request
 *  Output: None
 *--------------------------------------------------------------------------*/
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
			goto fs_stall;
		break;
	case INTERFACE_REQ:
	    break;
	case ENDPOINT_REQ:
   	    /*set appropriate endpoint to stall state */
	    if (REQ_VALUE(req).feature.bSelector != ENDPOINT_STALL ||
		    ep_no >= ENDPOINT_LAST || uja_dev_endpoints[ep_no] == NULL)
		goto fs_stall;
	    (ep_no == ENDPOINT_0)? STALL_EP0 : STALL_EP(ep_no);
	    break;
	case OTHER_REQ:
	default:
	fs_stall:
	
		STALL_EP0;
	    break;
    }
}

/*----------------------------------------------------------------------------
 *               usb_dev_set_address
 *
 *  Handles the SET_ADDRESS device request from the USB host.
 *
 *  Input: pointer to struct of USB request
 *  Output: None
 *--------------------------------------------------------------------------*/
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 uja 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;
    }
}

/*----------------------------------------------------------------------------
 *               usb_std_dev_get_descriptor
 *
 *  Handles the standard GET_DESCRIPTOR device request from the USB host.
 *
 *  Input: pointer to struct of USB request
 *  Output: None
 *--------------------------------------------------------------------------*/
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);
	int i;

	switch (REQ_RECIPIENT(req)) {
	case DEVICE_REQ:
		switch (REQ_VALUE(req).descriptor.bDescriptorType) {
		case DEVICE_DESCRIPTOR:
			desc_length = uja_device_desc.bLength;
			desc_buf = (byte *)&uja_device_desc;
			break;
		case CONFIG_DESCRIPTOR:
			desc_length = uja_dev_long_config_desc.uja_dev_config_desc.wTotalLength;
			desc_buf = (byte *)&uja_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
				device_buffers.zero_data=0; 
		else //zero lada length will be required
				device_buffers.zero_data=1; 

		send_control_data(desc_buf, desc_length);

		break;
	case INTERFACE_REQ:
	case ENDPOINT_REQ:
	case OTHER_REQ:
	default:
		STALL_EP0;
		return;
	}
}

/*----------------------------------------------------------------------------
 *               usb_vendor_dev_get_descriptor
 *
 *  Handles the vendor GET_DESCRIPTOR device request from the USB host.
 *
 *  Input: pointer to struct of USB request
 *  Output: None
 *--------------------------------------------------------------------------*/
void usb_vendor_dev_get_descriptor(USB_request_t *req)
{
    int desc_length;
    int desc_index = REQ_VALUE(req).descriptor.bDescriptorIndex;
	UJA_vendor_device_desc_t vendor_desc_buf;
    int max_desc_length = REQ_LENGTH(req);

	
	if (REQ_RECIPIENT(req) == DEVICE_REQ) {
		if (REQ_VALUE(req).descriptor.bDescriptorType == UJA_DEVICE_DESCRIPTOR) {
			desc_length = uja_vendor_dev_desc.bLength;
			switch (desc_index) {
			case HARDWARE_UJA_ID:
				//build uja device descriptor
				//copy uja vendor device desc from RAM to the local buffer
				memcpy((void *)&vendor_desc_buf, (void *)&uja_vendor_dev_desc, sizeof(UJA_vendor_device_desc_t));
				vendor_desc_buf.bDeviceIdValue = GET_DIP_SW1()&0x3f;//get_deep_switch_settings();
				break;
			case CURRENT_UJA_ID:
				//build uja device descriptor
				memcpy((void *)&vendor_desc_buf, (void *)&uja_vendor_dev_desc, sizeof(UJA_vendor_device_desc_t));
				vendor_desc_buf.bDeviceIdValue = uja_device_id.UJA_Device_ID_Value;
				break;
			default: /*unsupported id type index*/
				STALL_EP0;
				break;
			}
		desc_length = (desc_length < max_desc_length)? desc_length : max_desc_length;
		send_control_data((byte*)&vendor_desc_buf, desc_length);

		}
		else { /*unknown descriptor*/
			STALL_EP0;
		}
	}
	else {/*unknown recipient*/
			STALL_EP0;
	}
}


/*----------------------------------------------------------------------------
 *               usb_vendor_dev_set_descriptor
 *
 *  Handles the SET_DESCRIPTOR device request from the USB host.
 *  Not supported request. Stall Endpoint Zero.
 *
 *  Input: pointer to struct of USB request
 *  Output: None
 *--------------------------------------------------------------------------*/
void usb_vendor_dev_set_descriptor(USB_request_t *req)
{
    int desc_index = REQ_VALUE(req).descriptor.bDescriptorIndex;
	u_int desc_recipient = REQ_RECIPIENT(req);

⌨️ 快捷键说明

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