Hal Drivers for L4
Dependents: BSP OneHopeOnePrayer FINAL_AUDIO_RECORD AudioDemo
Fork of STM32L4xx_HAL_Driver by
stm32l4xx_ll_usb.c
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_ll_usb.c 00004 * @author MCD Application Team 00005 * @version V1.1.0 00006 * @date 16-September-2015 00007 * @brief USB Low Layer HAL module driver. 00008 * 00009 * This file provides firmware functions to manage the following 00010 * functionalities of the USB Peripheral Controller: 00011 * + Initialization/de-initialization functions 00012 * + I/O operation functions 00013 * + Peripheral Control functions 00014 * + Peripheral State functions 00015 * 00016 @verbatim 00017 ============================================================================== 00018 ##### How to use this driver ##### 00019 ============================================================================== 00020 [..] 00021 (#) Fill parameters of Init structure in USB_OTG_CfgTypeDef structure. 00022 00023 (#) Call USB_CoreInit() API to initialize the USB Core peripheral. 00024 00025 (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes. 00026 00027 @endverbatim 00028 ****************************************************************************** 00029 * @attention 00030 * 00031 * <h2><center>© COPYRIGHT(c) 2015 STMicroelectronics</center></h2> 00032 * 00033 * Redistribution and use in source and binary forms, with or without modification, 00034 * are permitted provided that the following conditions are met: 00035 * 1. Redistributions of source code must retain the above copyright notice, 00036 * this list of conditions and the following disclaimer. 00037 * 2. Redistributions in binary form must reproduce the above copyright notice, 00038 * this list of conditions and the following disclaimer in the documentation 00039 * and/or other materials provided with the distribution. 00040 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00041 * may be used to endorse or promote products derived from this software 00042 * without specific prior written permission. 00043 * 00044 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00045 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00046 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00047 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00048 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00049 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00050 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00051 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00052 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00053 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00054 * 00055 ****************************************************************************** 00056 */ 00057 00058 /* Includes ------------------------------------------------------------------*/ 00059 #include "stm32l4xx_hal.h" 00060 00061 #if defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx) 00062 00063 /** @addtogroup STM32L4xx_LL_USB_DRIVER 00064 * @{ 00065 */ 00066 00067 #if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) 00068 00069 /* Private typedef -----------------------------------------------------------*/ 00070 /* Private define ------------------------------------------------------------*/ 00071 /* Private macro -------------------------------------------------------------*/ 00072 /* Private variables ---------------------------------------------------------*/ 00073 /* Private function prototypes -----------------------------------------------*/ 00074 /* Private functions ---------------------------------------------------------*/ 00075 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx); 00076 00077 /* Exported functions --------------------------------------------------------*/ 00078 00079 /** @defgroup LL_USB_Exported_Functions USB Low Layer Exported Functions 00080 * @{ 00081 */ 00082 00083 /** @defgroup LL_USB_Group1 Initialization/de-initialization functions 00084 * @brief Initialization and Configuration functions 00085 * 00086 @verbatim 00087 =============================================================================== 00088 ##### Initialization/de-initialization functions ##### 00089 =============================================================================== 00090 [..] This section provides functions allowing to: 00091 00092 @endverbatim 00093 * @{ 00094 */ 00095 00096 /** 00097 * @brief Initializes the USB Core 00098 * @param USBx: USB Instance 00099 * @param cfg: pointer to a USB_OTG_CfgTypeDef structure that contains 00100 * the configuration information for the specified USBx peripheral. 00101 * @retval HAL status 00102 */ 00103 HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg) 00104 { 00105 /* Select FS Embedded PHY */ 00106 USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL; 00107 00108 /* Reset after a PHY select and set Host mode */ 00109 USB_CoreReset(USBx); 00110 00111 /* Deactivate the power down*/ 00112 USBx->GCCFG = USB_OTG_GCCFG_PWRDWN; 00113 00114 /* Enable srpcap*/ 00115 USBx->GUSBCFG |= USB_OTG_GUSBCFG_SRPCAP; 00116 00117 return HAL_OK; 00118 } 00119 00120 /** 00121 * @brief USB_EnableGlobalInt 00122 * Enables the controller's Global Int in the AHB Config reg 00123 * @param USBx: Selected device 00124 * @retval HAL status 00125 */ 00126 HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx) 00127 { 00128 USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT; 00129 return HAL_OK; 00130 } 00131 00132 00133 /** 00134 * @brief USB_DisableGlobalInt 00135 * Disable the controller's Global Int in the AHB Config reg 00136 * @param USBx: Selected device 00137 * @retval HAL status 00138 */ 00139 HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx) 00140 { 00141 USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT; 00142 return HAL_OK; 00143 } 00144 00145 /** 00146 * @brief USB_SetCurrentMode : Set functional mode 00147 * @param USBx: Selected device 00148 * @param mode: current core mode 00149 * This parameter can be one of these values: 00150 * @arg USB_OTG_DEVICE_MODE: Peripheral mode 00151 * @arg USB_OTG_HOST_MODE: Host mode 00152 * @arg USB_OTG_DRD_MODE: Dual Role Device mode 00153 * @retval HAL status 00154 */ 00155 HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx , USB_OTG_ModeTypeDef mode) 00156 { 00157 USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD); 00158 00159 if ( mode == USB_OTG_HOST_MODE) 00160 { 00161 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD; 00162 } 00163 else if ( mode == USB_OTG_DEVICE_MODE) 00164 { 00165 USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; 00166 } 00167 HAL_Delay(50); 00168 00169 return HAL_OK; 00170 } 00171 00172 /** 00173 * @brief USB_DevInit : Initializes the USB_OTG controller registers 00174 * for device mode 00175 * @param USBx: Selected device 00176 * @param cfg: pointer to a USB_OTG_CfgTypeDef structure that contains 00177 * the configuration information for the specified USBx peripheral. 00178 * @retval HAL status 00179 */ 00180 HAL_StatusTypeDef USB_DevInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg) 00181 { 00182 uint32_t i = 0; 00183 00184 /*Activate VBUS Sensing B */ 00185 USBx->GCCFG |= USB_OTG_GCCFG_VBDEN; 00186 00187 if (cfg.vbus_sensing_enable == 0) 00188 { 00189 /* Deactivate VBUS Sensing B */ 00190 USBx->GCCFG &= ~ USB_OTG_GCCFG_VBDEN; 00191 00192 /* B-peripheral session valid override enable*/ 00193 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; 00194 USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; 00195 } 00196 00197 /* Restart the Phy Clock */ 00198 USBx_PCGCCTL = 0; 00199 00200 /* Device mode configuration */ 00201 USBx_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80; 00202 00203 /* Set Full speed phy */ 00204 USB_SetDevSpeed (USBx , USB_OTG_SPEED_FULL); 00205 00206 /* Flush the FIFOs */ 00207 USB_FlushTxFifo(USBx , 0x10); /* all Tx FIFOs */ 00208 USB_FlushRxFifo(USBx); 00209 00210 /* Clear all pending Device Interrupts */ 00211 USBx_DEVICE->DIEPMSK = 0; 00212 USBx_DEVICE->DOEPMSK = 0; 00213 USBx_DEVICE->DAINT = 0xFFFFFFFF; 00214 USBx_DEVICE->DAINTMSK = 0; 00215 00216 for (i = 0; i < cfg.dev_endpoints ; i++) 00217 { 00218 if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA) 00219 { 00220 USBx_INEP(i)->DIEPCTL = (USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK); 00221 } 00222 else 00223 { 00224 USBx_INEP(i)->DIEPCTL = 0; 00225 } 00226 00227 USBx_INEP(i)->DIEPTSIZ = 0; 00228 USBx_INEP(i)->DIEPINT = 0xFF; 00229 } 00230 00231 for (i = 0; i < cfg.dev_endpoints ; i++) 00232 { 00233 if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA) 00234 { 00235 USBx_OUTEP(i)->DOEPCTL = (USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK); 00236 } 00237 else 00238 { 00239 USBx_OUTEP(i)->DOEPCTL = 0; 00240 } 00241 00242 USBx_OUTEP(i)->DOEPTSIZ = 0; 00243 USBx_OUTEP(i)->DOEPINT = 0xFF; 00244 } 00245 00246 USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM); 00247 00248 if (cfg.dma_enable == 1) 00249 { 00250 /*Set threshold parameters */ 00251 USBx_DEVICE->DTHRCTL = (USB_OTG_DTHRCTL_TXTHRLEN_6 | USB_OTG_DTHRCTL_RXTHRLEN_6); 00252 USBx_DEVICE->DTHRCTL |= (USB_OTG_DTHRCTL_RXTHREN | USB_OTG_DTHRCTL_ISOTHREN | USB_OTG_DTHRCTL_NONISOTHREN); 00253 00254 i= USBx_DEVICE->DTHRCTL; 00255 } 00256 00257 /* Disable all interrupts. */ 00258 USBx->GINTMSK = 0; 00259 00260 /* Clear any pending interrupts */ 00261 USBx->GINTSTS = 0xBFFFFFFF; 00262 00263 /* Enable the common interrupts */ 00264 if (cfg.dma_enable == DISABLE) 00265 { 00266 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; 00267 } 00268 00269 /* Enable interrupts matching to the Device mode ONLY */ 00270 USBx->GINTMSK |= (USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |\ 00271 USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |\ 00272 USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM|\ 00273 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM); 00274 00275 if(cfg.Sof_enable ) 00276 { 00277 USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM; 00278 } 00279 00280 if (cfg.vbus_sensing_enable == ENABLE) 00281 { 00282 USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT); 00283 } 00284 00285 return HAL_OK; 00286 } 00287 00288 00289 /** 00290 * @brief USB_OTG_FlushTxFifo : Flush a Tx FIFO 00291 * @param USBx: Selected device 00292 * @param num: FIFO number 00293 * This parameter can be a value from 1 to 15 00294 15 means Flush all Tx FIFOs 00295 * @retval HAL status 00296 */ 00297 HAL_StatusTypeDef USB_FlushTxFifo (USB_OTG_GlobalTypeDef *USBx, uint32_t num ) 00298 { 00299 uint32_t count = 0; 00300 00301 USBx->GRSTCTL = ( USB_OTG_GRSTCTL_TXFFLSH |(uint32_t)( num << 6)); 00302 00303 do 00304 { 00305 if (++count > 200000) 00306 { 00307 return HAL_TIMEOUT; 00308 } 00309 } 00310 while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH); 00311 00312 return HAL_OK; 00313 } 00314 00315 00316 /** 00317 * @brief USB_FlushRxFifo : Flush Rx FIFO 00318 * @param USBx: Selected device 00319 * @retval HAL status 00320 */ 00321 HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx) 00322 { 00323 uint32_t count = 0; 00324 00325 USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH; 00326 00327 do 00328 { 00329 if (++count > 200000) 00330 { 00331 return HAL_TIMEOUT; 00332 } 00333 } 00334 while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH); 00335 00336 return HAL_OK; 00337 } 00338 00339 /** 00340 * @brief USB_SetDevSpeed :Initializes the DevSpd field of DCFG register 00341 * depending the PHY type and the enumeration speed of the device. 00342 * @param USBx: Selected device 00343 * @param speed: device speed 00344 * This parameter can be one of these values: 00345 * @arg USB_OTG_SPEED_HIGH: High speed mode 00346 * @arg USB_OTG_SPEED_HIGH_IN_FULL: High speed core in Full Speed mode 00347 * @arg USB_OTG_SPEED_FULL: Full speed mode 00348 * @arg USB_OTG_SPEED_LOW: Low speed mode 00349 * @retval Hal status 00350 */ 00351 HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx , uint8_t speed) 00352 { 00353 USBx_DEVICE->DCFG |= speed; 00354 return HAL_OK; 00355 } 00356 00357 /** 00358 * @brief USB_GetDevSpeed :Return the Dev Speed 00359 * @param USBx: Selected device 00360 * @retval speed : device speed 00361 * This parameter can be one of these values: 00362 * @arg USB_OTG_SPEED_HIGH: High speed mode 00363 * @arg USB_OTG_SPEED_FULL: Full speed mode 00364 * @arg USB_OTG_SPEED_LOW: Low speed mode 00365 */ 00366 uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx) 00367 { 00368 uint8_t speed = 0; 00369 00370 if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ) 00371 { 00372 speed = USB_OTG_SPEED_HIGH; 00373 } 00374 else if (((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ)|| 00375 ((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_FS_PHY_48MHZ)) 00376 { 00377 speed = USB_OTG_SPEED_FULL; 00378 } 00379 else if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ) 00380 { 00381 speed = USB_OTG_SPEED_LOW; 00382 } 00383 00384 return speed; 00385 } 00386 00387 /** 00388 * @brief Activate and configure an endpoint 00389 * @param USBx: Selected device 00390 * @param ep: pointer to endpoint structure 00391 * @retval HAL status 00392 */ 00393 HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep) 00394 { 00395 if (ep->is_in == 1) 00396 { 00397 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))); 00398 00399 if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0) 00400 { 00401 USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\ 00402 ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP)); 00403 } 00404 00405 } 00406 else 00407 { 00408 USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16); 00409 00410 if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0) 00411 { 00412 USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\ 00413 (USB_OTG_DIEPCTL_SD0PID_SEVNFRM)| (USB_OTG_DOEPCTL_USBAEP)); 00414 } 00415 } 00416 return HAL_OK; 00417 } 00418 /** 00419 * @brief Activate and configure a dedicated endpoint 00420 * @param USBx: Selected device 00421 * @param ep: pointer to endpoint structure 00422 * @retval HAL status 00423 */ 00424 HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep) 00425 { 00426 static __IO uint32_t debug = 0; 00427 00428 /* Read DEPCTLn register */ 00429 if (ep->is_in == 1) 00430 { 00431 if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0) 00432 { 00433 USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\ 00434 ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP)); 00435 } 00436 00437 00438 debug |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\ 00439 ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP)); 00440 00441 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))); 00442 } 00443 else 00444 { 00445 if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0) 00446 { 00447 USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\ 00448 ((ep->num) << 22 ) | (USB_OTG_DOEPCTL_USBAEP)); 00449 00450 debug = (uint32_t)(((uint32_t )USBx) + USB_OTG_OUT_ENDPOINT_BASE + (0)*USB_OTG_EP_REG_SIZE); 00451 debug = (uint32_t )&USBx_OUTEP(ep->num)->DOEPCTL; 00452 debug |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\ 00453 ((ep->num) << 22 ) | (USB_OTG_DOEPCTL_USBAEP)); 00454 } 00455 00456 USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16); 00457 } 00458 00459 return HAL_OK; 00460 } 00461 /** 00462 * @brief De-activate and de-initialize an endpoint 00463 * @param USBx: Selected device 00464 * @param ep: pointer to endpoint structure 00465 * @retval HAL status 00466 */ 00467 HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep) 00468 { 00469 /* Read DEPCTLn register */ 00470 if (ep->is_in == 1) 00471 { 00472 USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num)))); 00473 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num)))); 00474 USBx_INEP(ep->num)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP; 00475 } 00476 else 00477 { 00478 USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16)); 00479 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16)); 00480 USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP; 00481 } 00482 return HAL_OK; 00483 } 00484 00485 /** 00486 * @brief De-activate and de-initialize a dedicated endpoint 00487 * @param USBx: Selected device 00488 * @param ep: pointer to endpoint structure 00489 * @retval HAL status 00490 */ 00491 HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep) 00492 { 00493 /* Read DEPCTLn register */ 00494 if (ep->is_in == 1) 00495 { 00496 USBx_INEP(ep->num)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP; 00497 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num)))); 00498 } 00499 else 00500 { 00501 USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP; 00502 USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16)); 00503 } 00504 return HAL_OK; 00505 } 00506 00507 /** 00508 * @brief USB_EPStartXfer : setup and starts a transfer over an EP 00509 * @param USBx: Selected device 00510 * @param ep: pointer to endpoint structure 00511 * @param dma: USB dma enabled or disabled 00512 * This parameter can be one of these values: 00513 * 0 : DMA feature not used 00514 * 1 : DMA feature used 00515 * @retval HAL status 00516 */ 00517 HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep, uint8_t dma) 00518 { 00519 uint16_t pktcnt = 0; 00520 00521 /* IN endpoint */ 00522 if (ep->is_in == 1) 00523 { 00524 /* Zero Length Packet? */ 00525 if (ep->xfer_len == 0) 00526 { 00527 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT); 00528 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ; 00529 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ); 00530 } 00531 else 00532 { 00533 /* Program the transfer size and packet count 00534 * as follows: xfersize = N * maxpacket + 00535 * short_packet pktcnt = N + (short_packet 00536 * exist ? 1 : 0) 00537 */ 00538 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ); 00539 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT); 00540 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (((ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket) << 19)) ; 00541 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len); 00542 00543 if (ep->type == EP_TYPE_ISOC) 00544 { 00545 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT); 00546 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1 << 29)); 00547 } 00548 } 00549 00550 if (dma == 1) 00551 { 00552 USBx_INEP(ep->num)->DIEPDMA = (uint32_t)(ep->dma_addr); 00553 } 00554 else 00555 { 00556 if (ep->type != EP_TYPE_ISOC) 00557 { 00558 /* Enable the Tx FIFO Empty Interrupt for this EP */ 00559 if (ep->xfer_len > 0) 00560 { 00561 USBx_DEVICE->DIEPEMPMSK |= 1 << ep->num; 00562 } 00563 } 00564 } 00565 00566 if (ep->type == EP_TYPE_ISOC) 00567 { 00568 if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0) 00569 { 00570 USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM; 00571 } 00572 else 00573 { 00574 USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; 00575 } 00576 } 00577 00578 /* EP enable, IN data in FIFO */ 00579 USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA); 00580 00581 if (ep->type == EP_TYPE_ISOC) 00582 { 00583 USB_WritePacket(USBx, ep->xfer_buff, ep->num, ep->xfer_len, dma); 00584 } 00585 } 00586 else /* OUT endpoint */ 00587 { 00588 /* Program the transfer size and packet count as follows: 00589 * pktcnt = N 00590 * xfersize = N * maxpacket 00591 */ 00592 USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ); 00593 USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT); 00594 00595 if (ep->xfer_len == 0) 00596 { 00597 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket); 00598 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)) ; 00599 } 00600 else 00601 { 00602 pktcnt = (ep->xfer_len + ep->maxpacket -1)/ ep->maxpacket; 00603 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (pktcnt << 19)); ; 00604 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket * pktcnt)); 00605 } 00606 00607 if (dma == 1) 00608 { 00609 USBx_OUTEP(ep->num)->DOEPDMA = (uint32_t)ep->xfer_buff; 00610 } 00611 00612 if (ep->type == EP_TYPE_ISOC) 00613 { 00614 if ((USBx_DEVICE->DSTS & ( 1 << 8 )) == 0) 00615 { 00616 USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM; 00617 } 00618 else 00619 { 00620 USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; 00621 } 00622 } 00623 /* EP enable */ 00624 USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA); 00625 } 00626 return HAL_OK; 00627 } 00628 00629 /** 00630 * @brief USB_EP0StartXfer : setup and starts a transfer over the EP 0 00631 * @param USBx: Selected device 00632 * @param ep: pointer to endpoint structure 00633 * @param dma: USB dma enabled or disabled 00634 * This parameter can be one of these values: 00635 * 0 : DMA feature not used 00636 * 1 : DMA feature used 00637 * @retval HAL status 00638 */ 00639 HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep, uint8_t dma) 00640 { 00641 /* IN endpoint */ 00642 if (ep->is_in == 1) 00643 { 00644 /* Zero Length Packet? */ 00645 if (ep->xfer_len == 0) 00646 { 00647 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT); 00648 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ; 00649 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ); 00650 } 00651 else 00652 { 00653 /* Program the transfer size and packet count 00654 * as follows: xfersize = N * maxpacket + 00655 * short_packet pktcnt = N + (short_packet 00656 * exist ? 1 : 0) 00657 */ 00658 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ); 00659 USBx_INEP(ep->num)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT); 00660 00661 if(ep->xfer_len > ep->maxpacket) 00662 { 00663 ep->xfer_len = ep->maxpacket; 00664 } 00665 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1 << 19)) ; 00666 USBx_INEP(ep->num)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len); 00667 00668 } 00669 00670 if (dma == 1) 00671 { 00672 USBx_INEP(ep->num)->DIEPDMA = (uint32_t)(ep->dma_addr); 00673 } 00674 else 00675 { 00676 /* Enable the Tx FIFO Empty Interrupt for this EP */ 00677 if (ep->xfer_len > 0) 00678 { 00679 USBx_DEVICE->DIEPEMPMSK |= 1 << (ep->num); 00680 } 00681 } 00682 00683 /* EP enable, IN data in FIFO */ 00684 USBx_INEP(ep->num)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA); 00685 } 00686 else /* OUT endpoint */ 00687 { 00688 /* Program the transfer size and packet count as follows: 00689 * pktcnt = N 00690 * xfersize = N * maxpacket 00691 */ 00692 USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ); 00693 USBx_OUTEP(ep->num)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT); 00694 00695 if (ep->xfer_len > 0) 00696 { 00697 ep->xfer_len = ep->maxpacket; 00698 } 00699 00700 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)); 00701 USBx_OUTEP(ep->num)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket)); 00702 00703 00704 if (dma == 1) 00705 { 00706 USBx_OUTEP(ep->num)->DOEPDMA = (uint32_t)(ep->xfer_buff); 00707 } 00708 00709 /* EP enable */ 00710 USBx_OUTEP(ep->num)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA); 00711 } 00712 return HAL_OK; 00713 } 00714 00715 /** 00716 * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated 00717 * with the EP/channel 00718 * @param USBx: Selected device 00719 * @param src: pointer to source buffer 00720 * @param ch_ep_num: endpoint or host channel number 00721 * @param len: Number of bytes to write 00722 * @param dma: USB dma enabled or disabled 00723 * This parameter can be one of these values: 00724 * 0 : DMA feature not used 00725 * 1 : DMA feature used 00726 * @retval HAL status 00727 */ 00728 HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src, uint8_t ch_ep_num, uint16_t len, uint8_t dma) 00729 { 00730 uint32_t count32b= 0 , i= 0; 00731 00732 if (dma == 0) 00733 { 00734 count32b = (len + 3) / 4; 00735 for (i = 0; i < count32b; i++, src += 4) 00736 { 00737 USBx_DFIFO(ch_ep_num) = *((__packed uint32_t *)src); 00738 } 00739 } 00740 return HAL_OK; 00741 } 00742 00743 /** 00744 * @brief USB_ReadPacket : read a packet from the Tx FIFO associated 00745 * with the EP/channel 00746 * @param USBx: Selected device 00747 * @param src: source pointer 00748 * @param ch_ep_num: endpoint or host channel number 00749 * @param len: Number of bytes to read 00750 * @param dma: USB dma enabled or disabled 00751 * This parameter can be one of these values: 00752 * 0 : DMA feature not used 00753 * 1 : DMA feature used 00754 * @retval pointer to destination buffer 00755 */ 00756 void *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len) 00757 { 00758 uint32_t i=0; 00759 uint32_t count32b = (len + 3) / 4; 00760 00761 for ( i = 0; i < count32b; i++, dest += 4 ) 00762 { 00763 *(__packed uint32_t *)dest = USBx_DFIFO(0); 00764 00765 } 00766 return ((void *)dest); 00767 } 00768 00769 /** 00770 * @brief USB_EPSetStall : set a stall condition over an EP 00771 * @param USBx: Selected device 00772 * @param ep: pointer to endpoint structure 00773 * @retval HAL status 00774 */ 00775 HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx , USB_OTG_EPTypeDef *ep) 00776 { 00777 if (ep->is_in == 1) 00778 { 00779 if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_EPENA) == 0) 00780 { 00781 USBx_INEP(ep->num)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS); 00782 } 00783 USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_STALL; 00784 } 00785 else 00786 { 00787 if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_EPENA) == 0) 00788 { 00789 USBx_OUTEP(ep->num)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS); 00790 } 00791 USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_STALL; 00792 } 00793 return HAL_OK; 00794 } 00795 00796 00797 /** 00798 * @brief USB_EPClearStall : Clear a stall condition over an EP 00799 * @param USBx: Selected device 00800 * @param ep: pointer to endpoint structure 00801 * @retval HAL status 00802 */ 00803 HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep) 00804 { 00805 if (ep->is_in == 1) 00806 { 00807 USBx_INEP(ep->num)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL; 00808 if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK) 00809 { 00810 USBx_INEP(ep->num)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */ 00811 } 00812 } 00813 else 00814 { 00815 USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL; 00816 if (ep->type == EP_TYPE_INTR || ep->type == EP_TYPE_BULK) 00817 { 00818 USBx_OUTEP(ep->num)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */ 00819 } 00820 } 00821 return HAL_OK; 00822 } 00823 00824 /** 00825 * @brief USB_StopDevice : Stop the USB device mode 00826 * @param USBx: Selected device 00827 * @retval HAL status 00828 */ 00829 HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx) 00830 { 00831 uint32_t i; 00832 00833 /* Clear Pending interrupt */ 00834 for (i = 0; i < 15 ; i++) 00835 { 00836 USBx_INEP(i)->DIEPINT = 0xFF; 00837 USBx_OUTEP(i)->DOEPINT = 0xFF; 00838 } 00839 USBx_DEVICE->DAINT = 0xFFFFFFFF; 00840 00841 /* Clear interrupt masks */ 00842 USBx_DEVICE->DIEPMSK = 0; 00843 USBx_DEVICE->DOEPMSK = 0; 00844 USBx_DEVICE->DAINTMSK = 0; 00845 00846 /* Flush the FIFO */ 00847 USB_FlushRxFifo(USBx); 00848 USB_FlushTxFifo(USBx , 0x10 ); 00849 00850 return HAL_OK; 00851 } 00852 00853 /** 00854 * @brief USB_SetDevAddress : Stop the USB device mode 00855 * @param USBx: Selected device 00856 * @param address: new device address to be assigned 00857 * This parameter can be a value from 0 to 255 00858 * @retval HAL status 00859 */ 00860 HAL_StatusTypeDef USB_SetDevAddress (USB_OTG_GlobalTypeDef *USBx, uint8_t address) 00861 { 00862 USBx_DEVICE->DCFG &= ~ (USB_OTG_DCFG_DAD); 00863 USBx_DEVICE->DCFG |= (address << 4) & USB_OTG_DCFG_DAD ; 00864 00865 return HAL_OK; 00866 } 00867 00868 /** 00869 * @brief USB_DevConnect : Connect the USB device by enabling the pull-up/pull-down 00870 * @param USBx: Selected device 00871 * @retval HAL status 00872 */ 00873 HAL_StatusTypeDef USB_DevConnect (USB_OTG_GlobalTypeDef *USBx) 00874 { 00875 USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS ; 00876 HAL_Delay(3); 00877 00878 return HAL_OK; 00879 } 00880 00881 /** 00882 * @brief USB_DevDisconnect : Disconnect the USB device by disabling the pull-up/pull-down 00883 * @param USBx: Selected device 00884 * @retval HAL status 00885 */ 00886 HAL_StatusTypeDef USB_DevDisconnect (USB_OTG_GlobalTypeDef *USBx) 00887 { 00888 USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS ; 00889 HAL_Delay(3); 00890 00891 return HAL_OK; 00892 } 00893 00894 /** 00895 * @brief USB_ReadInterrupts: return the global USB interrupt status 00896 * @param USBx: Selected device 00897 * @retval HAL status 00898 */ 00899 uint32_t USB_ReadInterrupts (USB_OTG_GlobalTypeDef *USBx) 00900 { 00901 uint32_t v = 0; 00902 00903 v = USBx->GINTSTS; 00904 v &= USBx->GINTMSK; 00905 return v; 00906 } 00907 00908 /** 00909 * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status 00910 * @param USBx: Selected device 00911 * @retval HAL status 00912 */ 00913 uint32_t USB_ReadDevAllOutEpInterrupt (USB_OTG_GlobalTypeDef *USBx) 00914 { 00915 uint32_t v; 00916 v = USBx_DEVICE->DAINT; 00917 v &= USBx_DEVICE->DAINTMSK; 00918 return ((v & 0xffff0000) >> 16); 00919 } 00920 00921 /** 00922 * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status 00923 * @param USBx: Selected device 00924 * @retval HAL status 00925 */ 00926 uint32_t USB_ReadDevAllInEpInterrupt (USB_OTG_GlobalTypeDef *USBx) 00927 { 00928 uint32_t v; 00929 v = USBx_DEVICE->DAINT; 00930 v &= USBx_DEVICE->DAINTMSK; 00931 return ((v & 0xFFFF)); 00932 } 00933 00934 /** 00935 * @brief Returns Device OUT EP Interrupt register 00936 * @param USBx: Selected device 00937 * @param epnum: endpoint number 00938 * This parameter can be a value from 0 to 15 00939 * @retval Device OUT EP Interrupt register 00940 */ 00941 uint32_t USB_ReadDevOutEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum) 00942 { 00943 uint32_t v; 00944 v = USBx_OUTEP(epnum)->DOEPINT; 00945 v &= USBx_DEVICE->DOEPMSK; 00946 return v; 00947 } 00948 00949 /** 00950 * @brief Returns Device IN EP Interrupt register 00951 * @param USBx: Selected device 00952 * @param epnum: endpoint number 00953 * This parameter can be a value from 0 to 15 00954 * @retval Device IN EP Interrupt register 00955 */ 00956 uint32_t USB_ReadDevInEPInterrupt (USB_OTG_GlobalTypeDef *USBx , uint8_t epnum) 00957 { 00958 uint32_t v, msk, emp; 00959 00960 msk = USBx_DEVICE->DIEPMSK; 00961 emp = USBx_DEVICE->DIEPEMPMSK; 00962 msk |= ((emp >> epnum) & 0x1) << 7; 00963 v = USBx_INEP(epnum)->DIEPINT & msk; 00964 return v; 00965 } 00966 00967 /** 00968 * @brief USB_ClearInterrupts: clear a USB interrupt 00969 * @param USBx: Selected device 00970 * @param interrupt: interrupt flag 00971 * @retval None 00972 */ 00973 void USB_ClearInterrupts (USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt) 00974 { 00975 USBx->GINTSTS |= interrupt; 00976 } 00977 00978 /** 00979 * @brief Returns USB core mode 00980 * @param USBx: Selected device 00981 * @retval return core mode : Host or Device 00982 * This parameter can be one of these values: 00983 * 0 : Host 00984 * 1 : Device 00985 */ 00986 uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx) 00987 { 00988 return ((USBx->GINTSTS ) & 0x1); 00989 } 00990 00991 00992 /** 00993 * @brief Activate EP0 for Setup transactions 00994 * @param USBx: Selected device 00995 * @retval HAL status 00996 */ 00997 HAL_StatusTypeDef USB_ActivateSetup (USB_OTG_GlobalTypeDef *USBx) 00998 { 00999 /* Set the MPS of the IN EP based on the enumeration speed */ 01000 USBx_INEP(0)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ; 01001 01002 if((USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD) == DSTS_ENUMSPD_LS_PHY_6MHZ) 01003 { 01004 USBx_INEP(0)->DIEPCTL |= 3; 01005 } 01006 USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK; 01007 01008 return HAL_OK; 01009 } 01010 01011 01012 /** 01013 * @brief Prepare the EP0 to start the first control setup 01014 * @param USBx: Selected device 01015 * @param dma: USB dma enabled or disabled 01016 * This parameter can be one of these values: 01017 * 0 : DMA feature not used 01018 * 1 : DMA feature used 01019 * @param psetup: pointer to setup packet 01020 * @retval HAL status 01021 */ 01022 HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t dma, uint8_t *psetup) 01023 { 01024 USBx_OUTEP(0)->DOEPTSIZ = 0; 01025 USBx_OUTEP(0)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1 << 19)) ; 01026 USBx_OUTEP(0)->DOEPTSIZ |= (3 * 8); 01027 USBx_OUTEP(0)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT; 01028 01029 if (dma == 1) 01030 { 01031 USBx_OUTEP(0)->DOEPDMA = (uint32_t)psetup; 01032 /* EP enable */ 01033 USBx_OUTEP(0)->DOEPCTL = 0x80008000; 01034 } 01035 01036 return HAL_OK; 01037 } 01038 01039 01040 /** 01041 * @brief Reset the USB Core (needed after USB clock settings change) 01042 * @param USBx: Selected device 01043 * @retval HAL status 01044 */ 01045 static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx) 01046 { 01047 uint32_t count = 0; 01048 01049 /* Wait for AHB master IDLE state. */ 01050 do 01051 { 01052 if (++count > 200000) 01053 { 01054 return HAL_TIMEOUT; 01055 } 01056 } 01057 while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0); 01058 01059 /* Core Soft Reset */ 01060 count = 0; 01061 USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST; 01062 01063 do 01064 { 01065 if (++count > 200000) 01066 { 01067 return HAL_TIMEOUT; 01068 } 01069 } 01070 while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST); 01071 01072 return HAL_OK; 01073 } 01074 01075 01076 /** 01077 * @brief USB_HostInit : Initializes the USB OTG controller registers 01078 * for Host mode 01079 * @param USBx: Selected device 01080 * @param cfg: pointer to a USB_OTG_CfgTypeDef structure that contains 01081 * the configuration information for the specified USBx peripheral. 01082 * @retval HAL status 01083 */ 01084 HAL_StatusTypeDef USB_HostInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg) 01085 { 01086 uint32_t i; 01087 01088 /* Restart the Phy Clock */ 01089 USBx_PCGCCTL = 0; 01090 01091 /*Activate VBUS Sensing B */ 01092 USBx->GCCFG |= USB_OTG_GCCFG_VBDEN; 01093 01094 /* Disable the FS/LS support mode only */ 01095 if((cfg.speed == USB_OTG_SPEED_FULL)&& 01096 (USBx != USB_OTG_FS)) 01097 { 01098 USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS; 01099 } 01100 else 01101 { 01102 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS); 01103 } 01104 01105 /* Make sure the FIFOs are flushed. */ 01106 USB_FlushTxFifo(USBx, 0x10 ); /* all Tx FIFOs */ 01107 USB_FlushRxFifo(USBx); 01108 01109 /* Clear all pending HC Interrupts */ 01110 for (i = 0; i < cfg.Host_channels ; i++) 01111 { 01112 USBx_HC(i)->HCINT = 0xFFFFFFFF; 01113 USBx_HC(i)->HCINTMSK = 0; 01114 } 01115 01116 /* Enable VBUS driving */ 01117 USB_DriveVbus(USBx, 1); 01118 01119 HAL_Delay(200); 01120 01121 /* Disable all interrupts. */ 01122 USBx->GINTMSK = 0; 01123 01124 /* Clear any pending interrupts */ 01125 USBx->GINTSTS = 0xFFFFFFFF; 01126 01127 /* set Rx FIFO size */ 01128 USBx->GRXFSIZ = (uint32_t )0x80; 01129 USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x60 << 16)& USB_OTG_NPTXFD) | 0x80); 01130 USBx->HPTXFSIZ = (uint32_t )(((0x40 << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0); 01131 01132 /* Enable the common interrupts */ 01133 if (cfg.dma_enable == DISABLE) 01134 { 01135 USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; 01136 } 01137 01138 /* Enable interrupts matching to the Host mode ONLY */ 01139 USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM |\ 01140 USB_OTG_GINTMSK_SOFM |USB_OTG_GINTSTS_DISCINT|\ 01141 USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM); 01142 01143 return HAL_OK; 01144 } 01145 01146 /** 01147 * @brief USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the 01148 * HCFG register on the PHY type and set the right frame interval 01149 * @param USBx: Selected device 01150 * @param freq: clock frequency 01151 * This parameter can be one of these values: 01152 * HCFG_48_MHZ : Full Speed 48 MHz Clock 01153 * HCFG_6_MHZ : Low Speed 6 MHz Clock 01154 * @retval HAL status 01155 */ 01156 HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx , uint8_t freq) 01157 { 01158 USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS); 01159 USBx_HOST->HCFG |= (freq & USB_OTG_HCFG_FSLSPCS); 01160 01161 if (freq == HCFG_48_MHZ) 01162 { 01163 USBx_HOST->HFIR = (uint32_t)48000; 01164 } 01165 else if (freq == HCFG_6_MHZ) 01166 { 01167 USBx_HOST->HFIR = (uint32_t)6000; 01168 } 01169 return HAL_OK; 01170 } 01171 01172 /** 01173 * @brief USB_OTG_ResetPort : Reset Host Port 01174 * @param USBx: Selected device 01175 * @retval HAL status 01176 * @note (1)The application must wait at least 10 ms 01177 * before clearing the reset bit. 01178 */ 01179 HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx) 01180 { 01181 __IO uint32_t hprt0; 01182 01183 hprt0 = USBx_HPRT0; 01184 01185 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\ 01186 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ); 01187 01188 USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0); 01189 HAL_Delay (10); /* See Note #1 */ 01190 USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0); 01191 return HAL_OK; 01192 } 01193 01194 /** 01195 * @brief USB_DriveVbus : activate or de-activate vbus 01196 * @param state: VBUS state 01197 * This parameter can be one of these values: 01198 * 0 : VBUS Active 01199 * 1 : VBUS Inactive 01200 * @retval HAL status 01201 */ 01202 HAL_StatusTypeDef USB_DriveVbus (USB_OTG_GlobalTypeDef *USBx, uint8_t state) 01203 { 01204 __IO uint32_t hprt0; 01205 01206 hprt0 = USBx_HPRT0; 01207 hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\ 01208 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ); 01209 01210 if (((hprt0 & USB_OTG_HPRT_PPWR) == 0 ) && (state == 1 )) 01211 { 01212 USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0); 01213 } 01214 if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0 )) 01215 { 01216 USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0); 01217 } 01218 return HAL_OK; 01219 } 01220 01221 /** 01222 * @brief Return Host Core speed 01223 * @param USBx: Selected device 01224 * @retval speed : Host speed 01225 * This parameter can be one of these values: 01226 * @arg USB_OTG_SPEED_HIGH: High speed mode 01227 * @arg USB_OTG_SPEED_FULL: Full speed mode 01228 * @arg USB_OTG_SPEED_LOW: Low speed mode 01229 */ 01230 uint32_t USB_GetHostSpeed (USB_OTG_GlobalTypeDef *USBx) 01231 { 01232 __IO uint32_t hprt0; 01233 01234 hprt0 = USBx_HPRT0; 01235 return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17); 01236 } 01237 01238 /** 01239 * @brief Return Host Current Frame number 01240 * @param USBx: Selected device 01241 * @retval current frame number 01242 */ 01243 uint32_t USB_GetCurrentFrame (USB_OTG_GlobalTypeDef *USBx) 01244 { 01245 return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM); 01246 } 01247 01248 /** 01249 * @brief Initialize a host channel 01250 * @param USBx: Selected device 01251 * @param ch_num : Channel number 01252 * This parameter can be a value from 1 to 15 01253 * @param epnum: Endpoint number 01254 * This parameter can be a value from 1 to 15 01255 * @param dev_address: Current device address 01256 * This parameter can be a value from 0 to 255 01257 * @param speed: Current device speed 01258 * This parameter can be one of these values: 01259 * @arg USB_OTG_SPEED_HIGH: High speed mode 01260 * @arg USB_OTG_SPEED_FULL: Full speed mode 01261 * @arg USB_OTG_SPEED_LOW: Low speed mode 01262 * @param ep_type: Endpoint Type 01263 * This parameter can be one of these values: 01264 * @arg EP_TYPE_CTRL: Control type 01265 * @arg EP_TYPE_ISOC: Isochronous type 01266 * @arg EP_TYPE_BULK: Bulk type 01267 * @arg EP_TYPE_INTR: Interrupt type 01268 * @param mps: Max Packet Size 01269 * This parameter can be a value from 0 to32K 01270 * @retval HAL state 01271 */ 01272 HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, 01273 uint8_t ch_num, 01274 uint8_t epnum, 01275 uint8_t dev_address, 01276 uint8_t speed, 01277 uint8_t ep_type, 01278 uint16_t mps) 01279 { 01280 01281 /* Clear old interrupt conditions for this host channel. */ 01282 USBx_HC(ch_num)->HCINT = 0xFFFFFFFF; 01283 01284 /* Enable channel interrupts required for this transfer. */ 01285 switch (ep_type) 01286 { 01287 case EP_TYPE_CTRL: 01288 case EP_TYPE_BULK: 01289 01290 USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\ 01291 USB_OTG_HCINTMSK_STALLM |\ 01292 USB_OTG_HCINTMSK_TXERRM |\ 01293 USB_OTG_HCINTMSK_DTERRM |\ 01294 USB_OTG_HCINTMSK_AHBERR |\ 01295 USB_OTG_HCINTMSK_NAKM ; 01296 01297 if (epnum & 0x80) 01298 { 01299 USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM; 01300 } 01301 break; 01302 01303 case EP_TYPE_INTR: 01304 01305 USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\ 01306 USB_OTG_HCINTMSK_STALLM |\ 01307 USB_OTG_HCINTMSK_TXERRM |\ 01308 USB_OTG_HCINTMSK_DTERRM |\ 01309 USB_OTG_HCINTMSK_NAKM |\ 01310 USB_OTG_HCINTMSK_AHBERR |\ 01311 USB_OTG_HCINTMSK_FRMORM ; 01312 01313 if (epnum & 0x80) 01314 { 01315 USBx_HC(ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM; 01316 } 01317 01318 break; 01319 case EP_TYPE_ISOC: 01320 01321 USBx_HC(ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |\ 01322 USB_OTG_HCINTMSK_ACKM |\ 01323 USB_OTG_HCINTMSK_AHBERR |\ 01324 USB_OTG_HCINTMSK_FRMORM ; 01325 01326 if (epnum & 0x80) 01327 { 01328 USBx_HC(ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM); 01329 } 01330 break; 01331 } 01332 01333 /* Enable the top level host channel interrupt. */ 01334 USBx_HOST->HAINTMSK |= (1 << ch_num); 01335 01336 /* Make sure host channel interrupts are enabled. */ 01337 USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM; 01338 01339 /* Program the HCCHAR register */ 01340 USBx_HC(ch_num)->HCCHAR = (((dev_address << 22) & USB_OTG_HCCHAR_DAD) |\ 01341 (((epnum & 0x7F)<< 11) & USB_OTG_HCCHAR_EPNUM)|\ 01342 ((((epnum & 0x80) == 0x80)<< 15) & USB_OTG_HCCHAR_EPDIR)|\ 01343 (((speed == HPRT0_PRTSPD_LOW_SPEED)<< 17) & USB_OTG_HCCHAR_LSDEV)|\ 01344 ((ep_type << 18) & USB_OTG_HCCHAR_EPTYP)|\ 01345 (mps & USB_OTG_HCCHAR_MPSIZ)); 01346 01347 if (ep_type == EP_TYPE_INTR) 01348 { 01349 USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM ; 01350 } 01351 01352 return HAL_OK; 01353 } 01354 01355 /** 01356 * @brief Start a transfer over a host channel 01357 * @param USBx: Selected device 01358 * @param hc: pointer to host channel structure 01359 * @param dma: USB dma enabled or disabled 01360 * This parameter can be one of these values: 01361 * 0 : DMA feature not used 01362 * 1 : DMA feature used 01363 * @retval HAL state 01364 */ 01365 #if defined (__CC_ARM) /*!< ARM Compiler */ 01366 #pragma O0 01367 #elif defined (__GNUC__) /*!< GNU Compiler */ 01368 #pragma GCC optimize ("O0") 01369 #endif /* __CC_ARM */ 01370 HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc, uint8_t dma) 01371 { 01372 uint8_t is_oddframe = 0; 01373 uint16_t len_words = 0; 01374 uint16_t num_packets = 0; 01375 uint16_t max_hc_pkt_count = 256; 01376 uint32_t tmpreg = 0; 01377 01378 /* Compute the expected number of packets associated to the transfer */ 01379 if (hc->xfer_len > 0) 01380 { 01381 num_packets = (hc->xfer_len + hc->max_packet - 1) / hc->max_packet; 01382 01383 if (num_packets > max_hc_pkt_count) 01384 { 01385 num_packets = max_hc_pkt_count; 01386 hc->xfer_len = num_packets * hc->max_packet; 01387 } 01388 } 01389 else 01390 { 01391 num_packets = 1; 01392 } 01393 if (hc->ep_is_in) 01394 { 01395 hc->xfer_len = num_packets * hc->max_packet; 01396 } 01397 01398 /* Initialize the HCTSIZn register */ 01399 USBx_HC(hc->ch_num)->HCTSIZ = (((hc->xfer_len) & USB_OTG_HCTSIZ_XFRSIZ)) |\ 01400 ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |\ 01401 (((hc->data_pid) << 29) & USB_OTG_HCTSIZ_DPID); 01402 01403 if (dma) 01404 { 01405 /* xfer_buff MUST be 32-bits aligned */ 01406 USBx_HC(hc->ch_num)->HCDMA = (uint32_t)hc->xfer_buff; 01407 } 01408 01409 is_oddframe = (USBx_HOST->HFNUM & 0x01) ? 0 : 1; 01410 USBx_HC(hc->ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM; 01411 USBx_HC(hc->ch_num)->HCCHAR |= (is_oddframe << 29); 01412 01413 /* Set host channel enable */ 01414 tmpreg = USBx_HC(hc->ch_num)->HCCHAR; 01415 tmpreg &= ~USB_OTG_HCCHAR_CHDIS; 01416 tmpreg |= USB_OTG_HCCHAR_CHENA; 01417 USBx_HC(hc->ch_num)->HCCHAR = tmpreg; 01418 01419 if (dma == 0) /* Slave mode */ 01420 { 01421 if((hc->ep_is_in == 0) && (hc->xfer_len > 0)) 01422 { 01423 switch(hc->ep_type) 01424 { 01425 /* Non periodic transfer */ 01426 case EP_TYPE_CTRL: 01427 case EP_TYPE_BULK: 01428 01429 len_words = (hc->xfer_len + 3) / 4; 01430 01431 /* check if there is enough space in FIFO space */ 01432 if(len_words > (USBx->HNPTXSTS & 0xFFFF)) 01433 { 01434 /* need to process data in nptxfempty interrupt */ 01435 USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM; 01436 } 01437 break; 01438 /* Periodic transfer */ 01439 case EP_TYPE_INTR: 01440 case EP_TYPE_ISOC: 01441 len_words = (hc->xfer_len + 3) / 4; 01442 /* check if there is enough space in FIFO space */ 01443 if(len_words > (USBx_HOST->HPTXSTS & 0xFFFF)) /* split the transfer */ 01444 { 01445 /* need to process data in ptxfempty interrupt */ 01446 USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM; 01447 } 01448 break; 01449 01450 default: 01451 break; 01452 } 01453 01454 /* Write packet into the Tx FIFO. */ 01455 USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, hc->xfer_len, 0); 01456 } 01457 } 01458 01459 return HAL_OK; 01460 } 01461 01462 /** 01463 * @brief Read all host channel interrupts status 01464 * @param USBx: Selected device 01465 * @retval HAL state 01466 */ 01467 uint32_t USB_HC_ReadInterrupt (USB_OTG_GlobalTypeDef *USBx) 01468 { 01469 return ((USBx_HOST->HAINT) & 0xFFFF); 01470 } 01471 01472 /** 01473 * @brief Halt a host channel 01474 * @param USBx: Selected device 01475 * @param hc_num: Host Channel number 01476 * This parameter can be a value from 1 to 15 01477 * @retval HAL state 01478 */ 01479 HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx , uint8_t hc_num) 01480 { 01481 uint32_t count = 0; 01482 01483 /* Check for space in the request queue to issue the halt. */ 01484 if (((USBx_HC(hc_num)->HCCHAR) & (HCCHAR_CTRL << 18)) || ((USBx_HC(hc_num)->HCCHAR) & (HCCHAR_BULK << 18))) 01485 { 01486 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS; 01487 01488 if ((USBx->HNPTXSTS & 0xFFFF) == 0) 01489 { 01490 USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA; 01491 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA; 01492 USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR; 01493 do 01494 { 01495 if (++count > 1000) 01496 { 01497 break; 01498 } 01499 } 01500 while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA); 01501 } 01502 else 01503 { 01504 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA; 01505 } 01506 } 01507 else 01508 { 01509 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS; 01510 01511 if ((USBx_HOST->HPTXSTS & 0xFFFF) == 0) 01512 { 01513 USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA; 01514 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA; 01515 USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR; 01516 do 01517 { 01518 if (++count > 1000) 01519 { 01520 break; 01521 } 01522 } 01523 while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA); 01524 } 01525 else 01526 { 01527 USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA; 01528 } 01529 } 01530 01531 return HAL_OK; 01532 } 01533 01534 /** 01535 * @brief Initiate Do Ping protocol 01536 * @param USBx: Selected device 01537 * @param hc_num: Host Channel number 01538 * This parameter can be a value from 1 to 15 01539 * @retval HAL state 01540 */ 01541 HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx , uint8_t ch_num) 01542 { 01543 uint8_t num_packets = 1; 01544 uint32_t tmpreg = 0; 01545 01546 USBx_HC(ch_num)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |\ 01547 USB_OTG_HCTSIZ_DOPING; 01548 01549 /* Set host channel enable */ 01550 tmpreg = USBx_HC(ch_num)->HCCHAR; 01551 tmpreg &= ~USB_OTG_HCCHAR_CHDIS; 01552 tmpreg |= USB_OTG_HCCHAR_CHENA; 01553 USBx_HC(ch_num)->HCCHAR = tmpreg; 01554 01555 return HAL_OK; 01556 } 01557 01558 /** 01559 * @brief Stop Host Core 01560 * @param USBx: Selected device 01561 * @retval HAL state 01562 */ 01563 HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx) 01564 { 01565 uint8_t i; 01566 uint32_t count = 0; 01567 uint32_t value; 01568 01569 USB_DisableGlobalInt(USBx); 01570 01571 /* Flush FIFO */ 01572 USB_FlushTxFifo(USBx, 0x10); 01573 USB_FlushRxFifo(USBx); 01574 01575 /* Flush out any leftover queued requests. */ 01576 for (i = 0; i <= 15; i++) 01577 { 01578 01579 value = USBx_HC(i)->HCCHAR ; 01580 value |= USB_OTG_HCCHAR_CHDIS; 01581 value &= ~USB_OTG_HCCHAR_CHENA; 01582 value &= ~USB_OTG_HCCHAR_EPDIR; 01583 USBx_HC(i)->HCCHAR = value; 01584 } 01585 01586 /* Halt all channels to put them into a known state. */ 01587 for (i = 0; i <= 15; i++) 01588 { 01589 value = USBx_HC(i)->HCCHAR ; 01590 01591 value |= USB_OTG_HCCHAR_CHDIS; 01592 value |= USB_OTG_HCCHAR_CHENA; 01593 value &= ~USB_OTG_HCCHAR_EPDIR; 01594 01595 USBx_HC(i)->HCCHAR = value; 01596 do 01597 { 01598 if (++count > 1000) 01599 { 01600 break; 01601 } 01602 } 01603 while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA); 01604 } 01605 01606 /* Clear any pending Host interrupts */ 01607 USBx_HOST->HAINT = 0xFFFFFFFF; 01608 USBx->GINTSTS = 0xFFFFFFFF; 01609 USB_EnableGlobalInt(USBx); 01610 return HAL_OK; 01611 } 01612 /** 01613 * @} 01614 */ 01615 01616 #endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */ 01617 01618 /** 01619 * @} 01620 */ 01621 01622 #endif /* STM32L475xx || STM32L476xx || STM32L485xx || STM32L486xx */ 01623 01624 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 01625
Generated on Tue Jul 12 2022 11:35:17 by 1.7.2