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

📄 usb_cdc_enum.c

📁 C89c51 usb驱动程序,实现了usb转串口的功能,提供了一个虚拟的串口
💻 C
📖 第 1 页 / 共 2 页
字号:
/*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 + -