usbd_usbtmc.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116
  1. #include "usbd_usbtmc.h"
  2. #include "usbd_desc.h"
  3. #include "usbd_ctlreq.h"
  4. #include "usbd_usbtmc_desc.h"
  5. // @g_husbtmc:
  6. // Due to some methods can not use USBD_HandleTypeDef parameter, it is required
  7. // to get the device handle @pdev in the other way: the class handle contains the
  8. // "backward" pointer to the device handle @pdev, and in the same time,
  9. // the device handle contains the class handle @pClassData.
  10. // Metods refers to @g_husbtmc: USBD_USBTMC_DataIn_BeginSend, USBD_USBTMC_StallEP, USBD_USBTMC_ClearEP
  11. static USBD_USBTMC_HandleTypeDef * g_husbtmc = NULL;
  12. static uint8_t USBD_USBTMC_Init (USBD_HandleTypeDef *pdev,
  13. uint8_t cfgidx);
  14. static uint8_t USBD_USBTMC_DeInit (USBD_HandleTypeDef *pdev,
  15. uint8_t cfgidx);
  16. static uint8_t USBD_USBTMC_Setup (USBD_HandleTypeDef *pdev,
  17. USBD_SetupReqTypedef *req);
  18. static uint8_t USBD_USBTMC_Error (USBD_HandleTypeDef *pdev,
  19. uint8_t epnum);
  20. static uint8_t USBD_USBTMC_EP0_RxReady (USBD_HandleTypeDef *pdev, size_t * );
  21. static uint8_t USBD_USBTMC_EP0_TxSent (USBD_HandleTypeDef *pdev, size_t * );
  22. static uint8_t USBD_USBTMC_DataIn (USBD_HandleTypeDef *pdev, uint8_t );
  23. static uint8_t USBD_USBTMC_DataOut (USBD_HandleTypeDef *pdev, uint8_t, bool );
  24. /* Vendor interface class callbacks structure */
  25. const USBD_ClassTypeDef USBD_USBTMC =
  26. {
  27. .Init = USBD_USBTMC_Init,
  28. .DeInit = USBD_USBTMC_DeInit,
  29. .Error = USBD_USBTMC_Error,
  30. .Setup = USBD_USBTMC_Setup,
  31. .EP0_TxSent = USBD_USBTMC_EP0_TxSent,
  32. .EP0_RxReady = USBD_USBTMC_EP0_RxReady,
  33. .DataIn = USBD_USBTMC_DataIn,
  34. .DataOut = USBD_USBTMC_DataOut,
  35. .SOF = NULL,
  36. .pDesc = &USBD_USBTMC_DescriptorHandlers,
  37. };
  38. // @USBD_USBTMC_GetDescriptorHandlers
  39. // Returns the GetDesciptor handlers set pointer for current class
  40. const USBD_DescriptorsTypeDef * USBD_USBTMC_GetDescriptorHandlers()
  41. {
  42. if( NULL != g_husbtmc )
  43. return g_husbtmc->pdev->pClass->pDesc;
  44. return NULL;
  45. }
  46. /**
  47. * @brief USBD_USBTMC_Init
  48. * Initialize the Vendor interface
  49. * @param pdev: device instance
  50. * @param cfgidx: Configuration index
  51. * @retval status
  52. */
  53. static uint8_t USBD_USBTMC_Init (USBD_HandleTypeDef *pdev,
  54. uint8_t cfgidx)
  55. {
  56. uint8_t ret = USBD_OK;
  57. USBD_USBTMC_HandleTypeDef *husbtmc;
  58. pdev->pClassData = USBD_malloc(sizeof(USBD_USBTMC_HandleTypeDef));
  59. if(pdev->pClassData == NULL)
  60. {
  61. ret = USBD_FAIL;
  62. }
  63. else
  64. {
  65. husbtmc = (USBD_USBTMC_HandleTypeDef*) pdev->pClassData;
  66. husbtmc->pdev = pdev; // for @USBD_USBTMC_DataIn_BeginSend()
  67. g_husbtmc = husbtmc; // for @USBD_USBTMC_DataIn_BeginSend()
  68. USBD_COMMON_ItfTypeDef * pUserIface = ((USBD_COMMON_ItfTypeDef *)pdev->pUserData);
  69. /* Open EP1 OUT */
  70. USBD_LL_OpenEP(pdev,
  71. USBTMC_BULKOUT_EP,
  72. USBD_EP_TYPE_BULK,
  73. USBTMC_DATAOUT_MAX_PACKET_SIZE);
  74. pdev->ep_out[ (USBTMC_BULKOUT_EP) & 0x7F ].maxpacket = USBTMC_DATAOUT_MAX_PACKET_SIZE;
  75. //USBD_LL_ClearStallEP( pdev, USBTMC_BULKOUT_EP );
  76. /* Open EP1 IN */
  77. USBD_LL_OpenEP(pdev,
  78. USBTMC_BULKIN_EP,
  79. USBD_EP_TYPE_BULK,
  80. USBTMC_DATAIN_MAX_PACKET_SIZE);
  81. pdev->ep_in[ (USBTMC_BULKIN_EP) & 0x7F ].maxpacket = USBTMC_DATAIN_MAX_PACKET_SIZE;
  82. //USBD_LL_ClearStallEP( pdev, USBTMC_BULKIN_EP );
  83. /* Open EP2 IN */
  84. USBD_LL_OpenEP(pdev,
  85. USBTMC_INTERRUPTIN_EP,
  86. USBD_EP_TYPE_INTR,
  87. USBTMC_DATAIN_MAX_PACKET_SIZE);
  88. // USBD_LL_ClearStallEP( pdev, USBTMC_INTERRUPTIN_EP );
  89. pdev->ep_in[ (USBTMC_INTERRUPTIN_EP) & 0x7F ].maxpacket = USBTMC_INTIN_MAX_PACKET_SIZE;
  90. // Update PMA addresses for endpoints
  91. USBD_LL_UpdatePMA( pdev );
  92. usb_create_transfer( &husbtmc->ep0_tx_transfer,
  93. &husbtmc->ep0_tx_buffer[0],
  94. sizeof(husbtmc->ep0_tx_buffer),
  95. NULL, pdev );
  96. usb_create_transfer( &husbtmc->ep0_rx_transfer,
  97. &husbtmc->ep0_rx_buffer[0],
  98. sizeof(husbtmc->ep0_rx_buffer),
  99. NULL, pdev );
  100. usb_create_transfer( &husbtmc->ep1_tx_transfer,
  101. &husbtmc->ep1_tx_buffer[0],
  102. sizeof(husbtmc->ep1_tx_buffer),
  103. NULL, pdev );
  104. usb_create_transfer( &husbtmc->ep1_rx_transfer,
  105. &husbtmc->ep1_rx_buffer[0],
  106. sizeof(husbtmc->ep1_rx_buffer),
  107. NULL, pdev );
  108. usb_create_transfer( &husbtmc->ep2_tx_transfer,
  109. &husbtmc->ep2_tx_buffer[0],
  110. sizeof(husbtmc->ep2_tx_buffer),
  111. NULL, pdev );
  112. if( 0 == pUserIface->fUsbInit() )
  113. {
  114. // Prepare BulkOUT endpoint for the next transaction
  115. USBD_COMMON_DataOutBegin( pdev, USBTMC_BULKOUT_EP, &husbtmc->ep1_rx_transfer );
  116. if( USBD_STATE_DEFAULT == pdev->dev_state ) // useless
  117. {
  118. if( NULL != pUserIface->fResetEvent )
  119. {
  120. pUserIface->fResetEvent();
  121. }
  122. }
  123. if( pdev->dev_state == USBD_STATE_CONFIGURED )
  124. {
  125. if( NULL != pUserIface->fSetIface )
  126. {
  127. //--------------------------------------------------------------------------------------
  128. // Enumerate interface descriptors and call SetInterface callback
  129. uint16_t nConfDescLength = 0;
  130. const uint8_t * pDescBytePtr = NULL;
  131. #if USBD_GETDESCRIPTORS_ALTMETHOD == 0
  132. ret = USBD_CallGetDescriptorHandler( pdev,
  133. eGetDescriptorHandlerType_Config,
  134. &pbuf,
  135. &len );
  136. #else
  137. USBD_CallGetDescriptorHandlerAlt( ret, pdev, pDescBytePtr, nConfDescLength, GetConfigDescriptor );
  138. #endif
  139. if( USBD_OK == ret )
  140. {
  141. const sUSBConfigurationDescriptor_t * conf = (const sUSBConfigurationDescriptor_t *)pDescBytePtr;
  142. size_t ifidx = 0;
  143. while( nConfDescLength > 0 )
  144. {
  145. sUSBDescriptorHeader_t * pDescHeader = (sUSBDescriptorHeader_t*)pDescBytePtr;
  146. if( pDescHeader->bLength == 0 ) break;
  147. if( USB_DESC_TYPE_INTERFACE == pDescHeader->bDescriptorType )
  148. {
  149. const sUSBInterfaceDescriptor_t * ifdesc = (const sUSBInterfaceDescriptor_t *)pDescBytePtr;
  150. if( ! pUserIface->fSetIface( cfgidx, ifidx++, ifdesc ) )
  151. {
  152. ret = USBD_FAIL;
  153. break;
  154. }
  155. }
  156. nConfDescLength -= pDescHeader->bLength;
  157. pDescBytePtr += (pDescHeader->bLength);
  158. }
  159. (void)conf;
  160. }
  161. //--------------------------------------------------------------------------------------
  162. }
  163. }
  164. }
  165. else
  166. {
  167. ret = USBD_FAIL;
  168. }
  169. }
  170. return ret;
  171. }
  172. /* UNUSED FUNCTION
  173. static const sUSBInterfaceDescriptor_t * USBD_USBTMC_SearchInterfaceDescriptor( USBD_HandleTypeDef *pdev, uint8_t cfgidx, uint8_t nIf )
  174. {
  175. //--------------------------------------------------------------------------------------
  176. // Enumerate interface descriptors and call ClearInterface callback
  177. (void)cfgidx; // to do - use cfgidx to get configuration descriptor
  178. uint16_t nConfDescLength = 0;
  179. const uint8_t * pDescBytePtr = (const uint8_t * )pdev->pClass->GetFSConfigDescriptor(&nConfDescLength);
  180. const sUSBConfigurationDescriptor_t * conf = (const sUSBConfigurationDescriptor_t *)pDescBytePtr;
  181. while( nConfDescLength > 0 )
  182. {
  183. sUSBDescriptorHeader_t * pDescHeader = (sUSBDescriptorHeader_t*)pDescBytePtr;
  184. if( pDescHeader->bLength == 0 ) break;
  185. if( USB_DESC_TYPE_INTERFACE == pDescHeader->bDescriptorType )
  186. {
  187. const sUSBInterfaceDescriptor_t * ifdesc = (const sUSBInterfaceDescriptor_t *)pDescBytePtr;
  188. if( ifdesc->bInterfaceNumber == nIf )
  189. {
  190. return ifdesc;
  191. }
  192. }
  193. nConfDescLength -= pDescHeader->bLength;
  194. pDescBytePtr += (pDescHeader->bLength);
  195. }
  196. //--------------------------------------------------------------------------------------
  197. return NULL;
  198. }
  199. */
  200. /**
  201. * @brief USBD_USBTMC_Init
  202. * DeInitialize the Vendor layer
  203. * @param pdev: device instance
  204. * @param cfgidx: Configuration index
  205. * @retval status
  206. */
  207. static uint8_t USBD_USBTMC_DeInit (USBD_HandleTypeDef *pdev,
  208. uint8_t cfgidx)
  209. {
  210. uint8_t ret = USBD_OK;
  211. /* DeInit physical Interface components */
  212. if(pdev->pClassData != NULL)
  213. {
  214. if( pdev->pUserData != NULL )
  215. {
  216. USBD_COMMON_ItfTypeDef * pUserIface = ((USBD_COMMON_ItfTypeDef *)pdev->pUserData);
  217. if( NULL != pUserIface->fClrIface )
  218. {
  219. if( ((pdev->dev_old_state == USBD_STATE_CONFIGURED)
  220. || (pdev->dev_old_state == USBD_STATE_SUSPENDED) )
  221. && ((pdev->dev_state != USBD_STATE_CONFIGURED)
  222. || (pdev->dev_state != USBD_STATE_SUSPENDED) ) )
  223. {
  224. //--------------------------------------------------------------------------------------
  225. // Enumerate interface descriptors and call ClearInterface callback
  226. (void)cfgidx; // to do - use cfgidx to get configuration descriptor
  227. uint16_t nConfDescLength = 0;
  228. const uint8_t * pDescBytePtr = NULL;
  229. #if USBD_GETDESCRIPTORS_ALTMETHOD == 0
  230. ret = USBD_CallGetDescriptorHandler( pdev,
  231. eGetDescriptorHandlerType_Config,
  232. &pbuf,
  233. &len );
  234. #else
  235. USBD_CallGetDescriptorHandlerAlt( ret, pdev, pDescBytePtr, nConfDescLength, GetConfigDescriptor );
  236. #endif
  237. if( USBD_OK == ret )
  238. {
  239. const sUSBConfigurationDescriptor_t * conf = (const sUSBConfigurationDescriptor_t *)pDescBytePtr;
  240. size_t ifidx = 0;
  241. while( nConfDescLength > 0 )
  242. {
  243. sUSBDescriptorHeader_t * pDescHeader = (sUSBDescriptorHeader_t*)pDescBytePtr;
  244. if( pDescHeader->bLength == 0 ) break;
  245. if( USB_DESC_TYPE_INTERFACE == pDescHeader->bDescriptorType )
  246. {
  247. const sUSBInterfaceDescriptor_t * ifdesc = (const sUSBInterfaceDescriptor_t *)pDescBytePtr;
  248. pUserIface->fClrIface( cfgidx, ifidx++, ifdesc );
  249. }
  250. nConfDescLength -= pDescHeader->bLength;
  251. pDescBytePtr += (pDescHeader->bLength);
  252. }
  253. (void)conf;
  254. }
  255. //--------------------------------------------------------------------------------------
  256. }
  257. }
  258. if( USBD_STATE_DEFAULT == pdev->dev_state )
  259. {
  260. if( NULL != pUserIface->fResetEvent )
  261. {
  262. pUserIface->fResetEvent();
  263. }
  264. }
  265. pUserIface->fUsbDeInit();
  266. g_husbtmc = NULL; // for USBD_USBTMC_DataIn_BeginSend()
  267. USBD_free(pdev->pClassData);
  268. pdev->pClassData = NULL;
  269. USBD_LL_CloseEP( pdev, USBTMC_BULKOUT_EP );
  270. USBD_LL_CloseEP( pdev, USBTMC_BULKIN_EP );
  271. USBD_LL_CloseEP( pdev, USBTMC_INTERRUPTIN_EP );
  272. }
  273. }
  274. return ret;
  275. }
  276. static uint8_t USBD_USBTMC_Error (USBD_HandleTypeDef *pdev, uint8_t epnum)
  277. {
  278. if(pdev->pClassData != NULL)
  279. {
  280. if( pdev->pUserData != NULL )
  281. {
  282. USBD_COMMON_ItfTypeDef * pUserIface = ((USBD_COMMON_ItfTypeDef *)pdev->pUserData);
  283. if( epnum == 0 )
  284. {
  285. if( NULL != pUserIface->fUsbSetup )
  286. {
  287. pUserIface->fUsbSetup( &pdev->request, false, false );
  288. }
  289. }
  290. else
  291. {
  292. // Call user error handler
  293. if( NULL != pUserIface->fDataErrHandler )
  294. {
  295. pUserIface->fDataErrHandler( epnum, 0 );
  296. }
  297. #if 0
  298. // // Recover EP after the error
  299. // USBD_USBTMC_HandleTypeDef * husbtmc = (USBD_USBTMC_HandleTypeDef*) pdev->pClassData;
  300. //
  301. // switch( epnum )
  302. // {
  303. // case USBTMC_BULKOUT_EP:
  304. // {
  305. // // Prepare BulkOUT endpoint for the next transaction
  306. // USBD_COMMON_DataOutBegin( pdev, USBTMC_BULKOUT_EP, &husbtmc->ep1_rx_transfer );
  307. // }
  308. // break;
  309. // }
  310. #endif
  311. }
  312. }
  313. }
  314. return USBD_OK;
  315. }
  316. /**
  317. * @brief USBD_USBTMC_Setup
  318. * Handle the class specific requests
  319. * @param pdev: instance
  320. * @param req: usb requests
  321. * @retval status
  322. */
  323. static uint8_t USBD_USBTMC_Setup (USBD_HandleTypeDef *pdev,
  324. USBD_SetupReqTypedef *req)
  325. {
  326. uint8_t ret = USBD_OK;
  327. USBD_USBTMC_HandleTypeDef *husbtmc = (USBD_USBTMC_HandleTypeDef*) pdev->pClassData;
  328. USBD_COMMON_ItfTypeDef * pUserIface = ((USBD_COMMON_ItfTypeDef *)pdev->pUserData);
  329. if( NULL == pUserIface->fUsbSetup )
  330. {
  331. return USBD_FAIL; // @fUsbSetup is missing
  332. }
  333. if( ! pUserIface->fUsbSetup( req, true, false ) )
  334. {
  335. return USBD_FAIL; // do not call @fUsbSetup second time
  336. }
  337. else
  338. {
  339. switch (req->bmRequest & USB_REQ_TYPE_MASK)
  340. {
  341. case USB_REQ_TYPE_CLASS : // Class I/O
  342. case USB_REQ_TYPE_VENDOR : // Debug, Benchmarks
  343. {
  344. if (req->wLength > 0)
  345. {
  346. if (req->bmRequest & 0x80)
  347. {
  348. #if RECREATE_CONTROL_TRANSFER_OBJ
  349. usb_create_transfer( &husbtmc->ep0_tx_transfer,
  350. &husbtmc->ep0_tx_buffer[0],
  351. sizeof(husbtmc->ep0_tx_buffer),
  352. NULL, pdev );
  353. #endif
  354. ret = USBD_COMMON_Setup_DataProcess( pdev, req, &husbtmc->ep0_tx_transfer );
  355. }
  356. else
  357. {
  358. #if RECREATE_CONTROL_TRANSFER_OBJ
  359. usb_create_transfer( &husbtmc->ep0_rx_transfer,
  360. &husbtmc->ep0_rx_buffer[0],
  361. sizeof(husbtmc->ep0_rx_buffer),
  362. NULL, pdev );
  363. #endif
  364. ret = USBD_COMMON_Setup_DataProcess( pdev, req, &husbtmc->ep0_rx_transfer );
  365. }
  366. }
  367. else
  368. {
  369. USBD_CtlSendStatus( pdev ); // need answer for ZeroLength requests
  370. }
  371. }
  372. break;
  373. case USB_REQ_TYPE_STANDARD:
  374. {
  375. switch (req->bRequest)
  376. {
  377. case USB_REQ_GET_INTERFACE:
  378. {
  379. if( NULL != pUserIface->fGetIface )
  380. {
  381. uint8_t nIf = req->wIndex;
  382. uint8_t ifalt = 0;
  383. if( pUserIface->fGetIface( pdev->dev_config, nIf, &ifalt ) )
  384. {
  385. USBD_CtlSendData (pdev, &ifalt, sizeof(ifalt));
  386. }
  387. else
  388. {
  389. ret = USBD_FAIL;
  390. }
  391. }
  392. else
  393. {
  394. ret = USBD_FAIL;
  395. }
  396. }
  397. break;
  398. case USB_REQ_SET_INTERFACE:
  399. break;
  400. }
  401. }
  402. break;
  403. default:
  404. break;
  405. }
  406. }
  407. if( ret != USBD_OK )
  408. {
  409. pUserIface->fUsbSetup( req, false, false );
  410. }
  411. return ret;
  412. }
  413. #if USBTMC_USE_COMMON_EP0RXREADY
  414. static uint8_t USBD_USBTMC_EP0_RxReady (USBD_HandleTypeDef *pdev, size_t * pnBytesRollback )
  415. {
  416. USBD_USBTMC_HandleTypeDef *husbtmc = (USBD_USBTMC_HandleTypeDef*) pdev->pClassData;
  417. return USBD_COMMON_EP0_RxReady( pdev, &husbtmc->ep0_rx_transfer, pnBytesRollback );
  418. }
  419. #else
  420. static uint8_t USBD_USBTMC_EP0_RxReady (USBD_HandleTypeDef *pdev, size_t * pnBytesRollback )
  421. {
  422. USBD_USBTMC_HandleTypeDef *husbtmc = (USBD_USBTMC_HandleTypeDef*) pdev->pClassData;
  423. USBD_EndpointTypeDef * pep = &pdev->ep_out[0];
  424. USBD_StatusTypeDef ret = USBD_FAIL;
  425. sUSBTransfer_t * rx = &husbtmc->ep0_rx_transfer;
  426. if( pdev->pUserData != NULL && usb_validate_transfer(rx) )
  427. {
  428. USBD_COMMON_ItfTypeDef * pUserIface = ((USBD_COMMON_ItfTypeDef *)pdev->pUserData);
  429. if( NULL != pUserIface->fUsbCtlEpRx )
  430. {
  431. size_t nBytesReceived = ((pep->rem_length > pep->maxpacket)?pep->maxpacket:pep->rem_length);
  432. size_t nBytesRemaining = (pep->rem_length - nBytesReceived);
  433. // Since the core uses raw @ep0_rx_transfer->pWriteData pointer, it is required to update the transfer information.
  434. // Use 'virutal write' to shift the pointer:
  435. usb_transfer_virtual_write( rx, nBytesReceived );
  436. // Check if the trasfer have enough free space for receiving another packet?
  437. // Or maybe it is a last packet?
  438. if( (usb_space_transfer(rx) < MIN(nBytesRemaining, pep->maxpacket)) || (0 == nBytesRemaining) )
  439. {
  440. // No, there no enough free space
  441. // Need to call user handler.
  442. // Retirieve actual amount of data in transfer
  443. size_t nBytesInTransfer = usb_count_transfer(rx);
  444. // Calculate current data offset
  445. size_t nOffset = (pep->total_length - nBytesRemaining - nBytesInTransfer);
  446. // pass the data to user
  447. size_t nBytesProcessed = pUserIface->fUsbCtlEpRx( &pdev->request,
  448. rx,
  449. nOffset,
  450. nBytesRemaining + nBytesInTransfer );
  451. // user can perform move semantic on transfer @rx.
  452. // It is valid condition if no remaining bytes left only.
  453. // Let's check it:
  454. bool bValid = usb_validate_transfer( rx );
  455. #warning Check
  456. if( 0 == nBytesRemaining || bValid )
  457. {
  458. // Actually, it does not matter, what exactly the function @fUsbCtlEpRx returns.
  459. // The only that matters is the amount of data in the transfer.
  460. // Just check the return value for zero:
  461. if( nBytesProcessed > 0 )
  462. {
  463. // By default ( usb_count_transfer() is ZERO ) ==> @nCompressed equals to the number of bytes in the transfer before user handler call.
  464. size_t nCompressed = nBytesInTransfer;
  465. // It is required that the transfer be valid only if @nBytesRemaining greater than zero
  466. if( bValid )
  467. {
  468. // If the transfer still contains data, it means user didn't perform full read.
  469. if( usb_count_transfer(rx) > 0 )
  470. {
  471. // it is required to compress the data in the transfer
  472. // optimize the transfer to compress stored data
  473. nCompressed = usb_transfer_compress( rx );
  474. // @bNeedPacketSpace - true if the core deadly needs at least MAX_PACKET free bytes in transfer
  475. bool bNeedPacketSpace = false;
  476. // After compressing: check if the transfer have enough space for next packet?
  477. if( usb_space_transfer(rx) >= MIN(nBytesRemaining, pep->maxpacket) )
  478. {
  479. // yes, ok
  480. ret = USBD_OK;
  481. }
  482. else
  483. {
  484. // nope, user didn't read enough data from the transfer to free enough space for next packet
  485. // Need to free at least MAX_PACKET free bytes in transfer
  486. bNeedPacketSpace = true;
  487. }
  488. // try to call user handler again:
  489. if( bNeedPacketSpace || (0 == nBytesRemaining) )
  490. {
  491. // Here: two reasons:
  492. // 1) if it is required to free MAX_PACKET bytes in transfer for next packet
  493. // 2) or this is a last packet: last chance to retrieve data. It is required to feed all data to user... Even if he resists!!!! >:D
  494. // For USB-core it does not matter if user processed all bytes or not...
  495. // There no incoming packets expected.
  496. // The only problem is to send a confirmation for this transaction.
  497. // As soon user process all bytes from the transfer @rx, this function returns control to the
  498. // core to send a confirmation.
  499. // Ok, lets feed user..
  500. while( nBytesProcessed > 0 )
  501. {
  502. nBytesInTransfer = usb_count_transfer(rx);
  503. size_t nLeftBytes = nBytesInTransfer + ((bNeedPacketSpace)?nBytesRemaining:0);
  504. size_t nOffset = (pep->total_length - nLeftBytes);
  505. // Call user handler, again...
  506. nBytesProcessed = pUserIface->fUsbCtlEpRx( &pdev->request,
  507. rx,
  508. nOffset,
  509. nLeftBytes );
  510. // user can perform move semantic on transfer @rx.
  511. // It is valid condition if no remaining bytes left only.
  512. // Let's check it:
  513. #warning Check
  514. if( 0 == nBytesRemaining || usb_validate_transfer( rx ) )
  515. {
  516. // ~~~ do not do this here, extra compressing possible (reduces performance) ~~ /* usb_transfer_compress( rx ); */
  517. // ~~~ do not do this here, extra compressing possible (reduces performance) ~~ /* nCompressed += (nBytesInTransfer - usb_count_transfer(rx)); */
  518. // Reason 1: (only if @bNeedPacketSpace is true)
  519. // check if the transfer has enough data for next packet
  520. if( bNeedPacketSpace
  521. && (usb_space_transfer(rx) >= MIN(nBytesRemaining, pep->maxpacket)) )
  522. {
  523. // Reason 1: exit, because transfer has enough free space for next packet
  524. // User have read data portion from the transfer, need to compress it again
  525. // Need to update @nCompressed variable to take in account new pointer to the free memory.
  526. usb_transfer_compress( rx );
  527. nCompressed += (nBytesInTransfer - usb_count_transfer(rx));
  528. ret = USBD_OK;
  529. break;
  530. }
  531. else
  532. {
  533. // User have read data portion from the transfer, need to compress it again
  534. // Need to update @nCompressed variable to take in account new pointer to the free memory.
  535. usb_transfer_compress( rx );
  536. nCompressed += (nBytesInTransfer - usb_count_transfer(rx));
  537. }
  538. // check if the transfer is still not empty
  539. if( 0 == usb_count_transfer(rx) )
  540. {
  541. // Reason 2: exit if transfer is empty
  542. // Empty! => Success (nBytesProcessed>0)
  543. break; // yee, at last!
  544. }
  545. }
  546. else
  547. {
  548. // Failed!
  549. ret = USBD_FAIL;
  550. }
  551. }
  552. // Check the last user call status
  553. if( 0 == nBytesProcessed )
  554. {
  555. // Failed!
  556. ret = USBD_FAIL;
  557. }
  558. }
  559. }
  560. else
  561. {
  562. // ~~~~~~~~~~~~ ADDED 18/04/19
  563. // Check if the trasfer have enough free space for receiving another packet?
  564. // Or maybe it is a last packet?
  565. if( (usb_space_transfer(rx) < MIN(nBytesRemaining, pep->maxpacket)) )
  566. {
  567. // it is required to compress the data in the transfer
  568. // optimize the transfer to compress stored data
  569. nCompressed = usb_transfer_compress( rx );
  570. }
  571. // ~~~~~~~~~~~~
  572. ret = USBD_OK;
  573. }
  574. }
  575. else
  576. {
  577. // If there no bytes left to receive
  578. // it is normal that the transfer is invalid (user may use move semantic)
  579. if( 0 == nBytesRemaining )
  580. {
  581. ret = USBD_OK;
  582. }
  583. }
  584. // let the core know how many excaclty bytes is required to shift the pointer back.
  585. if( (USBD_OK == ret) && (NULL != pnBytesRollback) )
  586. {
  587. // pass the exact number of bytes for rollback to the core
  588. *pnBytesRollback = nCompressed;
  589. }
  590. }
  591. else
  592. {
  593. // user must not return zero to proceed
  594. usb_reset_transfer( rx );
  595. ret = USBD_FAIL;
  596. }
  597. }
  598. else
  599. {
  600. ret = USBD_FAIL;
  601. }
  602. }
  603. else
  604. {
  605. // yep, there is free space for the next packet, let's receive it
  606. ret = USBD_CONTINUE;
  607. }
  608. }
  609. }
  610. return ret;
  611. }
  612. #endif
  613. #if USBTMC_USE_COMMON_EP0TXSENT
  614. static uint8_t USBD_USBTMC_EP0_TxSent (USBD_HandleTypeDef *pdev, size_t * pnBytesRollback )
  615. {
  616. USBD_USBTMC_HandleTypeDef *husbtmc = (USBD_USBTMC_HandleTypeDef*) pdev->pClassData;
  617. return USBD_COMMON_EP0_TxSent( pdev, &husbtmc->ep0_tx_transfer, pnBytesRollback );
  618. }
  619. #else
  620. // USBD_USBTMC_EP0_TxSent()
  621. // This function is called when at least one packet had been sent to the host
  622. // This function continues the transmitting
  623. static uint8_t USBD_USBTMC_EP0_TxSent (USBD_HandleTypeDef *pdev, size_t * pnBytesRollback )
  624. {
  625. USBD_USBTMC_HandleTypeDef *husbtmc = (USBD_USBTMC_HandleTypeDef*) pdev->pClassData;
  626. USBD_EndpointTypeDef * pep = &pdev->ep_in[0];
  627. sUSBTransfer_t * tx = &husbtmc->ep0_tx_transfer;
  628. uint8_t ret = USBD_FAIL;
  629. if( pdev->pUserData != NULL && usb_validate_transfer(tx) )
  630. {
  631. USBD_COMMON_ItfTypeDef * pUserIface = ((USBD_COMMON_ItfTypeDef *)pdev->pUserData);
  632. if( NULL != pUserIface->fUsbCtlEpTx )
  633. {
  634. // Due to the low-level driver uses dry transfer->@pReadData pointer, the
  635. // tranfer object must be modified.
  636. size_t nBytesRequested = 0;
  637. if( 0 == pep->rem_length )
  638. {
  639. // Update transfer information:
  640. // If @pep->rem_length is zero, the last packet sent was a last packet
  641. // The size of the short packet is a remainder of the division the
  642. // full transaction size and the endpoint size.
  643. // If the result of operation is non zero, the last packet was a short packet.
  644. // If the result of operation is zero, the last packet was full packet
  645. size_t last_packet_size = (pep->total_length % pep->maxpacket);
  646. if( last_packet_size == 0 )
  647. {
  648. last_packet_size = pep->maxpacket;
  649. }
  650. usb_transfer_virtual_read( tx, last_packet_size );
  651. }
  652. else
  653. {
  654. nBytesRequested = MIN( pep->maxpacket, pep->rem_length );
  655. // Update transfer information:
  656. // If @pep->rem_length is non zero, the last packet send was a full packet.
  657. // The size of full packet is pep->maxpacket
  658. usb_transfer_virtual_read( tx, pep->maxpacket );
  659. }
  660. // // Update transfer information:
  661. // usb_transfer_virtual_read( tx,
  662. // // The variable @nBytesRequested have quite confusing name, but this argument
  663. // // requires the length of already sent data. Actually the number of bytes already sent
  664. // // is numerially equals to @nBytesRequested
  665. // nBytesRequested // for pep->rem_length >= pep->maxpacket: the pep->maxpacket bytes just have been sent
  666. // ); // for pep->rem_length < pep->maxpacket: the pep->rem_length bytes just have been sent
  667. //
  668. // If the transaction is still not completed:
  669. if( pep->rem_length == 0 )
  670. {
  671. // transfer full reset
  672. usb_reset_transfer( tx );
  673. ret = USBD_OK;
  674. }
  675. else
  676. {
  677. size_t nBytesLeft = usb_count_transfer( tx );
  678. // If the transfer has enougth data to send another packet:
  679. if( nBytesLeft >= nBytesRequested )
  680. {
  681. ret = USBD_CONTINUE; // ask the core to continue sending the transfer (without rollback)
  682. }
  683. else
  684. {
  685. if( nBytesLeft > 0 )
  686. {
  687. // optimize the transfer to compress stored data
  688. size_t nCompressed = usb_transfer_compress( tx );
  689. if( NULL != pnBytesRollback )
  690. {
  691. // pass the exact number of bytes for rollback to the core
  692. *pnBytesRollback = nCompressed;
  693. }
  694. }
  695. else
  696. {
  697. // // transfer full reset
  698. // usb_reset_transfer( tx );
  699. size_t nCompressed = usb_transfer_compress( tx );
  700. if( NULL != pnBytesRollback )
  701. {
  702. // pass the exact number of bytes for rollback to the core
  703. *pnBytesRollback = nCompressed;
  704. }
  705. }
  706. size_t nOffset = (pep->total_length - pep->rem_length + nBytesLeft);
  707. size_t nBytesProcessed = pUserIface->fUsbCtlEpTx( &pdev->request,
  708. tx,
  709. nOffset,
  710. pep->rem_length );
  711. // User can perform move semantic on the @tx transfer.
  712. // This is an error condition, let's check it:
  713. #warning Check
  714. if( usb_validate_transfer( tx ) )
  715. {
  716. // Actually, does not matter what exactly the function @fUsbCtlEpTx returns,
  717. // because only transfer size really matters ( usb_count_transfer() ).
  718. // Just check the return value for zero:
  719. if( nBytesProcessed > 0 )
  720. {
  721. // If more than one FULL packet is required to send:
  722. if( pep->rem_length >= pep->maxpacket )
  723. {
  724. // This packet must be full: transfer must contain at least @pep->maxpacket bytes
  725. if( usb_count_transfer( tx ) >= pep->maxpacket )
  726. {
  727. ret = USBD_OK;
  728. }
  729. }
  730. else
  731. // No, it is required to send "short packet"
  732. {
  733. // This packet must be short: transfer must contain exactly @pep->rem_length bytes
  734. if( usb_count_transfer( tx ) == pep->rem_length )
  735. {
  736. ret = USBD_OK;
  737. }
  738. }
  739. }
  740. else
  741. {
  742. ret = USBD_FAIL;
  743. }
  744. }
  745. else
  746. {
  747. ret = USBD_FAIL;
  748. }
  749. }
  750. }
  751. }
  752. }
  753. return ret;
  754. }
  755. #endif
  756. // USBD_USBTMC_DataIn
  757. // Handle IN requests for Bulk or Interrupt requests
  758. // Note: this function is only called after the first packet sent!
  759. static uint8_t USBD_USBTMC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum )
  760. {
  761. USBD_USBTMC_HandleTypeDef * husbtmc = (USBD_USBTMC_HandleTypeDef*)pdev->pClassData;
  762. switch( epnum | 0x80 )
  763. {
  764. case USBTMC_BULKIN_EP:
  765. {
  766. return USBD_COMMON_DataInProcess( pdev, epnum, &husbtmc->ep1_tx_transfer );
  767. }
  768. case USBTMC_INTERRUPTIN_EP:
  769. {
  770. return USBD_COMMON_DataInProcess( pdev, epnum, &husbtmc->ep2_tx_transfer );
  771. }
  772. }
  773. return USBD_FAIL;
  774. }
  775. #if DATAIN_INITIATESEND_REQUIRED
  776. // USBD_USBTMC_DataIn_BeginSend
  777. // Initiates the first packet sending using virtual DataIN event
  778. // @bTxAlreadyPrepared - if the TX-transfer is already prepared to transmission, do not reset transfer, do not call TX-handler
  779. uint8_t USBD_USBTMC_DataIn_BeginSend( uint8_t epnum, bool bTxAlreadyPrepared )
  780. {
  781. USBD_USBTMC_HandleTypeDef * husbtmc = g_husbtmc; // impossible: "(USBD_USBTMC_HandleTypeDef*)pdev->pClassData"
  782. USBD_HandleTypeDef *pdev = husbtmc->pdev; // hack, I'm not satisfated with this hack, but it is required
  783. switch( epnum | 0x80 )
  784. {
  785. case USBTMC_BULKIN_EP:
  786. {
  787. return USBD_COMMON_DataIn_BeginSend( pdev, epnum, &husbtmc->ep1_tx_transfer, bTxAlreadyPrepared );
  788. }
  789. case USBTMC_INTERRUPTIN_EP:
  790. {
  791. return USBD_COMMON_DataIn_BeginSend( pdev, epnum, &husbtmc->ep2_tx_transfer, bTxAlreadyPrepared );
  792. }
  793. }
  794. return USBD_FAIL;
  795. }
  796. #endif
  797. // USBD_USBTMC_DataIn_ZeroSend
  798. // Queue zero packet in EP IN
  799. uint8_t USBD_USBTMC_DataIn_ZeroSend( uint8_t epnum )
  800. {
  801. USBD_USBTMC_HandleTypeDef * husbtmc = g_husbtmc; // impossible: "(USBD_USBTMC_HandleTypeDef*)pdev->pClassData"
  802. USBD_HandleTypeDef *pdev = husbtmc->pdev; // hack, I'm not satisfated with this hack, but it is required
  803. switch( epnum | 0x80 )
  804. {
  805. case USBTMC_BULKIN_EP:
  806. case USBTMC_INTERRUPTIN_EP:
  807. {
  808. return USBD_COMMON_DataIn_ZeroSend( pdev, epnum );
  809. }
  810. }
  811. return USBD_FAIL;
  812. }
  813. // USBD_USBTMC_StallEP()
  814. // Halt specfied data-endpoint by it's address and reset the buffer
  815. void USBD_USBTMC_StallEP( uint8_t epaddr )
  816. {
  817. USBD_USBTMC_HandleTypeDef * husbtmc = g_husbtmc; // impossible: "(USBD_USBTMC_HandleTypeDef*)pdev->pClassData"
  818. USBD_HandleTypeDef *pdev = husbtmc->pdev; // hack, I'm not satisfated with this hack, but it is required
  819. switch( epaddr )
  820. {
  821. case USBTMC_BULKIN_EP:
  822. {
  823. USBD_LL_StallEP( pdev, epaddr );
  824. usb_reset_transfer( &husbtmc->ep1_tx_transfer );
  825. }
  826. break;
  827. case USBTMC_BULKOUT_EP:
  828. {
  829. USBD_LL_StallEP( pdev, epaddr );
  830. usb_reset_transfer( &husbtmc->ep1_rx_transfer );
  831. }
  832. break;
  833. case USBTMC_INTERRUPTIN_EP:
  834. {
  835. USBD_LL_StallEP( pdev, epaddr );
  836. usb_reset_transfer( &husbtmc->ep2_tx_transfer );
  837. }
  838. break;
  839. }
  840. }
  841. // USBD_USBTMC_ClearEP()
  842. // Restore specfied halted data-endpoint by it's address and reset the buffer
  843. // Recover the Rx-transfer for specified endpoint
  844. // Restarts the receiving for the specified endpoint
  845. void USBD_USBTMC_ClearEP( uint8_t epaddr )
  846. {
  847. USBD_USBTMC_HandleTypeDef * husbtmc = g_husbtmc; // impossible: "(USBD_USBTMC_HandleTypeDef*)pdev->pClassData"
  848. USBD_HandleTypeDef *pdev = husbtmc->pdev; // hack, I'm not satisfated with this hack, but it is required
  849. switch( epaddr )
  850. {
  851. case USBTMC_BULKIN_EP:
  852. {
  853. usb_reset_transfer( &husbtmc->ep1_tx_transfer );
  854. USBD_LL_ClearStallEP( pdev, epaddr );
  855. }
  856. break;
  857. case USBTMC_BULKOUT_EP:
  858. {
  859. USBD_COMMON_DataOutBegin( pdev, epaddr, &husbtmc->ep1_rx_transfer );
  860. USBD_LL_ClearStallEP( pdev, epaddr );
  861. }
  862. break;
  863. case USBTMC_INTERRUPTIN_EP:
  864. {
  865. usb_reset_transfer( &husbtmc->ep2_tx_transfer );
  866. USBD_LL_ClearStallEP( pdev, epaddr );
  867. }
  868. break;
  869. }
  870. }
  871. // USBD_USBTMC_NakEP()
  872. // Reset hardware EP buffer and setup the end-point to Not-acknowlage mode
  873. // No data will be returned by EP util the data will be queued again
  874. void USBD_USBTMC_NakEP( uint8_t epaddr )
  875. {
  876. USBD_USBTMC_HandleTypeDef * husbtmc = g_husbtmc; // impossible: "(USBD_USBTMC_HandleTypeDef*)pdev->pClassData"
  877. USBD_HandleTypeDef *pdev = husbtmc->pdev; // hack, I'm not satisfated with this hack, but it is required
  878. switch( epaddr )
  879. {
  880. case USBTMC_BULKIN_EP:
  881. {
  882. usb_reset_transfer( &husbtmc->ep1_tx_transfer );
  883. USBD_LL_NakEP( pdev, epaddr );
  884. }
  885. break;
  886. case USBTMC_BULKOUT_EP:
  887. {
  888. usb_reset_transfer( &husbtmc->ep1_rx_transfer );
  889. USBD_LL_NakEP( pdev, epaddr );
  890. }
  891. break;
  892. case USBTMC_INTERRUPTIN_EP:
  893. {
  894. usb_reset_transfer( &husbtmc->ep2_tx_transfer );
  895. USBD_LL_NakEP( pdev, epaddr );
  896. }
  897. break;
  898. }
  899. }
  900. // USBD_USBTMC_DataOut
  901. // Handle OUT requests for Bulk or Interrupt requests
  902. static uint8_t USBD_USBTMC_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum, bool ShortPacketReceived )
  903. {
  904. USBD_USBTMC_HandleTypeDef * husbtmc = (USBD_USBTMC_HandleTypeDef*)pdev->pClassData;
  905. switch( epnum )
  906. {
  907. case USBTMC_BULKOUT_EP:
  908. {
  909. return USBD_COMMON_DataOutProcess( pdev, epnum, &husbtmc->ep1_rx_transfer, ShortPacketReceived );
  910. }
  911. }
  912. return USBD_FAIL;
  913. }
  914. sUSBTransfer_t * USBD_USBTMC_GetDataTxTransferHandle()
  915. {
  916. return &g_husbtmc->ep1_tx_transfer;
  917. }
  918. sUSBTransfer_t * USBD_USBTMC_GetDataRxTransferHandle()
  919. {
  920. return &g_husbtmc->ep1_rx_transfer;
  921. }
  922. sUSBTransfer_t * USBD_USBTMC_GetInterruptTxTransferHandle()
  923. {
  924. return &g_husbtmc->ep2_tx_transfer;
  925. }
  926. // USBD_USBTMC_GetTxQueuedSize
  927. // Returns amound of bytes queued in USBTMC IN endpoint.
  928. // @epaddr - USBTMC EP-IN number
  929. // @pCount - pointer to the value to store the packet length, can be NULL
  930. // Return: true if there is a queued packet in EP-IN, the length is stored in @pCount
  931. // false if there no queued packet in EP-IN, @pCount has not been modified
  932. bool USBD_USBTMC_GetTxQueuedSize( uint8_t epaddr, uint32_t * pCount )
  933. {
  934. USBD_USBTMC_HandleTypeDef * husbtmc = g_husbtmc; // impossible: "(USBD_USBTMC_HandleTypeDef*)pdev->pClassData"
  935. USBD_HandleTypeDef *pdev = husbtmc->pdev; // hack, I'm not satisfated with this hack, but it is required
  936. uint32_t len = 0;
  937. if( -1l == ( len = USBD_GetTxCount( pdev, epaddr ), len ) )
  938. {
  939. return false; // no packet queued in TX
  940. }
  941. if( NULL != pCount ) *pCount = len;
  942. return true; // return the packet len in @pCount
  943. }