June Feather
STM32 USB mutidevice 实现 CDC串口 + Mass内存盘 (二)
STM32 USB mutidevice 实现 CDC串口 + Mass内存盘 (二)

STM32 USB mutidevice 实现 CDC串口 + Mass内存盘 (二)

为了去掉感叹号需要实现每个端点的功能

首先是 ENDP0 控制端点

这个端点 的功能在 USBprop.c里面

主要是一大把函数指针

这是CDC下的 

DEVICE_PROP Device_Property =
  {
    Virtual_Com_Port_init,
    Virtual_Com_Port_Reset,
    Virtual_Com_Port_Status_In,
    Virtual_Com_Port_Status_Out,
    Virtual_Com_Port_Data_Setup,
    Virtual_Com_Port_NoData_Setup,
    Virtual_Com_Port_Get_Interface_Setting,
    Virtual_Com_Port_GetDeviceDescriptor,
    Virtual_Com_Port_GetConfigDescriptor,
    Virtual_Com_Port_GetStringDescriptor,
    0,
    0x40 /*MAX PACKET SIZE*/
  };

这是MassStroage下的

DEVICE_PROP Device_Property =
  {
    MASS_init,
    MASS_Reset,
    MASS_Status_In,
    MASS_Status_Out,
    MASS_Data_Setup,
    MASS_NoData_Setup,
    MASS_Get_Interface_Setting,
    MASS_GetDeviceDescriptor,
    MASS_GetConfigDescriptor,
    MASS_GetStringDescriptor,
    0,
    0x40 /*MAX PACKET SIZE*/
  };
可以看到这一部分都是一样的 我们修改时改个名字即可

DEVICE_PROP Device_Property =
  {
    Composite_init,
    Composite_Reset,
    Composite_Status_In,
    Composite_Status_Out,
    Composite_Data_Setup,
    Composite_NoData_Setup,
    Composite_Get_Interface_Setting,
    Composite_GetDeviceDescriptor,
    Composite_GetConfigDescriptor,
    Composite_GetStringDescriptor,
    0,
    0x40 /*MAX PACKET SIZE*/
  };

下一个函数指针组也是一样的,改个名字就好了

CDC

USER_STANDARD_REQUESTS User_Standard_Requests =
  {
    Virtual_Com_Port_GetConfiguration,
    Virtual_Com_Port_SetConfiguration,
    Virtual_Com_Port_GetInterface,
    Virtual_Com_Port_SetInterface,
    Virtual_Com_Port_GetStatus,
    Virtual_Com_Port_ClearFeature,
    Virtual_Com_Port_SetEndPointFeature,
    Virtual_Com_Port_SetDeviceFeature,
    Virtual_Com_Port_SetDeviceAddress
  };
MassStroage

USER_STANDARD_REQUESTS User_Standard_Requests =
  {
    Mass_Storage_GetConfiguration,
    Mass_Storage_SetConfiguration,
    Mass_Storage_GetInterface,
    Mass_Storage_SetInterface,
    Mass_Storage_GetStatus,
    Mass_Storage_ClearFeature,
    Mass_Storage_SetEndPointFeature,
    Mass_Storage_SetDeviceFeature,
    Mass_Storage_SetDeviceAddress
  };
如下
USER_STANDARD_REQUESTS User_Standard_Requests =
  {
    Composite_GetConfiguration,
    Composite_SetConfiguration,
    Composite_GetInterface,
    Composite_SetInterface,
    Composite_GetStatus,
    Composite_ClearFeature,
    Composite_SetEndPointFeature,
    Composite_SetDeviceFeature,
    Composite_SetDeviceAddress
  };

可以看到这些函数指针都是一样的,但是CDC和Mass的函数实现不同,我们需要把它们和到一起。

首先去看usbprop.h

可以看到

#define Virtual_Com_Port_GetConfiguration          NOP_Process
//#define Virtual_Com_Port_SetConfiguration          NOP_Process
#define Virtual_Com_Port_GetInterface              NOP_Process
#define Virtual_Com_Port_SetInterface              NOP_Process
#define Virtual_Com_Port_GetStatus                 NOP_Process
#define Virtual_Com_Port_ClearFeature              NOP_Process
#define Virtual_Com_Port_SetEndPointFeature        NOP_Process
#define Virtual_Com_Port_SetDeviceFeature          NOP_Process
//#define Virtual_Com_Port_SetDeviceAddress          NOP_Process

