Implement a secure ICS protocol targeting LoRa Node151 microcontroller for controlling irrigation.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

599 lines
12 KiB

  1. /**
  2. ******************************************************************************
  3. * @file usbd_core.c
  4. * @author MCD Application Team
  5. * @brief This file provides all the USBD core functions.
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
  10. * All rights reserved.</center></h2>
  11. *
  12. * This software component is licensed by ST under Ultimate Liberty license
  13. * SLA0044, the "License"; You may not use this file except in compliance with
  14. * the License. You may obtain a copy of the License at:
  15. * http://www.st.com/SLA0044
  16. *
  17. ******************************************************************************
  18. */
  19. /* Includes ------------------------------------------------------------------*/
  20. #include "usbd_core.h"
  21. /** @addtogroup STM32_USBD_DEVICE_LIBRARY
  22. * @{
  23. */
  24. /** @defgroup USBD_CORE
  25. * @brief usbd core module
  26. * @{
  27. */
  28. /** @defgroup USBD_CORE_Private_TypesDefinitions
  29. * @{
  30. */
  31. /**
  32. * @}
  33. */
  34. /** @defgroup USBD_CORE_Private_Defines
  35. * @{
  36. */
  37. /**
  38. * @}
  39. */
  40. /** @defgroup USBD_CORE_Private_Macros
  41. * @{
  42. */
  43. /**
  44. * @}
  45. */
  46. /** @defgroup USBD_CORE_Private_FunctionPrototypes
  47. * @{
  48. */
  49. /**
  50. * @}
  51. */
  52. /** @defgroup USBD_CORE_Private_Variables
  53. * @{
  54. */
  55. /**
  56. * @}
  57. */
  58. /** @defgroup USBD_CORE_Private_Functions
  59. * @{
  60. */
  61. /**
  62. * @brief USBD_Init
  63. * Initializes the device stack and load the class driver
  64. * @param pdev: device instance
  65. * @param pdesc: Descriptor structure address
  66. * @param id: Low level core index
  67. * @retval None
  68. */
  69. USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id)
  70. {
  71. /* Check whether the USB Host handle is valid */
  72. if(pdev == NULL)
  73. {
  74. #if (USBD_DEBUG_LEVEL > 1U)
  75. USBD_ErrLog("Invalid Device handle");
  76. #endif
  77. return USBD_FAIL;
  78. }
  79. /* Unlink previous class*/
  80. if(pdev->pClass != NULL)
  81. {
  82. pdev->pClass = NULL;
  83. }
  84. /* Assign USBD Descriptors */
  85. if(pdesc != NULL)
  86. {
  87. pdev->pDesc = pdesc;
  88. }
  89. /* Set Device initial State */
  90. pdev->dev_state = USBD_STATE_DEFAULT;
  91. pdev->id = id;
  92. /* Initialize low level driver */
  93. USBD_LL_Init(pdev);
  94. return USBD_OK;
  95. }
  96. /**
  97. * @brief USBD_DeInit
  98. * Re-Initialize th device library
  99. * @param pdev: device instance
  100. * @retval status: status
  101. */
  102. USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev)
  103. {
  104. /* Set Default State */
  105. pdev->dev_state = USBD_STATE_DEFAULT;
  106. /* Free Class Resources */
  107. pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
  108. /* Stop the low level driver */
  109. USBD_LL_Stop(pdev);
  110. /* Initialize low level driver */
  111. USBD_LL_DeInit(pdev);
  112. return USBD_OK;
  113. }
  114. /**
  115. * @brief USBD_RegisterClass
  116. * Link class driver to Device Core.
  117. * @param pDevice : Device Handle
  118. * @param pclass: Class handle
  119. * @retval USBD Status
  120. */
  121. USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass)
  122. {
  123. USBD_StatusTypeDef status = USBD_OK;
  124. if(pclass != 0)
  125. {
  126. /* link the class to the USB Device handle */
  127. pdev->pClass = pclass;
  128. status = USBD_OK;
  129. }
  130. else
  131. {
  132. #if (USBD_DEBUG_LEVEL > 1U)
  133. USBD_ErrLog("Invalid Class handle");
  134. #endif
  135. status = USBD_FAIL;
  136. }
  137. return status;
  138. }
  139. /**
  140. * @brief USBD_Start
  141. * Start the USB Device Core.
  142. * @param pdev: Device Handle
  143. * @retval USBD Status
  144. */
  145. USBD_StatusTypeDef USBD_Start (USBD_HandleTypeDef *pdev)
  146. {
  147. /* Start the low level driver */
  148. USBD_LL_Start(pdev);
  149. return USBD_OK;
  150. }
  151. /**
  152. * @brief USBD_Stop
  153. * Stop the USB Device Core.
  154. * @param pdev: Device Handle
  155. * @retval USBD Status
  156. */
  157. USBD_StatusTypeDef USBD_Stop (USBD_HandleTypeDef *pdev)
  158. {
  159. /* Free Class Resources */
  160. pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
  161. /* Stop the low level driver */
  162. USBD_LL_Stop(pdev);
  163. return USBD_OK;
  164. }
  165. /**
  166. * @brief USBD_RunTestMode
  167. * Launch test mode process
  168. * @param pdev: device instance
  169. * @retval status
  170. */
  171. USBD_StatusTypeDef USBD_RunTestMode (USBD_HandleTypeDef *pdev)
  172. {
  173. /* Prevent unused argument compilation warning */
  174. UNUSED(pdev);
  175. return USBD_OK;
  176. }
  177. /**
  178. * @brief USBD_SetClassConfig
  179. * Configure device and start the interface
  180. * @param pdev: device instance
  181. * @param cfgidx: configuration index
  182. * @retval status
  183. */
  184. USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
  185. {
  186. USBD_StatusTypeDef ret = USBD_FAIL;
  187. if(pdev->pClass != NULL)
  188. {
  189. /* Set configuration and Start the Class*/
  190. if(pdev->pClass->Init(pdev, cfgidx) == 0U)
  191. {
  192. ret = USBD_OK;
  193. }
  194. }
  195. return ret;
  196. }
  197. /**
  198. * @brief USBD_ClrClassConfig
  199. * Clear current configuration
  200. * @param pdev: device instance
  201. * @param cfgidx: configuration index
  202. * @retval status: USBD_StatusTypeDef
  203. */
  204. USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
  205. {
  206. /* Clear configuration and De-initialize the Class process*/
  207. pdev->pClass->DeInit(pdev, cfgidx);
  208. return USBD_OK;
  209. }
  210. /**
  211. * @brief USBD_SetupStage
  212. * Handle the setup stage
  213. * @param pdev: device instance
  214. * @retval status
  215. */
  216. USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup)
  217. {
  218. USBD_ParseSetupRequest(&pdev->request, psetup);
  219. pdev->ep0_state = USBD_EP0_SETUP;
  220. pdev->ep0_data_len = pdev->request.wLength;
  221. switch (pdev->request.bmRequest & 0x1FU)
  222. {
  223. case USB_REQ_RECIPIENT_DEVICE:
  224. USBD_StdDevReq (pdev, &pdev->request);
  225. break;
  226. case USB_REQ_RECIPIENT_INTERFACE:
  227. USBD_StdItfReq(pdev, &pdev->request);
  228. break;
  229. case USB_REQ_RECIPIENT_ENDPOINT:
  230. USBD_StdEPReq(pdev, &pdev->request);
  231. break;
  232. default:
  233. USBD_LL_StallEP(pdev, (pdev->request.bmRequest & 0x80U));
  234. break;
  235. }
  236. return USBD_OK;
  237. }
  238. /**
  239. * @brief USBD_DataOutStage
  240. * Handle data OUT stage
  241. * @param pdev: device instance
  242. * @param epnum: endpoint index
  243. * @retval status
  244. */
  245. USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev,
  246. uint8_t epnum, uint8_t *pdata)
  247. {
  248. USBD_EndpointTypeDef *pep;
  249. if(epnum == 0U)
  250. {
  251. pep = &pdev->ep_out[0];
  252. if ( pdev->ep0_state == USBD_EP0_DATA_OUT)
  253. {
  254. if(pep->rem_length > pep->maxpacket)
  255. {
  256. pep->rem_length -= pep->maxpacket;
  257. USBD_CtlContinueRx (pdev,
  258. pdata,
  259. (uint16_t)MIN(pep->rem_length, pep->maxpacket));
  260. }
  261. else
  262. {
  263. if((pdev->pClass->EP0_RxReady != NULL)&&
  264. (pdev->dev_state == USBD_STATE_CONFIGURED))
  265. {
  266. pdev->pClass->EP0_RxReady(pdev);
  267. }
  268. USBD_CtlSendStatus(pdev);
  269. }
  270. }
  271. else
  272. {
  273. if (pdev->ep0_state == USBD_EP0_STATUS_OUT)
  274. {
  275. /*
  276. * STATUS PHASE completed, update ep0_state to idle
  277. */
  278. pdev->ep0_state = USBD_EP0_IDLE;
  279. USBD_LL_StallEP(pdev, 0U);
  280. }
  281. }
  282. }
  283. else if((pdev->pClass->DataOut != NULL) &&
  284. (pdev->dev_state == USBD_STATE_CONFIGURED))
  285. {
  286. pdev->pClass->DataOut(pdev, epnum);
  287. }
  288. else
  289. {
  290. /* should never be in this condition */
  291. return USBD_FAIL;
  292. }
  293. return USBD_OK;
  294. }
  295. /**
  296. * @brief USBD_DataInStage
  297. * Handle data in stage
  298. * @param pdev: device instance
  299. * @param epnum: endpoint index
  300. * @retval status
  301. */
  302. USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev, uint8_t epnum,
  303. uint8_t *pdata)
  304. {
  305. USBD_EndpointTypeDef *pep;
  306. if(epnum == 0U)
  307. {
  308. pep = &pdev->ep_in[0];
  309. if ( pdev->ep0_state == USBD_EP0_DATA_IN)
  310. {
  311. if(pep->rem_length > pep->maxpacket)
  312. {
  313. pep->rem_length -= pep->maxpacket;
  314. USBD_CtlContinueSendData (pdev, pdata, (uint16_t)pep->rem_length);
  315. /* Prepare endpoint for premature end of transfer */
  316. USBD_LL_PrepareReceive (pdev, 0U, NULL, 0U);
  317. }
  318. else
  319. { /* last packet is MPS multiple, so send ZLP packet */
  320. if((pep->total_length % pep->maxpacket == 0U) &&
  321. (pep->total_length >= pep->maxpacket) &&
  322. (pep->total_length < pdev->ep0_data_len))
  323. {
  324. USBD_CtlContinueSendData(pdev, NULL, 0U);
  325. pdev->ep0_data_len = 0U;
  326. /* Prepare endpoint for premature end of transfer */
  327. USBD_LL_PrepareReceive (pdev, 0U, NULL, 0U);
  328. }
  329. else
  330. {
  331. if((pdev->pClass->EP0_TxSent != NULL)&&
  332. (pdev->dev_state == USBD_STATE_CONFIGURED))
  333. {
  334. pdev->pClass->EP0_TxSent(pdev);
  335. }
  336. USBD_LL_StallEP(pdev, 0x80U);
  337. USBD_CtlReceiveStatus(pdev);
  338. }
  339. }
  340. }
  341. else
  342. {
  343. if ((pdev->ep0_state == USBD_EP0_STATUS_IN) ||
  344. (pdev->ep0_state == USBD_EP0_IDLE))
  345. {
  346. USBD_LL_StallEP(pdev, 0x80U);
  347. }
  348. }
  349. if (pdev->dev_test_mode == 1U)
  350. {
  351. USBD_RunTestMode(pdev);
  352. pdev->dev_test_mode = 0U;
  353. }
  354. }
  355. else if((pdev->pClass->DataIn != NULL) &&
  356. (pdev->dev_state == USBD_STATE_CONFIGURED))
  357. {
  358. pdev->pClass->DataIn(pdev, epnum);
  359. }
  360. else
  361. {
  362. /* should never be in this condition */
  363. return USBD_FAIL;
  364. }
  365. return USBD_OK;
  366. }
  367. /**
  368. * @brief USBD_LL_Reset
  369. * Handle Reset event
  370. * @param pdev: device instance
  371. * @retval status
  372. */
  373. USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev)
  374. {
  375. /* Open EP0 OUT */
  376. USBD_LL_OpenEP(pdev, 0x00U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
  377. pdev->ep_out[0x00U & 0xFU].is_used = 1U;
  378. pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE;
  379. /* Open EP0 IN */
  380. USBD_LL_OpenEP(pdev, 0x80U, USBD_EP_TYPE_CTRL, USB_MAX_EP0_SIZE);
  381. pdev->ep_in[0x80U & 0xFU].is_used = 1U;
  382. pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE;
  383. /* Upon Reset call user call back */
  384. pdev->dev_state = USBD_STATE_DEFAULT;
  385. pdev->ep0_state = USBD_EP0_IDLE;
  386. pdev->dev_config= 0U;
  387. pdev->dev_remote_wakeup = 0U;
  388. if (pdev->pClassData)
  389. {
  390. pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
  391. }
  392. return USBD_OK;
  393. }
  394. /**
  395. * @brief USBD_LL_Reset
  396. * Handle Reset event
  397. * @param pdev: device instance
  398. * @retval status
  399. */
  400. USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed)
  401. {
  402. pdev->dev_speed = speed;
  403. return USBD_OK;
  404. }
  405. /**
  406. * @brief USBD_Suspend
  407. * Handle Suspend event
  408. * @param pdev: device instance
  409. * @retval status
  410. */
  411. USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev)
  412. {
  413. pdev->dev_old_state = pdev->dev_state;
  414. pdev->dev_state = USBD_STATE_SUSPENDED;
  415. return USBD_OK;
  416. }
  417. /**
  418. * @brief USBD_Resume
  419. * Handle Resume event
  420. * @param pdev: device instance
  421. * @retval status
  422. */
  423. USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev)
  424. {
  425. pdev->dev_state = pdev->dev_old_state;
  426. return USBD_OK;
  427. }
  428. /**
  429. * @brief USBD_SOF
  430. * Handle SOF event
  431. * @param pdev: device instance
  432. * @retval status
  433. */
  434. USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev)
  435. {
  436. if(pdev->dev_state == USBD_STATE_CONFIGURED)
  437. {
  438. if(pdev->pClass->SOF != NULL)
  439. {
  440. pdev->pClass->SOF(pdev);
  441. }
  442. }
  443. return USBD_OK;
  444. }
  445. /**
  446. * @brief USBD_IsoINIncomplete
  447. * Handle iso in incomplete event
  448. * @param pdev: device instance
  449. * @retval status
  450. */
  451. USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum)
  452. {
  453. /* Prevent unused arguments compilation warning */
  454. UNUSED(pdev);
  455. UNUSED(epnum);
  456. return USBD_OK;
  457. }
  458. /**
  459. * @brief USBD_IsoOUTIncomplete
  460. * Handle iso out incomplete event
  461. * @param pdev: device instance
  462. * @retval status
  463. */
  464. USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum)
  465. {
  466. /* Prevent unused arguments compilation warning */
  467. UNUSED(pdev);
  468. UNUSED(epnum);
  469. return USBD_OK;
  470. }
  471. /**
  472. * @brief USBD_DevConnected
  473. * Handle device connection event
  474. * @param pdev: device instance
  475. * @retval status
  476. */
  477. USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev)
  478. {
  479. /* Prevent unused argument compilation warning */
  480. UNUSED(pdev);
  481. return USBD_OK;
  482. }
  483. /**
  484. * @brief USBD_DevDisconnected
  485. * Handle device disconnection event
  486. * @param pdev: device instance
  487. * @retval status
  488. */
  489. USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev)
  490. {
  491. /* Free Class Resources */
  492. pdev->dev_state = USBD_STATE_DEFAULT;
  493. pdev->pClass->DeInit(pdev, (uint8_t)pdev->dev_config);
  494. return USBD_OK;
  495. }
  496. /**
  497. * @}
  498. */
  499. /**
  500. * @}
  501. */
  502. /**
  503. * @}
  504. */
  505. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/