Subversion Repositories DashDisplay

Rev

Rev 61 | Go to most recent revision | 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. /**
  176.   * @brief  USB_SetDevSpeed :Initializes the device speed
  177.   *         depending on the PHY type and the enumeration speed of the device.
  178.   * @param  USBx  Selected device
  179.   * @param  speed  device speed
  180.   * @retval  Hal status
  181.   */
  182. HAL_StatusTypeDef USB_SetDevSpeed(USB_TypeDef *USBx, uint8_t speed)
  183. {
  184.   /* Prevent unused argument(s) compilation warning */
  185.   UNUSED(USBx);
  186.   UNUSED(speed);
  187.  
  188.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  189.               only by USB OTG FS peripheral.
  190.             - This function is added to ensure compatibility across platforms.
  191.    */
  192.  
  193.   return HAL_OK;
  194. }
  195.  
  196. /**
  197.   * @brief  USB_FlushTxFifo : Flush a Tx FIFO
  198.   * @param  USBx : Selected device
  199.   * @param  num : FIFO number
  200.   *         This parameter can be a value from 1 to 15
  201.             15 means Flush all Tx FIFOs
  202.   * @retval HAL status
  203.   */
  204. HAL_StatusTypeDef USB_FlushTxFifo(USB_TypeDef *USBx, uint32_t num)
  205. {
  206.   /* Prevent unused argument(s) compilation warning */
  207.   UNUSED(USBx);
  208.   UNUSED(num);
  209.  
  210.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  211.               only by USB OTG FS peripheral.
  212.             - This function is added to ensure compatibility across platforms.
  213.    */
  214.  
  215.   return HAL_OK;
  216. }
  217.  
  218. /**
  219.   * @brief  USB_FlushRxFifo : Flush Rx FIFO
  220.   * @param  USBx : Selected device
  221.   * @retval HAL status
  222.   */
  223. HAL_StatusTypeDef USB_FlushRxFifo(USB_TypeDef *USBx)
  224. {
  225.   /* Prevent unused argument(s) compilation warning */
  226.   UNUSED(USBx);
  227.  
  228.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  229.               only by USB OTG FS peripheral.
  230.             - This function is added to ensure compatibility across platforms.
  231.    */
  232.  
  233.   return HAL_OK;
  234. }
  235.  
  236. /**
  237.   * @brief  Activate and configure an endpoint
  238.   * @param  USBx : Selected device
  239.   * @param  ep: pointer to endpoint structure
  240.   * @retval HAL status
  241.   */
  242. HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  243. {
  244.   HAL_StatusTypeDef ret = HAL_OK;
  245.   uint16_t wEpRegVal;
  246.  
  247.   wEpRegVal = PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_T_MASK;
  248.  
  249.   /* initialize Endpoint */
  250.   switch (ep->type)
  251.   {
  252.     case EP_TYPE_CTRL:
  253.       wEpRegVal |= USB_EP_CONTROL;
  254.       break;
  255.  
  256.     case EP_TYPE_BULK:
  257.       wEpRegVal |= USB_EP_BULK;
  258.       break;
  259.  
  260.     case EP_TYPE_INTR:
  261.       wEpRegVal |= USB_EP_INTERRUPT;
  262.       break;
  263.  
  264.     case EP_TYPE_ISOC:
  265.       wEpRegVal |= USB_EP_ISOCHRONOUS;
  266.       break;
  267.  
  268.     default:
  269.       ret = HAL_ERROR;
  270.       break;
  271.   }
  272.  
  273.   PCD_SET_ENDPOINT(USBx, ep->num, (wEpRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX));
  274.  
  275.   PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num);
  276.  
  277.   if (ep->doublebuffer == 0U)
  278.   {
  279.     if (ep->is_in != 0U)
  280.     {
  281.       /*Set the endpoint Transmit buffer address */
  282.       PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress);
  283.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  284.  
  285.       if (ep->type != EP_TYPE_ISOC)
  286.       {
  287.         /* Configure NAK status for the Endpoint */
  288.         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
  289.       }
  290.       else
  291.       {
  292.         /* Configure TX Endpoint to disabled state */
  293.         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  294.       }
  295.     }
  296.     else
  297.     {
  298.       /*Set the endpoint Receive buffer address */
  299.       PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress);
  300.       /*Set the endpoint Receive buffer counter*/
  301.       PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket);
  302.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  303.       /* Configure VALID status for the Endpoint*/
  304.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
  305.     }
  306.   }
  307.   /*Double Buffer*/
  308.   else
  309.   {
  310.     /* Set the endpoint as double buffered */
  311.     PCD_SET_EP_DBUF(USBx, ep->num);
  312.     /* Set buffer address for double buffered mode */
  313.     PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1);
  314.  
  315.     if (ep->is_in == 0U)
  316.     {
  317.       /* Clear the data toggle bits for the endpoint IN/OUT */
  318.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  319.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  320.  
  321.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
  322.       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  323.     }
  324.     else
  325.     {
  326.       /* Clear the data toggle bits for the endpoint IN/OUT */
  327.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  328.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  329.  
  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.  
  346.   return ret;
  347. }
  348.  
  349. /**
  350.   * @brief  De-activate and de-initialize an endpoint
  351.   * @param  USBx : Selected device
  352.   * @param  ep: pointer to endpoint structure
  353.   * @retval HAL status
  354.   */
  355. HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  356. {
  357.   if (ep->doublebuffer == 0U)
  358.   {
  359.     if (ep->is_in != 0U)
  360.     {
  361.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  362.       /* Configure DISABLE status for the Endpoint*/
  363.       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  364.     }
  365.     else
  366.     {
  367.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  368.       /* Configure DISABLE status for the Endpoint*/
  369.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
  370.     }
  371.   }
  372.   /*Double Buffer*/
  373.   else
  374.   {
  375.     if (ep->is_in == 0U)
  376.     {
  377.       /* Clear the data toggle bits for the endpoint IN/OUT*/
  378.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  379.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  380.  
  381.       /* Reset value of the data toggle bits for the endpoint out*/
  382.       PCD_TX_DTOG(USBx, ep->num);
  383.  
  384.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
  385.       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  386.     }
  387.     else
  388.     {
  389.       /* Clear the data toggle bits for the endpoint IN/OUT*/
  390.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  391.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  392.       PCD_RX_DTOG(USBx, ep->num);
  393.       /* Configure DISABLE status for the Endpoint*/
  394.       PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  395.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
  396.     }
  397.   }
  398.  
  399.   return HAL_OK;
  400. }
  401.  
  402. /**
  403.   * @brief  USB_EPStartXfer : setup and starts a transfer over an EP
  404.   * @param  USBx : Selected device
  405.   * @param  ep: pointer to endpoint structure
  406.   * @retval HAL status
  407.   */
  408. HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  409. {
  410.   uint16_t pmabuffer;
  411.   uint32_t len;
  412.   uint16_t wEPVal;
  413.  
  414.   /* IN endpoint */
  415.   if (ep->is_in == 1U)
  416.   {
  417.     /*Multi packet transfer*/
  418.     if (ep->xfer_len > ep->maxpacket)
  419.     {
  420.       len = ep->maxpacket;
  421.     }
  422.     else
  423.     {
  424.       len = ep->xfer_len;
  425.     }
  426.  
  427.     /* configure and validate Tx endpoint */
  428.     if (ep->doublebuffer == 0U)
  429.     {
  430.       USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len);
  431.       PCD_SET_EP_TX_CNT(USBx, ep->num, len);
  432.     }
  433.     else
  434.     {
  435.       /*double buffer bulk management */
  436.       if (ep->type == EP_TYPE_BULK)
  437.       {
  438.         if (ep->xfer_len_db > ep->maxpacket)
  439.         {
  440.           /*enable double buffer */
  441.           PCD_SET_EP_DBUF(USBx, ep->num);
  442.           len = ep->maxpacket;
  443.           /*each Time to write in PMA xfer_len_db will */
  444.           ep->xfer_len_db -= len;
  445.  
  446.           /* Fill the two first buffer in the Buffer0 & Buffer1*/
  447.           if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
  448.           {
  449.             /* Set the Double buffer counter for pmabuffer1 */
  450.             PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
  451.             pmabuffer = ep->pmaaddr1;
  452.  
  453.             /*Write the user buffer to USB PMA */
  454.             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  455.             ep->xfer_buff += len;
  456.  
  457.             if (ep->xfer_len_db > ep->maxpacket)
  458.             {
  459.               len = ep->maxpacket;
  460.               ep->xfer_len_db -= len;
  461.             }
  462.             else
  463.             {
  464.               len = ep->xfer_len_db;
  465.               ep->xfer_len_db = 0;
  466.             }
  467.  
  468.             /* Set the Double buffer counter for pmabuffer0 */
  469.             PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
  470.             pmabuffer = ep->pmaaddr0;
  471.             /*Write the user buffer to USB PMA */
  472.             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  473.           }
  474.           else
  475.           {
  476.             /* Set the Double buffer counter for pmabuffer0 */
  477.             PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
  478.             pmabuffer = ep->pmaaddr0;
  479.             /*Write the user buffer to USB PMA */
  480.             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  481.             ep->xfer_buff += len;
  482.  
  483.             if (ep->xfer_len_db > ep->maxpacket)
  484.             {
  485.               len = ep->maxpacket;
  486.               ep->xfer_len_db -= len;
  487.             }
  488.             else
  489.             {
  490.               len = ep->xfer_len_db;
  491.               ep->xfer_len_db = 0;
  492.             }
  493.  
  494.             /* Set the Double buffer counter for pmabuffer1 */
  495.             PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
  496.             pmabuffer = ep->pmaaddr1;
  497.             /*Write the user buffer to USB PMA */
  498.             USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  499.           }
  500.         }
  501.         /*auto Switch to single buffer mode when transfer <Mps no need to manage in double buffer*/
  502.         else
  503.         {
  504.           len = ep->xfer_len_db;
  505.           /*disable double buffer mode */
  506.           PCD_CLEAR_EP_DBUF(USBx, ep->num);
  507.           /*Set Tx count with nbre of byte to be transmitted */
  508.           PCD_SET_EP_TX_CNT(USBx, ep->num, len);
  509.           pmabuffer = ep->pmaaddr0;
  510.           /*Write the user buffer to USB PMA */
  511.           USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  512.         }
  513.       }/*end if bulk double buffer */
  514.  
  515.       /*mange isochronous double buffer IN mode */
  516.       else
  517.       {
  518.         /* Write the data to the USB endpoint */
  519.         if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
  520.         {
  521.           /* Set the Double buffer counter for pmabuffer1 */
  522.           PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
  523.           pmabuffer = ep->pmaaddr1;
  524.         }
  525.         else
  526.         {
  527.           /* Set the Double buffer counter for pmabuffer0 */
  528.           PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
  529.           pmabuffer = ep->pmaaddr0;
  530.         }
  531.         USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  532.         PCD_FreeUserBuffer(USBx, ep->num, ep->is_in);
  533.       }
  534.     }
  535.  
  536.     PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
  537.   }
  538.   else /* OUT endpoint */
  539.   {
  540.     if (ep->doublebuffer == 0U)
  541.     {
  542.       /* Multi packet transfer*/
  543.       if (ep->xfer_len > ep->maxpacket)
  544.       {
  545.         len = ep->maxpacket;
  546.         ep->xfer_len -= len;
  547.       }
  548.       else
  549.       {
  550.         len = ep->xfer_len;
  551.         ep->xfer_len = 0U;
  552.       }
  553.       /* configure and validate Rx endpoint */
  554.       /*Set RX buffer count*/
  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.         /*Coming from ISR*/
  565.         if (ep->xfer_count != 0U)
  566.         {
  567.           /* update last value to check if there is blocking state*/
  568.           wEPVal = PCD_GET_ENDPOINT(USBx, ep->num);
  569.           /*Blocking State */
  570.           if ((((wEPVal & USB_EP_DTOG_RX) != 0U) && ((wEPVal & USB_EP_DTOG_TX) != 0U)) ||
  571.               (((wEPVal & USB_EP_DTOG_RX) == 0U) && ((wEPVal & USB_EP_DTOG_TX) == 0U)))
  572.           {
  573.             PCD_FreeUserBuffer(USBx, ep->num, 0U);
  574.           }
  575.         }
  576.       }
  577.       /*iso out double */
  578.       else if (ep->type == EP_TYPE_ISOC)
  579.       {
  580.         /* Multi packet transfer*/
  581.         if (ep->xfer_len > ep->maxpacket)
  582.         {
  583.           len = ep->maxpacket;
  584.           ep->xfer_len -= len;
  585.         }
  586.         else
  587.         {
  588.           len = ep->xfer_len;
  589.           ep->xfer_len = 0U;
  590.         }
  591.         PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len);
  592.       }
  593.       else
  594.       {
  595.         return HAL_ERROR;
  596.       }
  597.     }
  598.  
  599.     PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
  600.   }
  601.  
  602.   return HAL_OK;
  603. }
  604.  
  605. /**
  606.   * @brief  USB_WritePacket : Writes a packet into the Tx FIFO associated
  607.   *         with the EP/channel
  608.   * @param  USBx : Selected device
  609.   * @param  src :  pointer to source buffer
  610.   * @param  ch_ep_num : endpoint or host channel number
  611.   * @param  len : Number of bytes to write
  612.   * @retval HAL status
  613.   */
  614. HAL_StatusTypeDef USB_WritePacket(USB_TypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len)
  615. {
  616.   /* Prevent unused argument(s) compilation warning */
  617.   UNUSED(USBx);
  618.   UNUSED(src);
  619.   UNUSED(ch_ep_num);
  620.   UNUSED(len);
  621.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  622.               only by USB OTG FS peripheral.
  623.             - This function is added to ensure compatibility across platforms.
  624.    */
  625.   return HAL_OK;
  626. }
  627.  
  628. /**
  629.   * @brief  USB_ReadPacket : read a packet from the Tx FIFO associated
  630.   *         with the EP/channel
  631.   * @param  USBx : Selected device
  632.   * @param  dest : destination pointer
  633.   * @param  len : Number of bytes to read
  634.   * @retval pointer to destination buffer
  635.   */
  636. void *USB_ReadPacket(USB_TypeDef *USBx, uint8_t *dest, uint16_t len)
  637. {
  638.   /* Prevent unused argument(s) compilation warning */
  639.   UNUSED(USBx);
  640.   UNUSED(dest);
  641.   UNUSED(len);
  642.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  643.               only by USB OTG FS peripheral.
  644.             - This function is added to ensure compatibility across platforms.
  645.    */
  646.   return ((void *)NULL);
  647. }
  648.  
  649. /**
  650.   * @brief  USB_EPSetStall : set 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_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  656. {
  657.   if (ep->is_in != 0U)
  658.   {
  659.     PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL);
  660.   }
  661.   else
  662.   {
  663.     PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL);
  664.   }
  665.  
  666.   return HAL_OK;
  667. }
  668.  
  669. /**
  670.   * @brief  USB_EPClearStall : Clear a stall condition over an EP
  671.   * @param  USBx : Selected device
  672.   * @param  ep: pointer to endpoint structure
  673.   * @retval HAL status
  674.   */
  675. HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  676. {
  677.   if (ep->doublebuffer == 0U)
  678.   {
  679.     if (ep->is_in != 0U)
  680.     {
  681.       PCD_CLEAR_TX_DTOG(USBx, ep->num);
  682.  
  683.       if (ep->type != EP_TYPE_ISOC)
  684.       {
  685.         /* Configure NAK status for the Endpoint */
  686.         PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
  687.       }
  688.     }
  689.     else
  690.     {
  691.       PCD_CLEAR_RX_DTOG(USBx, ep->num);
  692.  
  693.       /* Configure VALID status for the Endpoint*/
  694.       PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
  695.     }
  696.   }
  697.  
  698.   return HAL_OK;
  699. }
  700.  
  701. /**
  702.   * @brief  USB_StopDevice : Stop the usb device mode
  703.   * @param  USBx : Selected device
  704.   * @retval HAL status
  705.   */
  706. HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx)
  707. {
  708.   /* disable all interrupts and force USB reset */
  709.   USBx->CNTR = (uint16_t)USB_CNTR_FRES;
  710.  
  711.   /* clear interrupt status register */
  712.   USBx->ISTR = 0U;
  713.  
  714.   /* switch-off device */
  715.   USBx->CNTR = (uint16_t)(USB_CNTR_FRES | USB_CNTR_PDWN);
  716.  
  717.   return HAL_OK;
  718. }
  719.  
  720. /**
  721.   * @brief  USB_SetDevAddress : Stop the usb device mode
  722.   * @param  USBx : Selected device
  723.   * @param  address : new device address to be assigned
  724.   *          This parameter can be a value from 0 to 255
  725.   * @retval HAL status
  726.   */
  727. HAL_StatusTypeDef  USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address)
  728. {
  729.   if (address == 0U)
  730.   {
  731.     /* set device address and enable function */
  732.     USBx->DADDR = (uint16_t)USB_DADDR_EF;
  733.   }
  734.  
  735.   return HAL_OK;
  736. }
  737.  
  738. /**
  739.   * @brief  USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down
  740.   * @param  USBx : Selected device
  741.   * @retval HAL status
  742.   */
  743. HAL_StatusTypeDef  USB_DevConnect(USB_TypeDef *USBx)
  744. {
  745.   /* Prevent unused argument(s) compilation warning */
  746.   UNUSED(USBx);
  747.  
  748.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  749.               only by USB OTG FS peripheral.
  750.             - This function is added to ensure compatibility across platforms.
  751.    */
  752.  
  753.   return HAL_OK;
  754. }
  755.  
  756. /**
  757.   * @brief  USB_DevDisconnect : Disconnect the USB device by disabling the pull-up/pull-down
  758.   * @param  USBx : Selected device
  759.   * @retval HAL status
  760.   */
  761. HAL_StatusTypeDef  USB_DevDisconnect(USB_TypeDef *USBx)
  762. {
  763.   /* Prevent unused argument(s) compilation warning */
  764.   UNUSED(USBx);
  765.  
  766.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  767.               only by USB OTG FS peripheral.
  768.             - This function is added to ensure compatibility across platforms.
  769.    */
  770.  
  771.   return HAL_OK;
  772. }
  773.  
  774. /**
  775.   * @brief  USB_ReadInterrupts: return the global USB interrupt status
  776.   * @param  USBx : Selected device
  777.   * @retval HAL status
  778.   */
  779. uint32_t  USB_ReadInterrupts(USB_TypeDef *USBx)
  780. {
  781.   uint32_t tmpreg;
  782.  
  783.   tmpreg = USBx->ISTR;
  784.   return tmpreg;
  785. }
  786.  
  787. /**
  788.   * @brief  USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
  789.   * @param  USBx : Selected device
  790.   * @retval HAL status
  791.   */
  792. uint32_t USB_ReadDevAllOutEpInterrupt(USB_TypeDef *USBx)
  793. {
  794.   /* Prevent unused argument(s) compilation warning */
  795.   UNUSED(USBx);
  796.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  797.               only by USB OTG FS peripheral.
  798.             - This function is added to ensure compatibility across platforms.
  799.    */
  800.   return (0);
  801. }
  802.  
  803. /**
  804.   * @brief  USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
  805.   * @param  USBx : Selected device
  806.   * @retval HAL status
  807.   */
  808. uint32_t USB_ReadDevAllInEpInterrupt(USB_TypeDef *USBx)
  809. {
  810.   /* Prevent unused argument(s) compilation warning */
  811.   UNUSED(USBx);
  812.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  813.               only by USB OTG FS peripheral.
  814.             - This function is added to ensure compatibility across platforms.
  815.    */
  816.   return (0);
  817. }
  818.  
  819. /**
  820.   * @brief  Returns Device OUT EP Interrupt register
  821.   * @param  USBx : Selected device
  822.   * @param  epnum : endpoint number
  823.   *          This parameter can be a value from 0 to 15
  824.   * @retval Device OUT EP Interrupt register
  825.   */
  826. uint32_t USB_ReadDevOutEPInterrupt(USB_TypeDef *USBx, uint8_t epnum)
  827. {
  828.   /* Prevent unused argument(s) compilation warning */
  829.   UNUSED(USBx);
  830.   UNUSED(epnum);
  831.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  832.               only by USB OTG FS peripheral.
  833.             - This function is added to ensure compatibility across platforms.
  834.    */
  835.   return (0);
  836. }
  837.  
  838. /**
  839.   * @brief  Returns Device IN EP Interrupt register
  840.   * @param  USBx : Selected device
  841.   * @param  epnum : endpoint number
  842.   *          This parameter can be a value from 0 to 15
  843.   * @retval Device IN EP Interrupt register
  844.   */
  845. uint32_t USB_ReadDevInEPInterrupt(USB_TypeDef *USBx, uint8_t epnum)
  846. {
  847.   /* Prevent unused argument(s) compilation warning */
  848.   UNUSED(USBx);
  849.   UNUSED(epnum);
  850.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  851.               only by USB OTG FS peripheral.
  852.             - This function is added to ensure compatibility across platforms.
  853.    */
  854.   return (0);
  855. }
  856.  
  857. /**
  858.   * @brief  USB_ClearInterrupts: clear a USB interrupt
  859.   * @param  USBx  Selected device
  860.   * @param  interrupt  flag
  861.   * @retval None
  862.   */
  863. void  USB_ClearInterrupts(USB_TypeDef *USBx, uint32_t interrupt)
  864. {
  865.   /* Prevent unused argument(s) compilation warning */
  866.   UNUSED(USBx);
  867.   UNUSED(interrupt);
  868.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  869.               only by USB OTG FS peripheral.
  870.             - This function is added to ensure compatibility across platforms.
  871.    */
  872. }
  873.  
  874. /**
  875.   * @brief  Prepare the EP0 to start the first control setup
  876.   * @param  USBx  Selected device
  877.   * @param  psetup  pointer to setup packet
  878.   * @retval HAL status
  879.   */
  880. HAL_StatusTypeDef USB_EP0_OutStart(USB_TypeDef *USBx, uint8_t *psetup)
  881. {
  882.   /* Prevent unused argument(s) compilation warning */
  883.   UNUSED(USBx);
  884.   UNUSED(psetup);
  885.   /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  886.               only by USB OTG FS peripheral.
  887.             - This function is added to ensure compatibility across platforms.
  888.    */
  889.   return HAL_OK;
  890. }
  891.  
  892. /**
  893.   * @brief  USB_ActivateRemoteWakeup : active remote wakeup signalling
  894.   * @param  USBx  Selected device
  895.   * @retval HAL status
  896.   */
  897. HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx)
  898. {
  899.   USBx->CNTR |= (uint16_t)USB_CNTR_RESUME;
  900.  
  901.   return HAL_OK;
  902. }
  903.  
  904. /**
  905.   * @brief  USB_DeActivateRemoteWakeup : de-active remote wakeup signalling
  906.   * @param  USBx  Selected device
  907.   * @retval HAL status
  908.   */
  909. HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx)
  910. {
  911.   USBx->CNTR &= (uint16_t)(~USB_CNTR_RESUME);
  912.   return HAL_OK;
  913. }
  914.  
  915. /**
  916.   * @brief Copy a buffer from user memory area to packet memory area (PMA)
  917.   * @param   USBx USB peripheral instance register address.
  918.   * @param   pbUsrBuf pointer to user memory area.
  919.   * @param   wPMABufAddr address into PMA.
  920.   * @param   wNBytes: no. of bytes to be copied.
  921.   * @retval None
  922.   */
  923. void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
  924. {
  925.   uint32_t n = ((uint32_t)wNBytes + 1U) >> 1;
  926.   uint32_t BaseAddr = (uint32_t)USBx;
  927.   uint32_t i, temp1, temp2;
  928.   __IO uint16_t *pdwVal;
  929.   uint8_t *pBuf = pbUsrBuf;
  930.  
  931.   pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
  932.  
  933.   for (i = n; i != 0U; i--)
  934.   {
  935.     temp1 = *pBuf;
  936.     pBuf++;
  937.     temp2 = temp1 | ((uint16_t)((uint16_t) *pBuf << 8));
  938.     *pdwVal = (uint16_t)temp2;
  939.     pdwVal++;
  940.  
  941. #if PMA_ACCESS > 1U
  942.     pdwVal++;
  943. #endif
  944.  
  945.     pBuf++;
  946.   }
  947. }
  948.  
  949. /**
  950.   * @brief Copy data from packet memory area (PMA) to user memory buffer
  951.   * @param   USBx: USB peripheral instance register address.
  952.   * @param   pbUsrBuf pointer to user memory area.
  953.   * @param   wPMABufAddr address into PMA.
  954.   * @param   wNBytes: no. of bytes to be copied.
  955.   * @retval None
  956.   */
  957. void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
  958. {
  959.   uint32_t n = (uint32_t)wNBytes >> 1;
  960.   uint32_t BaseAddr = (uint32_t)USBx;
  961.   uint32_t i, temp;
  962.   __IO uint16_t *pdwVal;
  963.   uint8_t *pBuf = pbUsrBuf;
  964.  
  965.   pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
  966.  
  967.   for (i = n; i != 0U; i--)
  968.   {
  969.     temp = *(__IO uint16_t *)pdwVal;
  970.     pdwVal++;
  971.     *pBuf = (uint8_t)((temp >> 0) & 0xFFU);
  972.     pBuf++;
  973.     *pBuf = (uint8_t)((temp >> 8) & 0xFFU);
  974.     pBuf++;
  975.  
  976. #if PMA_ACCESS > 1U
  977.     pdwVal++;
  978. #endif
  979.   }
  980.  
  981.   if ((wNBytes % 2U) != 0U)
  982.   {
  983.     temp = *pdwVal;
  984.     *pBuf = (uint8_t)((temp >> 0) & 0xFFU);
  985.   }
  986. }
  987.  
  988.  
  989. /**
  990.   * @}
  991.   */
  992.  
  993. /**
  994.   * @}
  995.   */
  996. #endif /* defined (USB) */
  997. #endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
  998.  
  999. /**
  1000.   * @}
  1001.   */
  1002.  
  1003. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  1004.