CDC只要2函数 其他都为nop


#define Mass_Storage_GetConfiguration          NOP_Process
/* #define Mass_Storage_SetConfiguration          NOP_Process*/
#define Mass_Storage_GetInterface              NOP_Process
#define Mass_Storage_SetInterface              NOP_Process
#define Mass_Storage_GetStatus                 NOP_Process
/* #define Mass_Storage_ClearFeature              NOP_Process*/
#define Mass_Storage_SetEndPointFeature        NOP_Process
#define Mass_Storage_SetDeviceFeature          NOP_Process
/*#define Mass_Storage_SetDeviceAddress          NOP_Process*/
Mass则实现了3个,其中2个重合

我们先修改注释掉这3个nop

#define Composite_GetConfiguration          NOP_Process
//#define Composite_SetConfiguration          NOP_Process
#define Composite_GetInterface              NOP_Process
#define Composite_SetInterface              NOP_Process
#define Composite_GetStatus                 NOP_Process
//#define Composite_ClearFeature              NOP_Process
#define Composite_SetEndPointFeature        NOP_Process
#define Composite_SetDeviceFeature          NOP_Process
//#define Composite_SetDeviceAddress          NOP_Process


然后去看这些函数,主要是看这些函数都做了什么
CDC中

/*******************************************************************************
* Function Name  : Virtual_Com_Port_SetConfiguration.
* Description    : Update the device state to configured.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Virtual_Com_Port_SetConfiguration(void)
{
  DEVICE_INFO *pInfo = &Device_Info;
 
  if (pInfo->Current_Configuration != 0)
  {
    /* Device configured */
    bDeviceState = CONFIGURED;
  }
}
 
/*******************************************************************************
* Function Name  : Virtual_Com_Port_SetConfiguration.
* Description    : Update the device state to addressed.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Virtual_Com_Port_SetDeviceAddress (void)
{
  bDeviceState = ADDRESSED;
}

Mass
/*******************************************************************************
* Function Name  : Mass_Storage_SetConfiguration
* Description    : Handle the SetConfiguration request.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Mass_Storage_SetConfiguration(void)
{
  if (pInformation->Current_Configuration != 0)
  {
    /* Device configured */
    bDeviceState = CONFIGURED;
   
    ClearDTOG_TX(ENDP1);
    ClearDTOG_RX(ENDP2);
 
    Bot_State = BOT_IDLE; /* set the Bot state machine to the IDLE state */
  }
}
 
/*******************************************************************************
* Function Name  : Mass_Storage_ClearFeature
* Description    : Handle the ClearFeature request.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Mass_Storage_ClearFeature(void)
{
  /* when the host send a CBW with invalid signature or invalid length the two
     Endpoints (IN & OUT) shall stall until receiving a Mass Storage Reset     */
  if (CBW.dSignature != BOT_CBW_SIGNATURE)
    Bot_Abort(BOTH_DIR);
}
 
/*******************************************************************************
* Function Name  : Mass_Storage_SetConfiguration.
* Description    : Update the device state to addressed.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Mass_Storage_SetDeviceAddress (void)
{
  bDeviceState = ADDRESSED;
}
可以看到 CDC做的Mass都做了,所以直接用Mass的修改下名字即可 

/*******************************************************************************
* Function Name  : Composite_SetConfiguration.
* Description    : Udpade the device state to configured.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Composite_SetConfiguration(void)
{
  DEVICE_INFO *pInfo = &Device_Info;
 
  if (pInfo->Current_Configuration != 0)
  {
    /* Device configured */
    bDeviceState = CONFIGURED;
    ClearDTOG_TX(ENDP4);
    ClearDTOG_RX(ENDP5);
    Bot_State = BOT_IDLE; /* set the Bot state machine to the IDLE state */
  }
}
 
