|
|
@@ -0,0 +1,358 @@
|
|
|
+/*------------------------------------------------------------------------------
|
|
|
+ * 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 <stdint.h>
|
|
|
+#include <stdbool.h>
|
|
|
+#include <string.h>
|
|
|
+#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(5U), buf, num);
|
|
|
+}
|
|
|
+
|
|
|
+// SWO Data Abort Transfer
|
|
|
+void SWO_AbortTransfer (void) {
|
|
|
+ USBD_EndpointAbort(0U, USB_ENDPOINT_IN(5U));
|
|
|
+}
|
|
|
+
|
|
|
+//! [code_USBD_User_CustomClass]
|