0
mirror of https://github.com/OneOfEleven/uv-k5-firmware-custom.git synced 2025-06-20 06:58:39 +03:00

Initial commit

This commit is contained in:
OneOfEleven
2023-09-09 08:03:56 +01:00
parent 92305117f1
commit 54441e27d9
3388 changed files with 582553 additions and 0 deletions

View File

@ -0,0 +1,54 @@
[Version]
Signature = "$Windows NT$"
Class = USBDevice
ClassGUID = {88BAE032-5A81-49f0-BC3D-A4FF138216D6}
Provider = %ManufacturerName%
DriverVer = 04/13/2016, 1.0.0.0
CatalogFile.nt = CMSIS_DAP_v2_x86.cat
CatalogFile.ntx86 = CMSIS_DAP_v2_x86.cat
CatalogFile.ntamd64 = CMSIS_DAP_v2_amd64.cat
; ========== Manufacturer/Models sections ===========
[Manufacturer]
%ManufacturerName% = Devices, NTx86, NTamd64
[Devices.NTx86]
%DeviceName% = USB_Install, USB\VID_c251&PID_f000
[Devices.NTamd64]
%DeviceName% = USB_Install, USB\VID_c251&PID_f000
; ========== Class definition ===========
[ClassInstall32]
AddReg = ClassInstall_AddReg
[ClassInstall_AddReg]
HKR,,,,%ClassName%
HKR,,NoInstallClass,,1
HKR,,IconPath,0x10000,"%%SystemRoot%%\System32\setupapi.dll,-20"
HKR,,LowerLogoVersion,,5.2
; =================== Installation ===================
[USB_Install]
Include = winusb.inf
Needs = WINUSB.NT
[USB_Install.Services]
Include = winusb.inf
Needs = WINUSB.NT.Services
[USB_Install.HW]
AddReg = Dev_AddReg
[Dev_AddReg]
HKR,,DeviceInterfaceGUIDs,0x10000,"{CDB3B5AD-293B-4663-AA36-1AAE46463776}"
; =================== Strings ===================
[Strings]
ClassName = "Universal Serial Bus devices"
ManufacturerName = "KEIL - Tools By ARM"
DeviceName = "CMSIS-DAP v2"

View File

