📄 usb.c
字号:
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 + -