/*******************************************************************************
* Function Name  : Composite_SetConfiguration.
* Description    : Udpade the device state to addressed.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Composite_SetDeviceAddress (void)
{
  bDeviceState = ADDRESSED;
}
 
void Composite_ClearFeature (void)
{
    if (CBW.dSignature != BOT_CBW_SIGNATURE)
    Bot_Abort(BOTH_DIR);
}

下面需要一个一个看init Reset这些函数的实现并且融合
这里以Reset看

/*******************************************************************************
* Function Name  : Virtual_Com_Port_Reset
* Description    : Virtual_Com_Port Mouse reset routine
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Virtual_Com_Port_Reset(void)
{
  /* Set Virtual_Com_Port DEVICE as not configured */
  pInformation->Current_Configuration = 0;
 
  /* Current Feature initialization */
  pInformation->Current_Feature = Virtual_Com_Port_ConfigDescriptor[7];
 
  /* Set Virtual_Com_Port DEVICE with the default Interface*/
  pInformation->Current_Interface = 0;
 
  SetBTABLE(BTABLE_ADDRESS);
 
  /* Initialize Endpoint 0 */
  SetEPType(ENDP0, EP_CONTROL);
  SetEPTxStatus(ENDP0, EP_TX_STALL);
  SetEPRxAddr(ENDP0, ENDP0_RXADDR);
  SetEPTxAddr(ENDP0, ENDP0_TXADDR);
  Clear_Status_Out(ENDP0);
  SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
  SetEPRxValid(ENDP0);
 
  /* Initialize Endpoint 1 */
  SetEPType(ENDP1, EP_BULK);
  SetEPTxAddr(ENDP1, ENDP1_TXADDR);
  SetEPTxStatus(ENDP1, EP_TX_NAK);
  SetEPRxStatus(ENDP1, EP_RX_DIS);
 
  /* Initialize Endpoint 2 */
  SetEPType(ENDP2, EP_INTERRUPT);
  SetEPTxAddr(ENDP2, ENDP2_TXADDR);
  SetEPRxStatus(ENDP2, EP_RX_DIS);
  SetEPTxStatus(ENDP2, EP_TX_NAK);
 
  /* Initialize Endpoint 3 */
  SetEPType(ENDP3, EP_BULK);
  SetEPRxAddr(ENDP3, ENDP3_RXADDR);
  SetEPRxCount(ENDP3, VIRTUAL_COM_PORT_DATA_SIZE);
  SetEPRxStatus(ENDP3, EP_RX_VALID);
  SetEPTxStatus(ENDP3, EP_TX_DIS);
 
  /* Set this device to response on default address */
  SetDeviceAddress(0);
  
  bDeviceState = ATTACHED;
}
 
/*******************************************************************************
* Function Name  : MASS_Reset
* Description    : Mass Storage reset routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void MASS_Reset()
{
  /* Set the device as not configured */
  Device_Info.Current_Configuration = 0;
 
  /* Current Feature initialization */
  pInformation->Current_Feature = MASS_ConfigDescriptor[7];
 
  SetBTABLE(BTABLE_ADDRESS);
 
  /* Initialize Endpoint 0 */
  SetEPType(ENDP0, EP_CONTROL);
  SetEPTxStatus(ENDP0, EP_TX_NAK);
  SetEPRxAddr(ENDP0, ENDP0_RXADDR);
  SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
  SetEPTxAddr(ENDP0, ENDP0_TXADDR);
  Clear_Status_Out(ENDP0);
  SetEPRxValid(ENDP0);
 
  /* Initialize Endpoint 1 */
  SetEPType(ENDP1, EP_BULK);
  SetEPTxAddr(ENDP1, ENDP1_TXADDR);
  SetEPTxStatus(ENDP1, EP_TX_NAK);
  SetEPRxStatus(ENDP1, EP_RX_DIS);
 
  /* Initialize Endpoint 2 */
  SetEPType(ENDP2, EP_BULK);
  SetEPRxAddr(ENDP2, ENDP2_RXADDR);
  SetEPRxCount(ENDP2, Device_Property.MaxPacketSize);
  SetEPRxStatus(ENDP2, EP_RX_VALID);
  SetEPTxStatus(ENDP2, EP_TX_DIS);
 
 
  SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
  SetEPRxValid(ENDP0);
 
  /* Set the device to response on default address */
  SetDeviceAddress(0);
 
  bDeviceState = ATTACHED;
 
  CBW.dSignature = BOT_CBW_SIGNATURE;
  Bot_State = BOT_IDLE;
 
  USB_NotConfigured_LED();
}
我们看到这个两个函数实现由较大的差异
这个函数的功能可以看到是实现可USBEP的初始化,这里我们要按照实际情况写