@ -0,0 +1,381 @@
/*------------------------------------------------------------------------------
* MDK Middleware - Component ::USB:Device:CDC
* Copyright (c) 2004-2021 Arm Limited (or its affiliates). All rights reserved.
*------------------------------------------------------------------------------
* Name: USBD_User_CDC_ACM_UART_0.c
* Purpose: USB Device Communication Device Class (CDC)
* Abstract Control Model (ACM) USB <-> UART Bridge User module
* Rev.: V1.0.8
*----------------------------------------------------------------------------*/
/**
* \addtogroup usbd_cdcFunctions
*
* USBD_User_CDC_ACM_UART_0.c implements the application specific
* functionality of the CDC ACM class and is used to demonstrate a USB <-> UART
* bridge. All data received on USB is transmitted on UART and all data
* received on UART is transmitted on USB.
*
* Details of operation:
* UART -> USB:
* Initial reception on UART is started after the USB Host sets line coding
* with SetLineCoding command. Having received a full UART buffer, any
* new reception is restarted on the same buffer. Any data received on
* the UART is sent over USB using the CDC0_ACM_UART_to_USB_Thread thread.
* USB -> UART:
* While the UART transmit is not busy, data transmission on the UART is
* started in the USBD_CDC0_ACM_DataReceived callback as soon as data is
* received on the USB. Further data received on USB is transmitted on
* UART in the UART callback routine until there is no more data available.
* In this case, the next UART transmit is restarted from the
* USBD_CDC0_ACM_DataReceived callback as soon as new data is received
* on the USB.
*
* The following constants in this module affect the module functionality:
*
* - UART_PORT: specifies UART Port
* default value: 0 (=UART0)
* - UART_BUFFER_SIZE: specifies UART data Buffer Size
* default value: 512
*
* Notes:
* If the USB is slower than the UART, data can get lost. This may happen
* when USB is pausing during data reception because of the USB Host being
* too loaded with other tasks and not polling the Bulk IN Endpoint often
* enough (up to 2 seconds of gap in polling Bulk IN Endpoint may occur).
* This problem can be solved by using a large enough UART buffer to
* compensate up to a few seconds of received UART data or by using UART
* flow control.
* If the device that receives the UART data (usually a PC) is too loaded
* with other tasks it can also loose UART data. This problem can only be
* solved by using UART flow control.
*
* This file has to be adapted in case of UART flow control usage.
*/
//! [code_USBD_User_CDC_ACM]
#include <stdio.h>
#include <string.h>
#include "rl_usb.h"
#include "Driver_USART.h"
#include "DAP_config.h"
#include "DAP.h"
// UART Configuration ----------------------------------------------------------
#define UART_BUFFER_SIZE (512) // UART Buffer Size
//------------------------------------------------------------------------------
#define _UART_Driver_(n) Driver_USART##n
#define UART_Driver_(n) _UART_Driver_(n)
extern ARM_DRIVER_USART UART_Driver_(DAP_UART_DRIVER);
#define ptrUART (&UART_Driver_(DAP_UART_DRIVER))
// Local Variables
static uint8_t uart_rx_buf[UART_BUFFER_SIZE];
static uint8_t uart_tx_buf[UART_BUFFER_SIZE];
static volatile int32_t uart_rx_cnt = 0;
static volatile int32_t usb_tx_cnt = 0;
static void *cdc_acm_bridge_tid = 0U;
static CDC_LINE_CODING cdc_acm_line_coding = { 0U, 0U, 0U, 0U };
static uint8_t cdc_acm_active = 1U;
static osMutexId_t cdc_acm_mutex_id = NULL;
// Acquire mutex
__STATIC_INLINE void CDC_ACM_Lock (void) {
if (cdc_acm_mutex_id == NULL) {
cdc_acm_mutex_id = osMutexNew(NULL);
}
osMutexAcquire(cdc_acm_mutex_id, osWaitForever);
}
// Release mutex
__STATIC_INLINE void CDC_ACM_Unlock (void) {
osMutexRelease(cdc_acm_mutex_id);
}
// Change communication settings.
// \param[in] line_coding pointer to CDC_LINE_CODING structure.
// \return true set line coding request processed.
// \return false set line coding request not supported or not processed.
static bool CDC_ACM_SetLineCoding (const CDC_LINE_CODING *line_coding) {
uint32_t data_bits = 0U, parity = 0U, stop_bits = 0U;
int32_t status;
(void)ptrUART->Control (ARM_USART_ABORT_SEND, 0U);
(void)ptrUART->Control (ARM_USART_ABORT_RECEIVE, 0U);
(void)ptrUART->Control (ARM_USART_CONTROL_TX, 0U);
(void)ptrUART->Control (ARM_USART_CONTROL_RX, 0U);
switch (line_coding->bCharFormat) {
case 0: // 1 Stop bit
stop_bits = ARM_USART_STOP_BITS_1;
break;
case 1: // 1.5 Stop bits
stop_bits = ARM_USART_STOP_BITS_1_5;
break;
case 2: // 2 Stop bits
stop_bits = ARM_USART_STOP_BITS_2;
break;
default:
return false;
}
switch (line_coding->bParityType) {
case 0: // None
parity = ARM_USART_PARITY_NONE;
break;
case 1: // Odd
parity = ARM_USART_PARITY_ODD;
break;
case 2: // Even
parity = ARM_USART_PARITY_EVEN;
break;
default:
return false;
}
switch (line_coding->bDataBits) {
case 5:
data_bits = ARM_USART_DATA_BITS_5;
break;
case 6:
data_bits = ARM_USART_DATA_BITS_6;
break;
case 7:
data_bits = ARM_USART_DATA_BITS_7;
break;
case 8:
data_bits = ARM_USART_DATA_BITS_8;
break;
default:
return false;
}
status = ptrUART->Control(ARM_USART_MODE_ASYNCHRONOUS |
data_bits |
parity |
stop_bits ,
line_coding->dwDTERate );
if (status != ARM_DRIVER_OK) {
return false;
}
// Store requested settings to local variable
memcpy(&cdc_acm_line_coding, line_coding, sizeof(cdc_acm_line_coding));
uart_rx_cnt = 0;
usb_tx_cnt = 0;
(void)ptrUART->Control (ARM_USART_CONTROL_TX, 1U);
(void)ptrUART->Control (ARM_USART_CONTROL_RX, 1U);
(void)ptrUART->Receive (uart_rx_buf, UART_BUFFER_SIZE);
return true;
}
// Activate or Deactivate USBD COM PORT
// \param[in] cmd 0=deactivate, 1=activate
// \return 0=Ok, 0xFF=Error
uint8_t USB_COM_PORT_Activate (uint32_t cmd) {
switch (cmd) {
case 0U:
cdc_acm_active = 0U;
USBD_CDC0_ACM_Uninitialize();
break;
case 1U:
USBD_CDC0_ACM_Initialize();
CDC_ACM_Lock();
CDC_ACM_SetLineCoding(&cdc_acm_line_coding);
cdc_acm_active = 1U;
CDC_ACM_Unlock();
break;
}
return 0U;
}
// Called when UART has transmitted or received requested number of bytes.
// \param[in] event UART event
// - ARM_USART_EVENT_SEND_COMPLETE: all requested data was sent
// - ARM_USART_EVENT_RECEIVE_COMPLETE: all requested data was received
static void UART_Callback (uint32_t event) {
int32_t cnt;
if (cdc_acm_active == 0U) {
return;
}
if (event & ARM_USART_EVENT_SEND_COMPLETE) {
// USB -> UART
cnt = USBD_CDC_ACM_ReadData(0U, uart_tx_buf, UART_BUFFER_SIZE);
if (cnt > 0) {
(void)ptrUART->Send(uart_tx_buf, (uint32_t)(cnt));
}
}
if (event & ARM_USART_EVENT_RECEIVE_COMPLETE) {
// UART data received, restart new reception
uart_rx_cnt += UART_BUFFER_SIZE;
(void)ptrUART->Receive(uart_rx_buf, UART_BUFFER_SIZE);
}
}
// Thread: Sends data received on UART to USB
// \param[in] arg not used.
__NO_RETURN static void CDC0_ACM_UART_to_USB_Thread (void *arg) {
int32_t cnt, cnt_to_wrap;
(void)(arg);
for (;;) {
// UART - > USB
if (ptrUART->GetStatus().rx_busy != 0U) {
cnt = uart_rx_cnt;
cnt += (int32_t)ptrUART->GetRxCount();
cnt -= usb_tx_cnt;
if (cnt >= (UART_BUFFER_SIZE - 32)) {
// Dump old data in UART receive buffer if USB is not consuming fast enough
cnt = (UART_BUFFER_SIZE - 32);
usb_tx_cnt = uart_rx_cnt - (UART_BUFFER_SIZE - 32);
}
if (cnt > 0) {
cnt_to_wrap = (int32_t)(UART_BUFFER_SIZE - ((uint32_t)usb_tx_cnt & (UART_BUFFER_SIZE - 1)));
if (cnt > cnt_to_wrap) {
cnt = cnt_to_wrap;
}
cnt = USBD_CDC_ACM_WriteData(0U, (uart_rx_buf + ((uint32_t)usb_tx_cnt & (UART_BUFFER_SIZE - 1))), cnt);
if (cnt > 0) {
usb_tx_cnt += cnt;
}
}
}
(void)osDelay(10U);
}
}
static osRtxThread_t cdc0_acm_uart_to_usb_thread_cb_mem __SECTION(.bss.os.thread.cb);
static uint64_t cdc0_acm_uart_to_usb_thread_stack_mem[512U / 8U] __SECTION(.bss.os.thread.cdc.stack);
static const osThreadAttr_t cdc0_acm_uart_to_usb_thread_attr = {
"CDC0_ACM_UART_to_USB_Thread",
0U,
&cdc0_acm_uart_to_usb_thread_cb_mem,
sizeof(osRtxThread_t),
&cdc0_acm_uart_to_usb_thread_stack_mem[0],
sizeof(cdc0_acm_uart_to_usb_thread_stack_mem),
osPriorityNormal,
0U,
0U
};
// CDC ACM Callbacks -----------------------------------------------------------
// Called when new data was received from the USB Host.
// \param[in] len number of bytes available to read.
void USBD_CDC0_ACM_DataReceived (uint32_t len) {
int32_t cnt;
(void)(len);
if (cdc_acm_active == 0U) {
return;
}
if (ptrUART->GetStatus().tx_busy == 0U) {
// Start USB -> UART
cnt = USBD_CDC_ACM_ReadData(0U, uart_tx_buf, UART_BUFFER_SIZE);
if (cnt > 0) {
(void)ptrUART->Send(uart_tx_buf, (uint32_t)(cnt));
}
}
}
// Called during USBD_Initialize to initialize the USB CDC class instance (ACM).
void USBD_CDC0_ACM_Initialize (void) {
(void)ptrUART->Initialize (UART_Callback);
(void)ptrUART->PowerControl (ARM_POWER_FULL);
cdc_acm_bridge_tid = osThreadNew (CDC0_ACM_UART_to_USB_Thread, NULL, &cdc0_acm_uart_to_usb_thread_attr);
}
// Called during USBD_Uninitialize to de-initialize the USB CDC class instance (ACM).
void USBD_CDC0_ACM_Uninitialize (void) {
if (osThreadTerminate (cdc_acm_bridge_tid) == osOK) {
cdc_acm_bridge_tid = NULL;
}
(void)ptrUART->Control (ARM_USART_ABORT_RECEIVE, 0U);
(void)ptrUART->PowerControl (ARM_POWER_OFF);
(void)ptrUART->Uninitialize ();
}
// Called upon USB Bus Reset Event.
void USBD_CDC0_ACM_Reset (void) {
if (cdc_acm_active == 0U ) {
return;
}
(void)ptrUART->Control (ARM_USART_ABORT_SEND, 0U);
(void)ptrUART->Control (ARM_USART_ABORT_RECEIVE, 0U);
}
// Called upon USB Host request to change communication settings.
// \param[in] line_coding pointer to CDC_LINE_CODING structure.
// \return true set line coding request processed.
// \return false set line coding request not supported or not processed.
bool USBD_CDC0_ACM_SetLineCoding (const CDC_LINE_CODING *line_coding) {
bool ret = false;
CDC_ACM_Lock();
if (cdc_acm_active == 0U) {
// Store requested settings to local variable
memcpy(&cdc_acm_line_coding, line_coding, sizeof(cdc_acm_line_coding));
ret = true;
} else {
ret = CDC_ACM_SetLineCoding(line_coding);
}
CDC_ACM_Unlock();
return ret;
}
// Called upon USB Host request to retrieve communication settings.
// \param[out] line_coding pointer to CDC_LINE_CODING structure.
// \return true get line coding request processed.
// \return false get line coding request not supported or not processed.
bool USBD_CDC0_ACM_GetLineCoding (CDC_LINE_CODING *line_coding) {
// Load settings from ones stored on USBD_CDC0_ACM_SetLineCoding callback
*line_coding = cdc_acm_line_coding;
return true;
}
// Called upon USB Host request to set control line states.
// \param [in] state control line settings bitmap.
// - bit 0: DTR state
// - bit 1: RTS state
// \return true set control line state request processed.
// \return false set control line state request not supported or not processed.
bool USBD_CDC0_ACM_SetControlLineState (uint16_t state) {
// Add code for set control line state
(void)(state);
return true;
}
//! [code_USBD_User_CDC_ACM]

View File

@ -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(2U), buf, num);
}
// SWO Data Abort Transfer
void SWO_AbortTransfer (void) {
USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));
}
//! [code_USBD_User_CustomClass]

View File

@ -0,0 +1,246 @@
/*------------------------------------------------------------------------------
* MDK Middleware - Component ::USB:Device
* Copyright (c) 2004-2017 ARM Germany GmbH. All rights reserved.
*------------------------------------------------------------------------------
* Name: USBD_User_HID_0.c
* Purpose: USB Device Human Interface Device class (HID) User module
* Rev.: V6.2.3
*----------------------------------------------------------------------------*/
/**
* \addtogroup usbd_hidFunctions
*
* USBD_User_HID_0.c implements the application specific functionality of the
* HID class and is used to receive and send data reports to the USB Host.
*
* The implementation must match the configuration file USBD_Config_HID_0.h.
* The following values in USBD_Config_HID_0.h affect the user code:
*
* - 'Endpoint polling Interval' specifies the frequency of requests
* initiated by USB Host for \ref USBD_HIDn_GetReport.
*
* - 'Number of Output Reports' configures the values for \em rid of
* \ref USBD_HIDn_SetReport.
*
* - 'Number of Input Reports' configures the values for \em rid of
* \ref USBD_HIDn_GetReport and \ref USBD_HID_GetReportTrigger.
*
* - 'Maximum Input Report Size' specifies the maximum value for:
* - return of \ref USBD_HIDn_GetReport
* - len of \ref USBD_HID_GetReportTrigger.
*
* - 'Maximum Output Report Size' specifies the maximum value for \em len
* in \ref USBD_HIDn_SetReport for rtype=HID_REPORT_OUTPUT
*
* - 'Maximum Feature Report Size' specifies the maximum value for \em len
* in \ref USBD_HIDn_SetReport for rtype=HID_REPORT_FEATURE
*
*/
//! [code_USBD_User_HID]
#include <stdint.h>
#include <string.h>
#include "cmsis_os2.h"
#define osObjectsExternal
#include "osObjects.h"
#include "rl_usb.h"
#include "RTE\USB\USBD_Config_HID_0.h"
#include "DAP_config.h"
#include "DAP.h"
#if (USBD_HID0_OUT_REPORT_MAX_SZ != DAP_PACKET_SIZE)
#error "USB HID0 Output Report Size must match DAP Packet Size"
#endif
#if (USBD_HID0_IN_REPORT_MAX_SZ != DAP_PACKET_SIZE)
#error "USB HID Input Report Size must match DAP Packet Size"
#endif
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 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]; // Request Buffer
static uint8_t USB_Response[DAP_PACKET_COUNT][DAP_PACKET_SIZE]; // Response Buffer
// Called during USBD_Initialize to initialize the USB HID class instance.
void USBD_HID0_Initialize (void) {
// Initialize variables
USB_RequestIndexI = 0U;
USB_RequestIndexO = 0U;
USB_RequestCountI = 0U;
USB_RequestCountO = 0U;
USB_ResponseIndexI = 0U;
USB_ResponseIndexO = 0U;
USB_ResponseCountI = 0U;
USB_ResponseCountO = 0U;
USB_ResponseIdle = 1U;
}
// Called during USBD_Uninitialize to de-initialize the USB HID class instance.
void USBD_HID0_Uninitialize (void) {
}
// \brief Prepare HID Report data to send.
// \param[in] rtype report type:
// - HID_REPORT_INPUT = input report requested
// - HID_REPORT_FEATURE = feature report requested
// \param[in] req request type:
// - USBD_HID_REQ_EP_CTRL = control endpoint request
// - USBD_HID_REQ_PERIOD_UPDATE = idle period expiration request
// - USBD_HID_REQ_EP_INT = previously sent report on interrupt endpoint request
// \param[in] rid report ID (0 if only one report exists).
// \param[out] buf buffer containing report data to send.
// \return number of report data bytes prepared to send or invalid report requested.
// - value >= 0: number of report data bytes prepared to send
// - value = -1: invalid report requested
int32_t USBD_HID0_GetReport (uint8_t rtype, uint8_t req, uint8_t rid, uint8_t *buf) {
(void)rid;
switch (rtype) {
case HID_REPORT_INPUT:
switch (req) {
case USBD_HID_REQ_EP_CTRL: // Explicit USB Host request via Control OUT Endpoint
case USBD_HID_REQ_PERIOD_UPDATE: // Periodic USB Host request via Interrupt OUT Endpoint
break;
case USBD_HID_REQ_EP_INT: // Called after USBD_HID_GetReportTrigger to signal data obtained.
if (USB_ResponseCountI != USB_ResponseCountO) {
// Load data from response buffer to be sent back
memcpy(buf, USB_Response[USB_ResponseIndexO], DAP_PACKET_SIZE);
USB_ResponseIndexO++;
if (USB_ResponseIndexO == DAP_PACKET_COUNT) {
USB_ResponseIndexO = 0U;
}
USB_ResponseCountO++;
return ((int32_t)DAP_PACKET_SIZE);
} else {
USB_ResponseIdle = 1U;
}
break;
}
break;
case HID_REPORT_FEATURE:
break;
}
return (0);
}
// \brief Process received HID Report data.
// \param[in] rtype report type:
// - HID_REPORT_OUTPUT = output report received
// - HID_REPORT_FEATURE = feature report received
// \param[in] req request type:
// - USBD_HID_REQ_EP_CTRL = report received on control endpoint
// - USBD_HID_REQ_EP_INT = report received on interrupt endpoint
// \param[in] rid report ID (0 if only one report exists).
// \param[in] buf buffer that receives report data.
// \param[in] len length of received report data.
// \return true received report data processed.
// \return false received report data not processed or request not supported.
bool USBD_HID0_SetReport (uint8_t rtype, uint8_t req, uint8_t rid, const uint8_t *buf, int32_t len) {
(void)req;
(void)rid;
switch (rtype) {
case HID_REPORT_OUTPUT:
if (len == 0) {
break;
}
if (buf[0] == ID_DAP_TransferAbort) {
DAP_TransferAbort = 1U;
break;
}
if ((uint16_t)(USB_RequestCountI - USB_RequestCountO) == DAP_PACKET_COUNT) {
osThreadFlagsSet(DAP_ThreadId, 0x80U);
break; // Discard packet when buffer is full
}
// Store received data into request buffer
memcpy(USB_Request[USB_RequestIndexI], buf, (uint32_t)len);
USB_RequestIndexI++;
if (USB_RequestIndexI == DAP_PACKET_COUNT) {
USB_RequestIndexI = 0U;
}
USB_RequestCountI++;
osThreadFlagsSet(DAP_ThreadId, 0x01U);
break;
case HID_REPORT_FEATURE:
break;
}
return true;
}
// 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)
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++;
// 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_HID_GetReportTrigger(0U, 0U, USB_Response[n], DAP_PACKET_SIZE);
}
}
}
}
}
//! [code_USBD_User_HID]

View File

@ -0,0 +1,71 @@
/*
* Copyright (c) 2013-2021 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ----------------------------------------------------------------------
*
* $Date: 21. May 2021
* $Revision: V2.0.0
*
* Project: CMSIS-DAP Template MDK5
* Title: main.c CMSIS-DAP Main module
*
*---------------------------------------------------------------------------*/
#include "cmsis_os2.h"
#include "osObjects.h"
#include "rl_usb.h"
#include "DAP_config.h"
#include "DAP.h"
// Application Main program
__NO_RETURN void app_main (void *argument) {
(void)argument;
DAP_Setup(); // DAP Setup
USBD_Initialize(0U); // USB Device Initialization
USBD_Connect(0U); // USB Device Connect
while (!USBD_Configured(0U)); // Wait for USB Device to configure
LED_CONNECTED_OUT(1U); // Turn on Debugger Connected LED
LED_RUNNING_OUT(1U); // Turn on Target Running LED
Delayms(500U); // Wait for 500ms
LED_RUNNING_OUT(0U); // Turn off Target Running LED
LED_CONNECTED_OUT(0U); // Turn off Debugger Connected LED
// Create DAP Thread
DAP_ThreadId = osThreadNew(DAP_Thread, NULL, &DAP_ThreadAttr);
// Create SWO Thread
SWO_ThreadId = osThreadNew(SWO_Thread, NULL, &SWO_ThreadAttr);
osDelay(osWaitForever);
for (;;) {}
}
int main (void) {
SystemCoreClockUpdate();
osKernelInitialize(); // Initialize CMSIS-RTOS
osThreadNew(app_main, NULL, NULL); // Create application main thread
if (osKernelGetState() == osKernelReady) {
osKernelStart(); // Start thread execution
}
for (;;) {}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ----------------------------------------------------------------------
*
* $Date: 11. June 2021
* $Revision: V2.0.0
*
* Project: CMSIS-DAP Template MDK5
* Title: osObjects.h CMSIS-DAP RTOS2 Objects
*
*---------------------------------------------------------------------------*/
#ifndef __osObjects_h__
#define __osObjects_h__
#include "cmsis_os2.h"
#ifdef osObjectsExternal
extern osThreadId_t DAP_ThreadId;
extern osThreadId_t SWO_ThreadId;
#else
static const osThreadAttr_t DAP_ThreadAttr = {
.priority = osPriorityNormal
};
static const osThreadAttr_t SWO_ThreadAttr = {
.priority = osPriorityAboveNormal
};
extern osThreadId_t DAP_ThreadId;
osThreadId_t DAP_ThreadId;
extern osThreadId_t SWO_ThreadId;
osThreadId_t SWO_ThreadId;
#endif
extern void DAP_Thread (void *argument);
extern void SWO_Thread (void *argument);
extern void app_main (void *argument);
#endif /* __osObjects_h__ */