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.   @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 "stm32l1xx_hal.h"
  42.  
  43. /** @addtogroup STM32L1xx_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;
  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. #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.     /* Set the endpoint as double buffered */
  253.     PCD_SET_EP_DBUF(USBx, ep->num);
  254.  
  255.     /* Set buffer address for double buffered mode */
  256.     PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1);
  257.  
  258.     if (ep->is_in == 0U)
  259.     {
  260.       /* Clear the data toggle bits for the endpoint IN/OUT */
  261.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  262.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  263.  
  264.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
  265.       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  266.     }
  267.     else
  268.     {
  269.       /* Clear the data toggle bits for the endpoint IN/OUT */
  270.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  271.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  272.  
  273.       if (ep->type != EP_TYPE_ISOC)
  274.       {
  275.         /* Configure NAK status for the Endpoint */
  276.         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
  277.       }
  278.       else
  279.       {
  280.         /* Configure TX Endpoint to disabled state */
  281.         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  282.       }
  283.  
  284.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
  285.     }
  286.   }
  287.  
  288.   return ret;
  289. }
  290.  
  291. /**
  292.   * @brief  De-activate and de-initialize an endpoint
  293.   * @param  USBx Selected device
  294.   * @param  ep pointer to endpoint structure
  295.   * @retval HAL status
  296.   */
  297. HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  298. {
  299.   if (ep->doublebuffer == 0U)
  300.   {
  301.     if (ep->is_in != 0U)
  302.     {
  303.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  304.  
  305.       /* Configure DISABLE status for the Endpoint*/
  306.       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  307.     }
  308.     else
  309.     {
  310.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  311.  
  312.       /* Configure DISABLE status for the Endpoint*/
  313.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
  314.     }
  315.   }
  316.   /*Double Buffer*/
  317.   else
  318.   {
  319.     if (ep->is_in == 0U)
  320.     {
  321.       /* Clear the data toggle bits for the endpoint IN/OUT*/
  322.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  323.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  324.  
  325.       /* Reset value of the data toggle bits for the endpoint out*/
  326.       PCD_TX_DTOG(USBx, ep->num);
  327.  
  328.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
  329.       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  330.     }
  331.     else
  332.     {
  333.       /* Clear the data toggle bits for the endpoint IN/OUT*/
  334.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  335.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  336.       PCD_RX_DTOG(USBx, ep->num);
  337.  
  338.       /* Configure DISABLE status for the Endpoint*/
  339.       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  340.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
  341.     }
  342.   }
  343.  
  344.   return HAL_OK;
  345. }
  346.  
  347. /**
  348.   * @brief  USB_EPStartXfer setup and starts a transfer over an EP
  349.   * @param  USBx Selected device
  350.   * @param  ep pointer to endpoint structure
  351.   * @retval HAL status
  352.   */
  353. HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  354. {
  355.   uint32_t len;
  356.   uint16_t pmabuffer;
  357.   uint16_t wEPVal;
  358.  
  359.   /* IN endpoint */
  360.   if (ep->is_in == 1U)
  361.   {
  362.     /*Multi packet transfer*/
  363.     if (ep->xfer_len > ep->maxpacket)
  364.     {
  365.       len = ep->maxpacket;
  366.     }
  367.     else
  368.     {
  369.       len = ep->xfer_len;
  370.     }
  371.  
  372.     /* configure and validate Tx endpoint */
  373.     if (ep->doublebuffer == 0U)
  374.     {
  375.       USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len);
  376.       PCD_SET_EP_TX_CNT(USBx, ep->num, len);
  377.     }
  378.     else
  379.     {
  380.       /* double buffer bulk management */
  381.       if (ep->type == EP_TYPE_BULK)
  382.       {
  383.         if (ep->xfer_len_db > ep->maxpacket)
  384.         {
  385.           /* enable double buffer */
  386.           PCD_SET_EP_DBUF(USBx, ep->num);
  387.  
  388.           /* each Time to write in PMA xfer_len_db will */
  389.           ep->xfer_len_db -= len;
  390.  
  391.           /* Fill the two first buffer in the Buffer0 & Buffer1 */
  392.           if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
  393.           {
  394.             /* Set the Double buffer counter for pmabuffer1 */
  395.             PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
  396.             pmabuffer = ep->pmaaddr1;
  397.  
  398.             /* Write the user buffer to USB PMA */
  399.             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  400.             ep->xfer_buff += len;
  401.  
  402.             if (ep->xfer_len_db > ep->maxpacket)
  403.             {
  404.               ep->xfer_len_db -= len;
  405.             }
  406.             else
  407.             {
  408.               len = ep->xfer_len_db;
  409.               ep->xfer_len_db = 0U;
  410.             }
  411.  
  412.             /* Set the Double buffer counter for pmabuffer0 */
  413.             PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
  414.             pmabuffer = ep->pmaaddr0;
  415.  
  416.             /* Write the user buffer to USB PMA */
  417.             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  418.           }
  419.           else
  420.           {
  421.             /* Set the Double buffer counter for pmabuffer0 */
  422.             PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
  423.             pmabuffer = ep->pmaaddr0;
  424.  
  425.             /* Write the user buffer to USB PMA */
  426.             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  427.             ep->xfer_buff += len;
  428.  
  429.             if (ep->xfer_len_db > ep->maxpacket)
  430.             {
  431.               ep->xfer_len_db -= len;
  432.             }
  433.             else
  434.             {
  435.               len = ep->xfer_len_db;
  436.               ep->xfer_len_db = 0U;
  437.             }
  438.  
  439.             /* Set the Double buffer counter for pmabuffer1 */
  440.             PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
  441.             pmabuffer = ep->pmaaddr1;
  442.  
  443.             /* Write the user buffer to USB PMA */
  444.             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  445.           }
  446.         }
  447.         /* auto Switch to single buffer mode when transfer <Mps no need to manage in double buffer */
  448.         else
  449.         {
  450.           len = ep->xfer_len_db;
  451.  
  452.           /* disable double buffer mode */
  453.           PCD_CLEAR_EP_DBUF(USBx, ep->num);
  454.  
  455.           /* Set Tx count with nbre of byte to be transmitted */
  456.           PCD_SET_EP_TX_CNT(USBx, ep->num, len);
  457.           pmabuffer = ep->pmaaddr0;
  458.  
  459.           /* Write the user buffer to USB PMA */
  460.           USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  461.         }
  462.       }/* end if bulk double buffer */
  463.  
  464.       /* manage isochronous double buffer IN mode */
  465.       else
  466.       {
  467.         /* enable double buffer */
  468.         PCD_SET_EP_DBUF(USBx, ep->num);
  469.  
  470.         /* each Time to write in PMA xfer_len_db will */
  471.         ep->xfer_len_db -= len;
  472.  
  473.         /* Fill the data buffer */
  474.         if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
  475.         {
  476.           /* Set the Double buffer counter for pmabuffer1 */
  477.           PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
  478.           pmabuffer = ep->pmaaddr1;
  479.  
  480.           /* Write the user buffer to USB PMA */
  481.           USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  482.           ep->xfer_buff += len;
  483.  
  484.           if (ep->xfer_len_db > ep->maxpacket)
  485.           {
  486.             ep->xfer_len_db -= len;
  487.           }
  488.           else
  489.           {
  490.             len = ep->xfer_len_db;
  491.             ep->xfer_len_db = 0U;
  492.           }
  493.  
  494.           if (len > 0U)
  495.           {
  496.             /* Set the Double buffer counter for pmabuffer0 */
  497.             PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
  498.             pmabuffer = ep->pmaaddr0;
  499.  
  500.             /* Write the user buffer to USB PMA */
  501.             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  502.           }
  503.         }
  504.         else
  505.         {
  506.           /* Set the Double buffer counter for pmabuffer0 */
  507.           PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
  508.           pmabuffer = ep->pmaaddr0;
  509.  
  510.           /* Write the user buffer to USB PMA */
  511.           USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  512.           ep->xfer_buff += len;
  513.  
  514.           if (ep->xfer_len_db > ep->maxpacket)
  515.           {
  516.             ep->xfer_len_db -= len;
  517.           }
  518.           else
  519.           {
  520.             len = ep->xfer_len_db;
  521.             ep->xfer_len_db = 0U;
  522.           }
  523.  
  524.           if (len > 0U)
  525.           {
  526.             /* Set the Double buffer counter for pmabuffer1 */
  527.             PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
  528.             pmabuffer = ep->pmaaddr1;
  529.  
  530.             /* Write the user buffer to USB PMA */
  531.             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  532.           }
  533.         }
  534.       }
  535.     }
  536.  
  537.     PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
  538.   }
  539.   else /* OUT endpoint */
  540.   {
  541.     if (ep->doublebuffer == 0U)
  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.       /* configure and validate Rx endpoint */
  555.       PCD_SET_EP_RX_CNT(USBx, ep->num, len);
  556.     }
  557.     else
  558.     {
  559.       /* First Transfer Coming From HAL_PCD_EP_Receive & From ISR */
  560.       /* Set the Double buffer counter */
  561.       if (ep->type == EP_TYPE_BULK)
  562.       {
  563.         PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, ep->maxpacket);
  564.  
  565.         /* Coming from ISR */
  566.         if (ep->xfer_count != 0U)
  567.         {
  568.           /* update last value to check if there is blocking state */
  569.           wEPVal = PCD_GET_ENDPOINT(USBx, ep->num);
  570.  
  571.           /*Blocking State */
  572.           if ((((wEPVal & USB_EP_DTOG_RX) != 0U) && ((wEPVal & USB_EP_DTOG_TX) != 0U)) ||
  573.               (((wEPVal & USB_EP_DTOG_RX) == 0U) && ((wEPVal & USB_EP_DTOG_TX) == 0U)))
  574.           {
  575.             PCD_FreeUserBuffer(USBx, ep->num, 0U);
  576.           }
  577.         }
  578.       }
  579.       /* iso out double */
  580.       else if (ep->type == EP_TYPE_ISOC)
  581.       {
  582.         /* Multi packet transfer */
  583.         if (ep->xfer_len > ep->maxpacket)
  584.         {
  585.           len = ep->maxpacket;
  586.           ep->xfer_len -= len;
  587.         }
  588.         else
  589.         {
  590.           len = ep->xfer_len;
  591.           ep->xfer_len = 0U;
  592.         }
  593.         PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len);
  594.       }
  595.       else
  596.       {
  597.         return HAL_ERROR;
  598.       }
  599.     }
  600.  
  601.     PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
  602.   }
  603.  
  604.   return HAL_OK;
  605. }
  606.  
  607.  
  608. /**
  609.   * @brief  USB_EPSetStall set a stall condition over an EP
  610.   * @param  USBx Selected device
  611.   * @param  ep pointer to endpoint structure
  612.   * @retval HAL status
  613.   */
  614. HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  615. {
  616.   if (ep->is_in != 0U)
  617.   {
  618.     PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL);
  619.   }
  620.   else
  621.   {
  622.     PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL);
  623.   }
  624.  
  625.   return HAL_OK;
  626. }
  627.  
  628. /**
  629.   * @brief  USB_EPClearStall Clear a stall condition over an EP
  630.   * @param  USBx Selected device
  631.   * @param  ep pointer to endpoint structure
  632.   * @retval HAL status
  633.   */
  634. HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  635. {
  636.   if (ep->doublebuffer == 0U)
  637.   {
  638.     if (ep->is_in != 0U)
  639.     {
  640.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  641.  
  642.       if (ep->type != EP_TYPE_ISOC)
  643.       {
  644.         /* Configure NAK status for the Endpoint */
  645.         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
  646.       }
  647.     }
  648.     else
  649.     {
  650.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  651.  
  652.       /* Configure VALID status for the Endpoint */
  653.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
  654.     }
  655.   }
  656.  
  657.   return HAL_OK;
  658. }
  659. #endif
  660.  
  661. /**
  662.   * @brief  USB_StopDevice Stop the usb device mode
  663.   * @param  USBx Selected device
  664.   * @retval HAL status
  665.   */
  666. HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx)
  667. {
  668.   /* disable all interrupts and force USB reset */
  669.   USBx->CNTR = (uint16_t)USB_CNTR_FRES;
  670.  
  671.   /* clear interrupt status register */
  672.   USBx->ISTR = 0U;
  673.  
  674.   /* switch-off device */
  675.   USBx->CNTR = (uint16_t)(USB_CNTR_FRES | USB_CNTR_PDWN);
  676.  
  677.   return HAL_OK;
  678. }
  679.  
  680. /**
  681.   * @brief  USB_SetDevAddress Stop the usb device mode
  682.   * @param  USBx Selected device
  683.   * @param  address new device address to be assigned
  684.   *          This parameter can be a value from 0 to 255
  685.   * @retval HAL status
  686.   */
  687. HAL_StatusTypeDef  USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address)
  688. {
  689.   if (address == 0U)
  690.   {
  691.     /* set device address and enable function */
  692.     USBx->DADDR = (uint16_t)USB_DADDR_EF;
  693.   }
  694.  
  695.   return HAL_OK;
  696. }
  697.  
  698. /**
  699.   * @brief  USB_DevConnect Connect the USB device by enabling the pull-up/pull-down
  700.   * @param  USBx Selected device
  701.   * @retval HAL status
  702.   */
  703. HAL_StatusTypeDef  USB_DevConnect(USB_TypeDef *USBx)
  704. {
  705.   /* Prevent unused argument(s) compilation warning */
  706.   UNUSED(USBx);
  707.  
  708.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  709.               only by USB OTG FS peripheral.
  710.             - This function is added to ensure compatibility across platforms.
  711.    */
  712.  
  713.   return HAL_OK;
  714. }
  715.  
  716. /**
  717.   * @brief  USB_DevDisconnect Disconnect the USB device by disabling the pull-up/pull-down
  718.   * @param  USBx Selected device
  719.   * @retval HAL status
  720.   */
  721. HAL_StatusTypeDef  USB_DevDisconnect(USB_TypeDef *USBx)
  722. {
  723.   /* Prevent unused argument(s) compilation warning */
  724.   UNUSED(USBx);
  725.  
  726.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  727.               only by USB OTG FS peripheral.
  728.             - This function is added to ensure compatibility across platforms.
  729.    */
  730.  
  731.   return HAL_OK;
  732. }
  733.  
  734. /**
  735.   * @brief  USB_ReadInterrupts return the global USB interrupt status
  736.   * @param  USBx Selected device
  737.   * @retval HAL status
  738.   */
  739. uint32_t  USB_ReadInterrupts(USB_TypeDef *USBx)
  740. {
  741.   uint32_t tmpreg;
  742.  
  743.   tmpreg = USBx->ISTR;
  744.   return tmpreg;
  745. }
  746.  
  747. /**
  748.   * @brief  USB_ActivateRemoteWakeup : active remote wakeup signalling
  749.   * @param  USBx Selected device
  750.   * @retval HAL status
  751.   */
  752. HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx)
  753. {
  754.   USBx->CNTR |= (uint16_t)USB_CNTR_RESUME;
  755.  
  756.   return HAL_OK;
  757. }
  758.  
  759. /**
  760.   * @brief  USB_DeActivateRemoteWakeup de-active remote wakeup signalling
  761.   * @param  USBx Selected device
  762.   * @retval HAL status
  763.   */
  764. HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx)
  765. {
  766.   USBx->CNTR &= (uint16_t)(~USB_CNTR_RESUME);
  767.  
  768.   return HAL_OK;
  769. }
  770.  
  771. /**
  772.   * @brief Copy a buffer from user memory area to packet memory area (PMA)
  773.   * @param   USBx USB peripheral instance register address.
  774.   * @param   pbUsrBuf pointer to user memory area.
  775.   * @param   wPMABufAddr address into PMA.
  776.   * @param   wNBytes no. of bytes to be copied.
  777.   * @retval None
  778.   */
  779. void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
  780. {
  781.   uint32_t n = ((uint32_t)wNBytes + 1U) >> 1;
  782.   uint32_t BaseAddr = (uint32_t)USBx;
  783.   uint32_t i, temp1, temp2;
  784.   __IO uint16_t *pdwVal;
  785.   uint8_t *pBuf = pbUsrBuf;
  786.  
  787.   pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
  788.  
  789.   for (i = n; i != 0U; i--)
  790.   {
  791.     temp1 = *pBuf;
  792.     pBuf++;
  793.     temp2 = temp1 | ((uint16_t)((uint16_t) *pBuf << 8));
  794.     *pdwVal = (uint16_t)temp2;
  795.     pdwVal++;
  796.  
  797. #if PMA_ACCESS > 1U
  798.     pdwVal++;
  799. #endif
  800.  
  801.     pBuf++;
  802.   }
  803. }
  804.  
  805. /**
  806.   * @brief Copy data from packet memory area (PMA) to user memory buffer
  807.   * @param   USBx USB peripheral instance register address.
  808.   * @param   pbUsrBuf pointer to user memory area.
  809.   * @param   wPMABufAddr address into PMA.
  810.   * @param   wNBytes no. of bytes to be copied.
  811.   * @retval None
  812.   */
  813. void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
  814. {
  815.   uint32_t n = (uint32_t)wNBytes >> 1;
  816.   uint32_t BaseAddr = (uint32_t)USBx;
  817.   uint32_t i, temp;
  818.   __IO uint16_t *pdwVal;
  819.   uint8_t *pBuf = pbUsrBuf;
  820.  
  821.   pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
  822.  
  823.   for (i = n; i != 0U; i--)
  824.   {
  825.     temp = *(__IO uint16_t *)pdwVal;
  826.     pdwVal++;
  827.     *pBuf = (uint8_t)((temp >> 0) & 0xFFU);
  828.     pBuf++;
  829.     *pBuf = (uint8_t)((temp >> 8) & 0xFFU);
  830.     pBuf++;
  831.  
  832. #if PMA_ACCESS > 1U
  833.     pdwVal++;
  834. #endif
  835.   }
  836.  
  837.   if ((wNBytes % 2U) != 0U)
  838.   {
  839.     temp = *pdwVal;
  840.     *pBuf = (uint8_t)((temp >> 0) & 0xFFU);
  841.   }
  842. }
  843.  
  844.  
  845. /**
  846.   * @}
  847.   */
  848.  
  849. /**
  850.   * @}
  851.   */
  852. #endif /* defined (USB) */
  853. #endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
  854.  
  855. /**
  856.   * @}
  857.   */
  858.  
  859. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  860.