📄 usb_cdc_enum.c
字号:
/*C**************************************************************************
* NAME: usb_cdc_enum.c
*----------------------------------------------------------------------------
* Copyright (c) 2003 Atmel.
*----------------------------------------------------------------------------
* RELEASE: c5131-usb-cdc-1_0_1
* REVISION: 1.2
*----------------------------------------------------------------------------
* PURPOSE:
* This file contains the USB Endpoint 0 (Control Pipe) management routines
*
*****************************************************************************/
/*_____ I N C L U D E S ____________________________________________________*/
#include "usb_config.h"
#include "a89c5131.h"
#include "c5131_drv.h"
#include "usb_drv.h"
#include "usb_cdc_enum.h"
/*_____ M A C R O S ________________________________________________________*/
/*_____ D E F I N I T I O N ________________________________________________*/
code struct usb_st_device_descriptor usb_device_descriptor =
{
sizeof(usb_device_descriptor), DEVICE, USB_SPECIFICATION, DEVICE_CLASS,
DEVICE_SUB_CLASS, DEVICE_PROTOCOL, EP_CONTROL_LENGTH, VENDOR_ID, PRODUCT_ID,
RELEASE_NUMBER, MAN_INDEX, PROD_INDEX, SN_INDEX, NB_CONFIGURATION
};
code struct usb_st_manufacturer usb_manufacturer =
{ sizeof(usb_manufacturer), STRING, USB_MANUFACTURER_NAME };
code struct usb_st_product usb_product =
{ sizeof(usb_product), STRING, USB_PRODUCT_NAME };
code struct usb_st_serial_number usb_serial_number =
{ sizeof(usb_serial_number), STRING, USB_SERIAL_NUMBER };
code struct usb_st_language_descriptor usb_language =
{ sizeof(usb_language), STRING, LANGUAGE_ID };
code struct
{ struct usb_st_configuration_descriptor cfg;
struct usb_st_interface_descriptor ifc0;
Uchar CS_INTERFACE0[19];
struct usb_st_endpoint_descriptor ep3 ;
struct usb_st_interface_descriptor ifc1;
struct usb_st_endpoint_descriptor ep1 ;
struct usb_st_endpoint_descriptor ep2 ;
}
usb_configuration =
{
{ 9, CONFIGURATION, CONF_LENGTH, NB_INTERFACE, CONF_NB,
CONF_INDEX, CONF_ATTRIBUTES, MAX_POWER},
{ 9, INTERFACE, INTERFACE0_NB, ALTERNATE0, NB_ENDPOINT0, INTERFACE0_CLASS,
INTERFACE0_SUB_CLASS, INTERFACE0_PROTOCOL, INTERFACE0_INDEX },
{ 0x05, 0x24, 0x00, 0x10, 0x01, 0x05, 0x24, 0x01, 0x03, 0x01, 0x04, 0x24, 0x02,
0x06, 0x05, 0x24, 0x06, 0x00, 0x01 },
{ 7, ENDPOINT, ENDPOINT_NB_3, EP_ATTRIBUTES_3, EP_SIZE_3, EP_INTERVAL_3 },
{ 9, INTERFACE, INTERFACE1_NB, ALTERNATE1, NB_ENDPOINT1, INTERFACE1_CLASS,
INTERFACE1_SUB_CLASS, INTERFACE1_PROTOCOL, INTERFACE1_INDEX },
{ 7, ENDPOINT, ENDPOINT_NB_1, EP_ATTRIBUTES_1, EP_SIZE_1, EP_INTERVAL_1 },
{ 7, ENDPOINT, ENDPOINT_NB_2, EP_ATTRIBUTES_2, EP_SIZE_2, EP_INTERVAL_2 },
};
static bit zlp;
static Uchar endpoint_status[4];
static Uchar *pbuffer;
static Uchar bmRequestType;
Uchar line_coding[7];
Uchar usb_configuration_nb;
/*_____ D E C L A R A T I O N ______________________________________________*/
/*F**************************************************************************
* NAME: usb_var_init
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function initializes the USB controller and resets the endpoints FIFOs.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_var_init (void)
{
endpoint_status[1] = 0x00;
endpoint_status[2] = 0x00;
endpoint_status[3] = 0x00;
usb_configuration_nb = 0x00;
line_coding[0] = 0x00; // data terminal rate in bit per second - 4bytes
line_coding[1] = 0xC2;
line_coding[2] = 0x01;
line_coding[3] = 00;
line_coding[4] = 0; // stop bit
line_coding[5] = 0; // parity
line_coding[6] = 8; // data bits
}
/*F**************************************************************************
* NAME: usb_ep_init
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function configures the endpoints.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_ep_init (void)
{
usb_configure_endpoint(1 , BULK_IN);
usb_reset_endpoint(1);
usb_configure_endpoint(2 , BULK_OUT);
usb_reset_endpoint(2);
usb_configure_endpoint(3 , INTERRUPT_IN);
usb_reset_endpoint(3);
}
/*F**************************************************************************
* NAME: usb_enumeration_process
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function manages the enumeration process
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_enumeration_process (void)
{
Usb_select_ep(EP_CONTROL);
usb_read_request();
}
/*F**************************************************************************
* NAME: usb_read_request
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function reads the SETUP request sent to the default control endpoint
* and the appropriate function. When exiting of the usb_read_request
* function, the device is ready to manage the next request.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE: list of supported requests:
* GET_DESCRIPTOR
* GET_CONFIGURATION
* SET_ADDRESS
* SET_CONFIGURATION or SET_REPORT
* CLEAR_FEATURE
* SET_FEATURE
* GET_STATUS
* GET_MAX_LUN
* MASS_STORAGE_RESET
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_read_request (void)
{
bmRequestType = Usb_read_byte(); /* read bmRequestType */
switch (Usb_read_byte()) /* test the bRequest value */
{
case GET_DESCRIPTOR:
usb_get_descriptor(); break;
case GET_CONFIGURATION:
usb_get_configuration(); break;
case SET_ADDRESS:
usb_set_address(); break;
case SET_CONFIGURATION:
usb_set_configuration(); break;
case CLEAR_FEATURE: // or GET_ENCPASULATED_COMMAND //
if(bmRequestType == 0xA1) { cdc_get_encapsulated_command(); }
else {usb_clear_feature();} break;
case SET_FEATURE:
usb_set_feature(); break;
case GET_STATUS: // or SEND_ENCAPSULATED_COMMAND //
if(bmRequestType == 0x21) { cdc_send_encapsulated_command(); }
else {usb_get_status();} break;
case GET_INTERFACE:
usb_get_interface(); break;
/* CDC Specific requests */
case SET_LINE_CODING:
cdc_set_line_coding(); break;
case GET_LINE_CODING:
cdc_get_line_coding(); break;
case SET_CONTROL_LINE_STATE:
cdc_set_control_line_state(); break;
case SEND_BREAK:
cdc_send_break(); break;
case SET_DESCRIPTOR:
case SET_INTERFACE:
case SYNCH_FRAME:
default:
Usb_clear_rx_setup();
Usb_set_stall_request();
while (!Usb_stall_sent());
Usb_clear_stall_request();
Usb_clear_stalled();
break;
}
Usb_clear_DIR();
}
/*F**************************************************************************
* NAME: usb_set_address
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function manages the SET_ADDRESS request. The new address is stored
* in the USBADDR register
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_set_address (void)
{
Uchar add;
add = Usb_read_byte(); /* store the LSB of wValue = address */
Usb_clear_rx_setup();
Usb_set_tx_ready(); /* send a ZLP for STATUS phase */
Usb_set_FADDEN();
while (!(Usb_tx_complete()));
Usb_clear_tx_complete();
Usb_configure_address(add);
}
/*F**************************************************************************
* NAME: usb_set_configuration
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function manages the SET_CONFIGURATION request.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_set_configuration (void)
{
Uchar configuration_number;
configuration_number = Usb_read_byte(); /* read the conf. num. in wValue */
Usb_clear_DIR();
Usb_clear_rx_setup();
/* switch (configuration_number)
{
case 0:
Usb_clear_CONFG();
usb_configurion = 0x00;
break;
case CONF_NB:
Usb_set_CONFG();
Usb_set_usb_configured();
break;
default:
Usb_set_stall_request();
while (!Usb_stall_sent());
Usb_clear_stall_request();
Usb_clear_stalled();
return;
}*/
if (configuration_number <= CONF_NB)
{
usb_configuration_nb = configuration_number;
}
else
{
Usb_set_stall_request();
while (!Usb_stall_sent());
Usb_clear_stall_request();
Usb_clear_stalled();
return;
}
Usb_set_tx_ready(); /* send a ZLP for STATUS phase */
while (!Usb_tx_complete());
Usb_clear_tx_complete();
usb_ep_init(); /* endpoints configuration */
}
/*F**************************************************************************
* NAME: usb_get_descriptor
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function manages the GET_DESCRIPTOR request.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_get_descriptor (void)
{
Uchar data_to_transfer;
Uint16 wLength;
Uchar descriptor_type;
Uchar string_type;
zlp = FALSE; /* no zero length packet */
string_type = Usb_read_byte(); /* read LSB of wValue */
descriptor_type = Usb_read_byte(); /* read MSB of wValue */
switch (descriptor_type)
{
case DEVICE:
{
data_to_transfer = sizeof (usb_device_descriptor);
pbuffer = (Uchar *) &(usb_device_descriptor.bLength);
break;
}
case CONFIGURATION:
{
data_to_transfer = sizeof (usb_configuration);
pbuffer = (Uchar *) &(usb_configuration.cfg.bLength);
break;
}
/* case REPORT:
{
data_to_transfer = SIZE_OF_REPORT;
pbuffer = &(usb_configuration.rep[0]);
break;
}
case HID:
{
data_to_transfer = sizeof(usb_configuration.hid);
pbuffer = &(usb_configuration.hid.bLength);
break;
}
case STRING:
{
switch (string_type)
{
case LANG_ID:
{
data_to_transfer = sizeof (usb_language);
pbuffer = &(usb_language.bLength);
break;
}
case MAN_INDEX:
{
data_to_transfer = sizeof (usb_manufacturer);
pbuffer = &(usb_manufacturer.bLength);
break;
}
case PROD_INDEX:
{
data_to_transfer = sizeof (usb_product);
pbuffer = &(usb_product.bLength);
break;
}
case SN_INDEX:
{
data_to_transfer = sizeof (usb_serial_number);
pbuffer = &(usb_serial_number.bLength);
break;
}
default:
{
Usb_clear_rx_setup();
Usb_set_stall_request();
while ((!(Usb_stall_sent())) && (Usb_setup_received()));
Usb_clear_stalled();
Usb_clear_stall_request();
Usb_clear_DIR();
return;
}
}
break;
}
*/
default:
{
Usb_clear_rx_setup();
Usb_set_stall_request();
while ((!(Usb_stall_sent())) && (Usb_setup_received()));
Usb_clear_stalled();
Usb_clear_stall_request();
Usb_clear_DIR();
return;
}
}
ACC = Usb_read_byte(); /* don't care of wIndex field */
ACC = Usb_read_byte();
((Uchar*)&wLength)[1] = Usb_read_byte(); /* read wLength */
((Uchar*)&wLength)[0] = Usb_read_byte();
if (wLength > data_to_transfer)
{
if ((data_to_transfer % EP_CONTROL_LENGTH) == 0) { zlp = TRUE; }
else { zlp = FALSE; } /* no need of zero length packet */
}
else
{
data_to_transfer = (Uchar)wLength; /* send only requested number of data */
}
Usb_clear_rx_setup() ; /* clear the receive setup flag */
Usb_set_DIR(); /* set out on EP0 */
while (data_to_transfer > EP_CONTROL_LENGTH)
{
pbuffer = usb_send_ep0_packet(pbuffer, EP_CONTROL_LENGTH);
data_to_transfer -= EP_CONTROL_LENGTH;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -