USBD_User_CustomClass_0.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. /*------------------------------------------------------------------------------
  2. * MDK Middleware - Component ::USB:Device
  3. * Copyright (c) 2004-2016 ARM Germany GmbH. All rights reserved.
  4. *------------------------------------------------------------------------------
  5. * Name: USBD_User_CustomClass_0.c
  6. * Purpose: USB Device Custom Class User module
  7. * Rev.: V6.7.3
  8. *----------------------------------------------------------------------------*/
  9. /*
  10. * USBD_User_CustomClass_0.c is a code template for the Custom Class 0
  11. * class request handling. It allows user to handle all Custom Class class
  12. * requests.
  13. *
  14. * Uncomment "Example code" lines to see example that receives data on
  15. * Endpoint 1 OUT and echoes it back on Endpoint 1 IN.
  16. * To try the example you also have to enable Bulk Endpoint 1 IN/OUT in Custom
  17. * Class configuration in USBD_Config_CustomClass_0.h file.
  18. */
  19. /**
  20. * \addtogroup usbd_custom_classFunctions
  21. *
  22. */
  23. //! [code_USBD_User_CustomClass]
  24. #include <stdint.h>
  25. #include <stdbool.h>
  26. #include <string.h>
  27. #include "cmsis_os2.h"
  28. #define osObjectsExternal
  29. #include "osObjects.h"
  30. #include "rl_usb.h"
  31. #include "Driver_USBD.h"
  32. #include "DAP_config.h"
  33. #include "DAP.h"
  34. static volatile uint16_t USB_RequestIndexI; // Request Index In
  35. static volatile uint16_t USB_RequestIndexO; // Request Index Out
  36. static volatile uint16_t USB_RequestCountI; // Request Count In
  37. static volatile uint16_t USB_RequestCountO; // Request Count Out
  38. static volatile uint8_t USB_RequestIdle; // Request Idle Flag
  39. static volatile uint16_t USB_ResponseIndexI; // Response Index In
  40. static volatile uint16_t USB_ResponseIndexO; // Response Index Out
  41. static volatile uint16_t USB_ResponseCountI; // Response Count In
  42. static volatile uint16_t USB_ResponseCountO; // Response Count Out
  43. static volatile uint8_t USB_ResponseIdle; // Response Idle Flag
  44. static uint8_t USB_Request [DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO"))); // Request Buffer
  45. static uint8_t USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO"))); // Response Buffer
  46. static uint16_t USB_RespSize[DAP_PACKET_COUNT]; // Response Size
  47. // \brief Callback function called during USBD_Initialize to initialize the USB Custom class instance
  48. void USBD_CustomClass0_Initialize (void) {
  49. // Handle Custom Class Initialization
  50. // Initialize variables
  51. USB_RequestIndexI = 0U;
  52. USB_RequestIndexO = 0U;
  53. USB_RequestCountI = 0U;
  54. USB_RequestCountO = 0U;
  55. USB_RequestIdle = 1U;
  56. USB_ResponseIndexI = 0U;
  57. USB_ResponseIndexO = 0U;
  58. USB_ResponseCountI = 0U;
  59. USB_ResponseCountO = 0U;
  60. USB_ResponseIdle = 1U;
  61. }
  62. // \brief Callback function called during USBD_Uninitialize to de-initialize the USB Custom class instance
  63. void USBD_CustomClass0_Uninitialize (void) {
  64. // Handle Custom Class De-initialization
  65. }
  66. // \brief Callback function called upon USB Bus Reset signaling
  67. void USBD_CustomClass0_Reset (void) {
  68. // Handle USB Bus Reset Event
  69. }
  70. // \brief Callback function called when Endpoint Start was requested (by activating interface or configuration)
  71. // \param[in] ep_addr endpoint address.
  72. void USBD_CustomClass0_EndpointStart (uint8_t ep_addr) {
  73. // Start communication on Endpoint
  74. if (ep_addr == USB_ENDPOINT_OUT(1U)) {
  75. USB_RequestIdle = 0U;
  76. USBD_EndpointRead(0U, USB_ENDPOINT_OUT(1U), USB_Request[0], DAP_PACKET_SIZE);
  77. }
  78. }
  79. // \brief Callback function called when Endpoint Stop was requested (by de-activating interface or activating configuration 0)
  80. // \param[in] ep_addr endpoint address.
  81. void USBD_CustomClass0_EndpointStop (uint8_t ep_addr) {
  82. // Handle Endpoint communication stopped
  83. (void)ep_addr;
  84. }
  85. // \brief Callback function called when Custom Class 0 received SETUP PACKET on Control Endpoint 0
  86. // (this callback will be called only for Class Requests (USB_REQUEST_CLASS) if it was not processed
  87. // previously by Device callback)
  88. // \param[in] setup_packet pointer to received setup packet.
  89. // \param[out] buf pointer to data buffer used for data stage requested by setup packet.
  90. // \param[out] len pointer to number of data bytes in data stage requested by setup packet.
  91. // \return usbdRequestStatus enumerator value indicating the function execution status
  92. // \return usbdRequestNotProcessed:request was not processed; processing will be done by USB library
  93. // \return usbdRequestOK: request was processed successfully (send Zero-Length Packet if no data stage)
  94. // \return usbdRequestStall: request was processed but is not supported (stall Endpoint 0)
  95. usbdRequestStatus USBD_CustomClass0_Endpoint0_SetupPacketReceived (const USB_SETUP_PACKET *setup_packet, uint8_t **buf, uint32_t *len) {
  96. (void)setup_packet;
  97. (void)buf;
  98. (void)len;
  99. switch (setup_packet->bmRequestType.Recipient) {
  100. case USB_REQUEST_TO_DEVICE:
  101. break;
  102. case USB_REQUEST_TO_INTERFACE:
  103. break;
  104. case USB_REQUEST_TO_ENDPOINT:
  105. break;
  106. default:
  107. break;
  108. }
  109. return usbdRequestNotProcessed;
  110. }
  111. // \brief Callback function called when SETUP PACKET was processed by USB library
  112. // (this callback will be called only for Class Requests (USB_REQUEST_CLASS) if it was not processed
  113. // previously by Device callback nor by Custom Class callback)
  114. // \param[in] setup_packet pointer to processed setup packet.
  115. void USBD_CustomClass0_Endpoint0_SetupPacketProcessed (const USB_SETUP_PACKET *setup_packet) {
  116. (void)setup_packet;
  117. switch (setup_packet->bmRequestType.Recipient) {
  118. case USB_REQUEST_TO_DEVICE:
  119. break;
  120. case USB_REQUEST_TO_INTERFACE:
  121. break;
  122. case USB_REQUEST_TO_ENDPOINT:
  123. break;
  124. default:
  125. break;
  126. }
  127. }
  128. // \brief Callback function called when Custom Class 0 received OUT DATA on Control Endpoint 0
  129. // (this callback will be called only for Class Requests (USB_REQUEST_CLASS) if it was not processed
  130. // previously by Device callback)
  131. // \param[in] len number of received data bytes.
  132. // \return usbdRequestStatus enumerator value indicating the function execution status
  133. // \return usbdRequestNotProcessed:request was not processed; processing will be done by USB library
  134. // \return usbdRequestOK: request was processed successfully (send Zero-Length Packet)
  135. // \return usbdRequestStall: request was processed but is not supported (stall Endpoint 0)
  136. // \return usbdRequestNAK: request was processed but the device is busy (return NAK)
  137. usbdRequestStatus USBD_CustomClass0_Endpoint0_OutDataReceived (uint32_t len) {
  138. (void)len;
  139. return usbdRequestNotProcessed;
  140. }
  141. // \brief Callback function called when Custom Class 0 sent IN DATA on Control Endpoint 0
  142. // (this callback will be called only for Class Requests (USB_REQUEST_CLASS) if it was not processed
  143. // previously by Device callback)
  144. // \param[in] len number of sent data bytes.
  145. // \return usbdRequestStatus enumerator value indicating the function execution status
  146. // \return usbdRequestNotProcessed:request was not processed; processing will be done by USB library
  147. // \return usbdRequestOK: request was processed successfully (return ACK)
  148. // \return usbdRequestStall: request was processed but is not supported (stall Endpoint 0)
  149. // \return usbdRequestNAK: request was processed but the device is busy (return NAK)
  150. usbdRequestStatus USBD_CustomClass0_Endpoint0_InDataSent (uint32_t len) {
  151. (void)len;
  152. return usbdRequestNotProcessed;
  153. }
  154. // \brief Callback function called when DATA was sent or received on Endpoint n
  155. // \param[in] event event on Endpoint:
  156. // - ARM_USBD_EVENT_OUT = data OUT received
  157. // - ARM_USBD_EVENT_IN = data IN sent
  158. void USBD_CustomClass0_Endpoint1_Event (uint32_t event) {
  159. // Handle Endpoint 1 events
  160. uint32_t n;
  161. if (event & ARM_USBD_EVENT_OUT) {
  162. n = USBD_EndpointReadGetResult(0U, USB_ENDPOINT_OUT(1U));
  163. if (n != 0U) {
  164. if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) {
  165. DAP_TransferAbort = 1U;
  166. } else {
  167. USB_RequestIndexI++;
  168. if (USB_RequestIndexI == DAP_PACKET_COUNT) {
  169. USB_RequestIndexI = 0U;
  170. }
  171. USB_RequestCountI++;
  172. osThreadFlagsSet(DAP_ThreadId, 0x01);
  173. }
  174. }
  175. // Start reception of next request packet
  176. if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
  177. USBD_EndpointRead(0U, USB_ENDPOINT_OUT(1U), USB_Request[USB_RequestIndexI], DAP_PACKET_SIZE);
  178. } else {
  179. USB_RequestIdle = 1U;
  180. }
  181. }
  182. if (event & ARM_USBD_EVENT_IN) {
  183. if (USB_ResponseCountI != USB_ResponseCountO) {
  184. // Load data from response buffer to be sent back
  185. USBD_EndpointWrite(0U, USB_ENDPOINT_IN(1U), USB_Response[USB_ResponseIndexO], USB_RespSize[USB_ResponseIndexO]);
  186. USB_ResponseIndexO++;
  187. if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
  188. USB_ResponseIndexO = 0U;
  189. }
  190. USB_ResponseCountO++;
  191. } else {
  192. USB_ResponseIdle = 1U;
  193. }
  194. }
  195. }
  196. void USBD_CustomClass0_Endpoint2_Event (uint32_t event) {
  197. // Handle Endpoint 2 events
  198. if (event & ARM_USBD_EVENT_IN) {
  199. SWO_TransferComplete();
  200. }
  201. }
  202. void USBD_CustomClass0_Endpoint3_Event (uint32_t event) {
  203. // Handle Endpoint 3 events
  204. (void)event;
  205. }
  206. void USBD_CustomClass0_Endpoint4_Event (uint32_t event) {
  207. // Handle Endpoint 4 events
  208. (void)event;
  209. }
  210. void USBD_CustomClass0_Endpoint5_Event (uint32_t event) {
  211. // Handle Endpoint 5 events
  212. (void)event;
  213. }
  214. void USBD_CustomClass0_Endpoint6_Event (uint32_t event) {
  215. // Handle Endpoint 6 events
  216. (void)event;
  217. }
  218. void USBD_CustomClass0_Endpoint7_Event (uint32_t event) {
  219. // Handle Endpoint 7 events
  220. (void)event;
  221. }
  222. void USBD_CustomClass0_Endpoint8_Event (uint32_t event) {
  223. // Handle Endpoint 8 events
  224. (void)event;
  225. }
  226. void USBD_CustomClass0_Endpoint9_Event (uint32_t event) {
  227. // Handle Endpoint 9 events
  228. (void)event;
  229. }
  230. void USBD_CustomClass0_Endpoint10_Event (uint32_t event) {
  231. // Handle Endpoint 10 events
  232. (void)event;
  233. }
  234. void USBD_CustomClass0_Endpoint11_Event (uint32_t event) {
  235. // Handle Endpoint 11 events
  236. (void)event;
  237. }
  238. void USBD_CustomClass0_Endpoint12_Event (uint32_t event) {
  239. // Handle Endpoint 12 events
  240. (void)event;
  241. }
  242. void USBD_CustomClass0_Endpoint13_Event (uint32_t event) {
  243. // Handle Endpoint 13 events
  244. (void)event;
  245. }
  246. void USBD_CustomClass0_Endpoint14_Event (uint32_t event) {
  247. // Handle Endpoint 14 events
  248. (void)event;
  249. }
  250. void USBD_CustomClass0_Endpoint15_Event (uint32_t event) {
  251. // Handle Endpoint 15 events
  252. (void)event;
  253. }
  254. // DAP Thread.
  255. __NO_RETURN void DAP_Thread (void *argument) {
  256. uint32_t flags;
  257. uint32_t n;
  258. (void) argument;
  259. for (;;) {
  260. osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever);
  261. // Process pending requests
  262. while (USB_RequestCountI != USB_RequestCountO) {
  263. // Handle Queue Commands
  264. n = USB_RequestIndexO;
  265. while (USB_Request[n][0] == ID_DAP_QueueCommands) {
  266. USB_Request[n][0] = ID_DAP_ExecuteCommands;
  267. n++;
  268. if (n == DAP_PACKET_COUNT) {
  269. n = 0U;
  270. }
  271. if (n == USB_RequestIndexI) {
  272. flags = osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever);
  273. if (flags & 0x80U) {
  274. break;
  275. }
  276. }
  277. }
  278. // Execute DAP Command (process request and prepare response)
  279. USB_RespSize[USB_ResponseIndexI] =
  280. (uint16_t)DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]);
  281. // Update Request Index and Count
  282. USB_RequestIndexO++;
  283. if (USB_RequestIndexO == DAP_PACKET_COUNT) {
  284. USB_RequestIndexO = 0U;
  285. }
  286. USB_RequestCountO++;
  287. if (USB_RequestIdle) {
  288. if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) {
  289. USB_RequestIdle = 0U;
  290. USBD_EndpointRead(0U, USB_ENDPOINT_OUT(1U), USB_Request[USB_RequestIndexI], DAP_PACKET_SIZE);
  291. }
  292. }
  293. // Update Response Index and Count
  294. USB_ResponseIndexI++;
  295. if (USB_ResponseIndexI == DAP_PACKET_COUNT) {
  296. USB_ResponseIndexI = 0U;
  297. }
  298. USB_ResponseCountI++;
  299. if (USB_ResponseIdle) {
  300. if (USB_ResponseCountI != USB_ResponseCountO) {
  301. // Load data from response buffer to be sent back
  302. n = USB_ResponseIndexO++;
  303. if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
  304. USB_ResponseIndexO = 0U;
  305. }
  306. USB_ResponseCountO++;
  307. USB_ResponseIdle = 0U;
  308. USBD_EndpointWrite(0U, USB_ENDPOINT_IN(1U), USB_Response[n], USB_RespSize[n]);
  309. }
  310. }
  311. }
  312. }
  313. }
  314. // SWO Data Queue Transfer
  315. // buf: pointer to buffer with data
  316. // num: number of bytes to transfer
  317. void SWO_QueueTransfer (uint8_t *buf, uint32_t num) {
  318. USBD_EndpointWrite(0U, USB_ENDPOINT_IN(2U), buf, num);
  319. }
  320. // SWO Data Abort Transfer
  321. void SWO_AbortTransfer (void) {
  322. USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));
  323. }
  324. //! [code_USBD_User_CustomClass]