Subversion Repositories DashDisplay

Rev

Rev 61 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /**
  2.   ******************************************************************************
  3.   * @file    stm32l1xx_ll_usb.c
  4.   * @author  MCD Application Team
  5.   * @brief   USB Low Layer HAL module driver.
  6.   *
  7.   *          This file provides firmware functions to manage the following
  8.   *          functionalities of the USB Peripheral Controller:
  9.   *           + Initialization/de-initialization functions
  10.   *           + I/O operation functions
  11.   *           + Peripheral Control functions
  12.   *           + Peripheral State functions
  13.   *
  14.   ******************************************************************************
  15.   * @attention
  16.   *
  17.   * Copyright (c) 2016 STMicroelectronics.
  18.   * All rights reserved.
  19.   *
  20.   * This software is licensed under terms that can be found in the LICENSE file
  21.   * in the root directory of this software component.
  22.   * If no LICENSE file comes with this software, it is provided AS-IS.
  23.   *
  24.   ******************************************************************************
  25.   @verbatim
  26.   ==============================================================================
  27.                     ##### How to use this driver #####
  28.   ==============================================================================
  29.     [..]
  30.       (#) Fill parameters of Init structure in USB_CfgTypeDef structure.
  31.  
  32.       (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
  33.  
  34.       (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
  35.  
  36.   @endverbatim
  37.  
  38.   ******************************************************************************
  39.   */
  40.  
  41. /* Includes ------------------------------------------------------------------*/
  42. #include "stm32l1xx_hal.h"
  43.  
  44. /** @addtogroup STM32L1xx_LL_USB_DRIVER
  45.   * @{
  46.   */
  47.  
  48. #if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
  49. #if defined (USB)
  50. /* Private typedef -----------------------------------------------------------*/
  51. /* Private define ------------------------------------------------------------*/
  52. /* Private macro -------------------------------------------------------------*/
  53. /* Private variables ---------------------------------------------------------*/
  54. /* Private function prototypes -----------------------------------------------*/
  55. /* Private functions ---------------------------------------------------------*/
  56.  
  57. /**
  58.   * @brief  Initializes the USB Core
  59.   * @param  USBx USB Instance
  60.   * @param  cfg pointer to a USB_CfgTypeDef structure that contains
  61.   *         the configuration information for the specified USBx peripheral.
  62.   * @retval HAL status
  63.   */
  64. HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
  65. {
  66.   /* Prevent unused argument(s) compilation warning */
  67.   UNUSED(USBx);
  68.   UNUSED(cfg);
  69.  
  70.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  71.               only by USB OTG FS peripheral.
  72.             - This function is added to ensure compatibility across platforms.
  73.    */
  74.  
  75.   return HAL_OK;
  76. }
  77.  
  78. /**
  79.   * @brief  USB_EnableGlobalInt
  80.   *         Enables the controller's Global Int in the AHB Config reg
  81.   * @param  USBx Selected device
  82.   * @retval HAL status
  83.   */
  84. HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx)
  85. {
  86.   uint32_t winterruptmask;
  87.  
  88.   /* Clear pending interrupts */
  89.   USBx->ISTR = 0U;
  90.  
  91.   /* Set winterruptmask variable */
  92.   winterruptmask = USB_CNTR_CTRM  | USB_CNTR_WKUPM |
  93.                    USB_CNTR_SUSPM | USB_CNTR_ERRM |
  94.                    USB_CNTR_SOFM | USB_CNTR_ESOFM |
  95.                    USB_CNTR_RESETM;
  96.  
  97.   /* Set interrupt mask */
  98.   USBx->CNTR = (uint16_t)winterruptmask;
  99.  
  100.   return HAL_OK;
  101. }
  102.  
  103. /**
  104.   * @brief  USB_DisableGlobalInt
  105.   *         Disable the controller's Global Int in the AHB Config reg
  106.   * @param  USBx Selected device
  107.   * @retval HAL status
  108.   */
  109. HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx)
  110. {
  111.   uint32_t winterruptmask;
  112.  
  113.   /* Set winterruptmask variable */
  114.   winterruptmask = USB_CNTR_CTRM  | USB_CNTR_WKUPM |
  115.                    USB_CNTR_SUSPM | USB_CNTR_ERRM |
  116.                    USB_CNTR_SOFM | USB_CNTR_ESOFM |
  117.                    USB_CNTR_RESETM;
  118.  
  119.   /* Clear interrupt mask */
  120.   USBx->CNTR &= (uint16_t)(~winterruptmask);
  121.  
  122.   return HAL_OK;
  123. }
  124.  
  125. /**
  126.   * @brief  USB_SetCurrentMode Set functional mode
  127.   * @param  USBx Selected device
  128.   * @param  mode current core mode
  129.   *          This parameter can be one of the these values:
  130.   *            @arg USB_DEVICE_MODE Peripheral mode
  131.   * @retval HAL status
  132.   */
  133. HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx, USB_ModeTypeDef mode)
  134. {
  135.   /* Prevent unused argument(s) compilation warning */
  136.   UNUSED(USBx);
  137.   UNUSED(mode);
  138.  
  139.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  140.               only by USB OTG FS peripheral.
  141.             - This function is added to ensure compatibility across platforms.
  142.    */
  143.   return HAL_OK;
  144. }
  145.  
  146. /**
  147.   * @brief  USB_DevInit Initializes the USB controller registers
  148.   *         for device mode
  149.   * @param  USBx Selected device
  150.   * @param  cfg  pointer to a USB_CfgTypeDef structure that contains
  151.   *         the configuration information for the specified USBx peripheral.
  152.   * @retval HAL status
  153.   */
  154. HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
  155. {
  156.   /* Prevent unused argument(s) compilation warning */
  157.   UNUSED(cfg);
  158.  
  159.   /* Init Device */
  160.   /* CNTR_FRES = 1 */
  161.   USBx->CNTR = (uint16_t)USB_CNTR_FRES;
  162.  
  163.   /* CNTR_FRES = 0 */
  164.   USBx->CNTR = 0U;
  165.  
  166.   /* Clear pending interrupts */
  167.   USBx->ISTR = 0U;
  168.  
  169.   /*Set Btable Address*/
  170.   USBx->BTABLE = BTABLE_ADDRESS;
  171.  
  172.   return HAL_OK;
  173. }
  174.  
  175. /**
  176.   * @brief  USB_FlushTxFifo : Flush a Tx FIFO
  177.   * @param  USBx : Selected device
  178.   * @param  num : FIFO number
  179.   *         This parameter can be a value from 1 to 15
  180.             15 means Flush all Tx FIFOs
  181.   * @retval HAL status
  182.   */
  183. HAL_StatusTypeDef USB_FlushTxFifo(USB_TypeDef const *USBx, uint32_t num)
  184. {
  185.   /* Prevent unused argument(s) compilation warning */
  186.   UNUSED(USBx);
  187.   UNUSED(num);
  188.  
  189.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  190.               only by USB OTG FS peripheral.
  191.             - This function is added to ensure compatibility across platforms.
  192.    */
  193.  
  194.   return HAL_OK;
  195. }
  196.  
  197. /**
  198.   * @brief  USB_FlushRxFifo : Flush Rx FIFO
  199.   * @param  USBx : Selected device
  200.   * @retval HAL status
  201.   */
  202. HAL_StatusTypeDef USB_FlushRxFifo(USB_TypeDef const *USBx)
  203. {
  204.   /* Prevent unused argument(s) compilation warning */
  205.   UNUSED(USBx);
  206.  
  207.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  208.               only by USB OTG FS peripheral.
  209.             - This function is added to ensure compatibility across platforms.
  210.    */
  211.  
  212.   return HAL_OK;
  213. }
  214.  
  215.  
  216. #if defined (HAL_PCD_MODULE_ENABLED)
  217. /**
  218.   * @brief  Activate and configure an endpoint
  219.   * @param  USBx Selected device
  220.   * @param  ep pointer to endpoint structure
  221.   * @retval HAL status
  222.   */
  223. HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  224. {
  225.   HAL_StatusTypeDef ret = HAL_OK;
  226.   uint16_t wEpRegVal;
  227.  
  228.   wEpRegVal = PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_T_MASK;
  229.  
  230.   /* initialize Endpoint */
  231.   switch (ep->type)
  232.   {
  233.     case EP_TYPE_CTRL:
  234.       wEpRegVal |= USB_EP_CONTROL;
  235.       break;
  236.  
  237.     case EP_TYPE_BULK:
  238.       wEpRegVal |= USB_EP_BULK;
  239.       break;
  240.  
  241.     case EP_TYPE_INTR:
  242.       wEpRegVal |= USB_EP_INTERRUPT;
  243.       break;
  244.  
  245.     case EP_TYPE_ISOC:
  246.       wEpRegVal |= USB_EP_ISOCHRONOUS;
  247.       break;
  248.  
  249.     default:
  250.       ret = HAL_ERROR;
  251.       break;
  252.   }
  253.  
  254.   PCD_SET_ENDPOINT(USBx, ep->num, (wEpRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX));
  255.  
  256.   PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num);
  257.  
  258.   if (ep->doublebuffer == 0U)
  259.   {
  260.     if (ep->is_in != 0U)
  261.     {
  262.       /*Set the endpoint Transmit buffer address */
  263.       PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress);
  264.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  265.  
  266.       if (ep->type != EP_TYPE_ISOC)
  267.       {
  268.         /* Configure NAK status for the Endpoint */
  269.         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
  270.       }
  271.       else
  272.       {
  273.         /* Configure TX Endpoint to disabled state */
  274.         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  275.       }
  276.     }
  277.     else
  278.     {
  279.       /* Set the endpoint Receive buffer address */
  280.       PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress);
  281.  
  282.       /* Set the endpoint Receive buffer counter */
  283.       PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket);
  284.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  285.  
  286.       if (ep->num == 0U)
  287.       {
  288.         /* Configure VALID status for EP0 */
  289.         PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
  290.       }
  291.       else
  292.       {
  293.         /* Configure NAK status for OUT Endpoint */
  294.         PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_NAK);
  295.       }
  296.     }
  297.   }
  298. #if (USE_USB_DOUBLE_BUFFER == 1U)
  299.   /* Double Buffer */
  300.   else
  301.   {
  302.     if (ep->type == EP_TYPE_BULK)
  303.     {
  304.       /* Set bulk endpoint as double buffered */
  305.       PCD_SET_BULK_EP_DBUF(USBx, ep->num);
  306.     }
  307.     else
  308.     {
  309.       /* Set the ISOC endpoint in double buffer mode */
  310.       PCD_CLEAR_EP_KIND(USBx, ep->num);
  311.     }
  312.  
  313.     /* Set buffer address for double buffered mode */
  314.     PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1);
  315.  
  316.     if (ep->is_in == 0U)
  317.     {
  318.       /* Clear the data toggle bits for the endpoint IN/OUT */
  319.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  320.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  321.  
  322.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
  323.       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  324.     }
  325.     else
  326.     {
  327.       /* Clear the data toggle bits for the endpoint IN/OUT */
  328.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  329.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  330.  
  331.       if (ep->type != EP_TYPE_ISOC)
  332.       {
  333.         /* Configure NAK status for the Endpoint */
  334.         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
  335.       }
  336.       else
  337.       {
  338.         /* Configure TX Endpoint to disabled state */
  339.         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  340.       }
  341.  
  342.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
  343.     }
  344.   }
  345. #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
  346.  
  347.   return ret;
  348. }
  349.  
  350. /**
  351.   * @brief  De-activate and de-initialize an endpoint
  352.   * @param  USBx Selected device
  353.   * @param  ep pointer to endpoint structure
  354.   * @retval HAL status
  355.   */
  356. HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  357. {
  358.   if (ep->doublebuffer == 0U)
  359.   {
  360.     if (ep->is_in != 0U)
  361.     {
  362.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  363.  
  364.       /* Configure DISABLE status for the Endpoint */
  365.       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  366.     }
  367.  
  368.     else
  369.     {
  370.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  371.  
  372.       /* Configure DISABLE status for the Endpoint */
  373.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
  374.     }
  375.   }
  376. #if (USE_USB_DOUBLE_BUFFER == 1U)
  377.   /* Double Buffer */
  378.   else
  379.   {
  380.     if (ep->is_in == 0U)
  381.     {
  382.       /* Clear the data toggle bits for the endpoint IN/OUT*/
  383.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  384.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  385.  
  386.       /* Reset value of the data toggle bits for the endpoint out*/
  387.       PCD_TX_DTOG(USBx, ep->num);
  388.  
  389.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
  390.       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  391.     }
  392.     else
  393.     {
  394.       /* Clear the data toggle bits for the endpoint IN/OUT*/
  395.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  396.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  397.       PCD_RX_DTOG(USBx, ep->num);
  398.  
  399.       /* Configure DISABLE status for the Endpoint*/
  400.       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  401.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
  402.     }
  403.   }
  404. #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
  405.  
  406.   return HAL_OK;
  407. }
  408.  
  409. /**
  410.   * @brief  USB_EPStartXfer setup and starts a transfer over an EP
  411.   * @param  USBx Selected device
  412.   * @param  ep pointer to endpoint structure
  413.   * @retval HAL status
  414.   */
  415. HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  416. {
  417.   uint32_t len;
  418. #if (USE_USB_DOUBLE_BUFFER == 1U)
  419.   uint16_t pmabuffer;
  420.   uint16_t wEPVal;
  421. #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
  422.  
  423.   /* IN endpoint */
  424.   if (ep->is_in == 1U)
  425.   {
  426.     /*Multi packet transfer*/
  427.     if (ep->xfer_len > ep->maxpacket)
  428.     {
  429.       len = ep->maxpacket;
  430.     }
  431.     else
  432.     {
  433.       len = ep->xfer_len;
  434.     }
  435.  
  436.     /* configure and validate Tx endpoint */
  437.     if (ep->doublebuffer == 0U)
  438.     {
  439.       USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len);
  440.       PCD_SET_EP_TX_CNT(USBx, ep->num, len);
  441.     }
  442. #if (USE_USB_DOUBLE_BUFFER == 1U)
  443.     else
  444.     {
  445.       /* double buffer bulk management */
  446.       if (ep->type == EP_TYPE_BULK)
  447.       {
  448.         if (ep->xfer_len_db > ep->maxpacket)
  449.         {
  450.           /* enable double buffer */
  451.           PCD_SET_BULK_EP_DBUF(USBx, ep->num);
  452.  
  453.           /* each Time to write in PMA xfer_len_db will */
  454.           ep->xfer_len_db -= len;
  455.  
  456.           /* Fill the two first buffer in the Buffer0 & Buffer1 */
  457.           if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
  458.           {
  459.             /* Set the Double buffer counter for pmabuffer1 */
  460.             PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
  461.             pmabuffer = ep->pmaaddr1;
  462.  
  463.             /* Write the user buffer to USB PMA */
  464.             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  465.             ep->xfer_buff += len;
  466.  
  467.             if (ep->xfer_len_db > ep->maxpacket)
  468.             {
  469.               ep->xfer_len_db -= len;
  470.             }
  471.             else
  472.             {
  473.               len = ep->xfer_len_db;
  474.               ep->xfer_len_db = 0U;
  475.             }
  476.  
  477.             /* Set the Double buffer counter for pmabuffer0 */
  478.             PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
  479.             pmabuffer = ep->pmaaddr0;
  480.  
  481.             /* Write the user buffer to USB PMA */
  482.             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  483.           }
  484.           else
  485.           {
  486.             /* Set the Double buffer counter for pmabuffer0 */
  487.             PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
  488.             pmabuffer = ep->pmaaddr0;
  489.  
  490.             /* Write the user buffer to USB PMA */
  491.             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  492.             ep->xfer_buff += len;
  493.  
  494.             if (ep->xfer_len_db > ep->maxpacket)
  495.             {
  496.               ep->xfer_len_db -= len;
  497.             }
  498.             else
  499.             {
  500.               len = ep->xfer_len_db;
  501.               ep->xfer_len_db = 0U;
  502.             }
  503.  
  504.             /* Set the Double buffer counter for pmabuffer1 */
  505.             PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
  506.             pmabuffer = ep->pmaaddr1;
  507.  
  508.             /* Write the user buffer to USB PMA */
  509.             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  510.           }
  511.         }
  512.         /* auto Switch to single buffer mode when transfer <Mps no need to manage in double buffer */
  513.         else
  514.         {
  515.           len = ep->xfer_len_db;
  516.  
  517.           /* disable double buffer mode for Bulk endpoint */
  518.           PCD_CLEAR_BULK_EP_DBUF(USBx, ep->num);
  519.  
  520.           /* Set Tx count with nbre of byte to be transmitted */
  521.           PCD_SET_EP_TX_CNT(USBx, ep->num, len);
  522.           pmabuffer = ep->pmaaddr0;
  523.  
  524.           /* Write the user buffer to USB PMA */
  525.           USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  526.         }
  527.       }
  528.       else /* manage isochronous double buffer IN mode */
  529.       {
  530.         /* each Time to write in PMA xfer_len_db will */
  531.         ep->xfer_len_db -= len;
  532.  
  533.         /* Fill the data buffer */
  534.         if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
  535.         {
  536.           /* Set the Double buffer counter for pmabuffer1 */
  537.           PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
  538.           pmabuffer = ep->pmaaddr1;
  539.  
  540.           /* Write the user buffer to USB PMA */
  541.           USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  542.         }
  543.         else
  544.         {
  545.           /* Set the Double buffer counter for pmabuffer0 */
  546.           PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
  547.           pmabuffer = ep->pmaaddr0;
  548.  
  549.           /* Write the user buffer to USB PMA */
  550.           USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  551.         }
  552.       }
  553.     }
  554. #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
  555.  
  556.     PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
  557.   }
  558.   else /* OUT endpoint */
  559.   {
  560.     if (ep->doublebuffer == 0U)
  561.     {
  562.       /* Multi packet transfer */
  563.       if (ep->xfer_len > ep->maxpacket)
  564.       {
  565.         len = ep->maxpacket;
  566.         ep->xfer_len -= len;
  567.       }
  568.       else
  569.       {
  570.         len = ep->xfer_len;
  571.         ep->xfer_len = 0U;
  572.       }
  573.       /* configure and validate Rx endpoint */
  574.       PCD_SET_EP_RX_CNT(USBx, ep->num, len);
  575.     }
  576. #if (USE_USB_DOUBLE_BUFFER == 1U)
  577.     else
  578.     {
  579.       /* First Transfer Coming From HAL_PCD_EP_Receive & From ISR */
  580.       /* Set the Double buffer counter */
  581.       if (ep->type == EP_TYPE_BULK)
  582.       {
  583.         PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, ep->maxpacket);
  584.  
  585.         /* Coming from ISR */
  586.         if (ep->xfer_count != 0U)
  587.         {
  588.           /* update last value to check if there is blocking state */
  589.           wEPVal = PCD_GET_ENDPOINT(USBx, ep->num);
  590.  
  591.           /*Blocking State */
  592.           if ((((wEPVal & USB_EP_DTOG_RX) != 0U) && ((wEPVal & USB_EP_DTOG_TX) != 0U)) ||
  593.               (((wEPVal & USB_EP_DTOG_RX) == 0U) && ((wEPVal & USB_EP_DTOG_TX) == 0U)))
  594.           {
  595.             PCD_FREE_USER_BUFFER(USBx, ep->num, 0U);
  596.           }
  597.         }
  598.       }
  599.       /* iso out double */
  600.       else if (ep->type == EP_TYPE_ISOC)
  601.       {
  602.         /* Multi packet transfer */
  603.         if (ep->xfer_len > ep->maxpacket)
  604.         {
  605.           len = ep->maxpacket;
  606.           ep->xfer_len -= len;
  607.         }
  608.         else
  609.         {
  610.           len = ep->xfer_len;
  611.           ep->xfer_len = 0U;
  612.         }
  613.         PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len);
  614.       }
  615.       else
  616.       {
  617.         return HAL_ERROR;
  618.       }
  619.     }
  620. #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
  621.  
  622.     PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
  623.   }
  624.  
  625.   return HAL_OK;
  626. }
  627.  
  628.  
  629. /**
  630.   * @brief  USB_EPSetStall set a stall condition over an EP
  631.   * @param  USBx Selected device
  632.   * @param  ep pointer to endpoint structure
  633.   * @retval HAL status
  634.   */
  635. HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  636. {
  637.   if (ep->is_in != 0U)
  638.   {
  639.     PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL);
  640.   }
  641.   else
  642.   {
  643.     PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL);
  644.   }
  645.  
  646.   return HAL_OK;
  647. }
  648.  
  649. /**
  650.   * @brief  USB_EPClearStall Clear a stall condition over an EP
  651.   * @param  USBx Selected device
  652.   * @param  ep pointer to endpoint structure
  653.   * @retval HAL status
  654.   */
  655. HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  656. {
  657.   if (ep->doublebuffer == 0U)
  658.   {
  659.     if (ep->is_in != 0U)
  660.     {
  661.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  662.  
  663.       if (ep->type != EP_TYPE_ISOC)
  664.       {
  665.         /* Configure NAK status for the Endpoint */
  666.         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
  667.       }
  668.     }
  669.     else
  670.     {
  671.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  672.  
  673.       /* Configure VALID status for the Endpoint */
  674.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
  675.     }
  676.   }
  677.  
  678.   return HAL_OK;
  679. }
  680.  
  681. /**
  682.    * @brief  USB_EPStoptXfer  Stop transfer on an EP
  683.    * @param  USBx  usb device instance
  684.    * @param  ep pointer to endpoint structure
  685.    * @retval HAL status
  686.    */
  687. HAL_StatusTypeDef USB_EPStopXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  688. {
  689.   /* IN endpoint */
  690.   if (ep->is_in == 1U)
  691.   {
  692.     if (ep->doublebuffer == 0U)
  693.     {
  694.       if (ep->type != EP_TYPE_ISOC)
  695.       {
  696.         /* Configure NAK status for the Endpoint */
  697.         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
  698.       }
  699.       else
  700.       {
  701.         /* Configure TX Endpoint to disabled state */
  702.         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  703.       }
  704.     }
  705.   }
  706.   else /* OUT endpoint */
  707.   {
  708.     if (ep->doublebuffer == 0U)
  709.     {
  710.       if (ep->type != EP_TYPE_ISOC)
  711.       {
  712.         /* Configure NAK status for the Endpoint */
  713.         PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_NAK);
  714.       }
  715.       else
  716.       {
  717.         /* Configure RX Endpoint to disabled state */
  718.         PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
  719.       }
  720.     }
  721.   }
  722.  
  723.   return HAL_OK;
  724. }
  725. #endif /* defined (HAL_PCD_MODULE_ENABLED) */
  726.  
  727. /**
  728.   * @brief  USB_StopDevice Stop the usb device mode
  729.   * @param  USBx Selected device
  730.   * @retval HAL status
  731.   */
  732. HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx)
  733. {
  734.   /* disable all interrupts and force USB reset */
  735.   USBx->CNTR = (uint16_t)USB_CNTR_FRES;
  736.  
  737.   /* clear interrupt status register */
  738.   USBx->ISTR = 0U;
  739.  
  740.   /* switch-off device */
  741.   USBx->CNTR = (uint16_t)(USB_CNTR_FRES | USB_CNTR_PDWN);
  742.  
  743.   return HAL_OK;
  744. }
  745.  
  746. /**
  747.   * @brief  USB_SetDevAddress Stop the usb device mode
  748.   * @param  USBx Selected device
  749.   * @param  address new device address to be assigned
  750.   *          This parameter can be a value from 0 to 255
  751.   * @retval HAL status
  752.   */
  753. HAL_StatusTypeDef  USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address)
  754. {
  755.   if (address == 0U)
  756.   {
  757.     /* set device address and enable function */
  758.     USBx->DADDR = (uint16_t)USB_DADDR_EF;
  759.   }
  760.  
  761.   return HAL_OK;
  762. }
  763.  
  764. /**
  765.   * @brief  USB_DevConnect Connect the USB device by enabling the pull-up/pull-down
  766.   * @param  USBx Selected device
  767.   * @retval HAL status
  768.   */
  769. HAL_StatusTypeDef  USB_DevConnect(USB_TypeDef *USBx)
  770. {
  771.   /* Prevent unused argument(s) compilation warning */
  772.   UNUSED(USBx);
  773.  
  774.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  775.               only by USB OTG FS peripheral.
  776.             - This function is added to ensure compatibility across platforms.
  777.    */
  778.  
  779.   return HAL_OK;
  780. }
  781.  
  782. /**
  783.   * @brief  USB_DevDisconnect Disconnect the USB device by disabling the pull-up/pull-down
  784.   * @param  USBx Selected device
  785.   * @retval HAL status
  786.   */
  787. HAL_StatusTypeDef  USB_DevDisconnect(USB_TypeDef *USBx)
  788. {
  789.   /* Prevent unused argument(s) compilation warning */
  790.   UNUSED(USBx);
  791.  
  792.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  793.               only by USB OTG FS peripheral.
  794.             - This function is added to ensure compatibility across platforms.
  795.    */
  796.  
  797.   return HAL_OK;
  798. }
  799.  
  800. /**
  801.   * @brief  USB_ReadInterrupts return the global USB interrupt status
  802.   * @param  USBx Selected device
  803.   * @retval USB Global Interrupt status
  804.   */
  805. uint32_t USB_ReadInterrupts(USB_TypeDef const *USBx)
  806. {
  807.   uint32_t tmpreg;
  808.  
  809.   tmpreg = USBx->ISTR;
  810.   return tmpreg;
  811. }
  812.  
  813. /**
  814.   * @brief  USB_ActivateRemoteWakeup : active remote wakeup signalling
  815.   * @param  USBx Selected device
  816.   * @retval HAL status
  817.   */
  818. HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx)
  819. {
  820.   USBx->CNTR |= (uint16_t)USB_CNTR_RESUME;
  821.  
  822.   return HAL_OK;
  823. }
  824.  
  825. /**
  826.   * @brief  USB_DeActivateRemoteWakeup de-active remote wakeup signalling
  827.   * @param  USBx Selected device
  828.   * @retval HAL status
  829.   */
  830. HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx)
  831. {
  832.   USBx->CNTR &= (uint16_t)(~USB_CNTR_RESUME);
  833.  
  834.   return HAL_OK;
  835. }
  836.  
  837. /**
  838.   * @brief Copy a buffer from user memory area to packet memory area (PMA)
  839.   * @param   USBx USB peripheral instance register address.
  840.   * @param   pbUsrBuf pointer to user memory area.
  841.   * @param   wPMABufAddr address into PMA.
  842.   * @param   wNBytes no. of bytes to be copied.
  843.   * @retval None
  844.   */
  845. void USB_WritePMA(USB_TypeDef const *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
  846. {
  847.   uint32_t n = ((uint32_t)wNBytes + 1U) >> 1;
  848.   uint32_t BaseAddr = (uint32_t)USBx;
  849.   uint32_t count;
  850.   uint16_t WrVal;
  851.   __IO uint16_t *pdwVal;
  852.   uint8_t *pBuf = pbUsrBuf;
  853.  
  854.   pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
  855.  
  856.   for (count = n; count != 0U; count--)
  857.   {
  858.     WrVal = pBuf[0];
  859.     WrVal |= (uint16_t)pBuf[1] << 8;
  860.     *pdwVal = (WrVal & 0xFFFFU);
  861.     pdwVal++;
  862.  
  863. #if PMA_ACCESS > 1U
  864.     pdwVal++;
  865. #endif /* PMA_ACCESS */
  866.  
  867.     pBuf++;
  868.     pBuf++;
  869.   }
  870. }
  871.  
  872. /**
  873.   * @brief Copy data from packet memory area (PMA) to user memory buffer
  874.   * @param   USBx USB peripheral instance register address.
  875.   * @param   pbUsrBuf pointer to user memory area.
  876.   * @param   wPMABufAddr address into PMA.
  877.   * @param   wNBytes no. of bytes to be copied.
  878.   * @retval None
  879.   */
  880. void USB_ReadPMA(USB_TypeDef const *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
  881. {
  882.   uint32_t n = (uint32_t)wNBytes >> 1;
  883.   uint32_t BaseAddr = (uint32_t)USBx;
  884.   uint32_t count;
  885.   uint32_t RdVal;
  886.   __IO uint16_t *pdwVal;
  887.   uint8_t *pBuf = pbUsrBuf;
  888.  
  889.   pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
  890.  
  891.   for (count = n; count != 0U; count--)
  892.   {
  893.     RdVal = *(__IO uint16_t *)pdwVal;
  894.     pdwVal++;
  895.     *pBuf = (uint8_t)((RdVal >> 0) & 0xFFU);
  896.     pBuf++;
  897.     *pBuf = (uint8_t)((RdVal >> 8) & 0xFFU);
  898.     pBuf++;
  899.  
  900. #if PMA_ACCESS > 1U
  901.     pdwVal++;
  902. #endif /* PMA_ACCESS */
  903.   }
  904.  
  905.   if ((wNBytes % 2U) != 0U)
  906.   {
  907.     RdVal = *pdwVal;
  908.     *pBuf = (uint8_t)((RdVal >> 0) & 0xFFU);
  909.   }
  910. }
  911.  
  912.  
  913. /**
  914.   * @}
  915.   */
  916.  
  917. /**
  918.   * @}
  919.   */
  920. #endif /* defined (USB) */
  921. #endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
  922.  
  923. /**
  924.   * @}
  925.   */
  926.