把Mass的ENDP1,ENDP2 改换为我们配置的 ENDP4 ENDP5 然后叠加到CDC的配置上去,结果就成了这样
/*******************************************************************************
* Function Name  : Composite_Reset
* Description    : Composite Mouse reset routine
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Composite_Reset(void)
{
  /* Set Composite DEVICE as not configured */
  pInformation->Current_Configuration = 0;
 
  /* Current Feature initialization */
  pInformation->Current_Feature = Composite_ConfigDescriptor[7];
 
  /* Set Composite DEVICE with the default Interface*/
  pInformation->Current_Interface = 0;
  SetBTABLE(BTABLE_ADDRESS);
 
  /* Initialize Endpoint 0 */
  SetEPType(ENDP0, EP_CONTROL);
  SetEPTxStatus(ENDP0, EP_TX_STALL);
  SetEPRxAddr(ENDP0, ENDP0_RXADDR);
  SetEPTxAddr(ENDP0, ENDP0_TXADDR);
  Clear_Status_Out(ENDP0);
  SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
  SetEPRxValid(ENDP0);
 
  /* Initialize Endpoint 1 */
  SetEPType(ENDP1, EP_BULK);
  SetEPTxAddr(ENDP1, ENDP1_TXADDR);
  SetEPTxStatus(ENDP1, EP_TX_NAK);
  SetEPRxStatus(ENDP1, EP_RX_DIS);
 
  /* Initialize Endpoint 2 */
  SetEPType(ENDP2, EP_INTERRUPT);
  SetEPTxAddr(ENDP2, ENDP2_TXADDR);
  SetEPRxStatus(ENDP2, EP_RX_DIS);
  SetEPTxStatus(ENDP2, EP_TX_NAK);
 
  /* Initialize Endpoint 3 */
  SetEPType(ENDP3, EP_BULK);
  SetEPRxAddr(ENDP3, ENDP3_RXADDR);
  SetEPRxCount(ENDP3, Composite_DATA_SIZE);
  SetEPRxStatus(ENDP3, EP_RX_VALID);
  SetEPTxStatus(ENDP3, EP_TX_DIS);
 
/* Initialize Endpoint 2 IN */
  SetEPType(ENDP4, EP_BULK);
  SetEPTxCount(ENDP4, 64);
  SetEPTxAddr(ENDP4, ENDP4_TXADDR);
  SetEPTxStatus(ENDP4, EP_TX_NAK);
  SetEPRxStatus(ENDP4, EP_RX_DIS);
 
  /* Initialize Endpoint 2 OUT */
  SetEPType(ENDP5, EP_BULK);
  SetEPRxAddr(ENDP5, ENDP5_RXADDR);
  SetEPRxCount(ENDP5, 64);
  SetEPRxStatus(ENDP5, EP_RX_VALID);
  SetEPTxStatus(ENDP5, EP_TX_DIS);
  
  /* Set this device to response on default address */
  SetDeviceAddress(0);
  CBW.dSignature = BOT_CBW_SIGNATURE;
  Bot_State = BOT_IDLE;
 
 
  bDeviceState = ATTACHED;
}
其他函数也是根据实际情况进行修改
最终修改结果如下

uspprop.c
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name          : usb_prop.c
* Author             : MCD Application Team
* Version            : V2.2.0
* Date               : 06/13/2008
* Description        : All processing related to Virtual Com Port Demo
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
 
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
#include "usb_conf.h"
#include "usb_prop.h"
#include "usb_desc.h"
#include "usb_pwr.h"
#include "hw_config.h"
#include "usb_bot.h"
#include "memory.h"
#include "mass_mal.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
u8 Request = 0;
 
extern unsigned char Bot_State;
extern Bulk_Only_CBW CBW;
unsigned int Max_Lun = 0; 
 
LINE_CODING linecoding =
  {
    115200, /* baud rate*/
    0x00,   /* stop bits-1*/
    0x00,   /* parity - none*/
    0x08    /* no. of bits 8*/
  };
 
/* -------------------------------------------------------------------------- */
/*  Structures initializations */
/* -------------------------------------------------------------------------- */
 
DEVICE Device_Table =
  {
    EP_NUM,
    1
  };
 
