?? usb_drv.c
字號:
/*C**************************************************************************
* NAME: usb_drv.c
*----------------------------------------------------------------------------
* Copyright (c) 2003 Atmel.
*----------------------------------------------------------------------------
* RELEASE: snd1c-refd-nf-4_0_3
* REVISION: 1.12
*----------------------------------------------------------------------------
* PURPOSE:
* This file contains the USB driver routines
*
* NOTES:
* Driver Configuration (see config.h):
* - VENDOR_ID enum vendor ID delivered by USB organisation
* - PRODUCT_ID enum product number
* - RELEASE_NUMBER enum release number
* - USB_MANUFACTURER_NAME mass storage manufacturer string (unicode)
* - USB_MN_LENGTH mass storage manufacturer string length
* - USB_PRODUCT_NAME mass storage product name string (unicode)
* - USB_PN_LENGTH mass storage product name string length
* - USB_SERIAL_NUMBER mass storage product serial nb string (unicode)
* - USB_SN_LENGTH mass storage product serial nb string length
*****************************************************************************/
/*_____ I N C L U D E S ____________________________________________________*/
#include "config.h" /* system configuration */
#include "usb_drv.h" /* usb driver definition */
/*_____ 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, 0x1001, 0, 0, 0, EP_CONTROL_LENGTH,
VENDOR_ID, PRODUCT_ID, RELEASE_NUMBER, MAN_INDEX, PROD_INDEX, SN_INDEX, 1
};
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, 0x0904
};
code struct
{
struct usb_st_configuration_descriptor cfg;
struct usb_st_interface_descriptor ifc;
struct usb_st_endpoint_descriptor ep1;
struct usb_st_endpoint_descriptor ep2;
}
usb_configuration =
{
{ 9, CONFIGURATION, sizeof(usb_configuration) << 8, 1, 1, 0, USB_CONFIG_BUSPOWERED, 0x32},
{ 9, INTERFACE, 0, 0, 2, 0x08, 0x06, 0x50, 0 },
{ 7, ENDPOINT, 0x81, 0x02, EP_IN_LENGTH << 8, 0 },
{ 7, ENDPOINT, 0x02, 0x02, EP_OUT_LENGTH << 8, 0 }
};
static bdata bit zlp;
static idata Byte endpoint_status[3];
static idata Byte *pbuffer;
static idata Byte bmRequestType;
/*_____ D E C L A R A T I O N ______________________________________________*/
extern void usb_mass_storage_reset (void);
extern void usb_mass_storage_get_lun (void);
static void usb_get_descriptor (void);
static Byte* send_ep0_packet (Byte *, Byte);
static void usb_read_request (void);
static void usb_set_address (void);
static void usb_set_configuration (void);
static void usb_clear_feature (void);
static void usb_set_feature (void);
static void usb_get_status (void);
static void usb_get_configuration (void);
/*F**************************************************************************
* NAME: usb_init
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function initializes the USB controller and resets the endpoints FIFOs.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_init (void)
{
Usb_enable(); /* enable USB */
UEPRST = 0x07; /* Reset EP 0, 1 and 2 */
UEPRST = 0x00;
endpoint_status[EP_CONTROL] = 0x00;
endpoint_status[EP_IN] = 0x00;
endpoint_status[EP_OUT] = 0x00;
Usb_select_ep(EP_CONTROL); /* control endpoint config */
UEPCONX = CONTROL;
}
/*F**************************************************************************
* NAME: usb_ep_init
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function configures the endpoints.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_ep_init (void)
{
Usb_select_ep(EP_CONTROL);
UEPCONX = CONTROL;
Usb_select_ep(EP_IN); /* endpoints configuration */
UEPCONX = BULK_IN ;
Usb_select_ep(EP_OUT);
UEPCONX = BULK_OUT;
UEPRST = 0x07;
UEPRST = 0x00;
}
/*F**************************************************************************
* NAME: usb_send_ep0_packet
*----------------------------------------------------------------------------
* PARAMS:
* *tbuf: address of the first data to send
* data_length: number of bytes to send
*
* return: address of the next byte to send
*----------------------------------------------------------------------------
* PURPOSE:
* This function sends the data over the default control endpoint.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
Byte* send_ep0_packet (Byte *tbuf, Byte data_length)
{
Byte i;
Usb_select_ep(EP_CONTROL);
for (i = data_length; i != 0 ; i--, tbuf++)
{
Usb_write_byte(*tbuf);
}
Usb_set_TXRDY(); /* Send packet */
return tbuf;
}
/*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
* 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:
usb_clear_feature();
break;
case SET_FEATURE:
usb_set_feature();
break;
case GET_STATUS:
usb_get_status();
break;
case GET_MAX_LUN:
usb_mass_storage_get_lun();
break;
case MASS_STORAGE_RESET:
usb_mass_storage_reset();
break;
default:
Usb_clear_RXSETUP();
Usb_set_STALLRQ();
while (!Usb_STALL_sent());
Usb_clear_STALLRQ();
Usb_clear_STALLED();
break;
}
}
/*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)
{
Byte add;
Usb_clear_DIR();
add = Usb_read_byte(); /* store the LSB of wValue = address */
UEPRST = 0x01 ;
UEPRST = 0x00 ;
Usb_clear_RXSETUP();
Usb_set_TXRDY(); /* send a ZLP for STATUS phase */
Usb_set_FADDEN();
while (!(Usb_tx_complete()));
Usb_clear_TXCMPL();
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();
Usb_clear_DIR();
Usb_clear_RXSETUP();
Usb_set_TXRDY(); /* send a ZLP for STATUS phase */
if (configuration_number == 0)
{
Usb_clear_CONFG();
}
else
{
Usb_set_CONFG();
}
while (!Usb_tx_complete());
Usb_clear_TXCMPL();
Usb_select_ep(EP_IN); /* endpoints configuration */
UEPCONX = BULK_IN ;
Usb_select_ep(EP_OUT);
UEPCONX = BULK_OUT;
}
/*F**************************************************************************
* NAME: usb_get_descriptor
*----------------------------------------------------------------------------
* PARAMS:
*
* return:
*----------------------------------------------------------------------------
* PURPOSE:
* This function manages the GET_DESCRIPTOR request.
*----------------------------------------------------------------------------
* EXAMPLE:
*----------------------------------------------------------------------------
* NOTE:
*----------------------------------------------------------------------------
* REQUIREMENTS:
*****************************************************************************/
void usb_get_descriptor (void)
{
Byte data_to_transfer;
Uint16 wLength;
Byte descriptor_type;
Byte string_type;
Usb_set_DIR(); /* set out on EP0 */
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 = &(usb_device_descriptor.bLength);
break;
}
case CONFIGURATION:
{
data_to_transfer = sizeof (usb_configuration);
pbuffer = &(usb_configuration.cfg.bLength);
break;
}
case STRING:
{
switch (string_type)
{
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -