?? usb.c
字號(hào):
*--------------------------------------*/
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;
}
}
/*----------------------------------------------------------------------------------------------
* Prototype
* void usb_std_dev_set_descriptor(USB_request_t *req)
*
* Parameters
* req - pointer to struct of USB request
*
* Returns
* None
*
* Description
* Handles the SET_DESCRIPTOR device request from the USB host.
* Not supported request. Stall Endpoint Zero.
----------------------------------------------------------------------------------------------*/
void usb_std_dev_set_descriptor(USB_request_t *req)
{
STALL_EP0();
}
/*----------------------------------------------------------------------------------------------
* Prototype
* void usb_dev_get_config(USB_request_t *req)
*
* Parameters
* req - pointer to struct of USB request
*
* Returns
* None
*
* Description
* Handles the GET_CONFIGURATION device request from the USB host.
----------------------------------------------------------------------------------------------*/
void usb_dev_get_config(USB_request_t *req)
{
if (DEVICE_STATE(device_status) == DEV_ATTACHED)
{
STALL_EP0();
return;
}
/*-------------------------------------------
* wValue, wIndex, wLength must be zero.
* Otherwize device behavior is not specified.
*--------------------------------------------*/
if (IS_REQ_VALUE_NOT_ZERO(req))
{
STALL_EP0();
return;
}
if (IS_REQ_INDEX_NOT_ZERO(req))
{
STALL_EP0();
return;
}
if (REQ_LENGTH(req) != 0x1)
{
STALL_EP0();
return;
}
switch (REQ_RECIPIENT(req))
{
case DEVICE_REQ:
/*----------------------------------------
* returns configuration number as appears
* at the device configuration register
*---------------------------------------*/
device_buffers.state = (DEVICE_STATE(device_status) == DEV_CONFIGURED)?
usb_dev_long_config_desc.usb_dev_config_desc.bConfigurationValue : 0;
send_control_data((byte *)&device_buffers.state, sizeof(device_buffers.state));
break;
case INTERFACE_REQ:
case ENDPOINT_REQ:
case OTHER_REQ:
default:
STALL_EP0();
break;
}
}
/*----------------------------------------------------------------------------------------------
* Prototype
* void usb_dev_set_config(USB_request_t *req)
*
* Parameters
* req - pointer to struct of USB request
*
* Returns
* None
*
* Description
* Handles the SET_CONFIGURATION device request from the USB host.
----------------------------------------------------------------------------------------------*/
void usb_dev_set_config(USB_request_t *req)
{
int i;
/*-------------------------------------------
* wValue, wIndex, wLength must be zero.
* Otherwize device behavior is not specified.
*--------------------------------------------*/
if (IS_REQ_INDEX_NOT_ZERO(req))
{
STALL_EP0();
return;
}
if (REQ_LENGTH(req) != 0)
{
STALL_EP0();
return;
}
switch (REQ_RECIPIENT(req))
{
case DEVICE_REQ:
if (DEVICE_STATE(device_status) == DEV_ATTACHED)
{
STALL_EP0();
break;
}
if (REQ_VALUE(req).as_bytes.lsb == 0)
{
/*--------------------------------------------------------
* The zero value places the device in unconfigured state
*-------------------------------------------------------*/
if (DEVICE_STATE(device_status) == DEV_CONFIGURED)
{
/*----------------------------------
* Deactivate current configuration
*---------------------------------*/
for (i=1; i<MAX_NUM_OF_ENDPOINTS; i++)
{
if (usb_dev_endpoints[device_status.curAltSetting][i] != NULL)
usb_dev_disable_ep(usb_dev_endpoints[device_status.curAltSetting][i]);
}
SET_DEVICE_STATE(device_status, DEV_ADDRESS);
zero_length_data_response(ENDPOINT_0);
}
else
STALL_EP0();
}
else if (REQ_VALUE(req).as_bytes.lsb == usb_dev_long_config_desc.usb_dev_config_desc.bConfigurationValue)
{
/*----------------------------------
* Deactivate previous configuration
*---------------------------------*/
for (i=1; i<MAX_NUM_OF_ENDPOINTS; i++)
{
if (usb_dev_endpoints[device_status.curAltSetting][i] != NULL)
usb_dev_disable_ep(usb_dev_endpoints[device_status.curAltSetting][i]);
}
device_status.curAltSetting = 0;
/*---------------------------
* Activate this configuration
*---------------------------*/
for (i=0; i<MAX_NUM_OF_ENDPOINTS; i++)
if (usb_dev_endpoints[device_status.curAltSetting][i] != NULL)
{
usb_dev_enable_ep(usb_dev_endpoints[device_status.curAltSetting][i]);
}
endpoint_status_init();
SET_DEVICE_STATE(device_status, DEV_CONFIGURED);
zero_length_data_response(ENDPOINT_0);
}
else
/*---------------------------
* wrong configuration value
*-------------------------*/
STALL_EP0();
break;
case INTERFACE_REQ:
case ENDPOINT_REQ:
case OTHER_REQ:
default:
/*--------------------------------------------------------
* If configuration value is unsupported STALL Enpoint Zero
*---------------------------------------------------------*/
STALL_EP0();
break;
}
}
/*----------------------------------------------------------------------------------------------
* Prototype
* void usb_dev_get_interface(USB_request_t *req)
*
* Parameters
* req - pointer to struct of USB request
*
* Returns
* None
*
* Description
* Handles the GET_INTERFACE device request from the USB host.
----------------------------------------------------------------------------------------------*/
void usb_dev_get_interface(USB_request_t *req)
{
byte interface_no = REQ_INDEX(req).as_bytes.lsb;
if (DEVICE_STATE(device_status) != DEV_CONFIGURED)
{
STALL_EP0();
return;
}
if (interface_no != 0)
{
/*------------------------------------
* only single interface is supported
*-----------------------------------*/
STALL_EP0();
return;
}
if (IS_REQ_VALUE_NOT_ZERO(req))
{
STALL_EP0();
return;
}
if (REQ_LENGTH(req) != 0x1)
{
STALL_EP0();
return;
}
switch (REQ_RECIPIENT(req))
{
case INTERFACE_REQ:
device_buffers.state = device_status.curAltSetting;
send_control_data((byte *)&device_buffers.state, sizeof(device_buffers.state));
break;
/* If Interface value is unsupported STALL Enpoint Zero */
case DEVICE_REQ:
case ENDPOINT_REQ:
case OTHER_REQ:
default:
STALL_EP0();
break;
}
}
/*----------------------------------------------------------------------------------------------
* Prototype
* void usb_dev_set_interface(USB_request_t *req)
*
* Parameters
* req - pointer to struct of USB request
*
* Returns
* None
*
* Description
* Handles the SET_INTERFACE device request from the USB host.
----------------------------------------------------------------------------------------------*/
void usb_dev_set_interface(USB_request_t *req)
{
byte interface_no = REQ_INDEX(req).as_bytes.lsb;
byte altSet = REQ_VALUE(req).as_bytes.lsb;
int i;
if (DEVICE_STATE(device_status) != DEV_CONFIGURED)
{
STALL_EP0();
return;
}
if (interface_no != 0)
{
/*------------------------------------
* only single interface is supported
*-----------------------------------*/
STALL_EP0();
return;
}
if (IS_REQ_VALUE_NOT_ZERO(req))
{
STALL_EP0();
return;
}
if (REQ_LENGTH(req) != 0)
{
STALL_EP0();
return;
}
switch (REQ_RECIPIENT(req))
{
case INTERFACE_REQ:
if (altSet > 1)
{
/*------------------------------------
* Not supported Alternative setting
*-----------------------------------*/
STALL_EP0();
break;
}
if (altSet != device_status.curAltSetting)
{
/*----------------
* Change setting
*----------------*/
/*----------------------------------
* Deactivate previous setting
*---------------------------------*/
for (i=1; i<MAX_NUM_OF_ENDPOINTS; i++)
{
if (usb_dev_endpoints[device_status.curAltSetting][i] != NULL)
usb_dev_disable_ep(usb_dev_endpoints[device_status.curAltSetting][i]);
}
device_status.curAltSetting = altSet;
/*---------------------------
* Activate this configuration
*---------------------------*/
for (i=0; i<MAX_NUM_OF_ENDPOINTS; i++)
if (usb_dev_endpoints[device_status.curAltSetting][i] != NULL)
{
usb_dev_enable_ep(usb_dev_endpoints[device_status.curAltSetting][i]);
}
endpoint_status_init();
}
zero_length_data_response(ENDPOINT_0);
break;
/* If Interface value is unsupported STALL Enpoint Zero */
case DEVICE_REQ:
case ENDPOINT_REQ:
case OTHER_REQ:
default:
STALL_EP0();
break;
}
}
/*----------------------------------------------------------------------------------------------
* Prototype
* void usb_dev_sync_frame(USB_request_t *req)
*
* Parameters
* req - pointer to struct of USB request
*
* Returns
* None
*
* Description
* Handles the SYNCH_FRAME device request from the USB host.
*
* The SYNCH_FRAME device request is not a supported device request
* and stalls endpoint 0 immediately.
----------------------------------------------------------------------------------------------*/
void usb_dev_sync_frame(USB_request_t *req)
{
STALL_EP0();
}
/*----------------------------------------------------------------------------------------------
* Prototype
* void USB_req_reserved(USB_request_t *req)
*
* Parameters
* req - pointer to struct of USB request
*
* Returns
* None
*
* Description
* Place holder for undefined functions in Standard and Vendor device
* request arrays. When it's called that wrong request has been received,
* then stall endpoint 0. The input req is for compatibility only
----------------------------------------------------------------------------------------------*/
void USB_req_reserved(USB_request_t *req)
{
STALL_EP0();
}
/*----------------------------------------------------------------------------------------------
* Prototype
* void USB_req_undefined(USB_request_t *req)
*
* Parameters
* req - pointer to struct of USB request
*
* Returns
* None
*
* Description
*
----------------------------------------------------------------------------------------------*/
void USB_req_undefined(USB_request_t *req)
{
/*----------------------------
* undefined but don't stall;
*---------------------------*/
}
/*----------------------------------------------------------------------------------------------
* Prototype
* void usb_dev_enable_ep(const USB_endpoint_desc_t *ep)
*
* Parameters
* ep - pointer to the endpoint struct
*
* Returns
* None
*
* Description
* Enables the IN/OUT endpoints
----------------------------------------------------------------------------------------------*/
void usb_dev_enable_ep(const USB_endpoint_desc_t *ep)
{
endpoint_t ep_no = ep->bEndpointAddress.address;
if (ep->bEndpointAddress.direction == IN)
FLUSH_TXEP(ep_no);
else
FLUSH_RXEP(ep_no);
/*---------------------------------
* enable endpoint & set its address
*---------------------------------*/
if (ep->bmAttributes== ISOCHRONOUS_ENDPOINT)
write_usb(EPC_ADDR(ep_no), (byte)ep_no | EP_EN | ISO) ;
else
write_usb(EPC_ADDR(ep_no), (byte)ep_no | EP_EN) ;
if (ep->bEndpointAddress.direction == OUT)
ENABLE_RX(ep_no);
}
/*----------------------------------------------------------------------------------------------
* Prototype
* void usb_dev_disable_ep(const USB_endpoint_desc_t *ep)
*
* Parameters
* ep - pointer to the endpoint struct
*
* Returns
* None
*
* Description
* Disables the IN/OUT endpoints
----------------------------------------------------------------------------------------------*/
void usb_dev_disable_ep(const USB_endpoint_desc_t *ep)
{
if (ep->bEndpointAddress.direction == IN)
FLUSH_TXEP(ep->bEndpointAddress.address);
else
FLUSH_RXEP(ep->bEndpointAddress.address);
write_usb(EPC_ADDR(ep->bEndpointAddress.address),0);
}
/*----------------------------------------------------------------------------------------------
* Prototype
* void USB_device_req_handler()
*
* Parameters
* None
*
* Returns
* None
*
* Description
* Handles the device requests from the USB host.
*
* Check the request, if the request has at least one error, it stalls
* endpoint 0. Calls the request specific function.
----------------------------------------------------------------------------------------------*/
void USB_device_req_handler()
{
byte *msg = control_receive_buffer.data;
USB_request_t *req = (USB_request_t *)msg;
if (msg == NULL) return;
switch (REQ_TYPE(req)) {
case STANDARD_REQ:
(*usb_std_device_req[REQ_DEVICE(req)])(req);
device_status.last_req = REQ_DEVICE(req);
break;
case VENDOR_REQ:
(*usb_vendor_device_req[REQ_VENDOR_TYPE(req)])(req);
break;
case CLASS_REQ:
default:
STALL_EP0();
break;
}
}
__inline__ void STALL_EP0()
{
write_usb(EPC0, read_usb(EPC0) | STALL);
ENABLE_TX(ENDPOINT_0);
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -