当前位置: 首页 > article >正文

stm32 HSUSB

/

stm32f407xx.h

#define USB_OTG_HS_PERIPH_BASE 0x40040000UL

#define USB_OTG_HS ((USB_OTG_GlobalTypeDef *) USB_OTG_HS_PERIPH_BASE)

//

//

定义全局变量 USBD_HandleTypeDef hUsbDeviceHS;并默认全零初始化



/* USB Device handle structure */
typedef struct _USBD_HandleTypeDef
{
  uint8_t                 id;
  uint32_t                dev_config;
  uint32_t                dev_default_config;
  uint32_t                dev_config_status;
  USBD_SpeedTypeDef       dev_speed;
  USBD_EndpointTypeDef    ep_in[16];
  USBD_EndpointTypeDef    ep_out[16];
  __IO uint32_t           ep0_state;
  uint32_t                ep0_data_len;
  __IO uint8_t            dev_state;
  __IO uint8_t            dev_old_state;
  uint8_t                 dev_address;
  uint8_t                 dev_connection_status;
  uint8_t                 dev_test_mode;
  uint32_t                dev_remote_wakeup;
  uint8_t                 ConfIdx;

  USBD_SetupReqTypedef    request;
  USBD_DescriptorsTypeDef *pDesc;
  USBD_ClassTypeDef       *pClass[USBD_MAX_SUPPORTED_CLASS];
  void                    *pClassData;
  void                    *pClassDataCmsit[USBD_MAX_SUPPORTED_CLASS];
  void                    *pUserData[USBD_MAX_SUPPORTED_CLASS];
  void                    *pData;
  void                    *pBosDesc;
  void                    *pConfDesc;
  uint32_t                classId;
  uint32_t                NumClasses;
#ifdef USE_USBD_COMPOSITE
  USBD_CompositeElementTypeDef tclasslist[USBD_MAX_SUPPORTED_CLASS];
#endif /* USE_USBD_COMPOSITE */
} USBD_HandleTypeDef;

//

//

定义全局变量USBD_DescriptorsTypeDef HS_Desc,并赋值初始化
/** @defgroup USBD_DESC_Private_Variables USBD_DESC_Private_Variables
  * @brief Private variables.
  * @{
  */

USBD_DescriptorsTypeDef HS_Desc =
{
  USBD_HS_DeviceDescriptor
, USBD_HS_LangIDStrDescriptor
, USBD_HS_ManufacturerStrDescriptor
, USBD_HS_ProductStrDescriptor
, USBD_HS_SerialStrDescriptor
, USBD_HS_ConfigStrDescriptor
, USBD_HS_InterfaceStrDescriptor
#if (USBD_LPM_ENABLED == 1)
, USBD_HS_USR_BOSDescriptor
#endif /* (USBD_LPM_ENABLED == 1) */
};


//=====================================================//
//=====================================================//
/* USB Device descriptors structure */
typedef struct
{
  uint8_t *(*GetDeviceDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
  uint8_t *(*GetLangIDStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
  uint8_t *(*GetManufacturerStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
  uint8_t *(*GetProductStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
  uint8_t *(*GetSerialStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
  uint8_t *(*GetConfigurationStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
  uint8_t *(*GetInterfaceStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
#if (USBD_CLASS_USER_STRING_DESC == 1)
  uint8_t *(*GetUserStrDescriptor)(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length);
#endif /* USBD_CLASS_USER_STRING_DESC */
#if ((USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1))
  uint8_t *(*GetBOSDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
#endif /* (USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1) */
} USBD_DescriptorsTypeDef;


//=====================================================//
//=====================================================//
/**
  * @brief  Return the device descriptor
  * @param  speed : Current device speed
  * @param  length : Pointer to data length variable
  * @retval Pointer to descriptor buffer
  */
uint8_t * USBD_HS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
  UNUSED(speed);
  *length = sizeof(USBD_HS_DeviceDesc);
  return USBD_HS_DeviceDesc;
}

/**
  * @brief  Return the LangID string descriptor
  * @param  speed : Current device speed
  * @param  length : Pointer to data length variable
  * @retval Pointer to descriptor buffer
  */
uint8_t * USBD_HS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
  UNUSED(speed);
  *length = sizeof(USBD_LangIDDesc);
  return USBD_LangIDDesc;
}

/**
  * @brief  Return the product string descriptor
  * @param  speed : current device speed
  * @param  length : pointer to data length variable
  * @retval pointer to descriptor buffer
  */
uint8_t * USBD_HS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
  if(speed == 0)
  {
    USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_HS, USBD_StrDesc, length);
  }
  else
  {
    USBD_GetString((uint8_t *)USBD_PRODUCT_STRING_HS, USBD_StrDesc, length);
  }
  return USBD_StrDesc;
}

/**
  * @brief  Return the manufacturer string descriptor
  * @param  speed : Current device speed
  * @param  length : Pointer to data length variable
  * @retval Pointer to descriptor buffer
  */
uint8_t * USBD_HS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
  UNUSED(speed);
  USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
  return USBD_StrDesc;
}

/**
  * @brief  Return the serial number string descriptor
  * @param  speed : Current device speed
  * @param  length : Pointer to data length variable
  * @retval Pointer to descriptor buffer
  */
uint8_t * USBD_HS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
  UNUSED(speed);
  *length = USB_SIZ_STRING_SERIAL;

  /* Update the serial number string descriptor with the data from the unique
   * ID */
  Get_SerialNum();
  /* USER CODE BEGIN USBD_HS_SerialStrDescriptor */

  /* USER CODE END USBD_HS_SerialStrDescriptor */

  return (uint8_t *) USBD_StringSerial;
}

/**
  * @brief  Return the configuration string descriptor
  * @param  speed : Current device speed
  * @param  length : Pointer to data length variable
  * @retval Pointer to descriptor buffer
  */
uint8_t * USBD_HS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
  if(speed == USBD_SPEED_HIGH)
  {
    USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_HS, USBD_StrDesc, length);
  }
  else
  {
    USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING_HS, USBD_StrDesc, length);
  }
  return USBD_StrDesc;
}

/**
  * @brief  Return the interface string descriptor
  * @param  speed : Current device speed
  * @param  length : Pointer to data length variable
  * @retval Pointer to descriptor buffer
  */
uint8_t * USBD_HS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
  if(speed == 0)
  {
    USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_HS, USBD_StrDesc, length);
  }
  else
  {
    USBD_GetString((uint8_t *)USBD_INTERFACE_STRING_HS, USBD_StrDesc, length);
  }
  return USBD_StrDesc;
}

#if (USBD_LPM_ENABLED == 1)
/**
  * @brief  Return the BOS descriptor
  * @param  speed : Current device speed
  * @param  length : Pointer to data length variable
  * @retval Pointer to descriptor buffer
  */
uint8_t * USBD_HS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length)
{
  UNUSED(speed);
  *length = sizeof(USBD_HS_BOSDesc);
  return (uint8_t*)USBD_HS_BOSDesc;
}
#endif /* (USBD_LPM_ENABLED == 1) */

全局宏定义,区分高速和全速USB
/* #define for FS and HS identification */
#define DEVICE_FS 		0
#define DEVICE_HS 		1

//

//

定义全局变量USBD_CDC,并赋值初始化
/* CDC interface class callbacks structure */
USBD_ClassTypeDef  USBD_CDC =
{
  USBD_CDC_Init,
  USBD_CDC_DeInit,
  USBD_CDC_Setup,
  NULL,                 /* EP0_TxSent */
  USBD_CDC_EP0_RxReady,
  USBD_CDC_DataIn,
  USBD_CDC_DataOut,
  NULL,
  NULL,
  NULL,
#ifdef USE_USBD_COMPOSITE
  NULL,
  NULL,
  NULL,
  NULL,
#else
  USBD_CDC_GetHSCfgDesc,
  USBD_CDC_GetFSCfgDesc,
  USBD_CDC_GetOtherSpeedCfgDesc,
  USBD_CDC_GetDeviceQualifierDescriptor,
#endif /* USE_USBD_COMPOSITE  */
};


//=====================================================//
//=====================================================//
/**
  * @brief  USBD_RegisterClass
  *         Link class driver to Device Core.
  * @param  pDevice : Device Handle
  * @param  pclass: Class handle
  * @retval USBD Status
  */
USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass)
{
  uint16_t len = 0U;

  if (pclass == NULL)
  {
#if (USBD_DEBUG_LEVEL > 1U)
    USBD_ErrLog("Invalid Class handle");
#endif /* (USBD_DEBUG_LEVEL > 1U) */
    return USBD_FAIL;
  }

  /* link the class to the USB Device handle */
  pdev->pClass[0] = pclass;

  /* Get Device Configuration Descriptor */
#ifdef USE_USB_HS
  if (pdev->pClass[pdev->classId]->GetHSConfigDescriptor != NULL)
  {
    pdev->pConfDesc = (void *)pdev->pClass[pdev->classId]->GetHSConfigDescriptor(&len);
  }
#else /* Default USE_USB_FS */
  if (pdev->pClass[pdev->classId]->GetFSConfigDescriptor != NULL)
  {
    pdev->pConfDesc = (void *)pdev->pClass[pdev->classId]->GetFSConfigDescriptor(&len);
  }
#endif /* USE_USB_FS */

  /* Increment the NumClasses */
  pdev->NumClasses ++;

  return USBD_OK;
}



//=====================================================//
//=====================================================//
/**
  * @brief  USBD_LL_DataOutStage
  *         Handle data OUT stage
  * @param  pdev: device instance
  * @param  epnum: endpoint index
  * @param  pdata: data pointer
  * @retval status
  */
USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev,
                                        uint8_t epnum, uint8_t *pdata)
{
  USBD_EndpointTypeDef *pep;
  USBD_StatusTypeDef ret = USBD_OK;
  uint8_t idx;

  if (epnum == 0U)
  {
    pep = &pdev->ep_out[0];

    if (pdev->ep0_state == USBD_EP0_DATA_OUT)
    {
      if (pep->rem_length > pep->maxpacket)
      {
        pep->rem_length -= pep->maxpacket;

        (void)USBD_CtlContinueRx(pdev, pdata, MIN(pep->rem_length, pep->maxpacket));
      }
      else
      {
        /* Find the class ID relative to the current request */
        switch (pdev->request.bmRequest & 0x1FU)
        {
          case USB_REQ_RECIPIENT_DEVICE:
            /* Device requests must be managed by the first instantiated class
               (or duplicated by all classes for simplicity) */
            idx = 0U;
            break;

          case USB_REQ_RECIPIENT_INTERFACE:
            idx = USBD_CoreFindIF(pdev, LOBYTE(pdev->request.wIndex));
            break;

          case USB_REQ_RECIPIENT_ENDPOINT:
            idx = USBD_CoreFindEP(pdev, LOBYTE(pdev->request.wIndex));
            break;

          default:
            /* Back to the first class in case of doubt */
            idx = 0U;
            break;
        }

        if (idx < USBD_MAX_SUPPORTED_CLASS)
        {
          /* Setup the class ID and route the request to the relative class function */
          if (pdev->dev_state == USBD_STATE_CONFIGURED)
          {
            if (pdev->pClass[idx]->EP0_RxReady != NULL)
            {
              pdev->classId = idx;
              pdev->pClass[idx]->EP0_RxReady(pdev);
            }
          }
        }

        (void)USBD_CtlSendStatus(pdev);
      }
    }
    else
    {
#if 0
      if (pdev->ep0_state == USBD_EP0_STATUS_OUT)
      {
        /*
          * STATUS PHASE completed, update ep0_state to idle
          */
        pdev->ep0_state = USBD_EP0_IDLE;
        (void)USBD_LL_StallEP(pdev, 0U);
      }
#endif
    }
  }//if (epnum == 0U)
  else
  {
    /* Get the class index relative to this interface */
    idx = USBD_CoreFindEP(pdev, (epnum & 0x7FU));

    if (((uint16_t)idx != 0xFFU) && (idx < USBD_MAX_SUPPORTED_CLASS))
    {
      /* Call the class data out function to manage the request */
      if (pdev->dev_state == USBD_STATE_CONFIGURED)
      {
        if (pdev->pClass[idx]->DataOut != NULL)
        {
          pdev->classId = idx;
          ret = (USBD_StatusTypeDef)pdev->pClass[idx]->DataOut(pdev, epnum);//***//
        }
      }
      if (ret != USBD_OK)
      {
        return ret;
      }
    }
  }

  return USBD_OK;
}

/


http://www.kler.cn/a/133310.html

相关文章:

  • Odoo :一款免费开源的日化行业ERP管理系统
  • vue 项目使用 nginx 部署
  • python抓取工具【pyppeteer】用法 直接运行 无错
  • 24.11.13 机器学习 特征降维(主成份分析) KNN算法 交叉验证(K-Fold) 超参数搜索
  • go反射深入学习
  • 计算机网络(11)和流量控制补充
  • vscode运行dlv报错超时
  • 用5000字讲清楚压敏电阻
  • 基础模型的自然语言处理能力综述
  • Linux tc 使用
  • 李沐的学习Pytorch环境配置
  • 【数据结构】希尔排序(最小增量排序)
  • 大数据基础设施搭建 - Hadoop
  • R语言和RStudio的下载安装(非常简便舒适)
  • LeetCode701. Insert into a Binary Search Tree
  • 欢迎各位加入知识星球,带各位进入新的领域
  • 《2020年最新面经》—字节跳动Java社招面试题
  • 腾讯云CVM服务器标准型/高IO/计算/大数据使用场景及选择说明
  • C++ 日期推算
  • AM@函数展开成幂级数@间接法@常用麦克劳林幂级数展开公式
  • QEMU显示虚拟化的几种选项
  • 解锁数据安全之门:探秘迅软DSE的文件权限控制功能
  • 【ES常用查询】基于ElasticsearchRestTemplate及NativeSearchQuery的查询
  • LabVIEW和NIUSRP硬件加快了认知无线电开发
  • 拍照小白入坑
  • PHP接收并处理请求中携带的xml格式的信息