DEVICE_PROP Device_Property =
  {
    Composite_init,
    Composite_Reset,
    Composite_Status_In,
    Composite_Status_Out,
    Composite_Data_Setup,
    Composite_NoData_Setup,
    Composite_Get_Interface_Setting,
    Composite_GetDeviceDescriptor,
    Composite_GetConfigDescriptor,
    Composite_GetStringDescriptor,
    0,
    0x40 /*MAX PACKET SIZE*/
  };
 
USER_STANDARD_REQUESTS User_Standard_Requests =
  {
    Composite_GetConfiguration,
    Composite_SetConfiguration,
    Composite_GetInterface,
    Composite_SetInterface,
    Composite_GetStatus,
    Composite_ClearFeature,
    Composite_SetEndPointFeature,
    Composite_SetDeviceFeature,
    Composite_SetDeviceAddress
  };
 
ONE_DESCRIPTOR Device_Descriptor =
  {
    (u8*)Composite_DeviceDescriptor,
    Composite_SIZ_DEVICE_DESC
  };
 
ONE_DESCRIPTOR Config_Descriptor =
  {
    (u8*)Composite_ConfigDescriptor,
    Composite_SIZ_CONFIG_DESC
  };
 
ONE_DESCRIPTOR String_Descriptor[4] =
  {
    {(u8*)Composite_StringLangID, Composite_SIZ_STRING_LANGID},
    {(u8*)Composite_StringVendor, Composite_SIZ_STRING_VENDOR},
    {(u8*)Composite_StringProduct, Composite_SIZ_STRING_PRODUCT},
    {(u8*)Composite_StringSerial, Composite_SIZ_STRING_SERIAL}
  };
 
/* Extern variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Extern function prototypes ------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name  : Get_Max_Lun
* Description    : Handle the Get Max Lun request.
* Input          : unsigned short Length.
* Output         : None.
* Return         : None.
*******************************************************************************/
unsigned char *Get_Max_Lun(unsigned short Length)
{
  if (Length == 0)
  {
    pInformation->Ctrl_Info.Usb_wLength = LUN_DATA_LENGTH;
    return 0;
  }
  else
  {
    return((unsigned char*)(&Max_Lun));
  }
}
/*******************************************************************************
* Function Name  : Composite_init.
* Description    : Virtual COM Port Mouse init routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Composite_init(void)
{
 
  /* Update the serial number string descriptor with the data from the unique
  ID*/
  Get_SerialNum();
 
  pInformation->Current_Configuration = 0;
 
  /* Connect the device */
  PowerOn();
    
  USB_SIL_Init();  
//   /* USB interrupts initialization */
//   /* clear pending interrupts */
//   _SetISTR(0);
 
//   
//   wInterrupt_Mask = IMR_MSK;
//   /* set interrupts mask */
//   _SetCNTR(wInterrupt_Mask);
 
//   /* configure the USART 1 to the default settings */
//   //USART_Config_Default();
 
  bDeviceState = UNCONNECTED;
}
 
/*******************************************************************************
* Function Name  : Composite_Reset
* Description    : Composite Mouse reset routine
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Composite_Reset(void)
{
  /* Set Composite DEVICE as not configured */
  pInformation->Current_Configuration = 0;
 
  /* Current Feature initialization */
  pInformation->Current_Feature = Composite_ConfigDescriptor[7];
 
  /* Set Composite DEVICE with the default Interface*/
  pInformation->Current_Interface = 0;
  SetBTABLE(BTABLE_ADDRESS);
 
  /* Initialize Endpoint 0 */
  SetEPType(ENDP0, EP_CONTROL);
  SetEPTxStatus(ENDP0, EP_TX_STALL);
  SetEPRxAddr(ENDP0, ENDP0_RXADDR);
  SetEPTxAddr(ENDP0, ENDP0_TXADDR);
  Clear_Status_Out(ENDP0);
  SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
  SetEPRxValid(ENDP0);
 
  /* Initialize Endpoint 1 */
  SetEPType(ENDP1, EP_BULK);
  SetEPTxAddr(ENDP1, ENDP1_TXADDR);
  SetEPTxStatus(ENDP1, EP_TX_NAK);
  SetEPRxStatus(ENDP1, EP_RX_DIS);
 
  /* Initialize Endpoint 2 */
  SetEPType(ENDP2, EP_INTERRUPT);
  SetEPTxAddr(ENDP2, ENDP2_TXADDR);
  SetEPRxStatus(ENDP2, EP_RX_DIS);
  SetEPTxStatus(ENDP2, EP_TX_NAK);
 
  /* Initialize Endpoint 3 */
  SetEPType(ENDP3, EP_BULK);
  SetEPRxAddr(ENDP3, ENDP3_RXADDR);
  SetEPRxCount(ENDP3, Composite_DATA_SIZE);
  SetEPRxStatus(ENDP3, EP_RX_VALID);
  SetEPTxStatus(ENDP3, EP_TX_DIS);
 
