stm32f1xx_ll_usb.c 73 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674
  1. /**
  2. ******************************************************************************
  3. * @file stm32f1xx_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. (#) Call USB_CoreInit() API to initialize the USB Core peripheral.
  21. (#) The upper HAL HCD/PCD driver will call the right routines for its internal processes.
  22. @endverbatim
  23. ******************************************************************************
  24. * @attention
  25. *
  26. * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
  27. * All rights reserved.</center></h2>
  28. *
  29. * This software component is licensed by ST under BSD 3-Clause license,
  30. * the "License"; You may not use this file except in compliance with the
  31. * License. You may obtain a copy of the License at:
  32. * opensource.org/licenses/BSD-3-Clause
  33. *
  34. ******************************************************************************
  35. */
  36. /* Includes ------------------------------------------------------------------*/
  37. #include "stm32f1xx_hal.h"
  38. /** @addtogroup STM32F1xx_LL_USB_DRIVER
  39. * @{
  40. */
  41. #if defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED)
  42. #if defined (USB) || defined (USB_OTG_FS)
  43. /* Private typedef -----------------------------------------------------------*/
  44. /* Private define ------------------------------------------------------------*/
  45. /* Private macro -------------------------------------------------------------*/
  46. /* Private variables ---------------------------------------------------------*/
  47. /* Private function prototypes -----------------------------------------------*/
  48. /* Private functions ---------------------------------------------------------*/
  49. #if defined (USB_OTG_FS)
  50. static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx);
  51. /* Exported functions --------------------------------------------------------*/
  52. /** @defgroup USB_LL_Exported_Functions USB Low Layer Exported Functions
  53. * @{
  54. */
  55. /** @defgroup USB_LL_Exported_Functions_Group1 Initialization/de-initialization functions
  56. * @brief Initialization and Configuration functions
  57. *
  58. @verbatim
  59. ===============================================================================
  60. ##### Initialization/de-initialization functions #####
  61. ===============================================================================
  62. @endverbatim
  63. * @{
  64. */
  65. /**
  66. * @brief Initializes the USB Core
  67. * @param USBx USB Instance
  68. * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
  69. * the configuration information for the specified USBx peripheral.
  70. * @retval HAL status
  71. */
  72. HAL_StatusTypeDef USB_CoreInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
  73. {
  74. HAL_StatusTypeDef ret;
  75. if (cfg.phy_itface == USB_OTG_ULPI_PHY)
  76. {
  77. USBx->GCCFG &= ~(USB_OTG_GCCFG_PWRDWN);
  78. /* Init The ULPI Interface */
  79. USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
  80. /* Select vbus source */
  81. USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
  82. if (cfg.use_external_vbus == 1U)
  83. {
  84. USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
  85. }
  86. /* Reset after a PHY select */
  87. ret = USB_CoreReset(USBx);
  88. }
  89. else /* FS interface (embedded Phy) */
  90. {
  91. /* Select FS Embedded PHY */
  92. USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
  93. /* Reset after a PHY select */
  94. ret = USB_CoreReset(USBx);
  95. /* Activate the USB Transceiver */
  96. USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
  97. }
  98. return ret;
  99. }
  100. /**
  101. * @brief Set the USB turnaround time
  102. * @param USBx USB Instance
  103. * @param hclk: AHB clock frequency
  104. * @retval USB turnaround time In PHY Clocks number
  105. */
  106. HAL_StatusTypeDef USB_SetTurnaroundTime(USB_OTG_GlobalTypeDef *USBx,
  107. uint32_t hclk, uint8_t speed)
  108. {
  109. uint32_t UsbTrd;
  110. /* The USBTRD is configured according to the tables below, depending on AHB frequency
  111. used by application. In the low AHB frequency range it is used to stretch enough the USB response
  112. time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access
  113. latency to the Data FIFO */
  114. if (speed == USBD_FS_SPEED)
  115. {
  116. if ((hclk >= 14200000U) && (hclk < 15000000U))
  117. {
  118. /* hclk Clock Range between 14.2-15 MHz */
  119. UsbTrd = 0xFU;
  120. }
  121. else if ((hclk >= 15000000U) && (hclk < 16000000U))
  122. {
  123. /* hclk Clock Range between 15-16 MHz */
  124. UsbTrd = 0xEU;
  125. }
  126. else if ((hclk >= 16000000U) && (hclk < 17200000U))
  127. {
  128. /* hclk Clock Range between 16-17.2 MHz */
  129. UsbTrd = 0xDU;
  130. }
  131. else if ((hclk >= 17200000U) && (hclk < 18500000U))
  132. {
  133. /* hclk Clock Range between 17.2-18.5 MHz */
  134. UsbTrd = 0xCU;
  135. }
  136. else if ((hclk >= 18500000U) && (hclk < 20000000U))
  137. {
  138. /* hclk Clock Range between 18.5-20 MHz */
  139. UsbTrd = 0xBU;
  140. }
  141. else if ((hclk >= 20000000U) && (hclk < 21800000U))
  142. {
  143. /* hclk Clock Range between 20-21.8 MHz */
  144. UsbTrd = 0xAU;
  145. }
  146. else if ((hclk >= 21800000U) && (hclk < 24000000U))
  147. {
  148. /* hclk Clock Range between 21.8-24 MHz */
  149. UsbTrd = 0x9U;
  150. }
  151. else if ((hclk >= 24000000U) && (hclk < 27700000U))
  152. {
  153. /* hclk Clock Range between 24-27.7 MHz */
  154. UsbTrd = 0x8U;
  155. }
  156. else if ((hclk >= 27700000U) && (hclk < 32000000U))
  157. {
  158. /* hclk Clock Range between 27.7-32 MHz */
  159. UsbTrd = 0x7U;
  160. }
  161. else /* if(hclk >= 32000000) */
  162. {
  163. /* hclk Clock Range between 32-200 MHz */
  164. UsbTrd = 0x6U;
  165. }
  166. }
  167. else
  168. {
  169. UsbTrd = USBD_DEFAULT_TRDT_VALUE;
  170. }
  171. USBx->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
  172. USBx->GUSBCFG |= (uint32_t)((UsbTrd << 10) & USB_OTG_GUSBCFG_TRDT);
  173. return HAL_OK;
  174. }
  175. /**
  176. * @brief USB_EnableGlobalInt
  177. * Enables the controller's Global Int in the AHB Config reg
  178. * @param USBx Selected device
  179. * @retval HAL status
  180. */
  181. HAL_StatusTypeDef USB_EnableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
  182. {
  183. USBx->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
  184. return HAL_OK;
  185. }
  186. /**
  187. * @brief USB_DisableGlobalInt
  188. * Disable the controller's Global Int in the AHB Config reg
  189. * @param USBx Selected device
  190. * @retval HAL status
  191. */
  192. HAL_StatusTypeDef USB_DisableGlobalInt(USB_OTG_GlobalTypeDef *USBx)
  193. {
  194. USBx->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
  195. return HAL_OK;
  196. }
  197. /**
  198. * @brief USB_SetCurrentMode Set functional mode
  199. * @param USBx Selected device
  200. * @param mode current core mode
  201. * This parameter can be one of these values:
  202. * @arg USB_DEVICE_MODE Peripheral mode
  203. * @arg USB_HOST_MODE Host mode
  204. * @retval HAL status
  205. */
  206. HAL_StatusTypeDef USB_SetCurrentMode(USB_OTG_GlobalTypeDef *USBx, USB_ModeTypeDef mode)
  207. {
  208. USBx->GUSBCFG &= ~(USB_OTG_GUSBCFG_FHMOD | USB_OTG_GUSBCFG_FDMOD);
  209. if (mode == USB_HOST_MODE)
  210. {
  211. USBx->GUSBCFG |= USB_OTG_GUSBCFG_FHMOD;
  212. }
  213. else if (mode == USB_DEVICE_MODE)
  214. {
  215. USBx->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
  216. }
  217. else
  218. {
  219. return HAL_ERROR;
  220. }
  221. HAL_Delay(50U);
  222. return HAL_OK;
  223. }
  224. /**
  225. * @brief USB_DevInit Initializes the USB_OTG controller registers
  226. * for device mode
  227. * @param USBx Selected device
  228. * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
  229. * the configuration information for the specified USBx peripheral.
  230. * @retval HAL status
  231. */
  232. HAL_StatusTypeDef USB_DevInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
  233. {
  234. HAL_StatusTypeDef ret = HAL_OK;
  235. uint32_t USBx_BASE = (uint32_t)USBx;
  236. uint32_t i;
  237. for (i = 0U; i < 15U; i++)
  238. {
  239. USBx->DIEPTXF[i] = 0U;
  240. }
  241. /* Enable HW VBUS sensing */
  242. USBx->GCCFG |= USB_OTG_GCCFG_VBUSBSEN;
  243. /* Restart the Phy Clock */
  244. USBx_PCGCCTL = 0U;
  245. /* Device mode configuration */
  246. USBx_DEVICE->DCFG |= DCFG_FRAME_INTERVAL_80;
  247. /* Set Core speed to Full speed mode */
  248. (void)USB_SetDevSpeed(USBx, USB_OTG_SPEED_FULL);
  249. /* Flush the FIFOs */
  250. if (USB_FlushTxFifo(USBx, 0x10U) != HAL_OK) /* all Tx FIFOs */
  251. {
  252. ret = HAL_ERROR;
  253. }
  254. if (USB_FlushRxFifo(USBx) != HAL_OK)
  255. {
  256. ret = HAL_ERROR;
  257. }
  258. /* Clear all pending Device Interrupts */
  259. USBx_DEVICE->DIEPMSK = 0U;
  260. USBx_DEVICE->DOEPMSK = 0U;
  261. USBx_DEVICE->DAINTMSK = 0U;
  262. for (i = 0U; i < cfg.dev_endpoints; i++)
  263. {
  264. if ((USBx_INEP(i)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
  265. {
  266. if (i == 0U)
  267. {
  268. USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
  269. }
  270. else
  271. {
  272. USBx_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_EPDIS | USB_OTG_DIEPCTL_SNAK;
  273. }
  274. }
  275. else
  276. {
  277. USBx_INEP(i)->DIEPCTL = 0U;
  278. }
  279. USBx_INEP(i)->DIEPTSIZ = 0U;
  280. USBx_INEP(i)->DIEPINT = 0xFB7FU;
  281. }
  282. for (i = 0U; i < cfg.dev_endpoints; i++)
  283. {
  284. if ((USBx_OUTEP(i)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
  285. {
  286. if (i == 0U)
  287. {
  288. USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
  289. }
  290. else
  291. {
  292. USBx_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_EPDIS | USB_OTG_DOEPCTL_SNAK;
  293. }
  294. }
  295. else
  296. {
  297. USBx_OUTEP(i)->DOEPCTL = 0U;
  298. }
  299. USBx_OUTEP(i)->DOEPTSIZ = 0U;
  300. USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
  301. }
  302. USBx_DEVICE->DIEPMSK &= ~(USB_OTG_DIEPMSK_TXFURM);
  303. /* Disable all interrupts. */
  304. USBx->GINTMSK = 0U;
  305. /* Clear any pending interrupts */
  306. USBx->GINTSTS = 0xBFFFFFFFU;
  307. /* Enable the common interrupts */
  308. USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
  309. /* Enable interrupts matching to the Device mode ONLY */
  310. USBx->GINTMSK |= USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |
  311. USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |
  312. USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM |
  313. USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM;
  314. if (cfg.Sof_enable != 0U)
  315. {
  316. USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM;
  317. }
  318. if (cfg.vbus_sensing_enable == 1U)
  319. {
  320. USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT);
  321. }
  322. return ret;
  323. }
  324. /**
  325. * @brief USB_OTG_FlushTxFifo : Flush a Tx FIFO
  326. * @param USBx Selected device
  327. * @param num FIFO number
  328. * This parameter can be a value from 1 to 15
  329. 15 means Flush all Tx FIFOs
  330. * @retval HAL status
  331. */
  332. HAL_StatusTypeDef USB_FlushTxFifo(USB_OTG_GlobalTypeDef *USBx, uint32_t num)
  333. {
  334. uint32_t count = 0U;
  335. USBx->GRSTCTL = (USB_OTG_GRSTCTL_TXFFLSH | (num << 6));
  336. do
  337. {
  338. if (++count > 200000U)
  339. {
  340. return HAL_TIMEOUT;
  341. }
  342. } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH);
  343. return HAL_OK;
  344. }
  345. /**
  346. * @brief USB_FlushRxFifo : Flush Rx FIFO
  347. * @param USBx Selected device
  348. * @retval HAL status
  349. */
  350. HAL_StatusTypeDef USB_FlushRxFifo(USB_OTG_GlobalTypeDef *USBx)
  351. {
  352. uint32_t count = 0;
  353. USBx->GRSTCTL = USB_OTG_GRSTCTL_RXFFLSH;
  354. do
  355. {
  356. if (++count > 200000U)
  357. {
  358. return HAL_TIMEOUT;
  359. }
  360. } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH);
  361. return HAL_OK;
  362. }
  363. /**
  364. * @brief USB_SetDevSpeed Initializes the DevSpd field of DCFG register
  365. * depending the PHY type and the enumeration speed of the device.
  366. * @param USBx Selected device
  367. * @param speed device speed
  368. * This parameter can be one of these values:
  369. * @arg USB_OTG_SPEED_FULL: Full speed mode
  370. * @retval Hal status
  371. */
  372. HAL_StatusTypeDef USB_SetDevSpeed(USB_OTG_GlobalTypeDef *USBx, uint8_t speed)
  373. {
  374. uint32_t USBx_BASE = (uint32_t)USBx;
  375. USBx_DEVICE->DCFG |= speed;
  376. return HAL_OK;
  377. }
  378. /**
  379. * @brief USB_GetDevSpeed Return the Dev Speed
  380. * @param USBx Selected device
  381. * @retval speed device speed
  382. * This parameter can be one of these values:
  383. * @arg PCD_SPEED_FULL: Full speed mode
  384. */
  385. uint8_t USB_GetDevSpeed(USB_OTG_GlobalTypeDef *USBx)
  386. {
  387. uint32_t USBx_BASE = (uint32_t)USBx;
  388. uint8_t speed;
  389. uint32_t DevEnumSpeed = USBx_DEVICE->DSTS & USB_OTG_DSTS_ENUMSPD;
  390. if ((DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) ||
  391. (DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_48MHZ))
  392. {
  393. speed = USBD_FS_SPEED;
  394. }
  395. else
  396. {
  397. speed = 0xFU;
  398. }
  399. return speed;
  400. }
  401. /**
  402. * @brief Activate and configure an endpoint
  403. * @param USBx Selected device
  404. * @param ep pointer to endpoint structure
  405. * @retval HAL status
  406. */
  407. HAL_StatusTypeDef USB_ActivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
  408. {
  409. uint32_t USBx_BASE = (uint32_t)USBx;
  410. uint32_t epnum = (uint32_t)ep->num;
  411. if (ep->is_in == 1U)
  412. {
  413. USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
  414. if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_USBAEP) == 0U)
  415. {
  416. USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
  417. ((uint32_t)ep->type << 18) | (epnum << 22) |
  418. USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
  419. USB_OTG_DIEPCTL_USBAEP;
  420. }
  421. }
  422. else
  423. {
  424. USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
  425. if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
  426. {
  427. USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
  428. ((uint32_t)ep->type << 18) |
  429. USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
  430. USB_OTG_DOEPCTL_USBAEP;
  431. }
  432. }
  433. return HAL_OK;
  434. }
  435. /**
  436. * @brief Activate and configure a dedicated endpoint
  437. * @param USBx Selected device
  438. * @param ep pointer to endpoint structure
  439. * @retval HAL status
  440. */
  441. HAL_StatusTypeDef USB_ActivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
  442. {
  443. uint32_t USBx_BASE = (uint32_t)USBx;
  444. uint32_t epnum = (uint32_t)ep->num;
  445. /* Read DEPCTLn register */
  446. if (ep->is_in == 1U)
  447. {
  448. if (((USBx_INEP(epnum)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0U)
  449. {
  450. USBx_INEP(epnum)->DIEPCTL |= (ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ) |
  451. ((uint32_t)ep->type << 18) | (epnum << 22) |
  452. USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
  453. USB_OTG_DIEPCTL_USBAEP;
  454. }
  455. USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK));
  456. }
  457. else
  458. {
  459. if (((USBx_OUTEP(epnum)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0U)
  460. {
  461. USBx_OUTEP(epnum)->DOEPCTL |= (ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ) |
  462. ((uint32_t)ep->type << 18) | (epnum << 22) |
  463. USB_OTG_DOEPCTL_USBAEP;
  464. }
  465. USBx_DEVICE->DEACHMSK |= USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16);
  466. }
  467. return HAL_OK;
  468. }
  469. /**
  470. * @brief De-activate and de-initialize an endpoint
  471. * @param USBx Selected device
  472. * @param ep pointer to endpoint structure
  473. * @retval HAL status
  474. */
  475. HAL_StatusTypeDef USB_DeactivateEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
  476. {
  477. uint32_t USBx_BASE = (uint32_t)USBx;
  478. uint32_t epnum = (uint32_t)ep->num;
  479. /* Read DEPCTLn register */
  480. if (ep->is_in == 1U)
  481. {
  482. if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
  483. {
  484. USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
  485. USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
  486. }
  487. USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
  488. USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
  489. USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_USBAEP |
  490. USB_OTG_DIEPCTL_MPSIZ |
  491. USB_OTG_DIEPCTL_TXFNUM |
  492. USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
  493. USB_OTG_DIEPCTL_EPTYP);
  494. }
  495. else
  496. {
  497. if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
  498. {
  499. USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
  500. USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
  501. }
  502. USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
  503. USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
  504. USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_USBAEP |
  505. USB_OTG_DOEPCTL_MPSIZ |
  506. USB_OTG_DOEPCTL_SD0PID_SEVNFRM |
  507. USB_OTG_DOEPCTL_EPTYP);
  508. }
  509. return HAL_OK;
  510. }
  511. /**
  512. * @brief De-activate and de-initialize a dedicated endpoint
  513. * @param USBx Selected device
  514. * @param ep pointer to endpoint structure
  515. * @retval HAL status
  516. */
  517. HAL_StatusTypeDef USB_DeactivateDedicatedEndpoint(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
  518. {
  519. uint32_t USBx_BASE = (uint32_t)USBx;
  520. uint32_t epnum = (uint32_t)ep->num;
  521. /* Read DEPCTLn register */
  522. if (ep->is_in == 1U)
  523. {
  524. if ((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA)
  525. {
  526. USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
  527. USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
  528. }
  529. USBx_INEP(epnum)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP;
  530. USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep->num & EP_ADDR_MSK)));
  531. }
  532. else
  533. {
  534. if ((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
  535. {
  536. USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
  537. USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
  538. }
  539. USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP;
  540. USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep->num & EP_ADDR_MSK)) << 16));
  541. }
  542. return HAL_OK;
  543. }
  544. /**
  545. * @brief USB_EPStartXfer : setup and starts a transfer over an EP
  546. * @param USBx Selected device
  547. * @param ep pointer to endpoint structure
  548. * @retval HAL status
  549. */
  550. HAL_StatusTypeDef USB_EPStartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
  551. {
  552. uint32_t USBx_BASE = (uint32_t)USBx;
  553. uint32_t epnum = (uint32_t)ep->num;
  554. uint16_t pktcnt;
  555. /* IN endpoint */
  556. if (ep->is_in == 1U)
  557. {
  558. /* Zero Length Packet? */
  559. if (ep->xfer_len == 0U)
  560. {
  561. USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
  562. USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
  563. USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
  564. }
  565. else
  566. {
  567. /* Program the transfer size and packet count
  568. * as follows: xfersize = N * maxpacket +
  569. * short_packet pktcnt = N + (short_packet
  570. * exist ? 1 : 0)
  571. */
  572. USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
  573. USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
  574. USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket) << 19));
  575. USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
  576. if (ep->type == EP_TYPE_ISOC)
  577. {
  578. USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
  579. USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29));
  580. }
  581. }
  582. /* EP enable, IN data in FIFO */
  583. USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
  584. if (ep->type != EP_TYPE_ISOC)
  585. {
  586. /* Enable the Tx FIFO Empty Interrupt for this EP */
  587. if (ep->xfer_len > 0U)
  588. {
  589. USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK);
  590. }
  591. }
  592. else
  593. {
  594. if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
  595. {
  596. USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
  597. }
  598. else
  599. {
  600. USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
  601. }
  602. (void)USB_WritePacket(USBx, ep->xfer_buff, ep->num, (uint16_t)ep->xfer_len);
  603. }
  604. }
  605. else /* OUT endpoint */
  606. {
  607. /* Program the transfer size and packet count as follows:
  608. * pktcnt = N
  609. * xfersize = N * maxpacket
  610. */
  611. USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
  612. USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
  613. if (ep->xfer_len == 0U)
  614. {
  615. USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & ep->maxpacket);
  616. USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
  617. }
  618. else
  619. {
  620. pktcnt = (uint16_t)((ep->xfer_len + ep->maxpacket - 1U) / ep->maxpacket);
  621. USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_PKTCNT & ((uint32_t)pktcnt << 19);
  622. USBx_OUTEP(epnum)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket * pktcnt);
  623. }
  624. if (ep->type == EP_TYPE_ISOC)
  625. {
  626. if ((USBx_DEVICE->DSTS & (1U << 8)) == 0U)
  627. {
  628. USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SODDFRM;
  629. }
  630. else
  631. {
  632. USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
  633. }
  634. }
  635. /* EP enable */
  636. USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
  637. }
  638. return HAL_OK;
  639. }
  640. /**
  641. * @brief USB_EP0StartXfer : setup and starts a transfer over the EP 0
  642. * @param USBx Selected device
  643. * @param ep pointer to endpoint structure
  644. * @retval HAL status
  645. */
  646. HAL_StatusTypeDef USB_EP0StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
  647. {
  648. uint32_t USBx_BASE = (uint32_t)USBx;
  649. uint32_t epnum = (uint32_t)ep->num;
  650. /* IN endpoint */
  651. if (ep->is_in == 1U)
  652. {
  653. /* Zero Length Packet? */
  654. if (ep->xfer_len == 0U)
  655. {
  656. USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
  657. USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
  658. USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
  659. }
  660. else
  661. {
  662. /* Program the transfer size and packet count
  663. * as follows: xfersize = N * maxpacket +
  664. * short_packet pktcnt = N + (short_packet
  665. * exist ? 1 : 0)
  666. */
  667. USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_XFRSIZ);
  668. USBx_INEP(epnum)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_PKTCNT);
  669. if (ep->xfer_len > ep->maxpacket)
  670. {
  671. ep->xfer_len = ep->maxpacket;
  672. }
  673. USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_PKTCNT & (1U << 19));
  674. USBx_INEP(epnum)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & ep->xfer_len);
  675. }
  676. /* EP enable, IN data in FIFO */
  677. USBx_INEP(epnum)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
  678. /* Enable the Tx FIFO Empty Interrupt for this EP */
  679. if (ep->xfer_len > 0U)
  680. {
  681. USBx_DEVICE->DIEPEMPMSK |= 1UL << (ep->num & EP_ADDR_MSK);
  682. }
  683. }
  684. else /* OUT endpoint */
  685. {
  686. /* Program the transfer size and packet count as follows:
  687. * pktcnt = N
  688. * xfersize = N * maxpacket
  689. */
  690. USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_XFRSIZ);
  691. USBx_OUTEP(epnum)->DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT);
  692. if (ep->xfer_len > 0U)
  693. {
  694. ep->xfer_len = ep->maxpacket;
  695. }
  696. USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
  697. USBx_OUTEP(epnum)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & (ep->maxpacket));
  698. /* EP enable */
  699. USBx_OUTEP(epnum)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
  700. }
  701. return HAL_OK;
  702. }
  703. /**
  704. * @brief USB_WritePacket : Writes a packet into the Tx FIFO associated
  705. * with the EP/channel
  706. * @param USBx Selected device
  707. * @param src pointer to source buffer
  708. * @param ch_ep_num endpoint or host channel number
  709. * @param len Number of bytes to write
  710. * @retval HAL status
  711. */
  712. HAL_StatusTypeDef USB_WritePacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *src,
  713. uint8_t ch_ep_num, uint16_t len)
  714. {
  715. uint32_t USBx_BASE = (uint32_t)USBx;
  716. uint32_t *pSrc = (uint32_t *)src;
  717. uint32_t count32b, i;
  718. count32b = ((uint32_t)len + 3U) / 4U;
  719. for (i = 0U; i < count32b; i++)
  720. {
  721. USBx_DFIFO((uint32_t)ch_ep_num) = __UNALIGNED_UINT32_READ(pSrc);
  722. pSrc++;
  723. }
  724. return HAL_OK;
  725. }
  726. /**
  727. * @brief USB_ReadPacket : read a packet from the RX FIFO
  728. * @param USBx Selected device
  729. * @param dest source pointer
  730. * @param len Number of bytes to read
  731. * @retval pointer to destination buffer
  732. */
  733. void *USB_ReadPacket(USB_OTG_GlobalTypeDef *USBx, uint8_t *dest, uint16_t len)
  734. {
  735. uint32_t USBx_BASE = (uint32_t)USBx;
  736. uint32_t *pDest = (uint32_t *)dest;
  737. uint32_t i;
  738. uint32_t count32b = ((uint32_t)len + 3U) / 4U;
  739. for (i = 0U; i < count32b; i++)
  740. {
  741. __UNALIGNED_UINT32_WRITE(pDest, USBx_DFIFO(0U));
  742. pDest++;
  743. }
  744. return ((void *)pDest);
  745. }
  746. /**
  747. * @brief USB_EPSetStall : set a stall condition over an EP
  748. * @param USBx Selected device
  749. * @param ep pointer to endpoint structure
  750. * @retval HAL status
  751. */
  752. HAL_StatusTypeDef USB_EPSetStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
  753. {
  754. uint32_t USBx_BASE = (uint32_t)USBx;
  755. uint32_t epnum = (uint32_t)ep->num;
  756. if (ep->is_in == 1U)
  757. {
  758. if (((USBx_INEP(epnum)->DIEPCTL & USB_OTG_DIEPCTL_EPENA) == 0U) && (epnum != 0U))
  759. {
  760. USBx_INEP(epnum)->DIEPCTL &= ~(USB_OTG_DIEPCTL_EPDIS);
  761. }
  762. USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
  763. }
  764. else
  765. {
  766. if (((USBx_OUTEP(epnum)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == 0U) && (epnum != 0U))
  767. {
  768. USBx_OUTEP(epnum)->DOEPCTL &= ~(USB_OTG_DOEPCTL_EPDIS);
  769. }
  770. USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_STALL;
  771. }
  772. return HAL_OK;
  773. }
  774. /**
  775. * @brief USB_EPClearStall : Clear a stall condition over an EP
  776. * @param USBx Selected device
  777. * @param ep pointer to endpoint structure
  778. * @retval HAL status
  779. */
  780. HAL_StatusTypeDef USB_EPClearStall(USB_OTG_GlobalTypeDef *USBx, USB_OTG_EPTypeDef *ep)
  781. {
  782. uint32_t USBx_BASE = (uint32_t)USBx;
  783. uint32_t epnum = (uint32_t)ep->num;
  784. if (ep->is_in == 1U)
  785. {
  786. USBx_INEP(epnum)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
  787. if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
  788. {
  789. USBx_INEP(epnum)->DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; /* DATA0 */
  790. }
  791. }
  792. else
  793. {
  794. USBx_OUTEP(epnum)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
  795. if ((ep->type == EP_TYPE_INTR) || (ep->type == EP_TYPE_BULK))
  796. {
  797. USBx_OUTEP(epnum)->DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; /* DATA0 */
  798. }
  799. }
  800. return HAL_OK;
  801. }
  802. /**
  803. * @brief USB_StopDevice : Stop the usb device mode
  804. * @param USBx Selected device
  805. * @retval HAL status
  806. */
  807. HAL_StatusTypeDef USB_StopDevice(USB_OTG_GlobalTypeDef *USBx)
  808. {
  809. HAL_StatusTypeDef ret;
  810. uint32_t USBx_BASE = (uint32_t)USBx;
  811. uint32_t i;
  812. /* Clear Pending interrupt */
  813. for (i = 0U; i < 15U; i++)
  814. {
  815. USBx_INEP(i)->DIEPINT = 0xFB7FU;
  816. USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
  817. }
  818. /* Clear interrupt masks */
  819. USBx_DEVICE->DIEPMSK = 0U;
  820. USBx_DEVICE->DOEPMSK = 0U;
  821. USBx_DEVICE->DAINTMSK = 0U;
  822. /* Flush the FIFO */
  823. ret = USB_FlushRxFifo(USBx);
  824. if (ret != HAL_OK)
  825. {
  826. return ret;
  827. }
  828. ret = USB_FlushTxFifo(USBx, 0x10U);
  829. if (ret != HAL_OK)
  830. {
  831. return ret;
  832. }
  833. return ret;
  834. }
  835. /**
  836. * @brief USB_SetDevAddress : Stop the usb device mode
  837. * @param USBx Selected device
  838. * @param address new device address to be assigned
  839. * This parameter can be a value from 0 to 255
  840. * @retval HAL status
  841. */
  842. HAL_StatusTypeDef USB_SetDevAddress(USB_OTG_GlobalTypeDef *USBx, uint8_t address)
  843. {
  844. uint32_t USBx_BASE = (uint32_t)USBx;
  845. USBx_DEVICE->DCFG &= ~(USB_OTG_DCFG_DAD);
  846. USBx_DEVICE->DCFG |= ((uint32_t)address << 4) & USB_OTG_DCFG_DAD;
  847. return HAL_OK;
  848. }
  849. /**
  850. * @brief USB_DevConnect : Connect the USB device by enabling Rpu
  851. * @param USBx Selected device
  852. * @retval HAL status
  853. */
  854. HAL_StatusTypeDef USB_DevConnect(USB_OTG_GlobalTypeDef *USBx)
  855. {
  856. uint32_t USBx_BASE = (uint32_t)USBx;
  857. /* In case phy is stopped, ensure to ungate and restore the phy CLK */
  858. USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
  859. USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_SDIS;
  860. return HAL_OK;
  861. }
  862. /**
  863. * @brief USB_DevDisconnect : Disconnect the USB device by disabling Rpu
  864. * @param USBx Selected device
  865. * @retval HAL status
  866. */
  867. HAL_StatusTypeDef USB_DevDisconnect(USB_OTG_GlobalTypeDef *USBx)
  868. {
  869. uint32_t USBx_BASE = (uint32_t)USBx;
  870. /* In case phy is stopped, ensure to ungate and restore the phy CLK */
  871. USBx_PCGCCTL &= ~(USB_OTG_PCGCCTL_STOPCLK | USB_OTG_PCGCCTL_GATECLK);
  872. USBx_DEVICE->DCTL |= USB_OTG_DCTL_SDIS;
  873. return HAL_OK;
  874. }
  875. /**
  876. * @brief USB_ReadInterrupts: return the global USB interrupt status
  877. * @param USBx Selected device
  878. * @retval HAL status
  879. */
  880. uint32_t USB_ReadInterrupts(USB_OTG_GlobalTypeDef *USBx)
  881. {
  882. uint32_t tmpreg;
  883. tmpreg = USBx->GINTSTS;
  884. tmpreg &= USBx->GINTMSK;
  885. return tmpreg;
  886. }
  887. /**
  888. * @brief USB_ReadDevAllOutEpInterrupt: return the USB device OUT endpoints interrupt status
  889. * @param USBx Selected device
  890. * @retval HAL status
  891. */
  892. uint32_t USB_ReadDevAllOutEpInterrupt(USB_OTG_GlobalTypeDef *USBx)
  893. {
  894. uint32_t USBx_BASE = (uint32_t)USBx;
  895. uint32_t tmpreg;
  896. tmpreg = USBx_DEVICE->DAINT;
  897. tmpreg &= USBx_DEVICE->DAINTMSK;
  898. return ((tmpreg & 0xffff0000U) >> 16);
  899. }
  900. /**
  901. * @brief USB_ReadDevAllInEpInterrupt: return the USB device IN endpoints interrupt status
  902. * @param USBx Selected device
  903. * @retval HAL status
  904. */
  905. uint32_t USB_ReadDevAllInEpInterrupt(USB_OTG_GlobalTypeDef *USBx)
  906. {
  907. uint32_t USBx_BASE = (uint32_t)USBx;
  908. uint32_t tmpreg;
  909. tmpreg = USBx_DEVICE->DAINT;
  910. tmpreg &= USBx_DEVICE->DAINTMSK;
  911. return ((tmpreg & 0xFFFFU));
  912. }
  913. /**
  914. * @brief Returns Device OUT EP Interrupt register
  915. * @param USBx Selected device
  916. * @param epnum endpoint number
  917. * This parameter can be a value from 0 to 15
  918. * @retval Device OUT EP Interrupt register
  919. */
  920. uint32_t USB_ReadDevOutEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
  921. {
  922. uint32_t USBx_BASE = (uint32_t)USBx;
  923. uint32_t tmpreg;
  924. tmpreg = USBx_OUTEP((uint32_t)epnum)->DOEPINT;
  925. tmpreg &= USBx_DEVICE->DOEPMSK;
  926. return tmpreg;
  927. }
  928. /**
  929. * @brief Returns Device IN EP Interrupt register
  930. * @param USBx Selected device
  931. * @param epnum endpoint number
  932. * This parameter can be a value from 0 to 15
  933. * @retval Device IN EP Interrupt register
  934. */
  935. uint32_t USB_ReadDevInEPInterrupt(USB_OTG_GlobalTypeDef *USBx, uint8_t epnum)
  936. {
  937. uint32_t USBx_BASE = (uint32_t)USBx;
  938. uint32_t tmpreg, msk, emp;
  939. msk = USBx_DEVICE->DIEPMSK;
  940. emp = USBx_DEVICE->DIEPEMPMSK;
  941. msk |= ((emp >> (epnum & EP_ADDR_MSK)) & 0x1U) << 7;
  942. tmpreg = USBx_INEP((uint32_t)epnum)->DIEPINT & msk;
  943. return tmpreg;
  944. }
  945. /**
  946. * @brief USB_ClearInterrupts: clear a USB interrupt
  947. * @param USBx Selected device
  948. * @param interrupt flag
  949. * @retval None
  950. */
  951. void USB_ClearInterrupts(USB_OTG_GlobalTypeDef *USBx, uint32_t interrupt)
  952. {
  953. USBx->GINTSTS |= interrupt;
  954. }
  955. /**
  956. * @brief Returns USB core mode
  957. * @param USBx Selected device
  958. * @retval return core mode : Host or Device
  959. * This parameter can be one of these values:
  960. * 0 : Host
  961. * 1 : Device
  962. */
  963. uint32_t USB_GetMode(USB_OTG_GlobalTypeDef *USBx)
  964. {
  965. return ((USBx->GINTSTS) & 0x1U);
  966. }
  967. /**
  968. * @brief Activate EP0 for Setup transactions
  969. * @param USBx Selected device
  970. * @retval HAL status
  971. */
  972. HAL_StatusTypeDef USB_ActivateSetup(USB_OTG_GlobalTypeDef *USBx)
  973. {
  974. uint32_t USBx_BASE = (uint32_t)USBx;
  975. /* Set the MPS of the IN EP0 to 64 bytes */
  976. USBx_INEP(0U)->DIEPCTL &= ~USB_OTG_DIEPCTL_MPSIZ;
  977. USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGINAK;
  978. return HAL_OK;
  979. }
  980. /**
  981. * @brief Prepare the EP0 to start the first control setup
  982. * @param USBx Selected device
  983. * @param psetup pointer to setup packet
  984. * @retval HAL status
  985. */
  986. HAL_StatusTypeDef USB_EP0_OutStart(USB_OTG_GlobalTypeDef *USBx, uint8_t *psetup)
  987. {
  988. UNUSED(psetup);
  989. uint32_t USBx_BASE = (uint32_t)USBx;
  990. uint32_t gSNPSiD = *(__IO uint32_t *)(&USBx->CID + 0x1U);
  991. if (gSNPSiD > USB_OTG_CORE_ID_300A)
  992. {
  993. if ((USBx_OUTEP(0U)->DOEPCTL & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA)
  994. {
  995. return HAL_OK;
  996. }
  997. }
  998. USBx_OUTEP(0U)->DOEPTSIZ = 0U;
  999. USBx_OUTEP(0U)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_PKTCNT & (1U << 19));
  1000. USBx_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
  1001. USBx_OUTEP(0U)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
  1002. return HAL_OK;
  1003. }
  1004. /**
  1005. * @brief Reset the USB Core (needed after USB clock settings change)
  1006. * @param USBx Selected device
  1007. * @retval HAL status
  1008. */
  1009. static HAL_StatusTypeDef USB_CoreReset(USB_OTG_GlobalTypeDef *USBx)
  1010. {
  1011. uint32_t count = 0U;
  1012. /* Wait for AHB master IDLE state. */
  1013. do
  1014. {
  1015. if (++count > 200000U)
  1016. {
  1017. return HAL_TIMEOUT;
  1018. }
  1019. } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U);
  1020. /* Core Soft Reset */
  1021. count = 0U;
  1022. USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
  1023. do
  1024. {
  1025. if (++count > 200000U)
  1026. {
  1027. return HAL_TIMEOUT;
  1028. }
  1029. } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST);
  1030. return HAL_OK;
  1031. }
  1032. /**
  1033. * @brief USB_HostInit : Initializes the USB OTG controller registers
  1034. * for Host mode
  1035. * @param USBx Selected device
  1036. * @param cfg pointer to a USB_OTG_CfgTypeDef structure that contains
  1037. * the configuration information for the specified USBx peripheral.
  1038. * @retval HAL status
  1039. */
  1040. HAL_StatusTypeDef USB_HostInit(USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg)
  1041. {
  1042. uint32_t USBx_BASE = (uint32_t)USBx;
  1043. uint32_t i;
  1044. /* Restart the Phy Clock */
  1045. USBx_PCGCCTL = 0U;
  1046. /* Disable VBUS sensing */
  1047. USBx->GCCFG &= ~(USB_OTG_GCCFG_VBUSASEN);
  1048. USBx->GCCFG &= ~(USB_OTG_GCCFG_VBUSBSEN);
  1049. /* Set default Max speed support */
  1050. USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
  1051. /* Make sure the FIFOs are flushed. */
  1052. (void)USB_FlushTxFifo(USBx, 0x10U); /* all Tx FIFOs */
  1053. (void)USB_FlushRxFifo(USBx);
  1054. /* Clear all pending HC Interrupts */
  1055. for (i = 0U; i < cfg.Host_channels; i++)
  1056. {
  1057. USBx_HC(i)->HCINT = 0xFFFFFFFFU;
  1058. USBx_HC(i)->HCINTMSK = 0U;
  1059. }
  1060. /* Enable VBUS driving */
  1061. (void)USB_DriveVbus(USBx, 1U);
  1062. HAL_Delay(200U);
  1063. /* Disable all interrupts. */
  1064. USBx->GINTMSK = 0U;
  1065. /* Clear any pending interrupts */
  1066. USBx->GINTSTS = 0xFFFFFFFFU;
  1067. /* set Rx FIFO size */
  1068. USBx->GRXFSIZ = 0x80U;
  1069. USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((0x60U << 16) & USB_OTG_NPTXFD) | 0x80U);
  1070. USBx->HPTXFSIZ = (uint32_t)(((0x40U << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0U);
  1071. /* Enable the common interrupts */
  1072. USBx->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
  1073. /* Enable interrupts matching to the Host mode ONLY */
  1074. USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM | \
  1075. USB_OTG_GINTMSK_SOFM | USB_OTG_GINTSTS_DISCINT | \
  1076. USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM);
  1077. return HAL_OK;
  1078. }
  1079. /**
  1080. * @brief USB_InitFSLSPClkSel : Initializes the FSLSPClkSel field of the
  1081. * HCFG register on the PHY type and set the right frame interval
  1082. * @param USBx Selected device
  1083. * @param freq clock frequency
  1084. * This parameter can be one of these values:
  1085. * HCFG_48_MHZ : Full Speed 48 MHz Clock
  1086. * HCFG_6_MHZ : Low Speed 6 MHz Clock
  1087. * @retval HAL status
  1088. */
  1089. HAL_StatusTypeDef USB_InitFSLSPClkSel(USB_OTG_GlobalTypeDef *USBx, uint8_t freq)
  1090. {
  1091. uint32_t USBx_BASE = (uint32_t)USBx;
  1092. USBx_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSPCS);
  1093. USBx_HOST->HCFG |= (uint32_t)freq & USB_OTG_HCFG_FSLSPCS;
  1094. if (freq == HCFG_48_MHZ)
  1095. {
  1096. USBx_HOST->HFIR = 48000U;
  1097. }
  1098. else if (freq == HCFG_6_MHZ)
  1099. {
  1100. USBx_HOST->HFIR = 6000U;
  1101. }
  1102. else
  1103. {
  1104. /* ... */
  1105. }
  1106. return HAL_OK;
  1107. }
  1108. /**
  1109. * @brief USB_OTG_ResetPort : Reset Host Port
  1110. * @param USBx Selected device
  1111. * @retval HAL status
  1112. * @note (1)The application must wait at least 10 ms
  1113. * before clearing the reset bit.
  1114. */
  1115. HAL_StatusTypeDef USB_ResetPort(USB_OTG_GlobalTypeDef *USBx)
  1116. {
  1117. uint32_t USBx_BASE = (uint32_t)USBx;
  1118. __IO uint32_t hprt0 = 0U;
  1119. hprt0 = USBx_HPRT0;
  1120. hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
  1121. USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
  1122. USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0);
  1123. HAL_Delay(100U); /* See Note #1 */
  1124. USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0);
  1125. HAL_Delay(10U);
  1126. return HAL_OK;
  1127. }
  1128. /**
  1129. * @brief USB_DriveVbus : activate or de-activate vbus
  1130. * @param state VBUS state
  1131. * This parameter can be one of these values:
  1132. * 0 : Deactivate VBUS
  1133. * 1 : Activate VBUS
  1134. * @retval HAL status
  1135. */
  1136. HAL_StatusTypeDef USB_DriveVbus(USB_OTG_GlobalTypeDef *USBx, uint8_t state)
  1137. {
  1138. uint32_t USBx_BASE = (uint32_t)USBx;
  1139. __IO uint32_t hprt0 = 0U;
  1140. hprt0 = USBx_HPRT0;
  1141. hprt0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |
  1142. USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG);
  1143. if (((hprt0 & USB_OTG_HPRT_PPWR) == 0U) && (state == 1U))
  1144. {
  1145. USBx_HPRT0 = (USB_OTG_HPRT_PPWR | hprt0);
  1146. }
  1147. if (((hprt0 & USB_OTG_HPRT_PPWR) == USB_OTG_HPRT_PPWR) && (state == 0U))
  1148. {
  1149. USBx_HPRT0 = ((~USB_OTG_HPRT_PPWR) & hprt0);
  1150. }
  1151. return HAL_OK;
  1152. }
  1153. /**
  1154. * @brief Return Host Core speed
  1155. * @param USBx Selected device
  1156. * @retval speed : Host speed
  1157. * This parameter can be one of these values:
  1158. * @arg HCD_SPEED_FULL: Full speed mode
  1159. * @arg HCD_SPEED_LOW: Low speed mode
  1160. */
  1161. uint32_t USB_GetHostSpeed(USB_OTG_GlobalTypeDef *USBx)
  1162. {
  1163. uint32_t USBx_BASE = (uint32_t)USBx;
  1164. __IO uint32_t hprt0 = 0U;
  1165. hprt0 = USBx_HPRT0;
  1166. return ((hprt0 & USB_OTG_HPRT_PSPD) >> 17);
  1167. }
  1168. /**
  1169. * @brief Return Host Current Frame number
  1170. * @param USBx Selected device
  1171. * @retval current frame number
  1172. */
  1173. uint32_t USB_GetCurrentFrame(USB_OTG_GlobalTypeDef *USBx)
  1174. {
  1175. uint32_t USBx_BASE = (uint32_t)USBx;
  1176. return (USBx_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
  1177. }
  1178. /**
  1179. * @brief Initialize a host channel
  1180. * @param USBx Selected device
  1181. * @param ch_num Channel number
  1182. * This parameter can be a value from 1 to 15
  1183. * @param epnum Endpoint number
  1184. * This parameter can be a value from 1 to 15
  1185. * @param dev_address Current device address
  1186. * This parameter can be a value from 0 to 255
  1187. * @param speed Current device speed
  1188. * This parameter can be one of these values:
  1189. * @arg USB_OTG_SPEED_FULL: Full speed mode
  1190. * @arg USB_OTG_SPEED_LOW: Low speed mode
  1191. * @param ep_type Endpoint Type
  1192. * This parameter can be one of these values:
  1193. * @arg EP_TYPE_CTRL: Control type
  1194. * @arg EP_TYPE_ISOC: Isochronous type
  1195. * @arg EP_TYPE_BULK: Bulk type
  1196. * @arg EP_TYPE_INTR: Interrupt type
  1197. * @param mps Max Packet Size
  1198. * This parameter can be a value from 0 to32K
  1199. * @retval HAL state
  1200. */
  1201. HAL_StatusTypeDef USB_HC_Init(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num,
  1202. uint8_t epnum, uint8_t dev_address, uint8_t speed,
  1203. uint8_t ep_type, uint16_t mps)
  1204. {
  1205. HAL_StatusTypeDef ret = HAL_OK;
  1206. uint32_t USBx_BASE = (uint32_t)USBx;
  1207. uint32_t HCcharEpDir, HCcharLowSpeed;
  1208. /* Clear old interrupt conditions for this host channel. */
  1209. USBx_HC((uint32_t)ch_num)->HCINT = 0xFFFFFFFFU;
  1210. /* Enable channel interrupts required for this transfer. */
  1211. switch (ep_type)
  1212. {
  1213. case EP_TYPE_CTRL:
  1214. case EP_TYPE_BULK:
  1215. USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
  1216. USB_OTG_HCINTMSK_STALLM |
  1217. USB_OTG_HCINTMSK_TXERRM |
  1218. USB_OTG_HCINTMSK_DTERRM |
  1219. USB_OTG_HCINTMSK_AHBERR |
  1220. USB_OTG_HCINTMSK_NAKM;
  1221. if ((epnum & 0x80U) == 0x80U)
  1222. {
  1223. USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
  1224. }
  1225. break;
  1226. case EP_TYPE_INTR:
  1227. USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
  1228. USB_OTG_HCINTMSK_STALLM |
  1229. USB_OTG_HCINTMSK_TXERRM |
  1230. USB_OTG_HCINTMSK_DTERRM |
  1231. USB_OTG_HCINTMSK_NAKM |
  1232. USB_OTG_HCINTMSK_AHBERR |
  1233. USB_OTG_HCINTMSK_FRMORM;
  1234. if ((epnum & 0x80U) == 0x80U)
  1235. {
  1236. USBx_HC((uint32_t)ch_num)->HCINTMSK |= USB_OTG_HCINTMSK_BBERRM;
  1237. }
  1238. break;
  1239. case EP_TYPE_ISOC:
  1240. USBx_HC((uint32_t)ch_num)->HCINTMSK = USB_OTG_HCINTMSK_XFRCM |
  1241. USB_OTG_HCINTMSK_ACKM |
  1242. USB_OTG_HCINTMSK_AHBERR |
  1243. USB_OTG_HCINTMSK_FRMORM;
  1244. if ((epnum & 0x80U) == 0x80U)
  1245. {
  1246. USBx_HC((uint32_t)ch_num)->HCINTMSK |= (USB_OTG_HCINTMSK_TXERRM | USB_OTG_HCINTMSK_BBERRM);
  1247. }
  1248. break;
  1249. default:
  1250. ret = HAL_ERROR;
  1251. break;
  1252. }
  1253. /* Enable the top level host channel interrupt. */
  1254. USBx_HOST->HAINTMSK |= 1UL << (ch_num & 0xFU);
  1255. /* Make sure host channel interrupts are enabled. */
  1256. USBx->GINTMSK |= USB_OTG_GINTMSK_HCIM;
  1257. /* Program the HCCHAR register */
  1258. if ((epnum & 0x80U) == 0x80U)
  1259. {
  1260. HCcharEpDir = (0x1U << 15) & USB_OTG_HCCHAR_EPDIR;
  1261. }
  1262. else
  1263. {
  1264. HCcharEpDir = 0U;
  1265. }
  1266. if (speed == HPRT0_PRTSPD_LOW_SPEED)
  1267. {
  1268. HCcharLowSpeed = (0x1U << 17) & USB_OTG_HCCHAR_LSDEV;
  1269. }
  1270. else
  1271. {
  1272. HCcharLowSpeed = 0U;
  1273. }
  1274. USBx_HC((uint32_t)ch_num)->HCCHAR = (((uint32_t)dev_address << 22) & USB_OTG_HCCHAR_DAD) |
  1275. ((((uint32_t)epnum & 0x7FU) << 11) & USB_OTG_HCCHAR_EPNUM) |
  1276. (((uint32_t)ep_type << 18) & USB_OTG_HCCHAR_EPTYP) |
  1277. ((uint32_t)mps & USB_OTG_HCCHAR_MPSIZ) | HCcharEpDir | HCcharLowSpeed;
  1278. if (ep_type == EP_TYPE_INTR)
  1279. {
  1280. USBx_HC((uint32_t)ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM ;
  1281. }
  1282. return ret;
  1283. }
  1284. /**
  1285. * @brief Start a transfer over a host channel
  1286. * @param USBx Selected device
  1287. * @param hc pointer to host channel structure
  1288. * @retval HAL state
  1289. */
  1290. HAL_StatusTypeDef USB_HC_StartXfer(USB_OTG_GlobalTypeDef *USBx, USB_OTG_HCTypeDef *hc)
  1291. {
  1292. uint32_t USBx_BASE = (uint32_t)USBx;
  1293. uint32_t ch_num = (uint32_t)hc->ch_num;
  1294. static __IO uint32_t tmpreg = 0U;
  1295. uint8_t is_oddframe;
  1296. uint16_t len_words;
  1297. uint16_t num_packets;
  1298. uint16_t max_hc_pkt_count = 256U;
  1299. /* Compute the expected number of packets associated to the transfer */
  1300. if (hc->xfer_len > 0U)
  1301. {
  1302. num_packets = (uint16_t)((hc->xfer_len + hc->max_packet - 1U) / hc->max_packet);
  1303. if (num_packets > max_hc_pkt_count)
  1304. {
  1305. num_packets = max_hc_pkt_count;
  1306. hc->xfer_len = (uint32_t)num_packets * hc->max_packet;
  1307. }
  1308. }
  1309. else
  1310. {
  1311. num_packets = 1U;
  1312. }
  1313. if (hc->ep_is_in != 0U)
  1314. {
  1315. hc->xfer_len = (uint32_t)num_packets * hc->max_packet;
  1316. }
  1317. /* Initialize the HCTSIZn register */
  1318. USBx_HC(ch_num)->HCTSIZ = (hc->xfer_len & USB_OTG_HCTSIZ_XFRSIZ) |
  1319. (((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
  1320. (((uint32_t)hc->data_pid << 29) & USB_OTG_HCTSIZ_DPID);
  1321. is_oddframe = (((uint32_t)USBx_HOST->HFNUM & 0x01U) != 0U) ? 0U : 1U;
  1322. USBx_HC(ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_ODDFRM;
  1323. USBx_HC(ch_num)->HCCHAR |= (uint32_t)is_oddframe << 29;
  1324. /* Set host channel enable */
  1325. tmpreg = USBx_HC(ch_num)->HCCHAR;
  1326. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1327. /* make sure to set the correct ep direction */
  1328. if (hc->ep_is_in != 0U)
  1329. {
  1330. tmpreg |= USB_OTG_HCCHAR_EPDIR;
  1331. }
  1332. else
  1333. {
  1334. tmpreg &= ~USB_OTG_HCCHAR_EPDIR;
  1335. }
  1336. tmpreg |= USB_OTG_HCCHAR_CHENA;
  1337. USBx_HC(ch_num)->HCCHAR = tmpreg;
  1338. if ((hc->ep_is_in == 0U) && (hc->xfer_len > 0U))
  1339. {
  1340. switch (hc->ep_type)
  1341. {
  1342. /* Non periodic transfer */
  1343. case EP_TYPE_CTRL:
  1344. case EP_TYPE_BULK:
  1345. len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
  1346. /* check if there is enough space in FIFO space */
  1347. if (len_words > (USBx->HNPTXSTS & 0xFFFFU))
  1348. {
  1349. /* need to process data in nptxfempty interrupt */
  1350. USBx->GINTMSK |= USB_OTG_GINTMSK_NPTXFEM;
  1351. }
  1352. break;
  1353. /* Periodic transfer */
  1354. case EP_TYPE_INTR:
  1355. case EP_TYPE_ISOC:
  1356. len_words = (uint16_t)((hc->xfer_len + 3U) / 4U);
  1357. /* check if there is enough space in FIFO space */
  1358. if (len_words > (USBx_HOST->HPTXSTS & 0xFFFFU)) /* split the transfer */
  1359. {
  1360. /* need to process data in ptxfempty interrupt */
  1361. USBx->GINTMSK |= USB_OTG_GINTMSK_PTXFEM;
  1362. }
  1363. break;
  1364. default:
  1365. break;
  1366. }
  1367. /* Write packet into the Tx FIFO. */
  1368. (void)USB_WritePacket(USBx, hc->xfer_buff, hc->ch_num, (uint16_t)hc->xfer_len);
  1369. }
  1370. return HAL_OK;
  1371. }
  1372. /**
  1373. * @brief Read all host channel interrupts status
  1374. * @param USBx Selected device
  1375. * @retval HAL state
  1376. */
  1377. uint32_t USB_HC_ReadInterrupt(USB_OTG_GlobalTypeDef *USBx)
  1378. {
  1379. uint32_t USBx_BASE = (uint32_t)USBx;
  1380. return ((USBx_HOST->HAINT) & 0xFFFFU);
  1381. }
  1382. /**
  1383. * @brief Halt a host channel
  1384. * @param USBx Selected device
  1385. * @param hc_num Host Channel number
  1386. * This parameter can be a value from 1 to 15
  1387. * @retval HAL state
  1388. */
  1389. HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx, uint8_t hc_num)
  1390. {
  1391. uint32_t USBx_BASE = (uint32_t)USBx;
  1392. uint32_t hcnum = (uint32_t)hc_num;
  1393. uint32_t count = 0U;
  1394. uint32_t HcEpType = (USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_EPTYP) >> 18;
  1395. /* Check for space in the request queue to issue the halt. */
  1396. if ((HcEpType == HCCHAR_CTRL) || (HcEpType == HCCHAR_BULK))
  1397. {
  1398. USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
  1399. if ((USBx->HNPTXSTS & (0xFFU << 16)) == 0U)
  1400. {
  1401. USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
  1402. USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
  1403. USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
  1404. do
  1405. {
  1406. if (++count > 1000U)
  1407. {
  1408. break;
  1409. }
  1410. } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
  1411. }
  1412. else
  1413. {
  1414. USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
  1415. }
  1416. }
  1417. else
  1418. {
  1419. USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHDIS;
  1420. if ((USBx_HOST->HPTXSTS & (0xFFU << 16)) == 0U)
  1421. {
  1422. USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA;
  1423. USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
  1424. USBx_HC(hcnum)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR;
  1425. do
  1426. {
  1427. if (++count > 1000U)
  1428. {
  1429. break;
  1430. }
  1431. } while ((USBx_HC(hcnum)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
  1432. }
  1433. else
  1434. {
  1435. USBx_HC(hcnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
  1436. }
  1437. }
  1438. return HAL_OK;
  1439. }
  1440. /**
  1441. * @brief Initiate Do Ping protocol
  1442. * @param USBx Selected device
  1443. * @param hc_num Host Channel number
  1444. * This parameter can be a value from 1 to 15
  1445. * @retval HAL state
  1446. */
  1447. HAL_StatusTypeDef USB_DoPing(USB_OTG_GlobalTypeDef *USBx, uint8_t ch_num)
  1448. {
  1449. uint32_t USBx_BASE = (uint32_t)USBx;
  1450. uint32_t chnum = (uint32_t)ch_num;
  1451. uint32_t num_packets = 1U;
  1452. uint32_t tmpreg;
  1453. USBx_HC(chnum)->HCTSIZ = ((num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
  1454. USB_OTG_HCTSIZ_DOPING;
  1455. /* Set host channel enable */
  1456. tmpreg = USBx_HC(chnum)->HCCHAR;
  1457. tmpreg &= ~USB_OTG_HCCHAR_CHDIS;
  1458. tmpreg |= USB_OTG_HCCHAR_CHENA;
  1459. USBx_HC(chnum)->HCCHAR = tmpreg;
  1460. return HAL_OK;
  1461. }
  1462. /**
  1463. * @brief Stop Host Core
  1464. * @param USBx Selected device
  1465. * @retval HAL state
  1466. */
  1467. HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx)
  1468. {
  1469. uint32_t USBx_BASE = (uint32_t)USBx;
  1470. uint32_t count = 0U;
  1471. uint32_t value;
  1472. uint32_t i;
  1473. (void)USB_DisableGlobalInt(USBx);
  1474. /* Flush FIFO */
  1475. (void)USB_FlushTxFifo(USBx, 0x10U);
  1476. (void)USB_FlushRxFifo(USBx);
  1477. /* Flush out any leftover queued requests. */
  1478. for (i = 0U; i <= 15U; i++)
  1479. {
  1480. value = USBx_HC(i)->HCCHAR;
  1481. value |= USB_OTG_HCCHAR_CHDIS;
  1482. value &= ~USB_OTG_HCCHAR_CHENA;
  1483. value &= ~USB_OTG_HCCHAR_EPDIR;
  1484. USBx_HC(i)->HCCHAR = value;
  1485. }
  1486. /* Halt all channels to put them into a known state. */
  1487. for (i = 0U; i <= 15U; i++)
  1488. {
  1489. value = USBx_HC(i)->HCCHAR;
  1490. value |= USB_OTG_HCCHAR_CHDIS;
  1491. value |= USB_OTG_HCCHAR_CHENA;
  1492. value &= ~USB_OTG_HCCHAR_EPDIR;
  1493. USBx_HC(i)->HCCHAR = value;
  1494. do
  1495. {
  1496. if (++count > 1000U)
  1497. {
  1498. break;
  1499. }
  1500. } while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA);
  1501. }
  1502. /* Clear any pending Host interrupts */
  1503. USBx_HOST->HAINT = 0xFFFFFFFFU;
  1504. USBx->GINTSTS = 0xFFFFFFFFU;
  1505. (void)USB_EnableGlobalInt(USBx);
  1506. return HAL_OK;
  1507. }
  1508. /**
  1509. * @brief USB_ActivateRemoteWakeup active remote wakeup signalling
  1510. * @param USBx Selected device
  1511. * @retval HAL status
  1512. */
  1513. HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
  1514. {
  1515. uint32_t USBx_BASE = (uint32_t)USBx;
  1516. if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
  1517. {
  1518. /* active Remote wakeup signalling */
  1519. USBx_DEVICE->DCTL |= USB_OTG_DCTL_RWUSIG;
  1520. }
  1521. return HAL_OK;
  1522. }
  1523. /**
  1524. * @brief USB_DeActivateRemoteWakeup de-active remote wakeup signalling
  1525. * @param USBx Selected device
  1526. * @retval HAL status
  1527. */
  1528. HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_OTG_GlobalTypeDef *USBx)
  1529. {
  1530. uint32_t USBx_BASE = (uint32_t)USBx;
  1531. /* active Remote wakeup signalling */
  1532. USBx_DEVICE->DCTL &= ~(USB_OTG_DCTL_RWUSIG);
  1533. return HAL_OK;
  1534. }
  1535. #endif /* defined (USB_OTG_FS) */
  1536. #if defined (USB)
  1537. /**
  1538. * @brief Initializes the USB Core
  1539. * @param USBx USB Instance
  1540. * @param cfg pointer to a USB_CfgTypeDef structure that contains
  1541. * the configuration information for the specified USBx peripheral.
  1542. * @retval HAL status
  1543. */
  1544. HAL_StatusTypeDef USB_CoreInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
  1545. {
  1546. /* Prevent unused argument(s) compilation warning */
  1547. UNUSED(USBx);
  1548. UNUSED(cfg);
  1549. /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  1550. only by USB OTG FS peripheral.
  1551. - This function is added to ensure compatibility across platforms.
  1552. */
  1553. return HAL_OK;
  1554. }
  1555. /**
  1556. * @brief USB_EnableGlobalInt
  1557. * Enables the controller's Global Int in the AHB Config reg
  1558. * @param USBx Selected device
  1559. * @retval HAL status
  1560. */
  1561. HAL_StatusTypeDef USB_EnableGlobalInt(USB_TypeDef *USBx)
  1562. {
  1563. uint32_t winterruptmask;
  1564. /* Clear pending interrupts */
  1565. USBx->ISTR = 0U;
  1566. /* Set winterruptmask variable */
  1567. winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM |
  1568. USB_CNTR_SUSPM | USB_CNTR_ERRM |
  1569. USB_CNTR_SOFM | USB_CNTR_ESOFM |
  1570. USB_CNTR_RESETM;
  1571. /* Set interrupt mask */
  1572. USBx->CNTR = (uint16_t)winterruptmask;
  1573. return HAL_OK;
  1574. }
  1575. /**
  1576. * @brief USB_DisableGlobalInt
  1577. * Disable the controller's Global Int in the AHB Config reg
  1578. * @param USBx Selected device
  1579. * @retval HAL status
  1580. */
  1581. HAL_StatusTypeDef USB_DisableGlobalInt(USB_TypeDef *USBx)
  1582. {
  1583. uint32_t winterruptmask;
  1584. /* Set winterruptmask variable */
  1585. winterruptmask = USB_CNTR_CTRM | USB_CNTR_WKUPM |
  1586. USB_CNTR_SUSPM | USB_CNTR_ERRM |
  1587. USB_CNTR_SOFM | USB_CNTR_ESOFM |
  1588. USB_CNTR_RESETM;
  1589. /* Clear interrupt mask */
  1590. USBx->CNTR &= (uint16_t)(~winterruptmask);
  1591. return HAL_OK;
  1592. }
  1593. /**
  1594. * @brief USB_SetCurrentMode Set functional mode
  1595. * @param USBx Selected device
  1596. * @param mode current core mode
  1597. * This parameter can be one of the these values:
  1598. * @arg USB_DEVICE_MODE Peripheral mode
  1599. * @retval HAL status
  1600. */
  1601. HAL_StatusTypeDef USB_SetCurrentMode(USB_TypeDef *USBx, USB_ModeTypeDef mode)
  1602. {
  1603. /* Prevent unused argument(s) compilation warning */
  1604. UNUSED(USBx);
  1605. UNUSED(mode);
  1606. /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  1607. only by USB OTG FS peripheral.
  1608. - This function is added to ensure compatibility across platforms.
  1609. */
  1610. return HAL_OK;
  1611. }
  1612. /**
  1613. * @brief USB_DevInit Initializes the USB controller registers
  1614. * for device mode
  1615. * @param USBx Selected device
  1616. * @param cfg pointer to a USB_CfgTypeDef structure that contains
  1617. * the configuration information for the specified USBx peripheral.
  1618. * @retval HAL status
  1619. */
  1620. HAL_StatusTypeDef USB_DevInit(USB_TypeDef *USBx, USB_CfgTypeDef cfg)
  1621. {
  1622. /* Prevent unused argument(s) compilation warning */
  1623. UNUSED(cfg);
  1624. /* Init Device */
  1625. /* CNTR_FRES = 1 */
  1626. USBx->CNTR = (uint16_t)USB_CNTR_FRES;
  1627. /* CNTR_FRES = 0 */
  1628. USBx->CNTR = 0U;
  1629. /* Clear pending interrupts */
  1630. USBx->ISTR = 0U;
  1631. /*Set Btable Address*/
  1632. USBx->BTABLE = BTABLE_ADDRESS;
  1633. return HAL_OK;
  1634. }
  1635. /**
  1636. * @brief USB_FlushTxFifo : Flush a Tx FIFO
  1637. * @param USBx : Selected device
  1638. * @param num : FIFO number
  1639. * This parameter can be a value from 1 to 15
  1640. 15 means Flush all Tx FIFOs
  1641. * @retval HAL status
  1642. */
  1643. HAL_StatusTypeDef USB_FlushTxFifo(USB_TypeDef *USBx, uint32_t num)
  1644. {
  1645. /* Prevent unused argument(s) compilation warning */
  1646. UNUSED(USBx);
  1647. UNUSED(num);
  1648. /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  1649. only by USB OTG FS peripheral.
  1650. - This function is added to ensure compatibility across platforms.
  1651. */
  1652. return HAL_OK;
  1653. }
  1654. /**
  1655. * @brief USB_FlushRxFifo : Flush Rx FIFO
  1656. * @param USBx : Selected device
  1657. * @retval HAL status
  1658. */
  1659. HAL_StatusTypeDef USB_FlushRxFifo(USB_TypeDef *USBx)
  1660. {
  1661. /* Prevent unused argument(s) compilation warning */
  1662. UNUSED(USBx);
  1663. /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  1664. only by USB OTG FS peripheral.
  1665. - This function is added to ensure compatibility across platforms.
  1666. */
  1667. return HAL_OK;
  1668. }
  1669. /**
  1670. * @brief Activate and configure an endpoint
  1671. * @param USBx Selected device
  1672. * @param ep pointer to endpoint structure
  1673. * @retval HAL status
  1674. */
  1675. HAL_StatusTypeDef USB_ActivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  1676. {
  1677. HAL_StatusTypeDef ret = HAL_OK;
  1678. uint16_t wEpRegVal;
  1679. wEpRegVal = PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_T_MASK;
  1680. /* initialize Endpoint */
  1681. switch (ep->type)
  1682. {
  1683. case EP_TYPE_CTRL:
  1684. wEpRegVal |= USB_EP_CONTROL;
  1685. break;
  1686. case EP_TYPE_BULK:
  1687. wEpRegVal |= USB_EP_BULK;
  1688. break;
  1689. case EP_TYPE_INTR:
  1690. wEpRegVal |= USB_EP_INTERRUPT;
  1691. break;
  1692. case EP_TYPE_ISOC:
  1693. wEpRegVal |= USB_EP_ISOCHRONOUS;
  1694. break;
  1695. default:
  1696. ret = HAL_ERROR;
  1697. break;
  1698. }
  1699. PCD_SET_ENDPOINT(USBx, ep->num, (wEpRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX));
  1700. PCD_SET_EP_ADDRESS(USBx, ep->num, ep->num);
  1701. if (ep->doublebuffer == 0U)
  1702. {
  1703. if (ep->is_in != 0U)
  1704. {
  1705. /*Set the endpoint Transmit buffer address */
  1706. PCD_SET_EP_TX_ADDRESS(USBx, ep->num, ep->pmaadress);
  1707. PCD_CLEAR_TX_DTOG(USBx, ep->num);
  1708. if (ep->type != EP_TYPE_ISOC)
  1709. {
  1710. /* Configure NAK status for the Endpoint */
  1711. PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
  1712. }
  1713. else
  1714. {
  1715. /* Configure TX Endpoint to disabled state */
  1716. PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  1717. }
  1718. }
  1719. else
  1720. {
  1721. /*Set the endpoint Receive buffer address */
  1722. PCD_SET_EP_RX_ADDRESS(USBx, ep->num, ep->pmaadress);
  1723. /*Set the endpoint Receive buffer counter*/
  1724. PCD_SET_EP_RX_CNT(USBx, ep->num, ep->maxpacket);
  1725. PCD_CLEAR_RX_DTOG(USBx, ep->num);
  1726. /* Configure VALID status for the Endpoint*/
  1727. PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
  1728. }
  1729. }
  1730. /*Double Buffer*/
  1731. else
  1732. {
  1733. /* Set the endpoint as double buffered */
  1734. PCD_SET_EP_DBUF(USBx, ep->num);
  1735. /* Set buffer address for double buffered mode */
  1736. PCD_SET_EP_DBUF_ADDR(USBx, ep->num, ep->pmaaddr0, ep->pmaaddr1);
  1737. if (ep->is_in == 0U)
  1738. {
  1739. /* Clear the data toggle bits for the endpoint IN/OUT */
  1740. PCD_CLEAR_RX_DTOG(USBx, ep->num);
  1741. PCD_CLEAR_TX_DTOG(USBx, ep->num);
  1742. PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
  1743. PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  1744. }
  1745. else
  1746. {
  1747. /* Clear the data toggle bits for the endpoint IN/OUT */
  1748. PCD_CLEAR_RX_DTOG(USBx, ep->num);
  1749. PCD_CLEAR_TX_DTOG(USBx, ep->num);
  1750. if (ep->type != EP_TYPE_ISOC)
  1751. {
  1752. /* Configure NAK status for the Endpoint */
  1753. PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
  1754. }
  1755. else
  1756. {
  1757. /* Configure TX Endpoint to disabled state */
  1758. PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  1759. }
  1760. PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
  1761. }
  1762. }
  1763. return ret;
  1764. }
  1765. /**
  1766. * @brief De-activate and de-initialize an endpoint
  1767. * @param USBx Selected device
  1768. * @param ep pointer to endpoint structure
  1769. * @retval HAL status
  1770. */
  1771. HAL_StatusTypeDef USB_DeactivateEndpoint(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  1772. {
  1773. if (ep->doublebuffer == 0U)
  1774. {
  1775. if (ep->is_in != 0U)
  1776. {
  1777. PCD_CLEAR_TX_DTOG(USBx, ep->num);
  1778. /* Configure DISABLE status for the Endpoint*/
  1779. PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  1780. }
  1781. else
  1782. {
  1783. PCD_CLEAR_RX_DTOG(USBx, ep->num);
  1784. /* Configure DISABLE status for the Endpoint*/
  1785. PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
  1786. }
  1787. }
  1788. /*Double Buffer*/
  1789. else
  1790. {
  1791. if (ep->is_in == 0U)
  1792. {
  1793. /* Clear the data toggle bits for the endpoint IN/OUT*/
  1794. PCD_CLEAR_RX_DTOG(USBx, ep->num);
  1795. PCD_CLEAR_TX_DTOG(USBx, ep->num);
  1796. /* Reset value of the data toggle bits for the endpoint out*/
  1797. PCD_TX_DTOG(USBx, ep->num);
  1798. PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
  1799. PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  1800. }
  1801. else
  1802. {
  1803. /* Clear the data toggle bits for the endpoint IN/OUT*/
  1804. PCD_CLEAR_RX_DTOG(USBx, ep->num);
  1805. PCD_CLEAR_TX_DTOG(USBx, ep->num);
  1806. PCD_RX_DTOG(USBx, ep->num);
  1807. /* Configure DISABLE status for the Endpoint*/
  1808. PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_DIS);
  1809. PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_DIS);
  1810. }
  1811. }
  1812. return HAL_OK;
  1813. }
  1814. /**
  1815. * @brief USB_EPStartXfer setup and starts a transfer over an EP
  1816. * @param USBx Selected device
  1817. * @param ep pointer to endpoint structure
  1818. * @retval HAL status
  1819. */
  1820. HAL_StatusTypeDef USB_EPStartXfer(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  1821. {
  1822. uint32_t len;
  1823. uint16_t pmabuffer;
  1824. uint16_t wEPVal;
  1825. /* IN endpoint */
  1826. if (ep->is_in == 1U)
  1827. {
  1828. /*Multi packet transfer*/
  1829. if (ep->xfer_len > ep->maxpacket)
  1830. {
  1831. len = ep->maxpacket;
  1832. }
  1833. else
  1834. {
  1835. len = ep->xfer_len;
  1836. }
  1837. /* configure and validate Tx endpoint */
  1838. if (ep->doublebuffer == 0U)
  1839. {
  1840. USB_WritePMA(USBx, ep->xfer_buff, ep->pmaadress, (uint16_t)len);
  1841. PCD_SET_EP_TX_CNT(USBx, ep->num, len);
  1842. }
  1843. else
  1844. {
  1845. /* double buffer bulk management */
  1846. if (ep->type == EP_TYPE_BULK)
  1847. {
  1848. if (ep->xfer_len_db > ep->maxpacket)
  1849. {
  1850. /* enable double buffer */
  1851. PCD_SET_EP_DBUF(USBx, ep->num);
  1852. /* each Time to write in PMA xfer_len_db will */
  1853. ep->xfer_len_db -= len;
  1854. /* Fill the two first buffer in the Buffer0 & Buffer1 */
  1855. if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
  1856. {
  1857. /* Set the Double buffer counter for pmabuffer1 */
  1858. PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
  1859. pmabuffer = ep->pmaaddr1;
  1860. /* Write the user buffer to USB PMA */
  1861. USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  1862. ep->xfer_buff += len;
  1863. if (ep->xfer_len_db > ep->maxpacket)
  1864. {
  1865. ep->xfer_len_db -= len;
  1866. }
  1867. else
  1868. {
  1869. len = ep->xfer_len_db;
  1870. ep->xfer_len_db = 0U;
  1871. }
  1872. /* Set the Double buffer counter for pmabuffer0 */
  1873. PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
  1874. pmabuffer = ep->pmaaddr0;
  1875. /* Write the user buffer to USB PMA */
  1876. USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  1877. }
  1878. else
  1879. {
  1880. /* Set the Double buffer counter for pmabuffer0 */
  1881. PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
  1882. pmabuffer = ep->pmaaddr0;
  1883. /* Write the user buffer to USB PMA */
  1884. USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  1885. ep->xfer_buff += len;
  1886. if (ep->xfer_len_db > ep->maxpacket)
  1887. {
  1888. ep->xfer_len_db -= len;
  1889. }
  1890. else
  1891. {
  1892. len = ep->xfer_len_db;
  1893. ep->xfer_len_db = 0U;
  1894. }
  1895. /* Set the Double buffer counter for pmabuffer1 */
  1896. PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
  1897. pmabuffer = ep->pmaaddr1;
  1898. /* Write the user buffer to USB PMA */
  1899. USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  1900. }
  1901. }
  1902. /* auto Switch to single buffer mode when transfer <Mps no need to manage in double buffer */
  1903. else
  1904. {
  1905. len = ep->xfer_len_db;
  1906. /* disable double buffer mode */
  1907. PCD_CLEAR_EP_DBUF(USBx, ep->num);
  1908. /* Set Tx count with nbre of byte to be transmitted */
  1909. PCD_SET_EP_TX_CNT(USBx, ep->num, len);
  1910. pmabuffer = ep->pmaaddr0;
  1911. /* Write the user buffer to USB PMA */
  1912. USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  1913. }
  1914. }/* end if bulk double buffer */
  1915. /* manage isochronous double buffer IN mode */
  1916. else
  1917. {
  1918. /* Write the data to the USB endpoint */
  1919. if ((PCD_GET_ENDPOINT(USBx, ep->num) & USB_EP_DTOG_TX) != 0U)
  1920. {
  1921. /* Set the Double buffer counter for pmabuffer1 */
  1922. PCD_SET_EP_DBUF1_CNT(USBx, ep->num, ep->is_in, len);
  1923. pmabuffer = ep->pmaaddr1;
  1924. }
  1925. else
  1926. {
  1927. /* Set the Double buffer counter for pmabuffer0 */
  1928. PCD_SET_EP_DBUF0_CNT(USBx, ep->num, ep->is_in, len);
  1929. pmabuffer = ep->pmaaddr0;
  1930. }
  1931. USB_WritePMA(USBx, ep->xfer_buff, pmabuffer, (uint16_t)len);
  1932. PCD_FreeUserBuffer(USBx, ep->num, ep->is_in);
  1933. }
  1934. }
  1935. PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_VALID);
  1936. }
  1937. else /* OUT endpoint */
  1938. {
  1939. if (ep->doublebuffer == 0U)
  1940. {
  1941. /* Multi packet transfer */
  1942. if (ep->xfer_len > ep->maxpacket)
  1943. {
  1944. len = ep->maxpacket;
  1945. ep->xfer_len -= len;
  1946. }
  1947. else
  1948. {
  1949. len = ep->xfer_len;
  1950. ep->xfer_len = 0U;
  1951. }
  1952. /* configure and validate Rx endpoint */
  1953. PCD_SET_EP_RX_CNT(USBx, ep->num, len);
  1954. }
  1955. else
  1956. {
  1957. /* First Transfer Coming From HAL_PCD_EP_Receive & From ISR */
  1958. /* Set the Double buffer counter */
  1959. if (ep->type == EP_TYPE_BULK)
  1960. {
  1961. PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, ep->maxpacket);
  1962. /* Coming from ISR */
  1963. if (ep->xfer_count != 0U)
  1964. {
  1965. /* update last value to check if there is blocking state */
  1966. wEPVal = PCD_GET_ENDPOINT(USBx, ep->num);
  1967. /*Blocking State */
  1968. if ((((wEPVal & USB_EP_DTOG_RX) != 0U) && ((wEPVal & USB_EP_DTOG_TX) != 0U)) ||
  1969. (((wEPVal & USB_EP_DTOG_RX) == 0U) && ((wEPVal & USB_EP_DTOG_TX) == 0U)))
  1970. {
  1971. PCD_FreeUserBuffer(USBx, ep->num, 0U);
  1972. }
  1973. }
  1974. }
  1975. /* iso out double */
  1976. else if (ep->type == EP_TYPE_ISOC)
  1977. {
  1978. /* Multi packet transfer */
  1979. if (ep->xfer_len > ep->maxpacket)
  1980. {
  1981. len = ep->maxpacket;
  1982. ep->xfer_len -= len;
  1983. }
  1984. else
  1985. {
  1986. len = ep->xfer_len;
  1987. ep->xfer_len = 0U;
  1988. }
  1989. PCD_SET_EP_DBUF_CNT(USBx, ep->num, ep->is_in, len);
  1990. }
  1991. else
  1992. {
  1993. return HAL_ERROR;
  1994. }
  1995. }
  1996. PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
  1997. }
  1998. return HAL_OK;
  1999. }
  2000. /**
  2001. * @brief USB_EPSetStall set a stall condition over an EP
  2002. * @param USBx Selected device
  2003. * @param ep pointer to endpoint structure
  2004. * @retval HAL status
  2005. */
  2006. HAL_StatusTypeDef USB_EPSetStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  2007. {
  2008. if (ep->is_in != 0U)
  2009. {
  2010. PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_STALL);
  2011. }
  2012. else
  2013. {
  2014. PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_STALL);
  2015. }
  2016. return HAL_OK;
  2017. }
  2018. /**
  2019. * @brief USB_EPClearStall Clear a stall condition over an EP
  2020. * @param USBx Selected device
  2021. * @param ep pointer to endpoint structure
  2022. * @retval HAL status
  2023. */
  2024. HAL_StatusTypeDef USB_EPClearStall(USB_TypeDef *USBx, USB_EPTypeDef *ep)
  2025. {
  2026. if (ep->doublebuffer == 0U)
  2027. {
  2028. if (ep->is_in != 0U)
  2029. {
  2030. PCD_CLEAR_TX_DTOG(USBx, ep->num);
  2031. if (ep->type != EP_TYPE_ISOC)
  2032. {
  2033. /* Configure NAK status for the Endpoint */
  2034. PCD_SET_EP_TX_STATUS(USBx, ep->num, USB_EP_TX_NAK);
  2035. }
  2036. }
  2037. else
  2038. {
  2039. PCD_CLEAR_RX_DTOG(USBx, ep->num);
  2040. /* Configure VALID status for the Endpoint */
  2041. PCD_SET_EP_RX_STATUS(USBx, ep->num, USB_EP_RX_VALID);
  2042. }
  2043. }
  2044. return HAL_OK;
  2045. }
  2046. /**
  2047. * @brief USB_StopDevice Stop the usb device mode
  2048. * @param USBx Selected device
  2049. * @retval HAL status
  2050. */
  2051. HAL_StatusTypeDef USB_StopDevice(USB_TypeDef *USBx)
  2052. {
  2053. /* disable all interrupts and force USB reset */
  2054. USBx->CNTR = (uint16_t)USB_CNTR_FRES;
  2055. /* clear interrupt status register */
  2056. USBx->ISTR = 0U;
  2057. /* switch-off device */
  2058. USBx->CNTR = (uint16_t)(USB_CNTR_FRES | USB_CNTR_PDWN);
  2059. return HAL_OK;
  2060. }
  2061. /**
  2062. * @brief USB_SetDevAddress Stop the usb device mode
  2063. * @param USBx Selected device
  2064. * @param address new device address to be assigned
  2065. * This parameter can be a value from 0 to 255
  2066. * @retval HAL status
  2067. */
  2068. HAL_StatusTypeDef USB_SetDevAddress(USB_TypeDef *USBx, uint8_t address)
  2069. {
  2070. if (address == 0U)
  2071. {
  2072. /* set device address and enable function */
  2073. USBx->DADDR = (uint16_t)USB_DADDR_EF;
  2074. }
  2075. return HAL_OK;
  2076. }
  2077. /**
  2078. * @brief USB_DevConnect Connect the USB device by enabling the pull-up/pull-down
  2079. * @param USBx Selected device
  2080. * @retval HAL status
  2081. */
  2082. HAL_StatusTypeDef USB_DevConnect(USB_TypeDef *USBx)
  2083. {
  2084. /* Prevent unused argument(s) compilation warning */
  2085. UNUSED(USBx);
  2086. /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  2087. only by USB OTG FS peripheral.
  2088. - This function is added to ensure compatibility across platforms.
  2089. */
  2090. return HAL_OK;
  2091. }
  2092. /**
  2093. * @brief USB_DevDisconnect Disconnect the USB device by disabling the pull-up/pull-down
  2094. * @param USBx Selected device
  2095. * @retval HAL status
  2096. */
  2097. HAL_StatusTypeDef USB_DevDisconnect(USB_TypeDef *USBx)
  2098. {
  2099. /* Prevent unused argument(s) compilation warning */
  2100. UNUSED(USBx);
  2101. /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  2102. only by USB OTG FS peripheral.
  2103. - This function is added to ensure compatibility across platforms.
  2104. */
  2105. return HAL_OK;
  2106. }
  2107. /**
  2108. * @brief USB_ReadInterrupts return the global USB interrupt status
  2109. * @param USBx Selected device
  2110. * @retval HAL status
  2111. */
  2112. uint32_t USB_ReadInterrupts(USB_TypeDef *USBx)
  2113. {
  2114. uint32_t tmpreg;
  2115. tmpreg = USBx->ISTR;
  2116. return tmpreg;
  2117. }
  2118. /**
  2119. * @brief USB_ReadDevAllOutEpInterrupt return the USB device OUT endpoints interrupt status
  2120. * @param USBx Selected device
  2121. * @retval HAL status
  2122. */
  2123. uint32_t USB_ReadDevAllOutEpInterrupt(USB_TypeDef *USBx)
  2124. {
  2125. /* Prevent unused argument(s) compilation warning */
  2126. UNUSED(USBx);
  2127. /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  2128. only by USB OTG FS peripheral.
  2129. - This function is added to ensure compatibility across platforms.
  2130. */
  2131. return (0);
  2132. }
  2133. /**
  2134. * @brief USB_ReadDevAllInEpInterrupt return the USB device IN endpoints interrupt status
  2135. * @param USBx Selected device
  2136. * @retval HAL status
  2137. */
  2138. uint32_t USB_ReadDevAllInEpInterrupt(USB_TypeDef *USBx)
  2139. {
  2140. /* Prevent unused argument(s) compilation warning */
  2141. UNUSED(USBx);
  2142. /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  2143. only by USB OTG FS peripheral.
  2144. - This function is added to ensure compatibility across platforms.
  2145. */
  2146. return (0);
  2147. }
  2148. /**
  2149. * @brief Returns Device OUT EP Interrupt register
  2150. * @param USBx Selected device
  2151. * @param epnum endpoint number
  2152. * This parameter can be a value from 0 to 15
  2153. * @retval Device OUT EP Interrupt register
  2154. */
  2155. uint32_t USB_ReadDevOutEPInterrupt(USB_TypeDef *USBx, uint8_t epnum)
  2156. {
  2157. /* Prevent unused argument(s) compilation warning */
  2158. UNUSED(USBx);
  2159. UNUSED(epnum);
  2160. /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  2161. only by USB OTG FS peripheral.
  2162. - This function is added to ensure compatibility across platforms.
  2163. */
  2164. return (0);
  2165. }
  2166. /**
  2167. * @brief Returns Device IN EP Interrupt register
  2168. * @param USBx Selected device
  2169. * @param epnum endpoint number
  2170. * This parameter can be a value from 0 to 15
  2171. * @retval Device IN EP Interrupt register
  2172. */
  2173. uint32_t USB_ReadDevInEPInterrupt(USB_TypeDef *USBx, uint8_t epnum)
  2174. {
  2175. /* Prevent unused argument(s) compilation warning */
  2176. UNUSED(USBx);
  2177. UNUSED(epnum);
  2178. /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  2179. only by USB OTG FS peripheral.
  2180. - This function is added to ensure compatibility across platforms.
  2181. */
  2182. return (0);
  2183. }
  2184. /**
  2185. * @brief USB_ClearInterrupts: clear a USB interrupt
  2186. * @param USBx Selected device
  2187. * @param interrupt flag
  2188. * @retval None
  2189. */
  2190. void USB_ClearInterrupts(USB_TypeDef *USBx, uint32_t interrupt)
  2191. {
  2192. /* Prevent unused argument(s) compilation warning */
  2193. UNUSED(USBx);
  2194. UNUSED(interrupt);
  2195. /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  2196. only by USB OTG FS peripheral.
  2197. - This function is added to ensure compatibility across platforms.
  2198. */
  2199. }
  2200. /**
  2201. * @brief Prepare the EP0 to start the first control setup
  2202. * @param USBx Selected device
  2203. * @param psetup pointer to setup packet
  2204. * @retval HAL status
  2205. */
  2206. HAL_StatusTypeDef USB_EP0_OutStart(USB_TypeDef *USBx, uint8_t *psetup)
  2207. {
  2208. /* Prevent unused argument(s) compilation warning */
  2209. UNUSED(USBx);
  2210. UNUSED(psetup);
  2211. /* NOTE : - This function is not required by USB Device FS peripheral, it is used
  2212. only by USB OTG FS peripheral.
  2213. - This function is added to ensure compatibility across platforms.
  2214. */
  2215. return HAL_OK;
  2216. }
  2217. /**
  2218. * @brief USB_ActivateRemoteWakeup : active remote wakeup signalling
  2219. * @param USBx Selected device
  2220. * @retval HAL status
  2221. */
  2222. HAL_StatusTypeDef USB_ActivateRemoteWakeup(USB_TypeDef *USBx)
  2223. {
  2224. USBx->CNTR |= (uint16_t)USB_CNTR_RESUME;
  2225. return HAL_OK;
  2226. }
  2227. /**
  2228. * @brief USB_DeActivateRemoteWakeup de-active remote wakeup signalling
  2229. * @param USBx Selected device
  2230. * @retval HAL status
  2231. */
  2232. HAL_StatusTypeDef USB_DeActivateRemoteWakeup(USB_TypeDef *USBx)
  2233. {
  2234. USBx->CNTR &= (uint16_t)(~USB_CNTR_RESUME);
  2235. return HAL_OK;
  2236. }
  2237. /**
  2238. * @brief Copy a buffer from user memory area to packet memory area (PMA)
  2239. * @param USBx USB peripheral instance register address.
  2240. * @param pbUsrBuf pointer to user memory area.
  2241. * @param wPMABufAddr address into PMA.
  2242. * @param wNBytes no. of bytes to be copied.
  2243. * @retval None
  2244. */
  2245. void USB_WritePMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
  2246. {
  2247. uint32_t n = ((uint32_t)wNBytes + 1U) >> 1;
  2248. uint32_t BaseAddr = (uint32_t)USBx;
  2249. uint32_t i, temp1, temp2;
  2250. __IO uint16_t *pdwVal;
  2251. uint8_t *pBuf = pbUsrBuf;
  2252. pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
  2253. for (i = n; i != 0U; i--)
  2254. {
  2255. temp1 = *pBuf;
  2256. pBuf++;
  2257. temp2 = temp1 | ((uint16_t)((uint16_t) *pBuf << 8));
  2258. *pdwVal = (uint16_t)temp2;
  2259. pdwVal++;
  2260. #if PMA_ACCESS > 1U
  2261. pdwVal++;
  2262. #endif
  2263. pBuf++;
  2264. }
  2265. }
  2266. /**
  2267. * @brief Copy data from packet memory area (PMA) to user memory buffer
  2268. * @param USBx USB peripheral instance register address.
  2269. * @param pbUsrBuf pointer to user memory area.
  2270. * @param wPMABufAddr address into PMA.
  2271. * @param wNBytes no. of bytes to be copied.
  2272. * @retval None
  2273. */
  2274. void USB_ReadPMA(USB_TypeDef *USBx, uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
  2275. {
  2276. uint32_t n = (uint32_t)wNBytes >> 1;
  2277. uint32_t BaseAddr = (uint32_t)USBx;
  2278. uint32_t i, temp;
  2279. __IO uint16_t *pdwVal;
  2280. uint8_t *pBuf = pbUsrBuf;
  2281. pdwVal = (__IO uint16_t *)(BaseAddr + 0x400U + ((uint32_t)wPMABufAddr * PMA_ACCESS));
  2282. for (i = n; i != 0U; i--)
  2283. {
  2284. temp = *(__IO uint16_t *)pdwVal;
  2285. pdwVal++;
  2286. *pBuf = (uint8_t)((temp >> 0) & 0xFFU);
  2287. pBuf++;
  2288. *pBuf = (uint8_t)((temp >> 8) & 0xFFU);
  2289. pBuf++;
  2290. #if PMA_ACCESS > 1U
  2291. pdwVal++;
  2292. #endif
  2293. }
  2294. if ((wNBytes % 2U) != 0U)
  2295. {
  2296. temp = *pdwVal;
  2297. *pBuf = (uint8_t)((temp >> 0) & 0xFFU);
  2298. }
  2299. }
  2300. #endif /* defined (USB) */
  2301. /**
  2302. * @}
  2303. */
  2304. /**
  2305. * @}
  2306. */
  2307. #endif /* defined (USB) || defined (USB_OTG_FS) */
  2308. #endif /* defined (HAL_PCD_MODULE_ENABLED) || defined (HAL_HCD_MODULE_ENABLED) */
  2309. /**
  2310. * @}
  2311. */
  2312. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/