stm32f1xx_hal_pcd.c 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720
  1. /**
  2. ******************************************************************************
  3. * @file stm32f1xx_hal_pcd.c
  4. * @author MCD Application Team
  5. * @brief PCD HAL module driver.
  6. * This file provides firmware functions to manage the following
  7. * functionalities of the USB Peripheral Controller:
  8. * + Initialization and de-initialization functions
  9. * + IO operation functions
  10. * + Peripheral Control functions
  11. * + Peripheral State functions
  12. *
  13. ******************************************************************************
  14. * @attention
  15. *
  16. * Copyright (c) 2016 STMicroelectronics.
  17. * All rights reserved.
  18. *
  19. * This software is licensed under terms that can be found in the LICENSE file
  20. * in the root directory of this software component.
  21. * If no LICENSE file comes with this software, it is provided AS-IS.
  22. *
  23. ******************************************************************************
  24. @verbatim
  25. ==============================================================================
  26. ##### How to use this driver #####
  27. ==============================================================================
  28. [..]
  29. The PCD HAL driver can be used as follows:
  30. (#) Declare a PCD_HandleTypeDef handle structure, for example:
  31. PCD_HandleTypeDef hpcd;
  32. (#) Fill parameters of Init structure in HCD handle
  33. (#) Call HAL_PCD_Init() API to initialize the PCD peripheral (Core, Device core, ...)
  34. (#) Initialize the PCD low level resources through the HAL_PCD_MspInit() API:
  35. (##) Enable the PCD/USB Low Level interface clock using
  36. (+++) __HAL_RCC_USB_CLK_ENABLE(); For USB Device FS peripheral
  37. (+++) __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
  38. (##) Initialize the related GPIO clocks
  39. (##) Configure PCD pin-out
  40. (##) Configure PCD NVIC interrupt
  41. (#)Associate the Upper USB device stack to the HAL PCD Driver:
  42. (##) hpcd.pData = pdev;
  43. (#)Enable PCD transmission and reception:
  44. (##) HAL_PCD_Start();
  45. @endverbatim
  46. ******************************************************************************
  47. */
  48. /* Includes ------------------------------------------------------------------*/
  49. #include "stm32f1xx_hal.h"
  50. /** @addtogroup STM32F1xx_HAL_Driver
  51. * @{
  52. */
  53. /** @defgroup PCD PCD
  54. * @brief PCD HAL module driver
  55. * @{
  56. */
  57. #ifdef HAL_PCD_MODULE_ENABLED
  58. #if defined (USB) || defined (USB_OTG_FS)
  59. /* Private types -------------------------------------------------------------*/
  60. /* Private variables ---------------------------------------------------------*/
  61. /* Private constants ---------------------------------------------------------*/
  62. /* Private macros ------------------------------------------------------------*/
  63. /** @defgroup PCD_Private_Macros PCD Private Macros
  64. * @{
  65. */
  66. #define PCD_MIN(a, b) (((a) < (b)) ? (a) : (b))
  67. #define PCD_MAX(a, b) (((a) > (b)) ? (a) : (b))
  68. /**
  69. * @}
  70. */
  71. /* Private functions prototypes ----------------------------------------------*/
  72. /** @defgroup PCD_Private_Functions PCD Private Functions
  73. * @{
  74. */
  75. #if defined (USB_OTG_FS)
  76. static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum);
  77. static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
  78. static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum);
  79. #endif /* defined (USB_OTG_FS) */
  80. #if defined (USB)
  81. static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd);
  82. #if (USE_USB_DOUBLE_BUFFER == 1U)
  83. static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd, PCD_EPTypeDef *ep, uint16_t wEPVal);
  84. static uint16_t HAL_PCD_EP_DB_Receive(PCD_HandleTypeDef *hpcd, PCD_EPTypeDef *ep, uint16_t wEPVal);
  85. #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
  86. #endif /* defined (USB) */
  87. /**
  88. * @}
  89. */
  90. /* Exported functions --------------------------------------------------------*/
  91. /** @defgroup PCD_Exported_Functions PCD Exported Functions
  92. * @{
  93. */
  94. /** @defgroup PCD_Exported_Functions_Group1 Initialization and de-initialization functions
  95. * @brief Initialization and Configuration functions
  96. *
  97. @verbatim
  98. ===============================================================================
  99. ##### Initialization and de-initialization functions #####
  100. ===============================================================================
  101. [..] This section provides functions allowing to:
  102. @endverbatim
  103. * @{
  104. */
  105. /**
  106. * @brief Initializes the PCD according to the specified
  107. * parameters in the PCD_InitTypeDef and initialize the associated handle.
  108. * @param hpcd PCD handle
  109. * @retval HAL status
  110. */
  111. HAL_StatusTypeDef HAL_PCD_Init(PCD_HandleTypeDef *hpcd)
  112. {
  113. uint8_t i;
  114. /* Check the PCD handle allocation */
  115. if (hpcd == NULL)
  116. {
  117. return HAL_ERROR;
  118. }
  119. /* Check the parameters */
  120. assert_param(IS_PCD_ALL_INSTANCE(hpcd->Instance));
  121. if (hpcd->State == HAL_PCD_STATE_RESET)
  122. {
  123. /* Allocate lock resource and initialize it */
  124. hpcd->Lock = HAL_UNLOCKED;
  125. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  126. hpcd->SOFCallback = HAL_PCD_SOFCallback;
  127. hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
  128. hpcd->ResetCallback = HAL_PCD_ResetCallback;
  129. hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
  130. hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
  131. hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
  132. hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
  133. hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback;
  134. hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback;
  135. hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback;
  136. hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback;
  137. if (hpcd->MspInitCallback == NULL)
  138. {
  139. hpcd->MspInitCallback = HAL_PCD_MspInit;
  140. }
  141. /* Init the low level hardware */
  142. hpcd->MspInitCallback(hpcd);
  143. #else
  144. /* Init the low level hardware : GPIO, CLOCK, NVIC... */
  145. HAL_PCD_MspInit(hpcd);
  146. #endif /* (USE_HAL_PCD_REGISTER_CALLBACKS) */
  147. }
  148. hpcd->State = HAL_PCD_STATE_BUSY;
  149. /* Disable DMA mode for FS instance */
  150. hpcd->Init.dma_enable = 0U;
  151. /* Disable the Interrupts */
  152. __HAL_PCD_DISABLE(hpcd);
  153. /*Init the Core (common init.) */
  154. if (USB_CoreInit(hpcd->Instance, hpcd->Init) != HAL_OK)
  155. {
  156. hpcd->State = HAL_PCD_STATE_ERROR;
  157. return HAL_ERROR;
  158. }
  159. /* Force Device Mode */
  160. if (USB_SetCurrentMode(hpcd->Instance, USB_DEVICE_MODE) != HAL_OK)
  161. {
  162. hpcd->State = HAL_PCD_STATE_ERROR;
  163. return HAL_ERROR;
  164. }
  165. /* Init endpoints structures */
  166. for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
  167. {
  168. /* Init ep structure */
  169. hpcd->IN_ep[i].is_in = 1U;
  170. hpcd->IN_ep[i].num = i;
  171. #if defined (USB_OTG_FS)
  172. hpcd->IN_ep[i].tx_fifo_num = i;
  173. #endif /* defined (USB_OTG_FS) */
  174. /* Control until ep is activated */
  175. hpcd->IN_ep[i].type = EP_TYPE_CTRL;
  176. hpcd->IN_ep[i].maxpacket = 0U;
  177. hpcd->IN_ep[i].xfer_buff = 0U;
  178. hpcd->IN_ep[i].xfer_len = 0U;
  179. }
  180. for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
  181. {
  182. hpcd->OUT_ep[i].is_in = 0U;
  183. hpcd->OUT_ep[i].num = i;
  184. /* Control until ep is activated */
  185. hpcd->OUT_ep[i].type = EP_TYPE_CTRL;
  186. hpcd->OUT_ep[i].maxpacket = 0U;
  187. hpcd->OUT_ep[i].xfer_buff = 0U;
  188. hpcd->OUT_ep[i].xfer_len = 0U;
  189. }
  190. /* Init Device */
  191. if (USB_DevInit(hpcd->Instance, hpcd->Init) != HAL_OK)
  192. {
  193. hpcd->State = HAL_PCD_STATE_ERROR;
  194. return HAL_ERROR;
  195. }
  196. hpcd->USB_Address = 0U;
  197. hpcd->State = HAL_PCD_STATE_READY;
  198. (void)USB_DevDisconnect(hpcd->Instance);
  199. return HAL_OK;
  200. }
  201. /**
  202. * @brief DeInitializes the PCD peripheral.
  203. * @param hpcd PCD handle
  204. * @retval HAL status
  205. */
  206. HAL_StatusTypeDef HAL_PCD_DeInit(PCD_HandleTypeDef *hpcd)
  207. {
  208. /* Check the PCD handle allocation */
  209. if (hpcd == NULL)
  210. {
  211. return HAL_ERROR;
  212. }
  213. hpcd->State = HAL_PCD_STATE_BUSY;
  214. /* Stop Device */
  215. if (USB_StopDevice(hpcd->Instance) != HAL_OK)
  216. {
  217. return HAL_ERROR;
  218. }
  219. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  220. if (hpcd->MspDeInitCallback == NULL)
  221. {
  222. hpcd->MspDeInitCallback = HAL_PCD_MspDeInit; /* Legacy weak MspDeInit */
  223. }
  224. /* DeInit the low level hardware */
  225. hpcd->MspDeInitCallback(hpcd);
  226. #else
  227. /* DeInit the low level hardware: CLOCK, NVIC.*/
  228. HAL_PCD_MspDeInit(hpcd);
  229. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  230. hpcd->State = HAL_PCD_STATE_RESET;
  231. return HAL_OK;
  232. }
  233. /**
  234. * @brief Initializes the PCD MSP.
  235. * @param hpcd PCD handle
  236. * @retval None
  237. */
  238. __weak void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
  239. {
  240. /* Prevent unused argument(s) compilation warning */
  241. UNUSED(hpcd);
  242. /* NOTE : This function should not be modified, when the callback is needed,
  243. the HAL_PCD_MspInit could be implemented in the user file
  244. */
  245. }
  246. /**
  247. * @brief DeInitializes PCD MSP.
  248. * @param hpcd PCD handle
  249. * @retval None
  250. */
  251. __weak void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
  252. {
  253. /* Prevent unused argument(s) compilation warning */
  254. UNUSED(hpcd);
  255. /* NOTE : This function should not be modified, when the callback is needed,
  256. the HAL_PCD_MspDeInit could be implemented in the user file
  257. */
  258. }
  259. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  260. /**
  261. * @brief Register a User USB PCD Callback
  262. * To be used instead of the weak predefined callback
  263. * @param hpcd USB PCD handle
  264. * @param CallbackID ID of the callback to be registered
  265. * This parameter can be one of the following values:
  266. * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
  267. * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
  268. * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
  269. * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
  270. * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
  271. * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
  272. * @arg @ref HAL_PCD_DISCONNECT_CB_ID USB PCD Disconnect callback ID
  273. * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
  274. * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
  275. * @param pCallback pointer to the Callback function
  276. * @retval HAL status
  277. */
  278. HAL_StatusTypeDef HAL_PCD_RegisterCallback(PCD_HandleTypeDef *hpcd,
  279. HAL_PCD_CallbackIDTypeDef CallbackID,
  280. pPCD_CallbackTypeDef pCallback)
  281. {
  282. HAL_StatusTypeDef status = HAL_OK;
  283. if (pCallback == NULL)
  284. {
  285. /* Update the error code */
  286. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  287. return HAL_ERROR;
  288. }
  289. /* Process locked */
  290. __HAL_LOCK(hpcd);
  291. if (hpcd->State == HAL_PCD_STATE_READY)
  292. {
  293. switch (CallbackID)
  294. {
  295. case HAL_PCD_SOF_CB_ID :
  296. hpcd->SOFCallback = pCallback;
  297. break;
  298. case HAL_PCD_SETUPSTAGE_CB_ID :
  299. hpcd->SetupStageCallback = pCallback;
  300. break;
  301. case HAL_PCD_RESET_CB_ID :
  302. hpcd->ResetCallback = pCallback;
  303. break;
  304. case HAL_PCD_SUSPEND_CB_ID :
  305. hpcd->SuspendCallback = pCallback;
  306. break;
  307. case HAL_PCD_RESUME_CB_ID :
  308. hpcd->ResumeCallback = pCallback;
  309. break;
  310. case HAL_PCD_CONNECT_CB_ID :
  311. hpcd->ConnectCallback = pCallback;
  312. break;
  313. case HAL_PCD_DISCONNECT_CB_ID :
  314. hpcd->DisconnectCallback = pCallback;
  315. break;
  316. case HAL_PCD_MSPINIT_CB_ID :
  317. hpcd->MspInitCallback = pCallback;
  318. break;
  319. case HAL_PCD_MSPDEINIT_CB_ID :
  320. hpcd->MspDeInitCallback = pCallback;
  321. break;
  322. default :
  323. /* Update the error code */
  324. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  325. /* Return error status */
  326. status = HAL_ERROR;
  327. break;
  328. }
  329. }
  330. else if (hpcd->State == HAL_PCD_STATE_RESET)
  331. {
  332. switch (CallbackID)
  333. {
  334. case HAL_PCD_MSPINIT_CB_ID :
  335. hpcd->MspInitCallback = pCallback;
  336. break;
  337. case HAL_PCD_MSPDEINIT_CB_ID :
  338. hpcd->MspDeInitCallback = pCallback;
  339. break;
  340. default :
  341. /* Update the error code */
  342. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  343. /* Return error status */
  344. status = HAL_ERROR;
  345. break;
  346. }
  347. }
  348. else
  349. {
  350. /* Update the error code */
  351. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  352. /* Return error status */
  353. status = HAL_ERROR;
  354. }
  355. /* Release Lock */
  356. __HAL_UNLOCK(hpcd);
  357. return status;
  358. }
  359. /**
  360. * @brief Unregister an USB PCD Callback
  361. * USB PCD callback is redirected to the weak predefined callback
  362. * @param hpcd USB PCD handle
  363. * @param CallbackID ID of the callback to be unregistered
  364. * This parameter can be one of the following values:
  365. * @arg @ref HAL_PCD_SOF_CB_ID USB PCD SOF callback ID
  366. * @arg @ref HAL_PCD_SETUPSTAGE_CB_ID USB PCD Setup callback ID
  367. * @arg @ref HAL_PCD_RESET_CB_ID USB PCD Reset callback ID
  368. * @arg @ref HAL_PCD_SUSPEND_CB_ID USB PCD Suspend callback ID
  369. * @arg @ref HAL_PCD_RESUME_CB_ID USB PCD Resume callback ID
  370. * @arg @ref HAL_PCD_CONNECT_CB_ID USB PCD Connect callback ID
  371. * @arg @ref HAL_PCD_DISCONNECT_CB_ID USB PCD Disconnect callback ID
  372. * @arg @ref HAL_PCD_MSPINIT_CB_ID MspDeInit callback ID
  373. * @arg @ref HAL_PCD_MSPDEINIT_CB_ID MspDeInit callback ID
  374. * @retval HAL status
  375. */
  376. HAL_StatusTypeDef HAL_PCD_UnRegisterCallback(PCD_HandleTypeDef *hpcd, HAL_PCD_CallbackIDTypeDef CallbackID)
  377. {
  378. HAL_StatusTypeDef status = HAL_OK;
  379. /* Process locked */
  380. __HAL_LOCK(hpcd);
  381. /* Setup Legacy weak Callbacks */
  382. if (hpcd->State == HAL_PCD_STATE_READY)
  383. {
  384. switch (CallbackID)
  385. {
  386. case HAL_PCD_SOF_CB_ID :
  387. hpcd->SOFCallback = HAL_PCD_SOFCallback;
  388. break;
  389. case HAL_PCD_SETUPSTAGE_CB_ID :
  390. hpcd->SetupStageCallback = HAL_PCD_SetupStageCallback;
  391. break;
  392. case HAL_PCD_RESET_CB_ID :
  393. hpcd->ResetCallback = HAL_PCD_ResetCallback;
  394. break;
  395. case HAL_PCD_SUSPEND_CB_ID :
  396. hpcd->SuspendCallback = HAL_PCD_SuspendCallback;
  397. break;
  398. case HAL_PCD_RESUME_CB_ID :
  399. hpcd->ResumeCallback = HAL_PCD_ResumeCallback;
  400. break;
  401. case HAL_PCD_CONNECT_CB_ID :
  402. hpcd->ConnectCallback = HAL_PCD_ConnectCallback;
  403. break;
  404. case HAL_PCD_DISCONNECT_CB_ID :
  405. hpcd->DisconnectCallback = HAL_PCD_DisconnectCallback;
  406. break;
  407. case HAL_PCD_MSPINIT_CB_ID :
  408. hpcd->MspInitCallback = HAL_PCD_MspInit;
  409. break;
  410. case HAL_PCD_MSPDEINIT_CB_ID :
  411. hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
  412. break;
  413. default :
  414. /* Update the error code */
  415. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  416. /* Return error status */
  417. status = HAL_ERROR;
  418. break;
  419. }
  420. }
  421. else if (hpcd->State == HAL_PCD_STATE_RESET)
  422. {
  423. switch (CallbackID)
  424. {
  425. case HAL_PCD_MSPINIT_CB_ID :
  426. hpcd->MspInitCallback = HAL_PCD_MspInit;
  427. break;
  428. case HAL_PCD_MSPDEINIT_CB_ID :
  429. hpcd->MspDeInitCallback = HAL_PCD_MspDeInit;
  430. break;
  431. default :
  432. /* Update the error code */
  433. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  434. /* Return error status */
  435. status = HAL_ERROR;
  436. break;
  437. }
  438. }
  439. else
  440. {
  441. /* Update the error code */
  442. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  443. /* Return error status */
  444. status = HAL_ERROR;
  445. }
  446. /* Release Lock */
  447. __HAL_UNLOCK(hpcd);
  448. return status;
  449. }
  450. /**
  451. * @brief Register USB PCD Data OUT Stage Callback
  452. * To be used instead of the weak HAL_PCD_DataOutStageCallback() predefined callback
  453. * @param hpcd PCD handle
  454. * @param pCallback pointer to the USB PCD Data OUT Stage Callback function
  455. * @retval HAL status
  456. */
  457. HAL_StatusTypeDef HAL_PCD_RegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd,
  458. pPCD_DataOutStageCallbackTypeDef pCallback)
  459. {
  460. HAL_StatusTypeDef status = HAL_OK;
  461. if (pCallback == NULL)
  462. {
  463. /* Update the error code */
  464. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  465. return HAL_ERROR;
  466. }
  467. /* Process locked */
  468. __HAL_LOCK(hpcd);
  469. if (hpcd->State == HAL_PCD_STATE_READY)
  470. {
  471. hpcd->DataOutStageCallback = pCallback;
  472. }
  473. else
  474. {
  475. /* Update the error code */
  476. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  477. /* Return error status */
  478. status = HAL_ERROR;
  479. }
  480. /* Release Lock */
  481. __HAL_UNLOCK(hpcd);
  482. return status;
  483. }
  484. /**
  485. * @brief Unregister the USB PCD Data OUT Stage Callback
  486. * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataOutStageCallback() predefined callback
  487. * @param hpcd PCD handle
  488. * @retval HAL status
  489. */
  490. HAL_StatusTypeDef HAL_PCD_UnRegisterDataOutStageCallback(PCD_HandleTypeDef *hpcd)
  491. {
  492. HAL_StatusTypeDef status = HAL_OK;
  493. /* Process locked */
  494. __HAL_LOCK(hpcd);
  495. if (hpcd->State == HAL_PCD_STATE_READY)
  496. {
  497. hpcd->DataOutStageCallback = HAL_PCD_DataOutStageCallback; /* Legacy weak DataOutStageCallback */
  498. }
  499. else
  500. {
  501. /* Update the error code */
  502. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  503. /* Return error status */
  504. status = HAL_ERROR;
  505. }
  506. /* Release Lock */
  507. __HAL_UNLOCK(hpcd);
  508. return status;
  509. }
  510. /**
  511. * @brief Register USB PCD Data IN Stage Callback
  512. * To be used instead of the weak HAL_PCD_DataInStageCallback() predefined callback
  513. * @param hpcd PCD handle
  514. * @param pCallback pointer to the USB PCD Data IN Stage Callback function
  515. * @retval HAL status
  516. */
  517. HAL_StatusTypeDef HAL_PCD_RegisterDataInStageCallback(PCD_HandleTypeDef *hpcd,
  518. pPCD_DataInStageCallbackTypeDef pCallback)
  519. {
  520. HAL_StatusTypeDef status = HAL_OK;
  521. if (pCallback == NULL)
  522. {
  523. /* Update the error code */
  524. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  525. return HAL_ERROR;
  526. }
  527. /* Process locked */
  528. __HAL_LOCK(hpcd);
  529. if (hpcd->State == HAL_PCD_STATE_READY)
  530. {
  531. hpcd->DataInStageCallback = pCallback;
  532. }
  533. else
  534. {
  535. /* Update the error code */
  536. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  537. /* Return error status */
  538. status = HAL_ERROR;
  539. }
  540. /* Release Lock */
  541. __HAL_UNLOCK(hpcd);
  542. return status;
  543. }
  544. /**
  545. * @brief Unregister the USB PCD Data IN Stage Callback
  546. * USB PCD Data OUT Stage Callback is redirected to the weak HAL_PCD_DataInStageCallback() predefined callback
  547. * @param hpcd PCD handle
  548. * @retval HAL status
  549. */
  550. HAL_StatusTypeDef HAL_PCD_UnRegisterDataInStageCallback(PCD_HandleTypeDef *hpcd)
  551. {
  552. HAL_StatusTypeDef status = HAL_OK;
  553. /* Process locked */
  554. __HAL_LOCK(hpcd);
  555. if (hpcd->State == HAL_PCD_STATE_READY)
  556. {
  557. hpcd->DataInStageCallback = HAL_PCD_DataInStageCallback; /* Legacy weak DataInStageCallback */
  558. }
  559. else
  560. {
  561. /* Update the error code */
  562. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  563. /* Return error status */
  564. status = HAL_ERROR;
  565. }
  566. /* Release Lock */
  567. __HAL_UNLOCK(hpcd);
  568. return status;
  569. }
  570. /**
  571. * @brief Register USB PCD Iso OUT incomplete Callback
  572. * To be used instead of the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
  573. * @param hpcd PCD handle
  574. * @param pCallback pointer to the USB PCD Iso OUT incomplete Callback function
  575. * @retval HAL status
  576. */
  577. HAL_StatusTypeDef HAL_PCD_RegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd,
  578. pPCD_IsoOutIncpltCallbackTypeDef pCallback)
  579. {
  580. HAL_StatusTypeDef status = HAL_OK;
  581. if (pCallback == NULL)
  582. {
  583. /* Update the error code */
  584. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  585. return HAL_ERROR;
  586. }
  587. /* Process locked */
  588. __HAL_LOCK(hpcd);
  589. if (hpcd->State == HAL_PCD_STATE_READY)
  590. {
  591. hpcd->ISOOUTIncompleteCallback = pCallback;
  592. }
  593. else
  594. {
  595. /* Update the error code */
  596. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  597. /* Return error status */
  598. status = HAL_ERROR;
  599. }
  600. /* Release Lock */
  601. __HAL_UNLOCK(hpcd);
  602. return status;
  603. }
  604. /**
  605. * @brief Unregister the USB PCD Iso OUT incomplete Callback
  606. * USB PCD Iso OUT incomplete Callback is redirected
  607. * to the weak HAL_PCD_ISOOUTIncompleteCallback() predefined callback
  608. * @param hpcd PCD handle
  609. * @retval HAL status
  610. */
  611. HAL_StatusTypeDef HAL_PCD_UnRegisterIsoOutIncpltCallback(PCD_HandleTypeDef *hpcd)
  612. {
  613. HAL_StatusTypeDef status = HAL_OK;
  614. /* Process locked */
  615. __HAL_LOCK(hpcd);
  616. if (hpcd->State == HAL_PCD_STATE_READY)
  617. {
  618. hpcd->ISOOUTIncompleteCallback = HAL_PCD_ISOOUTIncompleteCallback; /* Legacy weak ISOOUTIncompleteCallback */
  619. }
  620. else
  621. {
  622. /* Update the error code */
  623. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  624. /* Return error status */
  625. status = HAL_ERROR;
  626. }
  627. /* Release Lock */
  628. __HAL_UNLOCK(hpcd);
  629. return status;
  630. }
  631. /**
  632. * @brief Register USB PCD Iso IN incomplete Callback
  633. * To be used instead of the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
  634. * @param hpcd PCD handle
  635. * @param pCallback pointer to the USB PCD Iso IN incomplete Callback function
  636. * @retval HAL status
  637. */
  638. HAL_StatusTypeDef HAL_PCD_RegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd,
  639. pPCD_IsoInIncpltCallbackTypeDef pCallback)
  640. {
  641. HAL_StatusTypeDef status = HAL_OK;
  642. if (pCallback == NULL)
  643. {
  644. /* Update the error code */
  645. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  646. return HAL_ERROR;
  647. }
  648. /* Process locked */
  649. __HAL_LOCK(hpcd);
  650. if (hpcd->State == HAL_PCD_STATE_READY)
  651. {
  652. hpcd->ISOINIncompleteCallback = pCallback;
  653. }
  654. else
  655. {
  656. /* Update the error code */
  657. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  658. /* Return error status */
  659. status = HAL_ERROR;
  660. }
  661. /* Release Lock */
  662. __HAL_UNLOCK(hpcd);
  663. return status;
  664. }
  665. /**
  666. * @brief Unregister the USB PCD Iso IN incomplete Callback
  667. * USB PCD Iso IN incomplete Callback is redirected
  668. * to the weak HAL_PCD_ISOINIncompleteCallback() predefined callback
  669. * @param hpcd PCD handle
  670. * @retval HAL status
  671. */
  672. HAL_StatusTypeDef HAL_PCD_UnRegisterIsoInIncpltCallback(PCD_HandleTypeDef *hpcd)
  673. {
  674. HAL_StatusTypeDef status = HAL_OK;
  675. /* Process locked */
  676. __HAL_LOCK(hpcd);
  677. if (hpcd->State == HAL_PCD_STATE_READY)
  678. {
  679. hpcd->ISOINIncompleteCallback = HAL_PCD_ISOINIncompleteCallback; /* Legacy weak ISOINIncompleteCallback */
  680. }
  681. else
  682. {
  683. /* Update the error code */
  684. hpcd->ErrorCode |= HAL_PCD_ERROR_INVALID_CALLBACK;
  685. /* Return error status */
  686. status = HAL_ERROR;
  687. }
  688. /* Release Lock */
  689. __HAL_UNLOCK(hpcd);
  690. return status;
  691. }
  692. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  693. /**
  694. * @}
  695. */
  696. /** @defgroup PCD_Exported_Functions_Group2 Input and Output operation functions
  697. * @brief Data transfers functions
  698. *
  699. @verbatim
  700. ===============================================================================
  701. ##### IO operation functions #####
  702. ===============================================================================
  703. [..]
  704. This subsection provides a set of functions allowing to manage the PCD data
  705. transfers.
  706. @endverbatim
  707. * @{
  708. */
  709. /**
  710. * @brief Start the USB device
  711. * @param hpcd PCD handle
  712. * @retval HAL status
  713. */
  714. HAL_StatusTypeDef HAL_PCD_Start(PCD_HandleTypeDef *hpcd)
  715. {
  716. __HAL_LOCK(hpcd);
  717. __HAL_PCD_ENABLE(hpcd);
  718. #if defined (USB)
  719. HAL_PCDEx_SetConnectionState(hpcd, 1U);
  720. #endif /* defined (USB) */
  721. (void)USB_DevConnect(hpcd->Instance);
  722. __HAL_UNLOCK(hpcd);
  723. return HAL_OK;
  724. }
  725. /**
  726. * @brief Stop the USB device.
  727. * @param hpcd PCD handle
  728. * @retval HAL status
  729. */
  730. HAL_StatusTypeDef HAL_PCD_Stop(PCD_HandleTypeDef *hpcd)
  731. {
  732. __HAL_LOCK(hpcd);
  733. __HAL_PCD_DISABLE(hpcd);
  734. #if defined (USB)
  735. HAL_PCDEx_SetConnectionState(hpcd, 0U);
  736. #endif /* defined (USB) */
  737. (void)USB_DevDisconnect(hpcd->Instance);
  738. #if defined (USB_OTG_FS)
  739. (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
  740. #endif /* defined (USB_OTG_FS) */
  741. __HAL_UNLOCK(hpcd);
  742. return HAL_OK;
  743. }
  744. #if defined (USB_OTG_FS)
  745. /**
  746. * @brief Handles PCD interrupt request.
  747. * @param hpcd PCD handle
  748. * @retval HAL status
  749. */
  750. void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
  751. {
  752. USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  753. uint32_t USBx_BASE = (uint32_t)USBx;
  754. USB_OTG_EPTypeDef *ep;
  755. uint32_t i;
  756. uint32_t ep_intr;
  757. uint32_t epint;
  758. uint32_t epnum;
  759. uint32_t fifoemptymsk;
  760. uint32_t RegVal;
  761. /* ensure that we are in device mode */
  762. if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE)
  763. {
  764. /* avoid spurious interrupt */
  765. if (__HAL_PCD_IS_INVALID_INTERRUPT(hpcd))
  766. {
  767. return;
  768. }
  769. /* store current frame number */
  770. hpcd->FrameNumber = (USBx_DEVICE->DSTS & USB_OTG_DSTS_FNSOF_Msk) >> USB_OTG_DSTS_FNSOF_Pos;
  771. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS))
  772. {
  773. /* incorrect mode, acknowledge the interrupt */
  774. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS);
  775. }
  776. /* Handle RxQLevel Interrupt */
  777. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_RXFLVL))
  778. {
  779. USB_MASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  780. RegVal = USBx->GRXSTSP;
  781. ep = &hpcd->OUT_ep[RegVal & USB_OTG_GRXSTSP_EPNUM];
  782. if (((RegVal & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_DATA_UPDT)
  783. {
  784. if ((RegVal & USB_OTG_GRXSTSP_BCNT) != 0U)
  785. {
  786. (void)USB_ReadPacket(USBx, ep->xfer_buff,
  787. (uint16_t)((RegVal & USB_OTG_GRXSTSP_BCNT) >> 4));
  788. ep->xfer_buff += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4;
  789. ep->xfer_count += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4;
  790. }
  791. }
  792. else if (((RegVal & USB_OTG_GRXSTSP_PKTSTS) >> 17) == STS_SETUP_UPDT)
  793. {
  794. (void)USB_ReadPacket(USBx, (uint8_t *)hpcd->Setup, 8U);
  795. ep->xfer_count += (RegVal & USB_OTG_GRXSTSP_BCNT) >> 4;
  796. }
  797. else
  798. {
  799. /* ... */
  800. }
  801. USB_UNMASK_INTERRUPT(hpcd->Instance, USB_OTG_GINTSTS_RXFLVL);
  802. }
  803. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT))
  804. {
  805. epnum = 0U;
  806. /* Read in the device interrupt bits */
  807. ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance);
  808. while (ep_intr != 0U)
  809. {
  810. if ((ep_intr & 0x1U) != 0U)
  811. {
  812. epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, (uint8_t)epnum);
  813. if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC)
  814. {
  815. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC);
  816. (void)PCD_EP_OutXfrComplete_int(hpcd, epnum);
  817. }
  818. if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP)
  819. {
  820. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP);
  821. /* Class B setup phase done for previous decoded setup */
  822. (void)PCD_EP_OutSetupPacket_int(hpcd, epnum);
  823. }
  824. if ((epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS)
  825. {
  826. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS);
  827. }
  828. /* Clear OUT Endpoint disable interrupt */
  829. if ((epint & USB_OTG_DOEPINT_EPDISD) == USB_OTG_DOEPINT_EPDISD)
  830. {
  831. if ((USBx->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF) == USB_OTG_GINTSTS_BOUTNAKEFF)
  832. {
  833. USBx_DEVICE->DCTL |= USB_OTG_DCTL_CGONAK;
  834. }
  835. ep = &hpcd->OUT_ep[epnum];
  836. if (ep->is_iso_incomplete == 1U)
  837. {
  838. ep->is_iso_incomplete = 0U;
  839. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  840. hpcd->ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
  841. #else
  842. HAL_PCD_ISOOUTIncompleteCallback(hpcd, (uint8_t)epnum);
  843. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  844. }
  845. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_EPDISD);
  846. }
  847. /* Clear Status Phase Received interrupt */
  848. if ((epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
  849. {
  850. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
  851. }
  852. /* Clear OUT NAK interrupt */
  853. if ((epint & USB_OTG_DOEPINT_NAK) == USB_OTG_DOEPINT_NAK)
  854. {
  855. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_NAK);
  856. }
  857. }
  858. epnum++;
  859. ep_intr >>= 1U;
  860. }
  861. }
  862. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT))
  863. {
  864. /* Read in the device interrupt bits */
  865. ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance);
  866. epnum = 0U;
  867. while (ep_intr != 0U)
  868. {
  869. if ((ep_intr & 0x1U) != 0U) /* In ITR */
  870. {
  871. epint = USB_ReadDevInEPInterrupt(hpcd->Instance, (uint8_t)epnum);
  872. if ((epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC)
  873. {
  874. fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
  875. USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
  876. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC);
  877. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  878. hpcd->DataInStageCallback(hpcd, (uint8_t)epnum);
  879. #else
  880. HAL_PCD_DataInStageCallback(hpcd, (uint8_t)epnum);
  881. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  882. }
  883. if ((epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC)
  884. {
  885. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC);
  886. }
  887. if ((epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE)
  888. {
  889. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE);
  890. }
  891. if ((epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE)
  892. {
  893. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE);
  894. }
  895. if ((epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD)
  896. {
  897. (void)USB_FlushTxFifo(USBx, epnum);
  898. ep = &hpcd->IN_ep[epnum];
  899. if (ep->is_iso_incomplete == 1U)
  900. {
  901. ep->is_iso_incomplete = 0U;
  902. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  903. hpcd->ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
  904. #else
  905. HAL_PCD_ISOINIncompleteCallback(hpcd, (uint8_t)epnum);
  906. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  907. }
  908. CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD);
  909. }
  910. if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE)
  911. {
  912. (void)PCD_WriteEmptyTxFifo(hpcd, epnum);
  913. }
  914. }
  915. epnum++;
  916. ep_intr >>= 1U;
  917. }
  918. }
  919. /* Handle Resume Interrupt */
  920. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT))
  921. {
  922. /* Clear the Remote Wake-up Signaling */
  923. USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
  924. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  925. hpcd->ResumeCallback(hpcd);
  926. #else
  927. HAL_PCD_ResumeCallback(hpcd);
  928. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  929. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT);
  930. }
  931. /* Handle Suspend Interrupt */
  932. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP))
  933. {
  934. if ((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS)
  935. {
  936. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  937. hpcd->SuspendCallback(hpcd);
  938. #else
  939. HAL_PCD_SuspendCallback(hpcd);
  940. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  941. }
  942. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP);
  943. }
  944. /* Handle Reset Interrupt */
  945. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBRST))
  946. {
  947. USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG;
  948. (void)USB_FlushTxFifo(hpcd->Instance, 0x10U);
  949. for (i = 0U; i < hpcd->Init.dev_endpoints; i++)
  950. {
  951. USBx_INEP(i)->DIEPINT = 0xFB7FU;
  952. USBx_INEP(i)->DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
  953. USBx_OUTEP(i)->DOEPINT = 0xFB7FU;
  954. USBx_OUTEP(i)->DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
  955. USBx_OUTEP(i)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
  956. }
  957. USBx_DEVICE->DAINTMSK |= 0x10001U;
  958. if (hpcd->Init.use_dedicated_ep1 != 0U)
  959. {
  960. USBx_DEVICE->DOUTEP1MSK |= USB_OTG_DOEPMSK_STUPM |
  961. USB_OTG_DOEPMSK_XFRCM |
  962. USB_OTG_DOEPMSK_EPDM;
  963. USBx_DEVICE->DINEP1MSK |= USB_OTG_DIEPMSK_TOM |
  964. USB_OTG_DIEPMSK_XFRCM |
  965. USB_OTG_DIEPMSK_EPDM;
  966. }
  967. else
  968. {
  969. USBx_DEVICE->DOEPMSK |= USB_OTG_DOEPMSK_STUPM |
  970. USB_OTG_DOEPMSK_XFRCM |
  971. USB_OTG_DOEPMSK_EPDM |
  972. USB_OTG_DOEPMSK_OTEPSPRM |
  973. USB_OTG_DOEPMSK_NAKM;
  974. USBx_DEVICE->DIEPMSK |= USB_OTG_DIEPMSK_TOM |
  975. USB_OTG_DIEPMSK_XFRCM |
  976. USB_OTG_DIEPMSK_EPDM;
  977. }
  978. /* Set Default Address to 0 */
  979. USBx_DEVICE->DCFG &= ~USB_OTG_DCFG_DAD;
  980. /* setup EP0 to receive SETUP packets */
  981. (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
  982. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBRST);
  983. }
  984. /* Handle Enumeration done Interrupt */
  985. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE))
  986. {
  987. (void)USB_ActivateSetup(hpcd->Instance);
  988. hpcd->Init.speed = USB_GetDevSpeed(hpcd->Instance);
  989. /* Set USB Turnaround time */
  990. (void)USB_SetTurnaroundTime(hpcd->Instance,
  991. HAL_RCC_GetHCLKFreq(),
  992. (uint8_t)hpcd->Init.speed);
  993. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  994. hpcd->ResetCallback(hpcd);
  995. #else
  996. HAL_PCD_ResetCallback(hpcd);
  997. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  998. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_ENUMDNE);
  999. }
  1000. /* Handle SOF Interrupt */
  1001. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SOF))
  1002. {
  1003. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1004. hpcd->SOFCallback(hpcd);
  1005. #else
  1006. HAL_PCD_SOFCallback(hpcd);
  1007. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1008. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SOF);
  1009. }
  1010. /* Handle Global OUT NAK effective Interrupt */
  1011. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_BOUTNAKEFF))
  1012. {
  1013. USBx->GINTMSK &= ~USB_OTG_GINTMSK_GONAKEFFM;
  1014. for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++)
  1015. {
  1016. if (hpcd->OUT_ep[epnum].is_iso_incomplete == 1U)
  1017. {
  1018. /* Abort current transaction and disable the EP */
  1019. (void)HAL_PCD_EP_Abort(hpcd, (uint8_t)epnum);
  1020. }
  1021. }
  1022. }
  1023. /* Handle Incomplete ISO IN Interrupt */
  1024. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR))
  1025. {
  1026. for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++)
  1027. {
  1028. RegVal = USBx_INEP(epnum)->DIEPCTL;
  1029. if ((hpcd->IN_ep[epnum].type == EP_TYPE_ISOC) &&
  1030. ((RegVal & USB_OTG_DIEPCTL_EPENA) == USB_OTG_DIEPCTL_EPENA))
  1031. {
  1032. hpcd->IN_ep[epnum].is_iso_incomplete = 1U;
  1033. /* Abort current transaction and disable the EP */
  1034. (void)HAL_PCD_EP_Abort(hpcd, (uint8_t)(epnum | 0x80U));
  1035. }
  1036. }
  1037. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_IISOIXFR);
  1038. }
  1039. /* Handle Incomplete ISO OUT Interrupt */
  1040. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
  1041. {
  1042. for (epnum = 1U; epnum < hpcd->Init.dev_endpoints; epnum++)
  1043. {
  1044. RegVal = USBx_OUTEP(epnum)->DOEPCTL;
  1045. if ((hpcd->OUT_ep[epnum].type == EP_TYPE_ISOC) &&
  1046. ((RegVal & USB_OTG_DOEPCTL_EPENA) == USB_OTG_DOEPCTL_EPENA) &&
  1047. ((RegVal & (0x1U << 16)) == (hpcd->FrameNumber & 0x1U)))
  1048. {
  1049. hpcd->OUT_ep[epnum].is_iso_incomplete = 1U;
  1050. USBx->GINTMSK |= USB_OTG_GINTMSK_GONAKEFFM;
  1051. if ((USBx->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF) == 0U)
  1052. {
  1053. USBx_DEVICE->DCTL |= USB_OTG_DCTL_SGONAK;
  1054. break;
  1055. }
  1056. }
  1057. }
  1058. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
  1059. }
  1060. /* Handle Connection event Interrupt */
  1061. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT))
  1062. {
  1063. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1064. hpcd->ConnectCallback(hpcd);
  1065. #else
  1066. HAL_PCD_ConnectCallback(hpcd);
  1067. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1068. __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_SRQINT);
  1069. }
  1070. /* Handle Disconnection event Interrupt */
  1071. if (__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OTGINT))
  1072. {
  1073. RegVal = hpcd->Instance->GOTGINT;
  1074. if ((RegVal & USB_OTG_GOTGINT_SEDET) == USB_OTG_GOTGINT_SEDET)
  1075. {
  1076. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1077. hpcd->DisconnectCallback(hpcd);
  1078. #else
  1079. HAL_PCD_DisconnectCallback(hpcd);
  1080. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1081. }
  1082. hpcd->Instance->GOTGINT |= RegVal;
  1083. }
  1084. }
  1085. }
  1086. /**
  1087. * @brief Handles PCD Wakeup interrupt request.
  1088. * @param hpcd PCD handle
  1089. * @retval HAL status
  1090. */
  1091. void HAL_PCD_WKUP_IRQHandler(PCD_HandleTypeDef *hpcd)
  1092. {
  1093. /* Clear EXTI pending Bit */
  1094. __HAL_USB_OTG_FS_WAKEUP_EXTI_CLEAR_FLAG();
  1095. }
  1096. #endif /* defined (USB_OTG_FS) */
  1097. #if defined (USB)
  1098. /**
  1099. * @brief This function handles PCD interrupt request.
  1100. * @param hpcd PCD handle
  1101. * @retval HAL status
  1102. */
  1103. void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd)
  1104. {
  1105. uint32_t wIstr = USB_ReadInterrupts(hpcd->Instance);
  1106. uint16_t store_ep[8];
  1107. uint8_t i;
  1108. if ((wIstr & USB_ISTR_CTR) == USB_ISTR_CTR)
  1109. {
  1110. /* servicing of the endpoint correct transfer interrupt */
  1111. /* clear of the CTR flag into the sub */
  1112. (void)PCD_EP_ISR_Handler(hpcd);
  1113. return;
  1114. }
  1115. if ((wIstr & USB_ISTR_RESET) == USB_ISTR_RESET)
  1116. {
  1117. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
  1118. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1119. hpcd->ResetCallback(hpcd);
  1120. #else
  1121. HAL_PCD_ResetCallback(hpcd);
  1122. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1123. (void)HAL_PCD_SetAddress(hpcd, 0U);
  1124. return;
  1125. }
  1126. if ((wIstr & USB_ISTR_PMAOVR) == USB_ISTR_PMAOVR)
  1127. {
  1128. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR);
  1129. return;
  1130. }
  1131. if ((wIstr & USB_ISTR_ERR) == USB_ISTR_ERR)
  1132. {
  1133. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR);
  1134. return;
  1135. }
  1136. if ((wIstr & USB_ISTR_WKUP) == USB_ISTR_WKUP)
  1137. {
  1138. hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_LP_MODE);
  1139. hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_FSUSP);
  1140. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1141. hpcd->ResumeCallback(hpcd);
  1142. #else
  1143. HAL_PCD_ResumeCallback(hpcd);
  1144. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1145. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP);
  1146. return;
  1147. }
  1148. if ((wIstr & USB_ISTR_SUSP) == USB_ISTR_SUSP)
  1149. {
  1150. /* WA: To Clear Wakeup flag if raised with suspend signal */
  1151. /* Store Endpoint registers */
  1152. for (i = 0U; i < 8U; i++)
  1153. {
  1154. store_ep[i] = PCD_GET_ENDPOINT(hpcd->Instance, i);
  1155. }
  1156. /* FORCE RESET */
  1157. hpcd->Instance->CNTR |= (uint16_t)(USB_CNTR_FRES);
  1158. /* CLEAR RESET */
  1159. hpcd->Instance->CNTR &= (uint16_t)(~USB_CNTR_FRES);
  1160. /* wait for reset flag in ISTR */
  1161. while ((hpcd->Instance->ISTR & USB_ISTR_RESET) == 0U)
  1162. {
  1163. }
  1164. /* Clear Reset Flag */
  1165. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET);
  1166. /* Restore Registre */
  1167. for (i = 0U; i < 8U; i++)
  1168. {
  1169. PCD_SET_ENDPOINT(hpcd->Instance, i, store_ep[i]);
  1170. }
  1171. /* Force low-power mode in the macrocell */
  1172. hpcd->Instance->CNTR |= (uint16_t)USB_CNTR_FSUSP;
  1173. /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
  1174. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP);
  1175. hpcd->Instance->CNTR |= (uint16_t)USB_CNTR_LP_MODE;
  1176. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1177. hpcd->SuspendCallback(hpcd);
  1178. #else
  1179. HAL_PCD_SuspendCallback(hpcd);
  1180. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1181. return;
  1182. }
  1183. if ((wIstr & USB_ISTR_SOF) == USB_ISTR_SOF)
  1184. {
  1185. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF);
  1186. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1187. hpcd->SOFCallback(hpcd);
  1188. #else
  1189. HAL_PCD_SOFCallback(hpcd);
  1190. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1191. return;
  1192. }
  1193. if ((wIstr & USB_ISTR_ESOF) == USB_ISTR_ESOF)
  1194. {
  1195. /* clear ESOF flag in ISTR */
  1196. __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF);
  1197. return;
  1198. }
  1199. }
  1200. /**
  1201. * @brief Handles PCD Wakeup interrupt request.
  1202. * @param hpcd PCD handle
  1203. * @retval HAL status
  1204. */
  1205. void HAL_PCD_WKUP_IRQHandler(PCD_HandleTypeDef *hpcd)
  1206. {
  1207. /* Clear EXTI pending Bit */
  1208. __HAL_USB_WAKEUP_EXTI_CLEAR_FLAG();
  1209. }
  1210. #endif /* defined (USB) */
  1211. /**
  1212. * @brief Data OUT stage callback.
  1213. * @param hpcd PCD handle
  1214. * @param epnum endpoint number
  1215. * @retval None
  1216. */
  1217. __weak void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1218. {
  1219. /* Prevent unused argument(s) compilation warning */
  1220. UNUSED(hpcd);
  1221. UNUSED(epnum);
  1222. /* NOTE : This function should not be modified, when the callback is needed,
  1223. the HAL_PCD_DataOutStageCallback could be implemented in the user file
  1224. */
  1225. }
  1226. /**
  1227. * @brief Data IN stage callback
  1228. * @param hpcd PCD handle
  1229. * @param epnum endpoint number
  1230. * @retval None
  1231. */
  1232. __weak void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1233. {
  1234. /* Prevent unused argument(s) compilation warning */
  1235. UNUSED(hpcd);
  1236. UNUSED(epnum);
  1237. /* NOTE : This function should not be modified, when the callback is needed,
  1238. the HAL_PCD_DataInStageCallback could be implemented in the user file
  1239. */
  1240. }
  1241. /**
  1242. * @brief Setup stage callback
  1243. * @param hpcd PCD handle
  1244. * @retval None
  1245. */
  1246. __weak void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
  1247. {
  1248. /* Prevent unused argument(s) compilation warning */
  1249. UNUSED(hpcd);
  1250. /* NOTE : This function should not be modified, when the callback is needed,
  1251. the HAL_PCD_SetupStageCallback could be implemented in the user file
  1252. */
  1253. }
  1254. /**
  1255. * @brief USB Start Of Frame callback.
  1256. * @param hpcd PCD handle
  1257. * @retval None
  1258. */
  1259. __weak void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
  1260. {
  1261. /* Prevent unused argument(s) compilation warning */
  1262. UNUSED(hpcd);
  1263. /* NOTE : This function should not be modified, when the callback is needed,
  1264. the HAL_PCD_SOFCallback could be implemented in the user file
  1265. */
  1266. }
  1267. /**
  1268. * @brief USB Reset callback.
  1269. * @param hpcd PCD handle
  1270. * @retval None
  1271. */
  1272. __weak void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
  1273. {
  1274. /* Prevent unused argument(s) compilation warning */
  1275. UNUSED(hpcd);
  1276. /* NOTE : This function should not be modified, when the callback is needed,
  1277. the HAL_PCD_ResetCallback could be implemented in the user file
  1278. */
  1279. }
  1280. /**
  1281. * @brief Suspend event callback.
  1282. * @param hpcd PCD handle
  1283. * @retval None
  1284. */
  1285. __weak void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
  1286. {
  1287. /* Prevent unused argument(s) compilation warning */
  1288. UNUSED(hpcd);
  1289. /* NOTE : This function should not be modified, when the callback is needed,
  1290. the HAL_PCD_SuspendCallback could be implemented in the user file
  1291. */
  1292. }
  1293. /**
  1294. * @brief Resume event callback.
  1295. * @param hpcd PCD handle
  1296. * @retval None
  1297. */
  1298. __weak void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
  1299. {
  1300. /* Prevent unused argument(s) compilation warning */
  1301. UNUSED(hpcd);
  1302. /* NOTE : This function should not be modified, when the callback is needed,
  1303. the HAL_PCD_ResumeCallback could be implemented in the user file
  1304. */
  1305. }
  1306. /**
  1307. * @brief Incomplete ISO OUT callback.
  1308. * @param hpcd PCD handle
  1309. * @param epnum endpoint number
  1310. * @retval None
  1311. */
  1312. __weak void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1313. {
  1314. /* Prevent unused argument(s) compilation warning */
  1315. UNUSED(hpcd);
  1316. UNUSED(epnum);
  1317. /* NOTE : This function should not be modified, when the callback is needed,
  1318. the HAL_PCD_ISOOUTIncompleteCallback could be implemented in the user file
  1319. */
  1320. }
  1321. /**
  1322. * @brief Incomplete ISO IN callback.
  1323. * @param hpcd PCD handle
  1324. * @param epnum endpoint number
  1325. * @retval None
  1326. */
  1327. __weak void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  1328. {
  1329. /* Prevent unused argument(s) compilation warning */
  1330. UNUSED(hpcd);
  1331. UNUSED(epnum);
  1332. /* NOTE : This function should not be modified, when the callback is needed,
  1333. the HAL_PCD_ISOINIncompleteCallback could be implemented in the user file
  1334. */
  1335. }
  1336. /**
  1337. * @brief Connection event callback.
  1338. * @param hpcd PCD handle
  1339. * @retval None
  1340. */
  1341. __weak void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
  1342. {
  1343. /* Prevent unused argument(s) compilation warning */
  1344. UNUSED(hpcd);
  1345. /* NOTE : This function should not be modified, when the callback is needed,
  1346. the HAL_PCD_ConnectCallback could be implemented in the user file
  1347. */
  1348. }
  1349. /**
  1350. * @brief Disconnection event callback.
  1351. * @param hpcd PCD handle
  1352. * @retval None
  1353. */
  1354. __weak void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
  1355. {
  1356. /* Prevent unused argument(s) compilation warning */
  1357. UNUSED(hpcd);
  1358. /* NOTE : This function should not be modified, when the callback is needed,
  1359. the HAL_PCD_DisconnectCallback could be implemented in the user file
  1360. */
  1361. }
  1362. /**
  1363. * @}
  1364. */
  1365. /** @defgroup PCD_Exported_Functions_Group3 Peripheral Control functions
  1366. * @brief management functions
  1367. *
  1368. @verbatim
  1369. ===============================================================================
  1370. ##### Peripheral Control functions #####
  1371. ===============================================================================
  1372. [..]
  1373. This subsection provides a set of functions allowing to control the PCD data
  1374. transfers.
  1375. @endverbatim
  1376. * @{
  1377. */
  1378. /**
  1379. * @brief Connect the USB device
  1380. * @param hpcd PCD handle
  1381. * @retval HAL status
  1382. */
  1383. HAL_StatusTypeDef HAL_PCD_DevConnect(PCD_HandleTypeDef *hpcd)
  1384. {
  1385. __HAL_LOCK(hpcd);
  1386. #if defined (USB)
  1387. HAL_PCDEx_SetConnectionState(hpcd, 1U);
  1388. #endif /* defined (USB) */
  1389. (void)USB_DevConnect(hpcd->Instance);
  1390. __HAL_UNLOCK(hpcd);
  1391. return HAL_OK;
  1392. }
  1393. /**
  1394. * @brief Disconnect the USB device.
  1395. * @param hpcd PCD handle
  1396. * @retval HAL status
  1397. */
  1398. HAL_StatusTypeDef HAL_PCD_DevDisconnect(PCD_HandleTypeDef *hpcd)
  1399. {
  1400. __HAL_LOCK(hpcd);
  1401. #if defined (USB)
  1402. HAL_PCDEx_SetConnectionState(hpcd, 0U);
  1403. #endif /* defined (USB) */
  1404. (void)USB_DevDisconnect(hpcd->Instance);
  1405. __HAL_UNLOCK(hpcd);
  1406. return HAL_OK;
  1407. }
  1408. /**
  1409. * @brief Set the USB Device address.
  1410. * @param hpcd PCD handle
  1411. * @param address new device address
  1412. * @retval HAL status
  1413. */
  1414. HAL_StatusTypeDef HAL_PCD_SetAddress(PCD_HandleTypeDef *hpcd, uint8_t address)
  1415. {
  1416. __HAL_LOCK(hpcd);
  1417. hpcd->USB_Address = address;
  1418. (void)USB_SetDevAddress(hpcd->Instance, address);
  1419. __HAL_UNLOCK(hpcd);
  1420. return HAL_OK;
  1421. }
  1422. /**
  1423. * @brief Open and configure an endpoint.
  1424. * @param hpcd PCD handle
  1425. * @param ep_addr endpoint address
  1426. * @param ep_mps endpoint max packet size
  1427. * @param ep_type endpoint type
  1428. * @retval HAL status
  1429. */
  1430. HAL_StatusTypeDef HAL_PCD_EP_Open(PCD_HandleTypeDef *hpcd, uint8_t ep_addr,
  1431. uint16_t ep_mps, uint8_t ep_type)
  1432. {
  1433. HAL_StatusTypeDef ret = HAL_OK;
  1434. PCD_EPTypeDef *ep;
  1435. if ((ep_addr & 0x80U) == 0x80U)
  1436. {
  1437. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1438. ep->is_in = 1U;
  1439. }
  1440. else
  1441. {
  1442. ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1443. ep->is_in = 0U;
  1444. }
  1445. ep->num = ep_addr & EP_ADDR_MSK;
  1446. ep->maxpacket = ep_mps;
  1447. ep->type = ep_type;
  1448. #if defined (USB_OTG_FS)
  1449. if (ep->is_in != 0U)
  1450. {
  1451. /* Assign a Tx FIFO */
  1452. ep->tx_fifo_num = ep->num;
  1453. }
  1454. #endif /* defined (USB_OTG_FS) */
  1455. /* Set initial data PID. */
  1456. if (ep_type == EP_TYPE_BULK)
  1457. {
  1458. ep->data_pid_start = 0U;
  1459. }
  1460. __HAL_LOCK(hpcd);
  1461. (void)USB_ActivateEndpoint(hpcd->Instance, ep);
  1462. __HAL_UNLOCK(hpcd);
  1463. return ret;
  1464. }
  1465. /**
  1466. * @brief Deactivate an endpoint.
  1467. * @param hpcd PCD handle
  1468. * @param ep_addr endpoint address
  1469. * @retval HAL status
  1470. */
  1471. HAL_StatusTypeDef HAL_PCD_EP_Close(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1472. {
  1473. PCD_EPTypeDef *ep;
  1474. if ((ep_addr & 0x80U) == 0x80U)
  1475. {
  1476. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1477. ep->is_in = 1U;
  1478. }
  1479. else
  1480. {
  1481. ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1482. ep->is_in = 0U;
  1483. }
  1484. ep->num = ep_addr & EP_ADDR_MSK;
  1485. __HAL_LOCK(hpcd);
  1486. (void)USB_DeactivateEndpoint(hpcd->Instance, ep);
  1487. __HAL_UNLOCK(hpcd);
  1488. return HAL_OK;
  1489. }
  1490. /**
  1491. * @brief Receive an amount of data.
  1492. * @param hpcd PCD handle
  1493. * @param ep_addr endpoint address
  1494. * @param pBuf pointer to the reception buffer
  1495. * @param len amount of data to be received
  1496. * @retval HAL status
  1497. */
  1498. HAL_StatusTypeDef HAL_PCD_EP_Receive(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  1499. {
  1500. PCD_EPTypeDef *ep;
  1501. ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1502. /*setup and start the Xfer */
  1503. ep->xfer_buff = pBuf;
  1504. ep->xfer_len = len;
  1505. ep->xfer_count = 0U;
  1506. ep->is_in = 0U;
  1507. ep->num = ep_addr & EP_ADDR_MSK;
  1508. (void)USB_EPStartXfer(hpcd->Instance, ep);
  1509. return HAL_OK;
  1510. }
  1511. /**
  1512. * @brief Get Received Data Size
  1513. * @param hpcd PCD handle
  1514. * @param ep_addr endpoint address
  1515. * @retval Data Size
  1516. */
  1517. uint32_t HAL_PCD_EP_GetRxCount(PCD_HandleTypeDef const *hpcd, uint8_t ep_addr)
  1518. {
  1519. return hpcd->OUT_ep[ep_addr & EP_ADDR_MSK].xfer_count;
  1520. }
  1521. /**
  1522. * @brief Send an amount of data
  1523. * @param hpcd PCD handle
  1524. * @param ep_addr endpoint address
  1525. * @param pBuf pointer to the transmission buffer
  1526. * @param len amount of data to be sent
  1527. * @retval HAL status
  1528. */
  1529. HAL_StatusTypeDef HAL_PCD_EP_Transmit(PCD_HandleTypeDef *hpcd, uint8_t ep_addr, uint8_t *pBuf, uint32_t len)
  1530. {
  1531. PCD_EPTypeDef *ep;
  1532. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1533. /*setup and start the Xfer */
  1534. ep->xfer_buff = pBuf;
  1535. ep->xfer_len = len;
  1536. #if defined (USB)
  1537. ep->xfer_fill_db = 1U;
  1538. ep->xfer_len_db = len;
  1539. #endif /* defined (USB) */
  1540. ep->xfer_count = 0U;
  1541. ep->is_in = 1U;
  1542. ep->num = ep_addr & EP_ADDR_MSK;
  1543. (void)USB_EPStartXfer(hpcd->Instance, ep);
  1544. return HAL_OK;
  1545. }
  1546. /**
  1547. * @brief Set a STALL condition over an endpoint
  1548. * @param hpcd PCD handle
  1549. * @param ep_addr endpoint address
  1550. * @retval HAL status
  1551. */
  1552. HAL_StatusTypeDef HAL_PCD_EP_SetStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1553. {
  1554. PCD_EPTypeDef *ep;
  1555. if (((uint32_t)ep_addr & EP_ADDR_MSK) > hpcd->Init.dev_endpoints)
  1556. {
  1557. return HAL_ERROR;
  1558. }
  1559. if ((0x80U & ep_addr) == 0x80U)
  1560. {
  1561. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1562. ep->is_in = 1U;
  1563. }
  1564. else
  1565. {
  1566. ep = &hpcd->OUT_ep[ep_addr];
  1567. ep->is_in = 0U;
  1568. }
  1569. ep->is_stall = 1U;
  1570. ep->num = ep_addr & EP_ADDR_MSK;
  1571. __HAL_LOCK(hpcd);
  1572. (void)USB_EPSetStall(hpcd->Instance, ep);
  1573. if ((ep_addr & EP_ADDR_MSK) == 0U)
  1574. {
  1575. (void)USB_EP0_OutStart(hpcd->Instance, (uint8_t *)hpcd->Setup);
  1576. }
  1577. __HAL_UNLOCK(hpcd);
  1578. return HAL_OK;
  1579. }
  1580. /**
  1581. * @brief Clear a STALL condition over in an endpoint
  1582. * @param hpcd PCD handle
  1583. * @param ep_addr endpoint address
  1584. * @retval HAL status
  1585. */
  1586. HAL_StatusTypeDef HAL_PCD_EP_ClrStall(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1587. {
  1588. PCD_EPTypeDef *ep;
  1589. if (((uint32_t)ep_addr & 0x0FU) > hpcd->Init.dev_endpoints)
  1590. {
  1591. return HAL_ERROR;
  1592. }
  1593. if ((0x80U & ep_addr) == 0x80U)
  1594. {
  1595. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1596. ep->is_in = 1U;
  1597. }
  1598. else
  1599. {
  1600. ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1601. ep->is_in = 0U;
  1602. }
  1603. ep->is_stall = 0U;
  1604. ep->num = ep_addr & EP_ADDR_MSK;
  1605. __HAL_LOCK(hpcd);
  1606. (void)USB_EPClearStall(hpcd->Instance, ep);
  1607. __HAL_UNLOCK(hpcd);
  1608. return HAL_OK;
  1609. }
  1610. /**
  1611. * @brief Abort an USB EP transaction.
  1612. * @param hpcd PCD handle
  1613. * @param ep_addr endpoint address
  1614. * @retval HAL status
  1615. */
  1616. HAL_StatusTypeDef HAL_PCD_EP_Abort(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1617. {
  1618. HAL_StatusTypeDef ret;
  1619. PCD_EPTypeDef *ep;
  1620. if ((0x80U & ep_addr) == 0x80U)
  1621. {
  1622. ep = &hpcd->IN_ep[ep_addr & EP_ADDR_MSK];
  1623. }
  1624. else
  1625. {
  1626. ep = &hpcd->OUT_ep[ep_addr & EP_ADDR_MSK];
  1627. }
  1628. /* Stop Xfer */
  1629. ret = USB_EPStopXfer(hpcd->Instance, ep);
  1630. return ret;
  1631. }
  1632. /**
  1633. * @brief Flush an endpoint
  1634. * @param hpcd PCD handle
  1635. * @param ep_addr endpoint address
  1636. * @retval HAL status
  1637. */
  1638. HAL_StatusTypeDef HAL_PCD_EP_Flush(PCD_HandleTypeDef *hpcd, uint8_t ep_addr)
  1639. {
  1640. __HAL_LOCK(hpcd);
  1641. if ((ep_addr & 0x80U) == 0x80U)
  1642. {
  1643. (void)USB_FlushTxFifo(hpcd->Instance, (uint32_t)ep_addr & EP_ADDR_MSK);
  1644. }
  1645. else
  1646. {
  1647. (void)USB_FlushRxFifo(hpcd->Instance);
  1648. }
  1649. __HAL_UNLOCK(hpcd);
  1650. return HAL_OK;
  1651. }
  1652. /**
  1653. * @brief Activate remote wakeup signalling
  1654. * @param hpcd PCD handle
  1655. * @retval HAL status
  1656. */
  1657. HAL_StatusTypeDef HAL_PCD_ActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  1658. {
  1659. return (USB_ActivateRemoteWakeup(hpcd->Instance));
  1660. }
  1661. /**
  1662. * @brief De-activate remote wakeup signalling.
  1663. * @param hpcd PCD handle
  1664. * @retval HAL status
  1665. */
  1666. HAL_StatusTypeDef HAL_PCD_DeActivateRemoteWakeup(PCD_HandleTypeDef *hpcd)
  1667. {
  1668. return (USB_DeActivateRemoteWakeup(hpcd->Instance));
  1669. }
  1670. /**
  1671. * @}
  1672. */
  1673. /** @defgroup PCD_Exported_Functions_Group4 Peripheral State functions
  1674. * @brief Peripheral State functions
  1675. *
  1676. @verbatim
  1677. ===============================================================================
  1678. ##### Peripheral State functions #####
  1679. ===============================================================================
  1680. [..]
  1681. This subsection permits to get in run-time the status of the peripheral
  1682. and the data flow.
  1683. @endverbatim
  1684. * @{
  1685. */
  1686. /**
  1687. * @brief Return the PCD handle state.
  1688. * @param hpcd PCD handle
  1689. * @retval HAL state
  1690. */
  1691. PCD_StateTypeDef HAL_PCD_GetState(PCD_HandleTypeDef const *hpcd)
  1692. {
  1693. return hpcd->State;
  1694. }
  1695. /**
  1696. * @}
  1697. */
  1698. /**
  1699. * @}
  1700. */
  1701. /* Private functions ---------------------------------------------------------*/
  1702. /** @addtogroup PCD_Private_Functions
  1703. * @{
  1704. */
  1705. #if defined (USB_OTG_FS)
  1706. /**
  1707. * @brief Check FIFO for the next packet to be loaded.
  1708. * @param hpcd PCD handle
  1709. * @param epnum endpoint number
  1710. * @retval HAL status
  1711. */
  1712. static HAL_StatusTypeDef PCD_WriteEmptyTxFifo(PCD_HandleTypeDef *hpcd, uint32_t epnum)
  1713. {
  1714. USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  1715. uint32_t USBx_BASE = (uint32_t)USBx;
  1716. USB_OTG_EPTypeDef *ep;
  1717. uint32_t len;
  1718. uint32_t len32b;
  1719. uint32_t fifoemptymsk;
  1720. ep = &hpcd->IN_ep[epnum];
  1721. if (ep->xfer_count > ep->xfer_len)
  1722. {
  1723. return HAL_ERROR;
  1724. }
  1725. len = ep->xfer_len - ep->xfer_count;
  1726. if (len > ep->maxpacket)
  1727. {
  1728. len = ep->maxpacket;
  1729. }
  1730. len32b = (len + 3U) / 4U;
  1731. while (((USBx_INEP(epnum)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= len32b) &&
  1732. (ep->xfer_count < ep->xfer_len) && (ep->xfer_len != 0U))
  1733. {
  1734. /* Write the FIFO */
  1735. len = ep->xfer_len - ep->xfer_count;
  1736. if (len > ep->maxpacket)
  1737. {
  1738. len = ep->maxpacket;
  1739. }
  1740. len32b = (len + 3U) / 4U;
  1741. (void)USB_WritePacket(USBx, ep->xfer_buff, (uint8_t)epnum, (uint16_t)len);
  1742. ep->xfer_buff += len;
  1743. ep->xfer_count += len;
  1744. }
  1745. if (ep->xfer_len <= ep->xfer_count)
  1746. {
  1747. fifoemptymsk = (uint32_t)(0x1UL << (epnum & EP_ADDR_MSK));
  1748. USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk;
  1749. }
  1750. return HAL_OK;
  1751. }
  1752. /**
  1753. * @brief process EP OUT transfer complete interrupt.
  1754. * @param hpcd PCD handle
  1755. * @param epnum endpoint number
  1756. * @retval HAL status
  1757. */
  1758. static HAL_StatusTypeDef PCD_EP_OutXfrComplete_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
  1759. {
  1760. const USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  1761. uint32_t USBx_BASE = (uint32_t)USBx;
  1762. uint32_t gSNPSiD = *(__IO const uint32_t *)(&USBx->CID + 0x1U);
  1763. uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
  1764. if (gSNPSiD == USB_OTG_CORE_ID_310A)
  1765. {
  1766. /* StupPktRcvd = 1 this is a setup packet */
  1767. if ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX)
  1768. {
  1769. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
  1770. }
  1771. else
  1772. {
  1773. if ((DoepintReg & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR)
  1774. {
  1775. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR);
  1776. }
  1777. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1778. hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
  1779. #else
  1780. HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
  1781. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1782. }
  1783. }
  1784. else
  1785. {
  1786. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1787. hpcd->DataOutStageCallback(hpcd, (uint8_t)epnum);
  1788. #else
  1789. HAL_PCD_DataOutStageCallback(hpcd, (uint8_t)epnum);
  1790. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1791. }
  1792. return HAL_OK;
  1793. }
  1794. /**
  1795. * @brief process EP OUT setup packet received interrupt.
  1796. * @param hpcd PCD handle
  1797. * @param epnum endpoint number
  1798. * @retval HAL status
  1799. */
  1800. static HAL_StatusTypeDef PCD_EP_OutSetupPacket_int(PCD_HandleTypeDef *hpcd, uint32_t epnum)
  1801. {
  1802. const USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
  1803. uint32_t USBx_BASE = (uint32_t)USBx;
  1804. uint32_t gSNPSiD = *(__IO const uint32_t *)(&USBx->CID + 0x1U);
  1805. uint32_t DoepintReg = USBx_OUTEP(epnum)->DOEPINT;
  1806. if ((gSNPSiD > USB_OTG_CORE_ID_300A) &&
  1807. ((DoepintReg & USB_OTG_DOEPINT_STPKTRX) == USB_OTG_DOEPINT_STPKTRX))
  1808. {
  1809. CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STPKTRX);
  1810. }
  1811. /* Inform the upper layer that a setup packet is available */
  1812. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1813. hpcd->SetupStageCallback(hpcd);
  1814. #else
  1815. HAL_PCD_SetupStageCallback(hpcd);
  1816. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1817. return HAL_OK;
  1818. }
  1819. #endif /* defined (USB_OTG_FS) */
  1820. #if defined (USB)
  1821. /**
  1822. * @brief This function handles PCD Endpoint interrupt request.
  1823. * @param hpcd PCD handle
  1824. * @retval HAL status
  1825. */
  1826. static HAL_StatusTypeDef PCD_EP_ISR_Handler(PCD_HandleTypeDef *hpcd)
  1827. {
  1828. PCD_EPTypeDef *ep;
  1829. uint16_t count;
  1830. uint16_t wIstr;
  1831. uint16_t wEPVal;
  1832. uint16_t TxPctSize;
  1833. uint8_t epindex;
  1834. #if (USE_USB_DOUBLE_BUFFER != 1U)
  1835. count = 0U;
  1836. #endif /* USE_USB_DOUBLE_BUFFER */
  1837. /* stay in loop while pending interrupts */
  1838. while ((hpcd->Instance->ISTR & USB_ISTR_CTR) != 0U)
  1839. {
  1840. wIstr = hpcd->Instance->ISTR;
  1841. /* extract highest priority endpoint number */
  1842. epindex = (uint8_t)(wIstr & USB_ISTR_EP_ID);
  1843. if (epindex == 0U)
  1844. {
  1845. /* Decode and service control endpoint interrupt */
  1846. /* DIR bit = origin of the interrupt */
  1847. if ((wIstr & USB_ISTR_DIR) == 0U)
  1848. {
  1849. /* DIR = 0 */
  1850. /* DIR = 0 => IN int */
  1851. /* DIR = 0 implies that (EP_CTR_TX = 1) always */
  1852. PCD_CLEAR_TX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1853. ep = &hpcd->IN_ep[0];
  1854. ep->xfer_count = PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  1855. ep->xfer_buff += ep->xfer_count;
  1856. /* TX COMPLETE */
  1857. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1858. hpcd->DataInStageCallback(hpcd, 0U);
  1859. #else
  1860. HAL_PCD_DataInStageCallback(hpcd, 0U);
  1861. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1862. if ((hpcd->USB_Address > 0U) && (ep->xfer_len == 0U))
  1863. {
  1864. hpcd->Instance->DADDR = ((uint16_t)hpcd->USB_Address | USB_DADDR_EF);
  1865. hpcd->USB_Address = 0U;
  1866. }
  1867. }
  1868. else
  1869. {
  1870. /* DIR = 1 */
  1871. /* DIR = 1 & CTR_RX => SETUP or OUT int */
  1872. /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
  1873. ep = &hpcd->OUT_ep[0];
  1874. wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
  1875. if ((wEPVal & USB_EP_SETUP) != 0U)
  1876. {
  1877. /* Get SETUP Packet */
  1878. ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1879. USB_ReadPMA(hpcd->Instance, (uint8_t *)hpcd->Setup,
  1880. ep->pmaadress, (uint16_t)ep->xfer_count);
  1881. /* SETUP bit kept frozen while CTR_RX = 1 */
  1882. PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1883. /* Process SETUP Packet*/
  1884. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1885. hpcd->SetupStageCallback(hpcd);
  1886. #else
  1887. HAL_PCD_SetupStageCallback(hpcd);
  1888. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1889. }
  1890. else if ((wEPVal & USB_EP_CTR_RX) != 0U)
  1891. {
  1892. PCD_CLEAR_RX_EP_CTR(hpcd->Instance, PCD_ENDP0);
  1893. /* Get Control Data OUT Packet */
  1894. ep->xfer_count = PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1895. if ((ep->xfer_count != 0U) && (ep->xfer_buff != 0U))
  1896. {
  1897. USB_ReadPMA(hpcd->Instance, ep->xfer_buff,
  1898. ep->pmaadress, (uint16_t)ep->xfer_count);
  1899. ep->xfer_buff += ep->xfer_count;
  1900. /* Process Control Data OUT Packet */
  1901. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1902. hpcd->DataOutStageCallback(hpcd, 0U);
  1903. #else
  1904. HAL_PCD_DataOutStageCallback(hpcd, 0U);
  1905. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1906. }
  1907. wEPVal = (uint16_t)PCD_GET_ENDPOINT(hpcd->Instance, PCD_ENDP0);
  1908. if (((wEPVal & USB_EP_SETUP) == 0U) && ((wEPVal & USB_EP_RX_STRX) != USB_EP_RX_VALID))
  1909. {
  1910. PCD_SET_EP_RX_CNT(hpcd->Instance, PCD_ENDP0, ep->maxpacket);
  1911. PCD_SET_EP_RX_STATUS(hpcd->Instance, PCD_ENDP0, USB_EP_RX_VALID);
  1912. }
  1913. }
  1914. }
  1915. }
  1916. else
  1917. {
  1918. /* Decode and service non control endpoints interrupt */
  1919. /* process related endpoint register */
  1920. wEPVal = PCD_GET_ENDPOINT(hpcd->Instance, epindex);
  1921. if ((wEPVal & USB_EP_CTR_RX) != 0U)
  1922. {
  1923. /* clear int flag */
  1924. PCD_CLEAR_RX_EP_CTR(hpcd->Instance, epindex);
  1925. ep = &hpcd->OUT_ep[epindex];
  1926. /* OUT Single Buffering */
  1927. if (ep->doublebuffer == 0U)
  1928. {
  1929. count = (uint16_t)PCD_GET_EP_RX_CNT(hpcd->Instance, ep->num);
  1930. if (count != 0U)
  1931. {
  1932. USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaadress, count);
  1933. }
  1934. }
  1935. #if (USE_USB_DOUBLE_BUFFER == 1U)
  1936. else
  1937. {
  1938. /* manage double buffer bulk out */
  1939. if (ep->type == EP_TYPE_BULK)
  1940. {
  1941. count = HAL_PCD_EP_DB_Receive(hpcd, ep, wEPVal);
  1942. }
  1943. else /* manage double buffer iso out */
  1944. {
  1945. /* free EP OUT Buffer */
  1946. PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 0U);
  1947. if ((PCD_GET_ENDPOINT(hpcd->Instance, ep->num) & USB_EP_DTOG_RX) != 0U)
  1948. {
  1949. /* read from endpoint BUF0Addr buffer */
  1950. count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  1951. if (count != 0U)
  1952. {
  1953. USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
  1954. }
  1955. }
  1956. else
  1957. {
  1958. /* read from endpoint BUF1Addr buffer */
  1959. count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  1960. if (count != 0U)
  1961. {
  1962. USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
  1963. }
  1964. }
  1965. }
  1966. }
  1967. #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
  1968. /* multi-packet on the NON control OUT endpoint */
  1969. ep->xfer_count += count;
  1970. ep->xfer_buff += count;
  1971. if ((ep->xfer_len == 0U) || (count < ep->maxpacket))
  1972. {
  1973. /* RX COMPLETE */
  1974. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  1975. hpcd->DataOutStageCallback(hpcd, ep->num);
  1976. #else
  1977. HAL_PCD_DataOutStageCallback(hpcd, ep->num);
  1978. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  1979. }
  1980. else
  1981. {
  1982. (void)USB_EPStartXfer(hpcd->Instance, ep);
  1983. }
  1984. }
  1985. if ((wEPVal & USB_EP_CTR_TX) != 0U)
  1986. {
  1987. ep = &hpcd->IN_ep[epindex];
  1988. /* clear int flag */
  1989. PCD_CLEAR_TX_EP_CTR(hpcd->Instance, epindex);
  1990. if (ep->type == EP_TYPE_ISOC)
  1991. {
  1992. ep->xfer_len = 0U;
  1993. #if (USE_USB_DOUBLE_BUFFER == 1U)
  1994. if (ep->doublebuffer != 0U)
  1995. {
  1996. if ((wEPVal & USB_EP_DTOG_TX) != 0U)
  1997. {
  1998. PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
  1999. }
  2000. else
  2001. {
  2002. PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
  2003. }
  2004. }
  2005. #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
  2006. /* TX COMPLETE */
  2007. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2008. hpcd->DataInStageCallback(hpcd, ep->num);
  2009. #else
  2010. HAL_PCD_DataInStageCallback(hpcd, ep->num);
  2011. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2012. }
  2013. else
  2014. {
  2015. /* Manage Single Buffer Transaction */
  2016. if ((wEPVal & USB_EP_KIND) == 0U)
  2017. {
  2018. /* multi-packet on the NON control IN endpoint */
  2019. TxPctSize = (uint16_t)PCD_GET_EP_TX_CNT(hpcd->Instance, ep->num);
  2020. if (ep->xfer_len > TxPctSize)
  2021. {
  2022. ep->xfer_len -= TxPctSize;
  2023. }
  2024. else
  2025. {
  2026. ep->xfer_len = 0U;
  2027. }
  2028. /* Zero Length Packet? */
  2029. if (ep->xfer_len == 0U)
  2030. {
  2031. /* TX COMPLETE */
  2032. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2033. hpcd->DataInStageCallback(hpcd, ep->num);
  2034. #else
  2035. HAL_PCD_DataInStageCallback(hpcd, ep->num);
  2036. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2037. }
  2038. else
  2039. {
  2040. /* Transfer is not yet Done */
  2041. ep->xfer_buff += TxPctSize;
  2042. ep->xfer_count += TxPctSize;
  2043. (void)USB_EPStartXfer(hpcd->Instance, ep);
  2044. }
  2045. }
  2046. #if (USE_USB_DOUBLE_BUFFER == 1U)
  2047. /* Double Buffer bulk IN (bulk transfer Len > Ep_Mps) */
  2048. else
  2049. {
  2050. (void)HAL_PCD_EP_DB_Transmit(hpcd, ep, wEPVal);
  2051. }
  2052. #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
  2053. }
  2054. }
  2055. }
  2056. }
  2057. return HAL_OK;
  2058. }
  2059. #if (USE_USB_DOUBLE_BUFFER == 1U)
  2060. /**
  2061. * @brief Manage double buffer bulk out transaction from ISR
  2062. * @param hpcd PCD handle
  2063. * @param ep current endpoint handle
  2064. * @param wEPVal Last snapshot of EPRx register value taken in ISR
  2065. * @retval HAL status
  2066. */
  2067. static uint16_t HAL_PCD_EP_DB_Receive(PCD_HandleTypeDef *hpcd,
  2068. PCD_EPTypeDef *ep, uint16_t wEPVal)
  2069. {
  2070. uint16_t count;
  2071. /* Manage Buffer0 OUT */
  2072. if ((wEPVal & USB_EP_DTOG_RX) != 0U)
  2073. {
  2074. /* Get count of received Data on buffer0 */
  2075. count = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  2076. if (ep->xfer_len >= count)
  2077. {
  2078. ep->xfer_len -= count;
  2079. }
  2080. else
  2081. {
  2082. ep->xfer_len = 0U;
  2083. }
  2084. if (ep->xfer_len == 0U)
  2085. {
  2086. /* set NAK to OUT endpoint since double buffer is enabled */
  2087. PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_NAK);
  2088. }
  2089. /* Check if Buffer1 is in blocked state which requires to toggle */
  2090. if ((wEPVal & USB_EP_DTOG_TX) != 0U)
  2091. {
  2092. PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 0U);
  2093. }
  2094. if (count != 0U)
  2095. {
  2096. USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, count);
  2097. }
  2098. }
  2099. /* Manage Buffer 1 DTOG_RX=0 */
  2100. else
  2101. {
  2102. /* Get count of received data */
  2103. count = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  2104. if (ep->xfer_len >= count)
  2105. {
  2106. ep->xfer_len -= count;
  2107. }
  2108. else
  2109. {
  2110. ep->xfer_len = 0U;
  2111. }
  2112. if (ep->xfer_len == 0U)
  2113. {
  2114. /* set NAK on the current endpoint */
  2115. PCD_SET_EP_RX_STATUS(hpcd->Instance, ep->num, USB_EP_RX_NAK);
  2116. }
  2117. /*Need to FreeUser Buffer*/
  2118. if ((wEPVal & USB_EP_DTOG_TX) == 0U)
  2119. {
  2120. PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 0U);
  2121. }
  2122. if (count != 0U)
  2123. {
  2124. USB_ReadPMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, count);
  2125. }
  2126. }
  2127. return count;
  2128. }
  2129. /**
  2130. * @brief Manage double buffer bulk IN transaction from ISR
  2131. * @param hpcd PCD handle
  2132. * @param ep current endpoint handle
  2133. * @param wEPVal Last snapshot of EPRx register value taken in ISR
  2134. * @retval HAL status
  2135. */
  2136. static HAL_StatusTypeDef HAL_PCD_EP_DB_Transmit(PCD_HandleTypeDef *hpcd,
  2137. PCD_EPTypeDef *ep, uint16_t wEPVal)
  2138. {
  2139. uint32_t len;
  2140. uint16_t TxPctSize;
  2141. /* Data Buffer0 ACK received */
  2142. if ((wEPVal & USB_EP_DTOG_TX) != 0U)
  2143. {
  2144. /* multi-packet on the NON control IN endpoint */
  2145. TxPctSize = (uint16_t)PCD_GET_EP_DBUF0_CNT(hpcd->Instance, ep->num);
  2146. if (ep->xfer_len > TxPctSize)
  2147. {
  2148. ep->xfer_len -= TxPctSize;
  2149. }
  2150. else
  2151. {
  2152. ep->xfer_len = 0U;
  2153. }
  2154. /* Transfer is completed */
  2155. if (ep->xfer_len == 0U)
  2156. {
  2157. PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
  2158. PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
  2159. /* TX COMPLETE */
  2160. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2161. hpcd->DataInStageCallback(hpcd, ep->num);
  2162. #else
  2163. HAL_PCD_DataInStageCallback(hpcd, ep->num);
  2164. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2165. if ((wEPVal & USB_EP_DTOG_RX) != 0U)
  2166. {
  2167. PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U);
  2168. }
  2169. }
  2170. else /* Transfer is not yet Done */
  2171. {
  2172. /* need to Free USB Buff */
  2173. if ((wEPVal & USB_EP_DTOG_RX) != 0U)
  2174. {
  2175. PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U);
  2176. }
  2177. /* Still there is data to Fill in the next Buffer */
  2178. if (ep->xfer_fill_db == 1U)
  2179. {
  2180. ep->xfer_buff += TxPctSize;
  2181. ep->xfer_count += TxPctSize;
  2182. /* Calculate the len of the new buffer to fill */
  2183. if (ep->xfer_len_db >= ep->maxpacket)
  2184. {
  2185. len = ep->maxpacket;
  2186. ep->xfer_len_db -= len;
  2187. }
  2188. else if (ep->xfer_len_db == 0U)
  2189. {
  2190. len = TxPctSize;
  2191. ep->xfer_fill_db = 0U;
  2192. }
  2193. else
  2194. {
  2195. ep->xfer_fill_db = 0U;
  2196. len = ep->xfer_len_db;
  2197. ep->xfer_len_db = 0U;
  2198. }
  2199. /* Write remaining Data to Buffer */
  2200. /* Set the Double buffer counter for pma buffer1 */
  2201. PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, len);
  2202. /* Copy user buffer to USB PMA */
  2203. USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr0, (uint16_t)len);
  2204. }
  2205. }
  2206. }
  2207. else /* Data Buffer1 ACK received */
  2208. {
  2209. /* multi-packet on the NON control IN endpoint */
  2210. TxPctSize = (uint16_t)PCD_GET_EP_DBUF1_CNT(hpcd->Instance, ep->num);
  2211. if (ep->xfer_len >= TxPctSize)
  2212. {
  2213. ep->xfer_len -= TxPctSize;
  2214. }
  2215. else
  2216. {
  2217. ep->xfer_len = 0U;
  2218. }
  2219. /* Transfer is completed */
  2220. if (ep->xfer_len == 0U)
  2221. {
  2222. PCD_SET_EP_DBUF0_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
  2223. PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, 0U);
  2224. /* TX COMPLETE */
  2225. #if (USE_HAL_PCD_REGISTER_CALLBACKS == 1U)
  2226. hpcd->DataInStageCallback(hpcd, ep->num);
  2227. #else
  2228. HAL_PCD_DataInStageCallback(hpcd, ep->num);
  2229. #endif /* USE_HAL_PCD_REGISTER_CALLBACKS */
  2230. /* need to Free USB Buff */
  2231. if ((wEPVal & USB_EP_DTOG_RX) == 0U)
  2232. {
  2233. PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U);
  2234. }
  2235. }
  2236. else /* Transfer is not yet Done */
  2237. {
  2238. /* need to Free USB Buff */
  2239. if ((wEPVal & USB_EP_DTOG_RX) == 0U)
  2240. {
  2241. PCD_FREE_USER_BUFFER(hpcd->Instance, ep->num, 1U);
  2242. }
  2243. /* Still there is data to Fill in the next Buffer */
  2244. if (ep->xfer_fill_db == 1U)
  2245. {
  2246. ep->xfer_buff += TxPctSize;
  2247. ep->xfer_count += TxPctSize;
  2248. /* Calculate the len of the new buffer to fill */
  2249. if (ep->xfer_len_db >= ep->maxpacket)
  2250. {
  2251. len = ep->maxpacket;
  2252. ep->xfer_len_db -= len;
  2253. }
  2254. else if (ep->xfer_len_db == 0U)
  2255. {
  2256. len = TxPctSize;
  2257. ep->xfer_fill_db = 0U;
  2258. }
  2259. else
  2260. {
  2261. len = ep->xfer_len_db;
  2262. ep->xfer_len_db = 0U;
  2263. ep->xfer_fill_db = 0;
  2264. }
  2265. /* Set the Double buffer counter for pmabuffer1 */
  2266. PCD_SET_EP_DBUF1_CNT(hpcd->Instance, ep->num, ep->is_in, len);
  2267. /* Copy the user buffer to USB PMA */
  2268. USB_WritePMA(hpcd->Instance, ep->xfer_buff, ep->pmaaddr1, (uint16_t)len);
  2269. }
  2270. }
  2271. }
  2272. /*enable endpoint IN*/
  2273. PCD_SET_EP_TX_STATUS(hpcd->Instance, ep->num, USB_EP_TX_VALID);
  2274. return HAL_OK;
  2275. }
  2276. #endif /* (USE_USB_DOUBLE_BUFFER == 1U) */
  2277. #endif /* defined (USB) */
  2278. /**
  2279. * @}
  2280. */
  2281. #endif /* defined (USB) || defined (USB_OTG_FS) */
  2282. #endif /* HAL_PCD_MODULE_ENABLED */
  2283. /**
  2284. * @}
  2285. */
  2286. /**
  2287. * @}
  2288. */