usbd_conf.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906
  1. /**
  2. ******************************************************************************
  3. * @file : Target/usbd_conf.c
  4. * @version : v2.0_Cube
  5. * @brief : This file implements the board support package for the USB device library
  6. ******************************************************************************/
  7. #include "stm32l1xx.h"
  8. #include "stm32l1xx_hal.h"
  9. #include "usbd_def.h"
  10. #include "usbd_core.h"
  11. #include "usbd_vendor.h"
  12. #include "usbd_usbtmc.h"
  13. #include "core/sleep_and_exti.h" // SleepManagerHandle
  14. // This module uses GPIO line as a USB_VCC presense line
  15. // PC13 (#2)
  16. // Place EP0 buffers in the tail of PMA
  17. #define USBD_UPDATEPMA_EP0TAIL 1
  18. PCD_HandleTypeDef hpcd_USB_FS;
  19. void Error_Handler(void);
  20. void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state);
  21. /*******************************************************************************
  22. LL Driver Callbacks (PCD -> USB Device Library)
  23. *******************************************************************************/
  24. /* MSP Init */
  25. void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle)
  26. {
  27. if(pcdHandle->Instance==USB)
  28. {
  29. /* Peripheral clock enable */
  30. __HAL_RCC_USB_CLK_ENABLE();
  31. /* Peripheral interrupt init */
  32. HAL_NVIC_SetPriority(USB_LP_IRQn, USB_INT_PRIORITY, 0);
  33. HAL_NVIC_EnableIRQ(USB_LP_IRQn);
  34. #if CONFIG_SLEEPMANAGER
  35. // Initialize WakeUp pin
  36. SleepManagerHandle.SetUSBWakeup( true );
  37. #endif
  38. /*Configure GPIO pins : PA11 PA12 for very high speed INPUT */
  39. {
  40. GPIO_InitTypeDef GPIO_InitStruct = {0};
  41. GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
  42. GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // Surprised???! it works! And only this works!
  43. GPIO_InitStruct.Pull = GPIO_NOPULL;
  44. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  45. HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  46. }
  47. }
  48. }
  49. void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle)
  50. {
  51. if(pcdHandle->Instance==USB)
  52. {
  53. #if CONFIG_SLEEPMANAGER
  54. // DeInitialize WakeUp pin
  55. SleepManagerHandle.SetUSBWakeup( false );
  56. #endif
  57. /* Peripheral clock disable */
  58. __HAL_RCC_USB_CLK_DISABLE();
  59. /* Peripheral interrupt Deinit*/
  60. HAL_NVIC_DisableIRQ(USB_LP_IRQn);
  61. }
  62. }
  63. /**
  64. * @brief Setup stage callback
  65. * @param hpcd: PCD handle
  66. * @retval None
  67. */
  68. void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
  69. {
  70. USBD_LL_SetupStage((USBD_HandleTypeDef*)hpcd->pData, (uint8_t *)hpcd->Setup);
  71. }
  72. /**
  73. * @brief Data Out stage callback.
  74. * @param hpcd: PCD handle
  75. * @param epnum: Endpoint number
  76. * @retval None
  77. */
  78. void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  79. {
  80. USBD_LL_DataOutStage((USBD_HandleTypeDef*)hpcd->pData, epnum,
  81. hpcd->OUT_ep[epnum].xfer_buff );
  82. }
  83. /**
  84. * @brief Data In stage callback.
  85. * @param hpcd: PCD handle
  86. * @param epnum: Endpoint number
  87. * @retval None
  88. */
  89. void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  90. {
  91. USBD_LL_DataInStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff);
  92. }
  93. /**
  94. * @brief SOF callback.
  95. * @param hpcd: PCD handle
  96. * @retval None
  97. */
  98. void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
  99. {
  100. USBD_LL_SOF((USBD_HandleTypeDef*)hpcd->pData);
  101. }
  102. /**
  103. * @brief Reset callback.
  104. * @param hpcd: PCD handle
  105. * @retval None
  106. */
  107. void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
  108. {
  109. USBD_LL_SetSpeed((USBD_HandleTypeDef*)hpcd->pData, USBD_SPEED_FULL );
  110. /* Reset Device. */
  111. USBD_LL_Reset((USBD_HandleTypeDef*)hpcd->pData);
  112. }
  113. /**
  114. * @brief Suspend callback.
  115. * When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it)
  116. * @param hpcd: PCD handle
  117. * @retval None
  118. */
  119. void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
  120. {
  121. /* Inform USB library that core enters in suspend Mode. */
  122. USBD_LL_Suspend((USBD_HandleTypeDef*)hpcd->pData);
  123. /* Enter in STOP mode. */
  124. /* USER CODE BEGIN 2 */
  125. if (hpcd->Init.low_power_enable)
  126. {
  127. /* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register. */
  128. SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
  129. }
  130. /* USER CODE END 2 */
  131. #if CONFIG_SLEEPMANAGER
  132. SleepManagerNotify.USBSuspendEvent();
  133. #endif
  134. }
  135. /**
  136. * @brief Resume callback.
  137. * When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it)
  138. * @param hpcd: PCD handle
  139. * @retval None
  140. */
  141. void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
  142. {
  143. USBD_LL_Resume((USBD_HandleTypeDef*)hpcd->pData);
  144. #if CONFIG_SLEEPMANAGER
  145. SleepManagerNotify.USBResumeEvent();
  146. #endif
  147. }
  148. /**
  149. * @brief ISOOUTIncomplete callback.
  150. * @param hpcd: PCD handle
  151. * @param epnum: Endpoint number
  152. * @retval None
  153. */
  154. void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  155. {
  156. USBD_LL_IsoOUTIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum);
  157. }
  158. /**
  159. * @brief ISOINIncomplete callback.
  160. * @param hpcd: PCD handle
  161. * @param epnum: Endpoint number
  162. * @retval None
  163. */
  164. void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
  165. {
  166. USBD_LL_IsoINIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum);
  167. }
  168. /**
  169. * @brief Connect callback.
  170. * @param hpcd: PCD handle
  171. * @retval None
  172. */
  173. void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
  174. {
  175. USBD_LL_DevConnected((USBD_HandleTypeDef*)hpcd->pData);
  176. }
  177. /**
  178. * @brief Disconnect callback.
  179. * @param hpcd: PCD handle
  180. * @retval None
  181. */
  182. void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
  183. {
  184. USBD_LL_DevDisconnected((USBD_HandleTypeDef*)hpcd->pData);
  185. }
  186. /*******************************************************************************
  187. LL Driver Interface (USB Device Library --> PCD)
  188. *******************************************************************************/
  189. /**
  190. * @brief Initializes the low level portion of the device driver.
  191. * @param pdev: Device handle
  192. * @retval USBD status
  193. */
  194. USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev)
  195. {
  196. /* Init USB Ip. */
  197. /* Link the driver to the stack. */
  198. hpcd_USB_FS.pData = pdev;
  199. pdev->pData = &hpcd_USB_FS;
  200. hpcd_USB_FS.Instance = USB;
  201. hpcd_USB_FS.Init.dev_endpoints = 8;
  202. hpcd_USB_FS.Init.speed = PCD_SPEED_FULL;
  203. hpcd_USB_FS.Init.ep0_mps = DEP0CTL_MPS_8;
  204. hpcd_USB_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
  205. hpcd_USB_FS.Init.low_power_enable = DISABLE;
  206. hpcd_USB_FS.Init.battery_charging_enable = DISABLE;
  207. if (HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK)
  208. {
  209. Error_Handler( );
  210. }
  211. #if USBD_UPDATEPMA_EP0TAIL
  212. // Prepare PMA for single EP0 configuration, if the application wants to use more EPs,
  213. // it should call USBD_LL_UpdatePMA() after USBD_LL_OpenEP() calls for these EPs
  214. HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 0x180 );
  215. HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x1C0 );
  216. #else
  217. // Prepare PMA for single EP0 configuration, if the application wants to use more EPs,
  218. // it should call USBD_LL_UpdatePMA() after USBD_LL_OpenEP() calls for these EPs
  219. HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 0x18);
  220. HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x58);
  221. #endif
  222. return USBD_OK;
  223. }
  224. /**
  225. * @brief De-Initializes the low level portion of the device driver.
  226. * @param pdev: Device handle
  227. * @retval USBD status
  228. */
  229. USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev)
  230. {
  231. HAL_StatusTypeDef hal_status = HAL_OK;
  232. USBD_StatusTypeDef usb_status = USBD_OK;
  233. hal_status = HAL_PCD_DeInit(pdev->pData);
  234. switch (hal_status) {
  235. case HAL_OK :
  236. usb_status = USBD_OK;
  237. break;
  238. case HAL_ERROR :
  239. usb_status = USBD_FAIL;
  240. break;
  241. case HAL_BUSY :
  242. usb_status = USBD_BUSY;
  243. break;
  244. case HAL_TIMEOUT :
  245. usb_status = USBD_FAIL;
  246. break;
  247. default :
  248. usb_status = USBD_FAIL;
  249. break;
  250. }
  251. return usb_status;
  252. }
  253. /**
  254. * @brief Starts the low level portion of the device driver.
  255. * @param pdev: Device handle
  256. * @retval USBD status
  257. */
  258. USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev)
  259. {
  260. HAL_StatusTypeDef hal_status = HAL_OK;
  261. USBD_StatusTypeDef usb_status = USBD_OK;
  262. hal_status = HAL_PCD_Start(pdev->pData);
  263. switch (hal_status) {
  264. case HAL_OK :
  265. usb_status = USBD_OK;
  266. break;
  267. case HAL_ERROR :
  268. usb_status = USBD_FAIL;
  269. break;
  270. case HAL_BUSY :
  271. usb_status = USBD_BUSY;
  272. break;
  273. case HAL_TIMEOUT :
  274. usb_status = USBD_FAIL;
  275. break;
  276. default :
  277. usb_status = USBD_FAIL;
  278. break;
  279. }
  280. return usb_status;
  281. }
  282. /**
  283. * @brief Stops the low level portion of the device driver.
  284. * @param pdev: Device handle
  285. * @retval USBD status
  286. */
  287. USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev)
  288. {
  289. HAL_StatusTypeDef hal_status = HAL_OK;
  290. USBD_StatusTypeDef usb_status = USBD_OK;
  291. hal_status = HAL_PCD_Stop(pdev->pData);
  292. switch (hal_status) {
  293. case HAL_OK :
  294. usb_status = USBD_OK;
  295. break;
  296. case HAL_ERROR :
  297. usb_status = USBD_FAIL;
  298. break;
  299. case HAL_BUSY :
  300. usb_status = USBD_BUSY;
  301. break;
  302. case HAL_TIMEOUT :
  303. usb_status = USBD_FAIL;
  304. break;
  305. default :
  306. usb_status = USBD_FAIL;
  307. break;
  308. }
  309. return usb_status;
  310. }
  311. /**
  312. * @brief Opens an endpoint of the low level driver.
  313. * @param pdev: Device handle
  314. * @param ep_addr: Endpoint number
  315. * @param ep_type: Endpoint type
  316. * @param ep_mps: Endpoint max packet size
  317. * @retval USBD status
  318. */
  319. USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps)
  320. {
  321. HAL_StatusTypeDef hal_status = HAL_OK;
  322. USBD_StatusTypeDef usb_status = USBD_OK;
  323. hal_status = HAL_PCD_EP_Open(pdev->pData, ep_addr, ep_mps, ep_type);
  324. switch (hal_status) {
  325. case HAL_OK :
  326. if( ep_addr & 0x80 )
  327. {
  328. pdev->ep_in[ ep_addr & 0x7F ].maxpacket = ep_mps;
  329. pdev->ep_in[ ep_addr & 0x7F ].rem_length = 0;
  330. pdev->ep_in[ ep_addr & 0x7F ].total_length = 0;
  331. pdev->ep_in[ ep_addr & 0x7F ].status = 0;
  332. }
  333. else
  334. {
  335. pdev->ep_out[ ep_addr & 0x7F ].maxpacket = ep_mps;
  336. pdev->ep_out[ ep_addr & 0x7F ].rem_length = 0;
  337. pdev->ep_out[ ep_addr & 0x7F ].total_length = 0;
  338. pdev->ep_out[ ep_addr & 0x7F ].status = 0;
  339. }
  340. usb_status = USBD_OK;
  341. break;
  342. case HAL_ERROR :
  343. usb_status = USBD_FAIL;
  344. break;
  345. case HAL_BUSY :
  346. usb_status = USBD_BUSY;
  347. break;
  348. case HAL_TIMEOUT :
  349. usb_status = USBD_FAIL;
  350. break;
  351. default :
  352. usb_status = USBD_FAIL;
  353. break;
  354. }
  355. return usb_status;
  356. }
  357. /**
  358. * @brief Closes an endpoint of the low level driver.
  359. * @param pdev: Device handle
  360. * @param ep_addr: Endpoint number
  361. * @retval USBD status
  362. */
  363. USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
  364. {
  365. HAL_StatusTypeDef hal_status = HAL_OK;
  366. USBD_StatusTypeDef usb_status = USBD_OK;
  367. hal_status = HAL_PCD_EP_Close(pdev->pData, ep_addr);
  368. switch (hal_status) {
  369. case HAL_OK :
  370. usb_status = USBD_OK;
  371. break;
  372. case HAL_ERROR :
  373. usb_status = USBD_FAIL;
  374. break;
  375. case HAL_BUSY :
  376. usb_status = USBD_BUSY;
  377. break;
  378. case HAL_TIMEOUT :
  379. usb_status = USBD_FAIL;
  380. break;
  381. default :
  382. usb_status = USBD_FAIL;
  383. break;
  384. }
  385. return usb_status;
  386. }
  387. /**
  388. * @brief Flushes an endpoint of the Low Level Driver.
  389. * @param pdev: Device handle
  390. * @param ep_addr: Endpoint number
  391. * @retval USBD status
  392. */
  393. USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
  394. {
  395. HAL_StatusTypeDef hal_status = HAL_OK;
  396. USBD_StatusTypeDef usb_status = USBD_OK;
  397. hal_status = HAL_PCD_EP_Flush(pdev->pData, ep_addr);
  398. switch (hal_status) {
  399. case HAL_OK :
  400. usb_status = USBD_OK;
  401. break;
  402. case HAL_ERROR :
  403. usb_status = USBD_FAIL;
  404. break;
  405. case HAL_BUSY :
  406. usb_status = USBD_BUSY;
  407. break;
  408. case HAL_TIMEOUT :
  409. usb_status = USBD_FAIL;
  410. break;
  411. default :
  412. usb_status = USBD_FAIL;
  413. break;
  414. }
  415. return usb_status;
  416. }
  417. /**
  418. * @brief Sets a Stall condition on an endpoint of the Low Level Driver.
  419. * @param pdev: Device handle
  420. * @param ep_addr: Endpoint number
  421. * @retval USBD status
  422. */
  423. USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
  424. {
  425. HAL_StatusTypeDef hal_status = HAL_OK;
  426. USBD_StatusTypeDef usb_status = USBD_OK;
  427. hal_status = HAL_PCD_EP_SetStall(pdev->pData, ep_addr);
  428. switch (hal_status) {
  429. case HAL_OK :
  430. usb_status = USBD_OK;
  431. break;
  432. case HAL_ERROR :
  433. usb_status = USBD_FAIL;
  434. break;
  435. case HAL_BUSY :
  436. usb_status = USBD_BUSY;
  437. break;
  438. case HAL_TIMEOUT :
  439. usb_status = USBD_FAIL;
  440. break;
  441. default :
  442. usb_status = USBD_FAIL;
  443. break;
  444. }
  445. return usb_status;
  446. }
  447. /**
  448. * @brief Clears a Stall condition on an endpoint of the Low Level Driver.
  449. * @param pdev: Device handle
  450. * @param ep_addr: Endpoint number
  451. * @retval USBD status
  452. */
  453. USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
  454. {
  455. HAL_StatusTypeDef hal_status = HAL_OK;
  456. USBD_StatusTypeDef usb_status = USBD_OK;
  457. hal_status = HAL_PCD_EP_ClrStall(pdev->pData, ep_addr);
  458. switch (hal_status) {
  459. case HAL_OK :
  460. usb_status = USBD_OK;
  461. break;
  462. case HAL_ERROR :
  463. usb_status = USBD_FAIL;
  464. break;
  465. case HAL_BUSY :
  466. usb_status = USBD_BUSY;
  467. break;
  468. case HAL_TIMEOUT :
  469. usb_status = USBD_FAIL;
  470. break;
  471. default :
  472. usb_status = USBD_FAIL;
  473. break;
  474. }
  475. return usb_status;
  476. }
  477. /**
  478. * @brief Set NAK condition on an endpoint of the Low Level Driver.
  479. * @param pdev: Device handle
  480. * @param ep_addr: Endpoint number
  481. * @retval USBD status
  482. */
  483. USBD_StatusTypeDef USBD_LL_NakEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
  484. {
  485. HAL_StatusTypeDef hal_status = HAL_OK;
  486. USBD_StatusTypeDef usb_status = USBD_OK;
  487. hal_status = HAL_PCD_EP_SetNak(pdev->pData, ep_addr);
  488. switch (hal_status) {
  489. case HAL_OK :
  490. usb_status = USBD_OK;
  491. break;
  492. case HAL_ERROR :
  493. usb_status = USBD_FAIL;
  494. break;
  495. case HAL_BUSY :
  496. usb_status = USBD_BUSY;
  497. break;
  498. case HAL_TIMEOUT :
  499. usb_status = USBD_FAIL;
  500. break;
  501. default :
  502. usb_status = USBD_FAIL;
  503. break;
  504. }
  505. return usb_status;
  506. }
  507. /**
  508. * @brief Returns Stall condition.
  509. * @param pdev: Device handle
  510. * @param ep_addr: Endpoint number
  511. * @retval Stall (1: Yes, 0: No)
  512. */
  513. uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
  514. {
  515. PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef*) pdev->pData;
  516. if((ep_addr & 0x80) == 0x80)
  517. {
  518. return hpcd->IN_ep[ep_addr & 0x7F].is_stall;
  519. }
  520. else
  521. {
  522. return hpcd->OUT_ep[ep_addr & 0x7F].is_stall;
  523. }
  524. }
  525. /**
  526. * @brief Assigns a USB address to the device.
  527. * @param pdev: Device handle
  528. * @param dev_addr: Device address
  529. * @retval USBD status
  530. */
  531. USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr)
  532. {
  533. HAL_StatusTypeDef hal_status = HAL_OK;
  534. USBD_StatusTypeDef usb_status = USBD_OK;
  535. hal_status = HAL_PCD_SetAddress(pdev->pData, dev_addr);
  536. switch (hal_status) {
  537. case HAL_OK :
  538. usb_status = USBD_OK;
  539. break;
  540. case HAL_ERROR :
  541. usb_status = USBD_FAIL;
  542. break;
  543. case HAL_BUSY :
  544. usb_status = USBD_BUSY;
  545. break;
  546. case HAL_TIMEOUT :
  547. usb_status = USBD_FAIL;
  548. break;
  549. default :
  550. usb_status = USBD_FAIL;
  551. break;
  552. }
  553. return usb_status;
  554. }
  555. /**
  556. * @brief Transmits data over an endpoint.
  557. * @param pdev: Device handle
  558. * @param ep_addr: Endpoint number
  559. * @param pbuf: Pointer to data to be sent
  560. * @param size: Data size
  561. * @retval USBD status
  562. */
  563. USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint16_t size)
  564. {
  565. HAL_StatusTypeDef hal_status = HAL_OK;
  566. USBD_StatusTypeDef usb_status = USBD_OK;
  567. hal_status = HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size);
  568. switch (hal_status) {
  569. case HAL_OK :
  570. usb_status = USBD_OK;
  571. break;
  572. case HAL_ERROR :
  573. usb_status = USBD_FAIL;
  574. break;
  575. case HAL_BUSY :
  576. usb_status = USBD_BUSY;
  577. break;
  578. case HAL_TIMEOUT :
  579. usb_status = USBD_FAIL;
  580. break;
  581. default :
  582. usb_status = USBD_FAIL;
  583. break;
  584. }
  585. return usb_status;
  586. }
  587. /**
  588. * @brief Prepares an endpoint for reception.
  589. * @param pdev: Device handle
  590. * @param ep_addr: Endpoint number
  591. * @param pbuf: Pointer to data to be received
  592. * @param size: Data size
  593. * @retval USBD status
  594. */
  595. USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint16_t size)
  596. {
  597. HAL_StatusTypeDef hal_status = HAL_OK;
  598. USBD_StatusTypeDef usb_status = USBD_OK;
  599. hal_status = HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size);
  600. switch (hal_status) {
  601. case HAL_OK :
  602. usb_status = USBD_OK;
  603. break;
  604. case HAL_ERROR :
  605. usb_status = USBD_FAIL;
  606. break;
  607. case HAL_BUSY :
  608. usb_status = USBD_BUSY;
  609. break;
  610. case HAL_TIMEOUT :
  611. usb_status = USBD_FAIL;
  612. break;
  613. default :
  614. usb_status = USBD_FAIL;
  615. break;
  616. }
  617. return usb_status;
  618. }
  619. /**
  620. * @brief Returns the last transfered packet size.
  621. * @param pdev: Device handle
  622. * @param ep_addr: Endpoint number
  623. * @retval Recived Data Size
  624. */
  625. uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
  626. {
  627. return HAL_PCD_EP_GetRxCount((PCD_HandleTypeDef*) pdev->pData, ep_addr);
  628. }
  629. /**
  630. * @brief Returns the last queued TX packet size.
  631. * @param pdev: Device handle
  632. * @param ep_addr: Endpoint number
  633. * @retval Queued packet size or -1 if there no queued packet in TX
  634. */
  635. int32_t USBD_LL_GetTxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
  636. {
  637. uint16_t len = 0;
  638. if( HAL_OK == HAL_PCD_EP_GetTxCount((PCD_HandleTypeDef*) pdev->pData, ep_addr, &len ) )
  639. {
  640. return len;
  641. }
  642. return (-1l); // there no packet queued
  643. }
  644. /**
  645. * @brief Delays routine for the USB device library.
  646. * @param Delay: Delay in ms
  647. * @retval None
  648. */
  649. void USBD_LL_Delay(uint32_t Delay)
  650. {
  651. HAL_Delay(Delay);
  652. }
  653. /**
  654. * @brief Static single allocation.
  655. * @param size: Size of allocated memory
  656. * @retval None
  657. */
  658. // @uUSBD_UNION_HandleTypeDef
  659. // Union type allows to calculate the maximum sturcture size to fit
  660. // for both interfaces: vendor and usbtmc
  661. typedef union
  662. {
  663. USBD_VENDOR_HandleTypeDef vendorIface;
  664. USBD_USBTMC_HandleTypeDef usbtmcIface;
  665. }
  666. uUSBD_UNION_HandleTypeDef;
  667. // @mem
  668. // Static memory is used instead of the dynamic allocation.
  669. // It works since only one interface is running at the same time.
  670. static uint32_t mem[(sizeof(uUSBD_UNION_HandleTypeDef)/4)+1];/* On 32-bit boundary */
  671. static bool mem_in_use = false;
  672. void *USBD_static_malloc(uint32_t size)
  673. {
  674. if( mem_in_use ) return NULL;
  675. mem_in_use = true;
  676. return mem;
  677. }
  678. /**
  679. * @brief Dummy memory free
  680. * @param p: Pointer to allocated memory address
  681. * @retval None
  682. */
  683. void USBD_static_free(void *p)
  684. {
  685. mem_in_use = false;
  686. }
  687. /**
  688. * @brief Software Device Connection
  689. * @param hpcd: PCD handle
  690. * @param state: Connection state (0: disconnected / 1: connected)
  691. * @retval None
  692. */
  693. void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state)
  694. {
  695. /* USER CODE BEGIN 6 */
  696. if (state == 1)
  697. {
  698. /* Configure Low connection state. */
  699. __HAL_SYSCFG_USBPULLUP_ENABLE();
  700. }
  701. else
  702. {
  703. /* Configure High connection state. */
  704. __HAL_SYSCFG_USBPULLUP_DISABLE();
  705. }
  706. /* USER CODE END 6 */
  707. }
  708. /** USBD_LL_UpdatePMA
  709. * @brief Update PMA Table for endpoints
  710. * @param pdev: Device handle
  711. * @retval Status
  712. */
  713. USBD_StatusTypeDef USBD_LL_UpdatePMA( USBD_HandleTypeDef *pdev )
  714. {
  715. PCD_HandleTypeDef *hpcd = pdev->pData;
  716. if( HAL_OK == HAL_PCD_UpdatePMA( hpcd ) )
  717. {
  718. return USBD_OK;
  719. }
  720. return USBD_FAIL;
  721. }
  722. #if 0
  723. // OLD IMPLEMENTATION
  724. /** USBD_LL_UpdatePMA
  725. * @brief Update PMA Table for endpoints
  726. * @param pdev: Device handle
  727. * @retval None
  728. */
  729. USBD_StatusTypeDef USBD_LL_UpdatePMA( USBD_HandleTypeDef *pdev )
  730. {
  731. PCD_HandleTypeDef *hpcd = pdev->pData;
  732. PCD_EPTypeDef *ep;
  733. #if USBD_UPDATEPMA_EP0TAIL
  734. uint8_t epCount = 1; // EP0 always is used
  735. #else
  736. uint8_t epCount = 0;
  737. #endif
  738. // Check each EP:
  739. #if USBD_UPDATEPMA_EP0TAIL
  740. for( uint8_t epidx = 1; epidx < 8; ++epidx )
  741. #else
  742. for( uint8_t epidx = 1; epidx < 8; ++epidx )
  743. #endif
  744. {
  745. bool epUsed = false;
  746. // Check EP IN:
  747. if( USB_EP_TX_DIS != PCD_GET_EP_TX_STATUS( hpcd->Instance, epidx ) )
  748. {
  749. PCD_EPTypeDef *ep = &hpcd->IN_ep[ epidx ];
  750. if(( ep->num == epidx ) && ( 0 != ep->is_in ) )
  751. {
  752. epUsed = true;
  753. }
  754. }
  755. // Check EP OUT:
  756. if( USB_EP_RX_DIS != PCD_GET_EP_RX_STATUS( hpcd->Instance, epidx ) )
  757. {
  758. PCD_EPTypeDef *ep = &hpcd->OUT_ep[ epidx ];
  759. if(( ep->num == epidx ) && ( 0 == ep->is_in ) )
  760. {
  761. epUsed = true;
  762. }
  763. }
  764. // Reset EP to the defaults: Single Buffer, zero packet memory address
  765. // HAL_PCDEx_PMAConfig(hpcd, 0x00 | epidx, PCD_SNG_BUF, 0 ); // set default value
  766. // HAL_PCDEx_PMAConfig(hpcd, 0x80 | epidx, PCD_SNG_BUF, 0 ); // set default value
  767. // count all used endpoints
  768. if( epUsed ) epCount++;
  769. }
  770. #if USBD_UPDATEPMA_EP0TAIL
  771. uint16_t pmaTableOffset = 8 * epCount; // each EP takes 8 bytes in PMATable, @pmaTableOffset is a table length now
  772. #else
  773. uint16_t pmaTableOffset = 8 * epCount; // each EP takes 8 bytes in PMATable, @pmaTableOffset is a table length now
  774. #endif
  775. // Check each EP:
  776. #if USBD_UPDATEPMA_EP0TAIL
  777. for( uint8_t epidx = 1; epidx < 8; ++epidx )
  778. #else
  779. for( uint8_t epidx = 0; epidx < 8; ++epidx )
  780. #endif
  781. {
  782. // Check EP OUT:
  783. if( USB_EP_RX_DIS != PCD_GET_EP_RX_STATUS( hpcd->Instance, epidx ) )
  784. {
  785. ep = &hpcd->OUT_ep[ epidx ];
  786. if(( ep->num == epidx ) && ( 0 == ep->is_in ) )
  787. {
  788. HAL_PCDEx_PMAConfig(hpcd , 0x00 | epidx , (( ep->doublebuffer == 0 )?PCD_SNG_BUF:PCD_DBL_BUF), pmaTableOffset );
  789. pmaTableOffset += ep->maxpacket * (( ep->doublebuffer == 0 )?1:2);
  790. }
  791. }
  792. // Check EP IN:
  793. if( USB_EP_TX_DIS != PCD_GET_EP_TX_STATUS( hpcd->Instance, epidx ) )
  794. {
  795. ep = &hpcd->IN_ep[ epidx ];
  796. if(( ep->num == epidx ) && ( 0 != ep->is_in ) )
  797. {
  798. HAL_PCDEx_PMAConfig(hpcd , 0x80 | epidx , (( ep->doublebuffer == 0 )?PCD_SNG_BUF:PCD_DBL_BUF), pmaTableOffset );
  799. pmaTableOffset += ep->maxpacket * (( ep->doublebuffer == 0 )?1:2);
  800. }
  801. }
  802. }
  803. }
  804. #endif