/* Initialize Endpoint 2 IN */
  SetEPType(ENDP4, EP_BULK);
  SetEPTxCount(ENDP4, 64);
  SetEPTxAddr(ENDP4, ENDP4_TXADDR);
  SetEPTxStatus(ENDP4, EP_TX_NAK);
  SetEPRxStatus(ENDP4, EP_RX_DIS);
 
  /* Initialize Endpoint 2 OUT */
  SetEPType(ENDP5, EP_BULK);
  SetEPRxAddr(ENDP5, ENDP5_RXADDR);
  SetEPRxCount(ENDP5, 64);
  SetEPRxStatus(ENDP5, EP_RX_VALID);
  SetEPTxStatus(ENDP5, EP_TX_DIS);
  
  /* Set this device to response on default address */
  SetDeviceAddress(0);
  CBW.dSignature = BOT_CBW_SIGNATURE;
  Bot_State = BOT_IDLE;
 
 
  bDeviceState = ATTACHED;
}
 
/*******************************************************************************
* Function Name  : Composite_SetConfiguration.
* Description    : Udpade the device state to configured.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Composite_SetConfiguration(void)
{
  DEVICE_INFO *pInfo = &Device_Info;
 
  if (pInfo->Current_Configuration != 0)
  {
    /* Device configured */
    bDeviceState = CONFIGURED;
    ClearDTOG_TX(ENDP4);
    ClearDTOG_RX(ENDP5);
    Bot_State = BOT_IDLE; /* set the Bot state machine to the IDLE state */
  }
}
 
/*******************************************************************************
* Function Name  : Composite_SetConfiguration.
* Description    : Udpade the device state to addressed.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Composite_SetDeviceAddress (void)
{
  bDeviceState = ADDRESSED;
}
 
/*******************************************************************************
* Function Name  : Composite_Status_In.
* Description    : Virtual COM Port Status In Routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Composite_Status_In(void)
{
  if (Request == SET_LINE_CODING)
  {
    USART_Config();
    Request = 0;
  }
}
 
/*******************************************************************************
* Function Name  : Composite_Status_Out
* Description    : Virtual COM Port Status OUT Routine.
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void Composite_Status_Out(void)
{}
 
/*******************************************************************************
* Function Name  : Composite_Data_Setup
* Description    : handle the data class specific requests
* Input          : Request Nb.
* Output         : None.
* Return         : USB_UNSUPPORT or USB_SUCCESS.
*******************************************************************************/
RESULT Composite_Data_Setup(u8 RequestNo)
{
  u8    *(*CopyRoutine)(u16);
  
  if (pInformation->USBwIndex != 0) 
    return USB_UNSUPPORT;  
  
  CopyRoutine = NULL;
 
  if (RequestNo == GET_LINE_CODING)
  {
    if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
    {
      CopyRoutine = Composite_GetLineCoding;
    }
  }
  else if (RequestNo == SET_LINE_CODING)
  {
    if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
    {
      CopyRoutine = Composite_SetLineCoding;
    }
    Request = SET_LINE_CODING;
  }
 
    
  if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
      && (RequestNo == GET_MAX_LUN) && (pInformation->USBwValue == 0)
      && (pInformation->USBwIndex == 0) && (pInformation->USBwLength == 0x01))
  {
    CopyRoutine = Get_Max_Lun;
  }
  else
  {
    return USB_UNSUPPORT;
  }
 
  if (CopyRoutine == NULL)
  {
    return USB_UNSUPPORT;
  }
 
  pInformation->Ctrl_Info.CopyData = CopyRoutine;
  pInformation->Ctrl_Info.Usb_wOffset = 0;
  (*CopyRoutine)(0);
  return USB_SUCCESS;
}
 
