/*------------------------------------------------------------------------------ * MDK Middleware - Component ::USB:Device * Copyright (c) 2004-2016 ARM Germany GmbH. All rights reserved. *------------------------------------------------------------------------------ * Name: USBD_User_CustomClass_0.c * Purpose: USB Device Custom Class User module * Rev.: V6.7.3 *----------------------------------------------------------------------------*/ /* * USBD_User_CustomClass_0.c is a code template for the Custom Class 0 * class request handling. It allows user to handle all Custom Class class * requests. * * Uncomment "Example code" lines to see example that receives data on * Endpoint 1 OUT and echoes it back on Endpoint 1 IN. * To try the example you also have to enable Bulk Endpoint 1 IN/OUT in Custom * Class configuration in USBD_Config_CustomClass_0.h file. */ /** * \addtogroup usbd_custom_classFunctions * */ //! [code_USBD_User_CustomClass] #include #include #include #include "cmsis_os2.h" #define osObjectsExternal #include "osObjects.h" #include "rl_usb.h" #include "Driver_USBD.h" #include "DAP_config.h" #include "DAP.h" static volatile uint16_t USB_RequestIndexI; // Request Index In static volatile uint16_t USB_RequestIndexO; // Request Index Out static volatile uint16_t USB_RequestCountI; // Request Count In static volatile uint16_t USB_RequestCountO; // Request Count Out static volatile uint8_t USB_RequestIdle; // Request Idle Flag static volatile uint16_t USB_ResponseIndexI; // Response Index In static volatile uint16_t USB_ResponseIndexO; // Response Index Out static volatile uint16_t USB_ResponseCountI; // Response Count In static volatile uint16_t USB_ResponseCountO; // Response Count Out static volatile uint8_t USB_ResponseIdle; // Response Idle Flag static uint8_t USB_Request [DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO"))); // Request Buffer static uint8_t USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE] __attribute__((section(".bss.USB_IO"))); // Response Buffer static uint16_t USB_RespSize[DAP_PACKET_COUNT]; // Response Size // \brief Callback function called during USBD_Initialize to initialize the USB Custom class instance void USBD_CustomClass0_Initialize (void) { // Handle Custom Class Initialization // Initialize variables USB_RequestIndexI = 0U; USB_RequestIndexO = 0U; USB_RequestCountI = 0U; USB_RequestCountO = 0U; USB_RequestIdle = 1U; USB_ResponseIndexI = 0U; USB_ResponseIndexO = 0U; USB_ResponseCountI = 0U; USB_ResponseCountO = 0U; USB_ResponseIdle = 1U; } // \brief Callback function called during USBD_Uninitialize to de-initialize the USB Custom class instance void USBD_CustomClass0_Uninitialize (void) { // Handle Custom Class De-initialization } // \brief Callback function called upon USB Bus Reset signaling void USBD_CustomClass0_Reset (void) { // Handle USB Bus Reset Event } // \brief Callback function called when Endpoint Start was requested (by activating interface or configuration) // \param[in] ep_addr endpoint address. void USBD_CustomClass0_EndpointStart (uint8_t ep_addr) { // Start communication on Endpoint if (ep_addr == USB_ENDPOINT_OUT(1U)) { USB_RequestIdle = 0U; USBD_EndpointRead(0U, USB_ENDPOINT_OUT(1U), USB_Request[0], DAP_PACKET_SIZE); } } // \brief Callback function called when Endpoint Stop was requested (by de-activating interface or activating configuration 0) // \param[in] ep_addr endpoint address. void USBD_CustomClass0_EndpointStop (uint8_t ep_addr) { // Handle Endpoint communication stopped (void)ep_addr; } // \brief Callback function called when Custom Class 0 received SETUP PACKET on Control Endpoint 0 // (this callback will be called only for Class Requests (USB_REQUEST_CLASS) if it was not processed // previously by Device callback) // \param[in] setup_packet pointer to received setup packet. // \param[out] buf pointer to data buffer used for data stage requested by setup packet. // \param[out] len pointer to number of data bytes in data stage requested by setup packet. // \return usbdRequestStatus enumerator value indicating the function execution status // \return usbdRequestNotProcessed:request was not processed; processing will be done by USB library // \return usbdRequestOK: request was processed successfully (send Zero-Length Packet if no data stage) // \return usbdRequestStall: request was processed but is not supported (stall Endpoint 0) usbdRequestStatus USBD_CustomClass0_Endpoint0_SetupPacketReceived (const USB_SETUP_PACKET *setup_packet, uint8_t **buf, uint32_t *len) { (void)setup_packet; (void)buf; (void)len; switch (setup_packet->bmRequestType.Recipient) { case USB_REQUEST_TO_DEVICE: break; case USB_REQUEST_TO_INTERFACE: break; case USB_REQUEST_TO_ENDPOINT: break; default: break; } return usbdRequestNotProcessed; } // \brief Callback function called when SETUP PACKET was processed by USB library // (this callback will be called only for Class Requests (USB_REQUEST_CLASS) if it was not processed // previously by Device callback nor by Custom Class callback) // \param[in] setup_packet pointer to processed setup packet. void USBD_CustomClass0_Endpoint0_SetupPacketProcessed (const USB_SETUP_PACKET *setup_packet) { (void)setup_packet; switch (setup_packet->bmRequestType.Recipient) { case USB_REQUEST_TO_DEVICE: break; case USB_REQUEST_TO_INTERFACE: break; case USB_REQUEST_TO_ENDPOINT: break; default: break; } } // \brief Callback function called when Custom Class 0 received OUT DATA on Control Endpoint 0 // (this callback will be called only for Class Requests (USB_REQUEST_CLASS) if it was not processed // previously by Device callback) // \param[in] len number of received data bytes. // \return usbdRequestStatus enumerator value indicating the function execution status // \return usbdRequestNotProcessed:request was not processed; processing will be done by USB library // \return usbdRequestOK: request was processed successfully (send Zero-Length Packet) // \return usbdRequestStall: request was processed but is not supported (stall Endpoint 0) // \return usbdRequestNAK: request was processed but the device is busy (return NAK) usbdRequestStatus USBD_CustomClass0_Endpoint0_OutDataReceived (uint32_t len) { (void)len; return usbdRequestNotProcessed; } // \brief Callback function called when Custom Class 0 sent IN DATA on Control Endpoint 0 // (this callback will be called only for Class Requests (USB_REQUEST_CLASS) if it was not processed // previously by Device callback) // \param[in] len number of sent data bytes. // \return usbdRequestStatus enumerator value indicating the function execution status // \return usbdRequestNotProcessed:request was not processed; processing will be done by USB library // \return usbdRequestOK: request was processed successfully (return ACK) // \return usbdRequestStall: request was processed but is not supported (stall Endpoint 0) // \return usbdRequestNAK: request was processed but the device is busy (return NAK) usbdRequestStatus USBD_CustomClass0_Endpoint0_InDataSent (uint32_t len) { (void)len; return usbdRequestNotProcessed; } // \brief Callback function called when DATA was sent or received on Endpoint n // \param[in] event event on Endpoint: // - ARM_USBD_EVENT_OUT = data OUT received // - ARM_USBD_EVENT_IN = data IN sent void USBD_CustomClass0_Endpoint1_Event (uint32_t event) { // Handle Endpoint 1 events uint32_t n; if (event & ARM_USBD_EVENT_OUT) { n = USBD_EndpointReadGetResult(0U, USB_ENDPOINT_OUT(1U)); if (n != 0U) { if (USB_Request[USB_RequestIndexI][0] == ID_DAP_TransferAbort) { DAP_TransferAbort = 1U; } else { USB_RequestIndexI++; if (USB_RequestIndexI == DAP_PACKET_COUNT) { USB_RequestIndexI = 0U; } USB_RequestCountI++; osThreadFlagsSet(DAP_ThreadId, 0x01); } } // Start reception of next request packet if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) { USBD_EndpointRead(0U, USB_ENDPOINT_OUT(1U), USB_Request[USB_RequestIndexI], DAP_PACKET_SIZE); } else { USB_RequestIdle = 1U; } } if (event & ARM_USBD_EVENT_IN) { if (USB_ResponseCountI != USB_ResponseCountO) { // Load data from response buffer to be sent back USBD_EndpointWrite(0U, USB_ENDPOINT_IN(1U), USB_Response[USB_ResponseIndexO], USB_RespSize[USB_ResponseIndexO]); USB_ResponseIndexO++; if (USB_ResponseIndexO == DAP_PACKET_COUNT) { USB_ResponseIndexO = 0U; } USB_ResponseCountO++; } else { USB_ResponseIdle = 1U; } } } void USBD_CustomClass0_Endpoint2_Event (uint32_t event) { // Handle Endpoint 2 events if (event & ARM_USBD_EVENT_IN) { SWO_TransferComplete(); } } void USBD_CustomClass0_Endpoint3_Event (uint32_t event) { // Handle Endpoint 3 events (void)event; } void USBD_CustomClass0_Endpoint4_Event (uint32_t event) { // Handle Endpoint 4 events (void)event; } void USBD_CustomClass0_Endpoint5_Event (uint32_t event) { // Handle Endpoint 5 events (void)event; } void USBD_CustomClass0_Endpoint6_Event (uint32_t event) { // Handle Endpoint 6 events (void)event; } void USBD_CustomClass0_Endpoint7_Event (uint32_t event) { // Handle Endpoint 7 events (void)event; } void USBD_CustomClass0_Endpoint8_Event (uint32_t event) { // Handle Endpoint 8 events (void)event; } void USBD_CustomClass0_Endpoint9_Event (uint32_t event) { // Handle Endpoint 9 events (void)event; } void USBD_CustomClass0_Endpoint10_Event (uint32_t event) { // Handle Endpoint 10 events (void)event; } void USBD_CustomClass0_Endpoint11_Event (uint32_t event) { // Handle Endpoint 11 events (void)event; } void USBD_CustomClass0_Endpoint12_Event (uint32_t event) { // Handle Endpoint 12 events (void)event; } void USBD_CustomClass0_Endpoint13_Event (uint32_t event) { // Handle Endpoint 13 events (void)event; } void USBD_CustomClass0_Endpoint14_Event (uint32_t event) { // Handle Endpoint 14 events (void)event; } void USBD_CustomClass0_Endpoint15_Event (uint32_t event) { // Handle Endpoint 15 events (void)event; } // DAP Thread. __NO_RETURN void DAP_Thread (void *argument) { uint32_t flags; uint32_t n; (void) argument; for (;;) { osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever); // Process pending requests while (USB_RequestCountI != USB_RequestCountO) { // Handle Queue Commands n = USB_RequestIndexO; while (USB_Request[n][0] == ID_DAP_QueueCommands) { USB_Request[n][0] = ID_DAP_ExecuteCommands; n++; if (n == DAP_PACKET_COUNT) { n = 0U; } if (n == USB_RequestIndexI) { flags = osThreadFlagsWait(0x81U, osFlagsWaitAny, osWaitForever); if (flags & 0x80U) { break; } } } // Execute DAP Command (process request and prepare response) USB_RespSize[USB_ResponseIndexI] = (uint16_t)DAP_ExecuteCommand(USB_Request[USB_RequestIndexO], USB_Response[USB_ResponseIndexI]); // Update Request Index and Count USB_RequestIndexO++; if (USB_RequestIndexO == DAP_PACKET_COUNT) { USB_RequestIndexO = 0U; } USB_RequestCountO++; if (USB_RequestIdle) { if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) != DAP_PACKET_COUNT) { USB_RequestIdle = 0U; USBD_EndpointRead(0U, USB_ENDPOINT_OUT(1U), USB_Request[USB_RequestIndexI], DAP_PACKET_SIZE); } } // Update Response Index and Count USB_ResponseIndexI++; if (USB_ResponseIndexI == DAP_PACKET_COUNT) { USB_ResponseIndexI = 0U; } USB_ResponseCountI++; if (USB_ResponseIdle) { if (USB_ResponseCountI != USB_ResponseCountO) { // Load data from response buffer to be sent back n = USB_ResponseIndexO++; if (USB_ResponseIndexO == DAP_PACKET_COUNT) { USB_ResponseIndexO = 0U; } USB_ResponseCountO++; USB_ResponseIdle = 0U; USBD_EndpointWrite(0U, USB_ENDPOINT_IN(1U), USB_Response[n], USB_RespSize[n]); } } } } } // SWO Data Queue Transfer // buf: pointer to buffer with data // num: number of bytes to transfer void SWO_QueueTransfer (uint8_t *buf, uint32_t num) { USBD_EndpointWrite(0U, USB_ENDPOINT_IN(2U), buf, num); } // SWO Data Abort Transfer void SWO_AbortTransfer (void) { USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U)); } //! [code_USBD_User_CustomClass]