Subversion Repositories FuelGauge

Rev

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

  1. /**
  2.   ******************************************************************************
  3.   * @file    stm32f0xx_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.   @verbatim
  15.   ==============================================================================
  16.                     ##### How to use this driver #####
  17.   ==============================================================================
  18.     [..]
  19.       (#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure.
  20.  
  21.       (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
  22.  
  23.       (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
  24.  
  25.   @endverbatim
  26.   ******************************************************************************
  27.   * @attention
  28.   *
  29.   * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
  30.   * All rights reserved.</center></h2>
  31.   *
  32.   * This software component is licensed by ST under BSD 3-Clause license,
  33.   * the "License"; You may not use this file except in compliance with the
  34.   * License. You may obtain a copy of the License at:
  35.   *                        opensource.org/licenses/BSD-3-Clause
  36.   *
  37.   ******************************************************************************
  38.   */
  39.  
  40. /* Includes ------------------------------------------------------------------*/
  41. #include "stm32f0xx_hal.h"
  42.  
  43. /** @addtogroup STM32F0xx_LL_USB_DRIVER
  44.   * @{
  45.   */
  46.  
  47. #if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
  48. #if defined (USB)
  49. /* Private typedef -----------------------------------------------------------*/
  50. /* Private define ------------------------------------------------------------*/
  51. /* Private macro -------------------------------------------------------------*/
  52. /* Private variables ---------------------------------------------------------*/
  53. /* Private function prototypes -----------------------------------------------*/
  54. /* Private functions ---------------------------------------------------------*/
  55.  
  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 | USB_CNTR_L1REQM;
  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 | USB_CNTR_L1REQM;
  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. #if defined (HAL_PCD_MODULE_ENABLED)
  176. /**
  177.   * @brief  Activate and configure an endpoint
  178.   * @param  USBx Selected device
  179.   * @param  ep pointer to endpoint structure
  180.   * @retval HAL status
  181.   */
  182. HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  183. {
  184.   HAL_StatusTypeDef ret = HAL_OK;
  185.   uint16_t wEpRegVal;
  186.  
  187.   wEpRegVal = PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_T_MASK;
  188.  
  189.   /* initialize Endpoint */
  190.   switch (ep->type)
  191.   {
  192.     case EP_TYPE_CTRL:
  193.       wEpRegVal |= USB_EP_CONTROL;
  194.       break;
  195.  
  196.     case EP_TYPE_BULK:
  197.       wEpRegVal |= USB_EP_BULK;
  198.       break;
  199.  
  200.     case EP_TYPE_INTR:
  201.       wEpRegVal |= USB_EP_INTERRUPT;
  202.       break;
  203.  
  204.     case EP_TYPE_ISOC:
  205.       wEpRegVal |= USB_EP_ISOCHRONOUS;
  206.       break;
  207.  
  208.     default:
  209.       ret = HAL_ERROR;
  210.       break;
  211.   }
  212.  
  213.   PCD_SET_ENDPOINT(USBx, ep->num, (wEpRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX));
  214.  
  215.   PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num);
  216.  
  217.   if (ep->doublebuffer == 0U)
  218.   {
  219.     if (ep->is_in != 0U)
  220.     {
  221.       /*Set the endpoint Transmit buffer address */
  222.       PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress);
  223.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  224.  
  225.       if (ep->type != EP_TYPE_ISOC)
  226.       {
  227.         /* Configure NAK status for the Endpoint */
  228.         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
  229.       }
  230.       else
  231.       {
  232.         /* Configure TX Endpoint to disabled state */
  233.         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  234.       }
  235.     }
  236.     else
  237.     {
  238.       /* Set the endpoint Receive buffer address */
  239.       PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress);
  240.  
  241.       /* Set the endpoint Receive buffer counter */
  242.       PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket);
  243.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  244.  
  245.       /* Configure VALID status for the Endpoint */
  246.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
  247.     }
  248.   }
  249.   /* Double Buffer */
  250.   else
  251.   {
  252.     if (ep->type == EP_TYPE_BULK)
  253.     {
  254.       /* Set bulk endpoint as double buffered */
  255.       PCD_SET_BULK_EP_DBUF(USBx, ep->num);
  256.     }
  257.     else
  258.     {
  259.       /* Set the ISOC endpoint in double buffer mode */
  260.       PCD_CLEAR_EP_KIND(USBx, ep->num);
  261.     }
  262.  
  263.     /* Set buffer address for double buffered mode */
  264.     PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1);
  265.  
  266.     if (ep->is_in == 0U)
  267.     {
  268.       /* Clear the data toggle bits for the endpoint IN/OUT */
  269.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  270.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  271.  
  272.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
  273.       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  274.     }
  275.     else
  276.     {
  277.       /* Clear the data toggle bits for the endpoint IN/OUT */
  278.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  279.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  280.  
  281.       if (ep->type != EP_TYPE_ISOC)
  282.       {
  283.         /* Configure NAK status for the Endpoint */
  284.         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
  285.       }
  286.       else
  287.       {
  288.         /* Configure TX Endpoint to disabled state */
  289.         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  290.       }
  291.  
  292.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
  293.     }
  294.   }
  295.  
  296.   return ret;
  297. }
  298.  
  299. /**
  300.   * @brief  De-activate and de-initialize an endpoint
  301.   * @param  USBx Selected device
  302.   * @param  ep pointer to endpoint structure
  303.   * @retval HAL status
  304.   */
  305. HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  306. {
  307.   if (ep->doublebuffer == 0U)
  308.   {
  309.     if (ep->is_in != 0U)
  310.     {
  311.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  312.  
  313.       /* Configure DISABLE status for the Endpoint*/
  314.       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  315.     }
  316.     else
  317.     {
  318.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  319.  
  320.       /* Configure DISABLE status for the Endpoint*/
  321.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
  322.     }
  323.   }
  324.   /*Double Buffer*/
  325.   else
  326.   {
  327.     if (ep->is_in == 0U)
  328.     {
  329.       /* Clear the data toggle bits for the endpoint IN/OUT*/
  330.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  331.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  332.  
  333.       /* Reset value of the data toggle bits for the endpoint out*/
  334.       PCD_TX_DTOG(USBx, ep->num);
  335.  
  336.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
  337.       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  338.     }
  339.     else
  340.     {
  341.       /* Clear the data toggle bits for the endpoint IN/OUT*/
  342.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  343.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  344.       PCD_RX_DTOG(USBx, ep->num);
  345.  
  346.       /* Configure DISABLE status for the Endpoint*/
  347.       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  348.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
  349.     }
  350.   }
  351.  
  352.   return HAL_OK;
  353. }
  354.  
  355. /**
  356.   * @brief  USB_EPStartXfer setup and starts a transfer over an EP
  357.   * @param  USBx Selected device
  358.   * @param  ep pointer to endpoint structure
  359.   * @retval HAL status
  360.   */
  361. HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  362. {
  363.   uint32_t len;
  364.   uint16_t pmabuffer;
  365.   uint16_t wEPVal;
  366.  
  367.   /* IN endpoint */
  368.   if (ep->is_in == 1U)
  369.   {
  370.     /*Multi packet transfer*/
  371.     if (ep->xfer_len > ep->maxpacket)
  372.     {
  373.       len = ep->maxpacket;
  374.     }
  375.     else
  376.     {
  377.       len = ep->xfer_len;
  378.     }
  379.  
  380.     /* configure and validate Tx endpoint */
  381.     if (ep->doublebuffer == 0U)
  382.     {
  383.       USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len);
  384.       PCD_SET_EP_TX_CNT(USBx, ep->num, len);
  385.     }
  386.     else
  387.     {
  388.       /* double buffer bulk management */
  389.       if (ep->type == EP_TYPE_BULK)
  390.       {
  391.         if (ep->xfer_len_db > ep->maxpacket)
  392.         {
  393.           /* enable double buffer */
  394.           PCD_SET_BULK_EP_DBUF(USBx, ep->num);
  395.  
  396.           /* each Time to write in PMA xfer_len_db will */
  397.           ep->xfer_len_db -= len;
  398.  
  399.           /* Fill the two first buffer in the Buffer0 & Buffer1 */
  400.           if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
  401.           {
  402.             /* Set the Double buffer counter for pmabuffer1 */
  403.             PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
  404.             pmabuffer = ep->pmaaddr1;
  405.  
  406.             /* Write the user buffer to USB PMA */
  407.             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  408.             ep->xfer_buff += len;
  409.  
  410.             if (ep->xfer_len_db > ep->maxpacket)
  411.             {
  412.               ep->xfer_len_db -= len;
  413.             }
  414.             else
  415.             {
  416.               len = ep->xfer_len_db;
  417.               ep->xfer_len_db = 0U;
  418.             }
  419.  
  420.             /* Set the Double buffer counter for pmabuffer0 */
  421.             PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
  422.             pmabuffer = ep->pmaaddr0;
  423.  
  424.             /* Write the user buffer to USB PMA */
  425.             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  426.           }
  427.           else
  428.           {
  429.             /* Set the Double buffer counter for pmabuffer0 */
  430.             PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
  431.             pmabuffer = ep->pmaaddr0;
  432.  
  433.             /* Write the user buffer to USB PMA */
  434.             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  435.             ep->xfer_buff += len;
  436.  
  437.             if (ep->xfer_len_db > ep->maxpacket)
  438.             {
  439.               ep->xfer_len_db -= len;
  440.             }
  441.             else
  442.             {
  443.               len = ep->xfer_len_db;
  444.               ep->xfer_len_db = 0U;
  445.             }
  446.  
  447.             /* Set the Double buffer counter for pmabuffer1 */
  448.             PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
  449.             pmabuffer = ep->pmaaddr1;
  450.  
  451.             /* Write the user buffer to USB PMA */
  452.             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  453.           }
  454.         }
  455.         /* auto Switch to single buffer mode when transfer <Mps no need to manage in double buffer */
  456.         else
  457.         {
  458.           len = ep->xfer_len_db;
  459.  
  460.           /* disable double buffer mode for Bulk endpoint */
  461.           PCD_CLEAR_BULK_EP_DBUF(USBx, ep->num);
  462.  
  463.           /* Set Tx count with nbre of byte to be transmitted */
  464.           PCD_SET_EP_TX_CNT(USBx, ep->num, len);
  465.           pmabuffer = ep->pmaaddr0;
  466.  
  467.           /* Write the user buffer to USB PMA */
  468.           USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  469.         }
  470.       }
  471.       else /* manage isochronous double buffer IN mode */
  472.       {
  473.         /* each Time to write in PMA xfer_len_db will */
  474.         ep->xfer_len_db -= len;
  475.  
  476.         /* Fill the data buffer */
  477.         if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
  478.         {
  479.           /* Set the Double buffer counter for pmabuffer1 */
  480.           PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
  481.           pmabuffer = ep->pmaaddr1;
  482.  
  483.           /* Write the user buffer to USB PMA */
  484.           USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  485.         }
  486.         else
  487.         {
  488.           /* Set the Double buffer counter for pmabuffer0 */
  489.           PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
  490.           pmabuffer = ep->pmaaddr0;
  491.  
  492.           /* Write the user buffer to USB PMA */
  493.           USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  494.         }
  495.       }
  496.     }
  497.  
  498.     PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
  499.   }
  500.   else /* OUT endpoint */
  501.   {
  502.     if (ep->doublebuffer == 0U)
  503.     {
  504.       /* Multi packet transfer */
  505.       if (ep->xfer_len > ep->maxpacket)
  506.       {
  507.         len = ep->maxpacket;
  508.         ep->xfer_len -= len;
  509.       }
  510.       else
  511.       {
  512.         len = ep->xfer_len;
  513.         ep->xfer_len = 0U;
  514.       }
  515.       /* configure and validate Rx endpoint */
  516.       PCD_SET_EP_RX_CNT(USBx, ep->num, len);
  517.     }
  518.     else
  519.     {
  520.       /* First Transfer Coming From HAL_PCD_EP_Receive & From ISR */
  521.       /* Set the Double buffer counter */
  522.       if (ep->type == EP_TYPE_BULK)
  523.       {
  524.         PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, ep->maxpacket);
  525.  
  526.         /* Coming from ISR */
  527.         if (ep->xfer_count != 0U)
  528.         {
  529.           /* update last value to check if there is blocking state */
  530.           wEPVal = PCD_GET_ENDPOINT(USBx, ep->num);
  531.  
  532.           /*Blocking State */
  533.           if ((((wEPVal & USB_EP_DTOG_RX) != 0U) && ((wEPVal & USB_EP_DTOG_TX) != 0U)) ||
  534.               (((wEPVal & USB_EP_DTOG_RX) == 0U) && ((wEPVal & USB_EP_DTOG_TX) == 0U)))
  535.           {
  536.             PCD_FreeUserBuffer(USBx, ep->num, 0U);
  537.           }
  538.         }
  539.       }
  540.       /* iso out double */
  541.       else if (ep->type == EP_TYPE_ISOC)
  542.       {
  543.         /* Multi packet transfer */
  544.         if (ep->xfer_len > ep->maxpacket)
  545.         {
  546.           len = ep->maxpacket;
  547.           ep->xfer_len -= len;
  548.         }
  549.         else
  550.         {
  551.           len = ep->xfer_len;
  552.           ep->xfer_len = 0U;
  553.         }
  554.         PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len);
  555.       }
  556.       else
  557.       {
  558.         return HAL_ERROR;
  559.       }
  560.     }
  561.  
  562.     PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
  563.   }
  564.  
  565.   return HAL_OK;
  566. }
  567.  
  568.  
  569. /**
  570.   * @brief  USB_EPSetStall set a stall condition over an EP
  571.   * @param  USBx Selected device
  572.   * @param  ep pointer to endpoint structure
  573.   * @retval HAL status
  574.   */
  575. HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  576. {
  577.   if (ep->is_in != 0U)
  578.   {
  579.     PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL);
  580.   }
  581.   else
  582.   {
  583.     PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL);
  584.   }
  585.  
  586.   return HAL_OK;
  587. }
  588.  
  589. /**
  590.   * @brief  USB_EPClearStall Clear a stall condition over an EP
  591.   * @param  USBx Selected device
  592.   * @param  ep pointer to endpoint structure
  593.   * @retval HAL status
  594.   */
  595. HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  596. {
  597.   if (ep->doublebuffer == 0U)
  598.   {
  599.     if (ep->is_in != 0U)
  600.     {
  601.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  602.  
  603.       if (ep->type != EP_TYPE_ISOC)
  604.       {
  605.         /* Configure NAK status for the Endpoint */
  606.         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
  607.       }
  608.     }
  609.     else
  610.     {
  611.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  612.  
  613.       /* Configure VALID status for the Endpoint */
  614.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
  615.     }
  616.   }
  617.  
  618.   return HAL_OK;
  619. }
  620. #endif /* defined (HAL_PCD_MODULE_ENABLED) */
  621.  
  622. /**
  623.   * @brief  USB_StopDevice Stop the usb device mode
  624.   * @param  USBx Selected device
  625.   * @retval HAL status
  626.   */
  627. HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx)
  628. {
  629.   /* disable all interrupts and force USB reset */
  630.   USBx->CNTR = (uint16_t)USB_CNTR_FRES;
  631.  
  632.   /* clear interrupt status register */
  633.   USBx->ISTR = 0U;
  634.  
  635.   /* switch-off device */
  636.   USBx->CNTR = (uint16_t)(USB_CNTR_FRES | USB_CNTR_PDWN);
  637.  
  638.   return HAL_OK;
  639. }
  640.  
  641. /**
  642.   * @brief  USB_SetDevAddress Stop the usb device mode
  643.   * @param  USBx Selected device
  644.   * @param  address new device address to be assigned
  645.   *          This parameter can be a value from 0 to 255
  646.   * @retval HAL status
  647.   */
  648. HAL_StatusTypeDef  USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address)
  649. {
  650.   if (address == 0U)
  651.   {
  652.     /* set device address and enable function */
  653.     USBx->DADDR = (uint16_t)USB_DADDR_EF;
  654.   }
  655.  
  656.   return HAL_OK;
  657. }
  658.  
  659. /**
  660.   * @brief  USB_DevConnect Connect the USB device by enabling the pull-up/pull-down
  661.   * @param  USBx Selected device
  662.   * @retval HAL status
  663.   */
  664. HAL_StatusTypeDef  USB_DevConnect(USB_TypeDef *USBx)
  665. {
  666.   /* Enabling DP Pull-UP bit to Connect internal PU resistor on USB DP line */
  667.   USBx->BCDR |= (uint16_t)USB_BCDR_DPPU;
  668.  
  669.   return HAL_OK;
  670. }
  671.  
  672. /**
  673.   * @brief  USB_DevDisconnect Disconnect the USB device by disabling the pull-up/pull-down
  674.   * @param  USBx Selected device
  675.   * @retval HAL status
  676.   */
  677. HAL_StatusTypeDef  USB_DevDisconnect(USB_TypeDef *USBx)
  678. {
  679.   /* Disable DP Pull-Up bit to disconnect the Internal PU resistor on USB DP line */
  680.   USBx->BCDR &= (uint16_t)(~(USB_BCDR_DPPU));
  681.  
  682.   return HAL_OK;
  683. }
  684.  
  685. /**
  686.   * @brief  USB_ReadInterrupts return the global USB interrupt status
  687.   * @param  USBx Selected device
  688.   * @retval HAL status
  689.   */
  690. uint32_t  USB_ReadInterrupts(USB_TypeDef *USBx)
  691. {
  692.   uint32_t tmpreg;
  693.  
  694.   tmpreg = USBx->ISTR;
  695.   return tmpreg;
  696. }
  697.  
  698. /**
  699.   * @brief  USB_ActivateRemoteWakeup : active remote wakeup signalling
  700.   * @param  USBx Selected device
  701.   * @retval HAL status
  702.   */
  703. HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx)
  704. {
  705.   USBx->CNTR |= (uint16_t)USB_CNTR_RESUME;
  706.  
  707.   return HAL_OK;
  708. }
  709.  
  710. /**
  711.   * @brief  USB_DeActivateRemoteWakeup de-active remote wakeup signalling
  712.   * @param  USBx Selected device
  713.   * @retval HAL status
  714.   */
  715. HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx)
  716. {
  717.   USBx->CNTR &= (uint16_t)(~USB_CNTR_RESUME);
  718.  
  719.   return HAL_OK;
  720. }
  721.  
  722. /**
  723.   * @brief Copy a buffer from user memory area to packet memory area (PMA)
  724.   * @param   USBx USB peripheral instance register address.
  725.   * @param   pbUsrBuf pointer to user memory area.
  726.   * @param   wPMABufAddr address into PMA.
  727.   * @param   wNBytes no. of bytes to be copied.
  728.   * @retval None
  729.   */
  730. void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
  731. {
  732.   uint32_t n = ((uint32_t)wNBytes + 1U) >> 1;
  733.   uint32_t BaseAddr = (uint32_t)USBx;
  734.   uint32_t i, temp1, temp2;
  735.   __IO uint16_t *pdwVal;
  736.   uint8_t *pBuf = pbUsrBuf;
  737.  
  738.   pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
  739.  
  740.   for (i = n; i != 0U; i--)
  741.   {
  742.     temp1 = *pBuf;
  743.     pBuf++;
  744.     temp2 = temp1 | ((uint16_t)((uint16_t) *pBuf << 8));
  745.     *pdwVal = (uint16_t)temp2;
  746.     pdwVal++;
  747.  
  748. #if PMA_ACCESS > 1U
  749.     pdwVal++;
  750. #endif
  751.  
  752.     pBuf++;
  753.   }
  754. }
  755.  
  756. /**
  757.   * @brief Copy data from packet memory area (PMA) to user memory buffer
  758.   * @param   USBx USB peripheral instance register address.
  759.   * @param   pbUsrBuf pointer to user memory area.
  760.   * @param   wPMABufAddr address into PMA.
  761.   * @param   wNBytes no. of bytes to be copied.
  762.   * @retval None
  763.   */
  764. void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
  765. {
  766.   uint32_t n = (uint32_t)wNBytes >> 1;
  767.   uint32_t BaseAddr = (uint32_t)USBx;
  768.   uint32_t i, temp;
  769.   __IO uint16_t *pdwVal;
  770.   uint8_t *pBuf = pbUsrBuf;
  771.  
  772.   pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
  773.  
  774.   for (i = n; i != 0U; i--)
  775.   {
  776.     temp = *(__IO uint16_t *)pdwVal;
  777.     pdwVal++;
  778.     *pBuf = (uint8_t)((temp >> 0) & 0xFFU);
  779.     pBuf++;
  780.     *pBuf = (uint8_t)((temp >> 8) & 0xFFU);
  781.     pBuf++;
  782.  
  783. #if PMA_ACCESS > 1U
  784.     pdwVal++;
  785. #endif
  786.   }
  787.  
  788.   if ((wNBytes % 2U) != 0U)
  789.   {
  790.     temp = *pdwVal;
  791.     *pBuf = (uint8_t)((temp >> 0) & 0xFFU);
  792.   }
  793. }
  794.  
  795.  
  796. /**
  797.   * @}
  798.   */
  799.  
  800. /**
  801.   * @}
  802.   */
  803. #endif /* defined (USB) */
  804. #endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
  805.  
  806. /**
  807.   * @}
  808.   */
  809.  
  810. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  811.