/*******************************************************************************
* Function Name  : Composite_NoData_Setup.
* Description    : handle the no data class specific requests.
* Input          : Request Nb.
* Output         : None.
* Return         : USB_UNSUPPORT or USB_SUCCESS.
*******************************************************************************/
RESULT Composite_NoData_Setup(u8 RequestNo)
{
    if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
      && (RequestNo == MASS_STORAGE_RESET) && (pInformation->USBwValue == 0)
      && (pInformation->USBwIndex == 0) && (pInformation->USBwLength == 0x00))
    {
    /* Initialize Endpoint 1 */
    ClearDTOG_TX(ENDP4);
 
    /* Initialize Endpoint 2 */
    ClearDTOG_RX(ENDP5);
 
    /*initialize the CBW signature to enable the clear feature*/
    CBW.dSignature = BOT_CBW_SIGNATURE;
    Bot_State = BOT_IDLE;
 
    return USB_SUCCESS;
    }
  if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
  {
    if (RequestNo == SET_COMM_FEATURE)
    {
      return USB_SUCCESS;
    }
    else if (RequestNo == SET_CONTROL_LINE_STATE)
    {
      return USB_SUCCESS;
    }
  }
 
  return USB_UNSUPPORT;
}
 
/*******************************************************************************
* Function Name  : MASS_Get_Interface_Setting
* Description    : Test the interface and the alternate setting according to the
*                  supported one.
* Input          : uint8_t Interface, uint8_t AlternateSetting.
* Output         : None.
* Return         : RESULT.
*******************************************************************************/
RESULT Composite_Get_Interface_Setting(u8 Interface, u8 AlternateSetting)
{
  if (AlternateSetting > 0)
  {
    return USB_UNSUPPORT;/* in this application we don't have AlternateSetting*/
  }
  else if (Interface > 2)
  {
    return USB_UNSUPPORT;/*in this application we have only 1 interfaces*/
  }
  return USB_SUCCESS;
}
 
/*******************************************************************************
* Function Name  : Composite_GetDeviceDescriptor.
* Description    : Gets the device descriptor.
* Input          : Length.
* Output         : None.
* Return         : The address of the device descriptor.
*******************************************************************************/
u8 *Composite_GetDeviceDescriptor(u16 Length)
{
  return Standard_GetDescriptorData(Length, &Device_Descriptor);
}
 
/*******************************************************************************
* Function Name  : Composite_GetConfigDescriptor.
* Description    : get the configuration descriptor.
* Input          : Length.
* Output         : None.
* Return         : The address of the configuration descriptor.
*******************************************************************************/
u8 *Composite_GetConfigDescriptor(u16 Length)
{
  return Standard_GetDescriptorData(Length, &Config_Descriptor);
}
 
/*******************************************************************************
* Function Name  : Composite_GetStringDescriptor
* Description    : Gets the string descriptors according to the needed index
* Input          : Length.
* Output         : None.
* Return         : The address of the string descriptors.
*******************************************************************************/
u8 *Composite_GetStringDescriptor(u16 Length)
{
  u8 wValue0 = pInformation->USBwValue0;
  if (wValue0 > 4)
  {
    return NULL;
  }
  else
  {
    return Standard_GetDescriptorData(Length, &String_Descriptor[wValue0]);
  }
}
 
/*******************************************************************************
* Function Name  : Composite_GetLineCoding.
* Description    : send the linecoding structure to the PC host.
* Input          : Length.
* Output         : None.
* Return         : Inecoding structure base address.
*******************************************************************************/
u8 *Composite_GetLineCoding(u16 Length)
{
  if (Length == 0)
  {
    pInformation->Ctrl_Info.Usb_wLength = sizeof(linecoding);
    return NULL;
  }
  return(u8 *)&linecoding;
}
 
/*******************************************************************************
* Function Name  : Composite_SetLineCoding.
* Description    : Set the linecoding structure fields.
* Input          : Length.
* Output         : None.
* Return         : Linecoding structure base address.
*******************************************************************************/
u8 *Composite_SetLineCoding(u16 Length)
{
  if (Length == 0)
  {
    pInformation->Ctrl_Info.Usb_wLength = sizeof(linecoding);
    return NULL;
  }
  return(u8 *)&linecoding;
}
 
void Composite_ClearFeature (void)
{
    if (CBW.dSignature != BOT_CBW_SIGNATURE)
    Bot_Abort(BOTH_DIR);
}
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/


发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注