0
0
Fork 0

feat(dap): Add support for cmsis-dap v2.1.0

- Enhanced DAP_Info
- Added extra UART support

Extra UART for native cmsis-dap is not yet support now.
This commit is contained in:
windowsair 2024-02-08 19:33:59 +08:00
parent acfd967106
commit 8abe565836
4 changed files with 897 additions and 49 deletions

View File

@ -17,8 +17,8 @@
* *
* ---------------------------------------------------------------------- * ----------------------------------------------------------------------
* *
* $Date: 1. December 2017 * $Date: 16. June 2021
* $Revision: V2.0.0 * $Revision: V2.1.0
* *
* Project: CMSIS-DAP Configuration * Project: CMSIS-DAP Configuration
* Title: DAP_config.h CMSIS-DAP Configuration File (Template) * Title: DAP_config.h CMSIS-DAP Configuration File (Template)
@ -31,10 +31,11 @@
* @brief Adaptation of GPIO and SPI pin * @brief Adaptation of GPIO and SPI pin
* @change: 2021-2-10 Support GPIO and SPI * @change: 2021-2-10 Support GPIO and SPI
* 2021-2-18 Try to support SWO * 2021-2-18 Try to support SWO
* @version 0.1 * 2024-1-28 Update to CMSIS-DAP v2.1.0
* @date 2021-2-10 * @version 0.3
* @date 2024-1-28
* *
* @copyright Copyright (c) 2021 * @copyright Copyright (c) 2021-2024
* *
*/ */
@ -149,6 +150,9 @@ This information includes:
/// This information is returned by the command \ref DAP_Info as part of <b>Capabilities</b>. /// This information is returned by the command \ref DAP_Info as part of <b>Capabilities</b>.
#define SWO_UART SWO_FUNCTION_ENABLE ///< SWO UART: 1 = available, 0 = not available. #define SWO_UART SWO_FUNCTION_ENABLE ///< SWO UART: 1 = available, 0 = not available.
/// USART Driver instance number for the UART SWO.
#define SWO_UART_DRIVER 0 ///< USART Driver instance number (Driver_USART#).
/// Maximum SWO UART Baudrate. /// Maximum SWO UART Baudrate.
#define SWO_UART_MAX_BAUDRATE (115200U * 40U) ///< SWO UART Maximum Baudrate in Hz. #define SWO_UART_MAX_BAUDRATE (115200U * 40U) ///< SWO UART Maximum Baudrate in Hz.
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<< 5MHz // <<<<<<<<<<<<<<<<<<<<<<<<<<<<< 5MHz
@ -170,22 +174,47 @@ This information includes:
#define TIMESTAMP_CLOCK 5000000U ///< Timestamp clock in Hz (0 = timestamps not supported). #define TIMESTAMP_CLOCK 5000000U ///< Timestamp clock in Hz (0 = timestamps not supported).
// <<<<<<<<<<<<<<<<<<<<<5MHz // <<<<<<<<<<<<<<<<<<<<<5MHz
/// Indicate that UART Communication Port is available.
/// This information is returned by the command \ref DAP_Info as part of <b>Capabilities</b>.
#define DAP_UART 0 ///< DAP UART: 1 = available, 0 = not available.
/// USART Driver instance number for the UART Communication Port.
#define DAP_UART_DRIVER 1 ///< USART Driver instance number (Driver_USART#).
/// UART Receive Buffer Size.
#define DAP_UART_RX_BUFFER_SIZE 1024U ///< Uart Receive Buffer Size in bytes (must be 2^n).
/// UART Transmit Buffer Size.
#define DAP_UART_TX_BUFFER_SIZE 1024U ///< Uart Transmit Buffer Size in bytes (must be 2^n).
/// Indicate that UART Communication via USB COM Port is available.
/// This information is returned by the command \ref DAP_Info as part of <b>Capabilities</b>.
#define DAP_UART_USB_COM_PORT 0 ///< USB COM Port: 1 = available, 0 = not available.
/// Debug Unit is connected to fixed Target Device. /// Debug Unit is connected to fixed Target Device.
/// The Debug Unit may be part of an evaluation board and always connected to a fixed /// The Debug Unit may be part of an evaluation board and always connected to a fixed
/// known device. In this case a Device Vendor and Device Name string is stored which /// known device. In this case a Device Vendor, Device Name, Board Vendor and Board Name strings
/// may be used by the debugger or IDE to configure device parameters. /// are stored and may be used by the debugger or IDE to configure device parameters.
#define TARGET_DEVICE_FIXED 0 ///< Target Device: 1 = known, 0 = unknown; #define TARGET_FIXED 1 ///< Target: 1 = known, 0 = unknown;
#if TARGET_DEVICE_FIXED #define TARGET_DEVICE_VENDOR "" ///< String indicating the Silicon Vendor
#define TARGET_DEVICE_VENDOR "ARM" ///< String indicating the Silicon Vendor #define TARGET_DEVICE_NAME "" ///< String indicating the Target Device
#define TARGET_DEVICE_NAME "Cortex-M4" ///< String indicating the Target Device #define TARGET_BOARD_VENDOR "windowsair" ///< String indicating the Board Vendor
#define TARGET_BOARD_NAME "ESP wireless DAP" ///< String indicating the Board Name
#if TARGET_FIXED != 0
#include <string.h>
static const char TargetDeviceVendor [] = TARGET_DEVICE_VENDOR;
static const char TargetDeviceName [] = TARGET_DEVICE_NAME;
static const char TargetBoardVendor [] = TARGET_BOARD_VENDOR;
static const char TargetBoardName [] = TARGET_BOARD_NAME;
#endif #endif
/** /**
* @brief Get Vendor ID string. * @brief Get Vendor ID string.
* *
* @param str Pointer to buffer to store the string. * @param str Pointer to buffer to store the string (max 60 characters).
* @return String length. * @return String length. (including terminating NULL character) or 0 (no string).
*/ */
__STATIC_INLINE uint8_t DAP_GetVendorString(char *str) __STATIC_INLINE uint8_t DAP_GetVendorString(char *str)
{ {
@ -199,8 +228,8 @@ __STATIC_INLINE uint8_t DAP_GetVendorString(char *str)
/** /**
* @brief Get Product ID string. * @brief Get Product ID string.
* *
* @param str Pointer to buffer to store the string. * @param str Pointer to buffer to store the string (max 60 characters).
* @return String length. * @return String length. (including terminating NULL character) or 0 (no string).
*/ */
__STATIC_INLINE uint8_t DAP_GetProductString(char *str) __STATIC_INLINE uint8_t DAP_GetProductString(char *str)
{ {
@ -212,8 +241,8 @@ __STATIC_INLINE uint8_t DAP_GetProductString(char *str)
/** /**
* @brief Get Serial Number string. * @brief Get Serial Number string.
* *
* @param str Pointer to buffer to store the string. * @param str Pointer to buffer to store the string (max 60 characters).
* @return String length. * @return String length. (including terminating NULL character) or 0 (no string).
*/ */
__STATIC_INLINE uint8_t DAP_GetSerNumString(char *str) __STATIC_INLINE uint8_t DAP_GetSerNumString(char *str)
{ {
@ -221,6 +250,93 @@ __STATIC_INLINE uint8_t DAP_GetSerNumString(char *str)
return (sizeof("1234")); return (sizeof("1234"));
} }
/**
* @brief Get Target Device Vendor string.
*
* @param str Pointer to buffer to store the string (max 60 characters).
* @return String length (including terminating NULL character) or 0 (no string).
*/
__STATIC_INLINE uint8_t DAP_GetTargetDeviceVendorString (char *str) {
#if TARGET_FIXED != 0
uint8_t len;
strcpy(str, TargetDeviceVendor);
len = (uint8_t)(strlen(TargetDeviceVendor) + 1U);
return (len);
#else
(void)str;
return (0U);
#endif
}
/**
* @brief Get Target Device Name string.
*
* @param str Pointer to buffer to store the string (max 60 characters).
* @return String length (including terminating NULL character) or 0 (no string).
*/
__STATIC_INLINE uint8_t DAP_GetTargetDeviceNameString (char *str) {
#if TARGET_FIXED != 0
uint8_t len;
strcpy(str, TargetDeviceName);
len = (uint8_t)(strlen(TargetDeviceName) + 1U);
return (len);
#else
(void)str;
return (0U);
#endif
}
/**
* @brief Get Target Board Vendor string.
*
* @param str Pointer to buffer to store the string (max 60 characters).
* @return String length (including terminating NULL character) or 0 (no string).
*/
__STATIC_INLINE uint8_t DAP_GetTargetBoardVendorString (char *str) {
#if TARGET_FIXED != 0
uint8_t len;
strcpy(str, TargetBoardVendor);
len = (uint8_t)(strlen(TargetBoardVendor) + 1U);
return (len);
#else
(void)str;
return (0U);
#endif
}
/**
* @brief Get Target Board Name string.
*
* @param str Pointer to buffer to store the string (max 60 characters).
* @return String length (including terminating NULL character) or 0 (no string).
*/
__STATIC_INLINE uint8_t DAP_GetTargetBoardNameString (char *str) {
#if TARGET_FIXED != 0
uint8_t len;
strcpy(str, TargetBoardName);
len = (uint8_t)(strlen(TargetBoardName) + 1U);
return (len);
#else
(void)str;
return (0U);
#endif
}
/**
* @brief Get Product Firmware Version string.
*
* @param str Pointer to buffer to store the string (max 60 characters).
* @return String length (including terminating NULL character) or 0 (no string).
*/
__STATIC_INLINE uint8_t DAP_GetProductFirmwareVersionString (char *str) {
(void)str;
return (0U);
}
///@} ///@}

View File

@ -17,8 +17,8 @@
* *
* ---------------------------------------------------------------------- * ----------------------------------------------------------------------
* *
* $Date: 26. November 2019 * $Date: 26. May 2021
* $Revision: V2.0.0 * $Revision: V2.1.0
* *
* Project: CMSIS-DAP Include * Project: CMSIS-DAP Include
* Title: DAP.h Definitions * Title: DAP.h Definitions
@ -31,9 +31,9 @@
// DAP Firmware Version // DAP Firmware Version
#ifdef DAP_FW_V1 #ifdef DAP_FW_V1
#define DAP_FW_VER "1.2.0" #define DAP_FW_VER "1.3.0"
#else #else
#define DAP_FW_VER "2.0.0" #define DAP_FW_VER "2.1.0"
#endif #endif
// DAP Command IDs // DAP Command IDs
@ -63,6 +63,11 @@
#define ID_DAP_SWO_Status 0x1BU #define ID_DAP_SWO_Status 0x1BU
#define ID_DAP_SWO_ExtendedStatus 0x1EU #define ID_DAP_SWO_ExtendedStatus 0x1EU
#define ID_DAP_SWO_Data 0x1CU #define ID_DAP_SWO_Data 0x1CU
#define ID_DAP_UART_Transport 0x1FU
#define ID_DAP_UART_Configure 0x20U
#define ID_DAP_UART_Control 0x22U
#define ID_DAP_UART_Status 0x23U
#define ID_DAP_UART_Transfer 0x21U
#define ID_DAP_QueueCommands 0x7EU #define ID_DAP_QueueCommands 0x7EU
#define ID_DAP_ExecuteCommands 0x7FU #define ID_DAP_ExecuteCommands 0x7FU
@ -111,11 +116,16 @@
#define DAP_ID_VENDOR 1U #define DAP_ID_VENDOR 1U
#define DAP_ID_PRODUCT 2U #define DAP_ID_PRODUCT 2U
#define DAP_ID_SER_NUM 3U #define DAP_ID_SER_NUM 3U
#define DAP_ID_FW_VER 4U #define DAP_ID_DAP_FW_VER 4U
#define DAP_ID_DEVICE_VENDOR 5U #define DAP_ID_DEVICE_VENDOR 5U
#define DAP_ID_DEVICE_NAME 6U #define DAP_ID_DEVICE_NAME 6U
#define DAP_ID_BOARD_VENDOR 7U
#define DAP_ID_BOARD_NAME 8U
#define DAP_ID_PRODUCT_FW_VER 9U
#define DAP_ID_CAPABILITIES 0xF0U #define DAP_ID_CAPABILITIES 0xF0U
#define DAP_ID_TIMESTAMP_CLOCK 0xF1U #define DAP_ID_TIMESTAMP_CLOCK 0xF1U
#define DAP_ID_UART_RX_BUFFER_SIZE 0xFBU
#define DAP_ID_UART_TX_BUFFER_SIZE 0xFCU
#define DAP_ID_SWO_BUFFER_SIZE 0xFDU #define DAP_ID_SWO_BUFFER_SIZE 0xFDU
#define DAP_ID_PACKET_COUNT 0xFEU #define DAP_ID_PACKET_COUNT 0xFEU
#define DAP_ID_PACKET_SIZE 0xFFU #define DAP_ID_PACKET_SIZE 0xFFU
@ -165,6 +175,30 @@
#define DAP_SWO_STREAM_ERROR (1U<<6) #define DAP_SWO_STREAM_ERROR (1U<<6)
#define DAP_SWO_BUFFER_OVERRUN (1U<<7) #define DAP_SWO_BUFFER_OVERRUN (1U<<7)
// DAP UART Transport
#define DAP_UART_TRANSPORT_NONE 0U
#define DAP_UART_TRANSPORT_USB_COM_PORT 1U
#define DAP_UART_TRANSPORT_DAP_COMMAND 2U
// DAP UART Control
#define DAP_UART_CONTROL_RX_ENABLE (1U<<0)
#define DAP_UART_CONTROL_RX_DISABLE (1U<<1)
#define DAP_UART_CONTROL_RX_BUF_FLUSH (1U<<2)
#define DAP_UART_CONTROL_TX_ENABLE (1U<<4)
#define DAP_UART_CONTROL_TX_DISABLE (1U<<5)
#define DAP_UART_CONTROL_TX_BUF_FLUSH (1U<<6)
// DAP UART Status
#define DAP_UART_STATUS_RX_ENABLED (1U<<0)
#define DAP_UART_STATUS_RX_DATA_LOST (1U<<1)
#define DAP_UART_STATUS_FRAMING_ERROR (1U<<2)
#define DAP_UART_STATUS_PARITY_ERROR (1U<<3)
#define DAP_UART_STATUS_TX_ENABLED (1U<<4)
// DAP UART Configure Error
#define DAP_UART_CFG_ERROR_DATA_BITS (1U<<0)
#define DAP_UART_CFG_ERROR_PARITY (1U<<1)
#define DAP_UART_CFG_ERROR_STOP_BITS (1U<<2)
// Debug Port Register Addresses // Debug Port Register Addresses
#define DP_IDCODE 0x00U // IDCODE Register (SW Read only) #define DP_IDCODE 0x00U // IDCODE Register (SW Read only)
@ -270,17 +304,25 @@ extern void SWO_QueueTransfer (uint8_t *buf, uint32_t num);
extern void SWO_AbortTransfer (void); extern void SWO_AbortTransfer (void);
extern void SWO_TransferComplete (void); extern void SWO_TransferComplete (void);
extern uint32_t UART_SWO_Mode (uint32_t enable); extern uint32_t SWO_Mode_UART (uint32_t enable);
extern uint32_t UART_SWO_Baudrate (uint32_t baudrate); extern uint32_t SWO_Baudrate_UART (uint32_t baudrate);
extern uint32_t UART_SWO_Control (uint32_t active); extern uint32_t SWO_Control_UART (uint32_t active);
// extern void UART_SWO_Capture (uint8_t *buf, uint32_t num); extern void SWO_Capture_UART (uint8_t *buf, uint32_t num);
// extern uint32_t UART_SWO_GetCount (void); extern uint32_t SWO_GetCount_UART (void);
extern uint32_t Manchester_SWO_Mode (uint32_t enable); extern uint32_t SWO_Mode_Manchester (uint32_t enable);
extern uint32_t Manchester_SWO_Baudrate (uint32_t baudrate); extern uint32_t SWO_Baudrate_Manchester (uint32_t baudrate);
extern uint32_t Manchester_SWO_Control (uint32_t active); extern uint32_t SWO_Control_Manchester (uint32_t active);
extern void Manchester_SWO_Capture (uint8_t *buf, uint32_t num); extern void SWO_Capture_Manchester (uint8_t *buf, uint32_t num);
extern uint32_t Manchester_SWO_GetCount (void); extern uint32_t SWO_GetCount_Manchester (void);
extern uint32_t UART_Transport (const uint8_t *request, uint8_t *response);
extern uint32_t UART_Configure (const uint8_t *request, uint8_t *response);
extern uint32_t UART_Control (const uint8_t *request, uint8_t *response);
extern uint32_t UART_Status (uint8_t *response);
extern uint32_t UART_Transfer (const uint8_t *request, uint8_t *response);
extern uint8_t USB_COM_PORT_Activate (uint32_t cmd);
extern uint32_t DAP_ProcessVendorCommand (const uint8_t *request, uint8_t *response); extern uint32_t DAP_ProcessVendorCommand (const uint8_t *request, uint8_t *response);
extern uint32_t DAP_ProcessCommand (const uint8_t *request, uint8_t *response); extern uint32_t DAP_ProcessCommand (const uint8_t *request, uint8_t *response);

View File

@ -17,8 +17,8 @@
* *
* ---------------------------------------------------------------------- * ----------------------------------------------------------------------
* *
* $Date: 1. December 2017 * $Date: 16. June 2021
* $Revision: V2.0.0 * $Revision: V2.1.0
* *
* Project: CMSIS-DAP Source * Project: CMSIS-DAP Source
* Title: DAP.c CMSIS-DAP Commands * Title: DAP.c CMSIS-DAP Commands
@ -63,10 +63,6 @@ volatile uint8_t DAP_TransferAbort; // Transfer Abort Flag
static const char DAP_FW_Ver [] = DAP_FW_VER; static const char DAP_FW_Ver [] = DAP_FW_VER;
#if TARGET_DEVICE_FIXED
static const char TargetDeviceVendor [] = TARGET_DEVICE_VENDOR;
static const char TargetDeviceName [] = TARGET_DEVICE_NAME;
#endif
// Get DAP Information // Get DAP Information
@ -86,21 +82,24 @@ static uint8_t DAP_Info(uint8_t id, uint8_t *info) {
case DAP_ID_SER_NUM: case DAP_ID_SER_NUM:
length = DAP_GetSerNumString((char *)info); length = DAP_GetSerNumString((char *)info);
break; break;
case DAP_ID_FW_VER: case DAP_ID_DAP_FW_VER:
length = (uint8_t)sizeof(DAP_FW_Ver); length = (uint8_t)sizeof(DAP_FW_Ver);
memcpy(info, DAP_FW_Ver, length); memcpy(info, DAP_FW_Ver, length);
break; break;
case DAP_ID_DEVICE_VENDOR: case DAP_ID_DEVICE_VENDOR:
#if TARGET_DEVICE_FIXED length = DAP_GetTargetDeviceVendorString((char *)info);
length = (uint8_t)sizeof(TargetDeviceVendor);
memcpy(info, TargetDeviceVendor, length);
#endif
break; break;
case DAP_ID_DEVICE_NAME: case DAP_ID_DEVICE_NAME:
#if TARGET_DEVICE_FIXED length = DAP_GetTargetDeviceNameString((char *)info);
length = (uint8_t)sizeof(TargetDeviceName); break;
memcpy(info, TargetDeviceName, length); case DAP_ID_BOARD_VENDOR:
#endif length = DAP_GetTargetBoardVendorString((char *)info);
break;
case DAP_ID_BOARD_NAME:
length = DAP_GetTargetBoardNameString((char *)info);
break;
case DAP_ID_PRODUCT_FW_VER:
length = DAP_GetProductFirmwareVersionString((char *)info);
break; break;
case DAP_ID_CAPABILITIES: case DAP_ID_CAPABILITIES:
info[0] = ((DAP_SWD != 0) ? (1U << 0) : 0U) | info[0] = ((DAP_SWD != 0) ? (1U << 0) : 0U) |
@ -109,8 +108,11 @@ static uint8_t DAP_Info(uint8_t id, uint8_t *info) {
((SWO_MANCHESTER != 0) ? (1U << 3) : 0U) | ((SWO_MANCHESTER != 0) ? (1U << 3) : 0U) |
/* Atomic Commands */ (1U << 4) | /* Atomic Commands */ (1U << 4) |
((TIMESTAMP_CLOCK != 0U) ? (1U << 5) : 0U) | ((TIMESTAMP_CLOCK != 0U) ? (1U << 5) : 0U) |
((SWO_STREAM != 0U) ? (1U << 6) : 0U); ((SWO_STREAM != 0U) ? (1U << 6) : 0U) |
length = 1U; ((DAP_UART != 0U) ? (1U << 7) : 0U);
info[1] = ((DAP_UART_USB_COM_PORT != 0) ? (1U << 0) : 0U);
length = 2U;
break; break;
case DAP_ID_TIMESTAMP_CLOCK: case DAP_ID_TIMESTAMP_CLOCK:
#if (TIMESTAMP_CLOCK != 0U) #if (TIMESTAMP_CLOCK != 0U)
@ -119,6 +121,24 @@ static uint8_t DAP_Info(uint8_t id, uint8_t *info) {
info[2] = (uint8_t)(TIMESTAMP_CLOCK >> 16); info[2] = (uint8_t)(TIMESTAMP_CLOCK >> 16);
info[3] = (uint8_t)(TIMESTAMP_CLOCK >> 24); info[3] = (uint8_t)(TIMESTAMP_CLOCK >> 24);
length = 4U; length = 4U;
#endif
break;
case DAP_ID_UART_RX_BUFFER_SIZE:
#if (DAP_UART != 0)
info[0] = (uint8_t)(DAP_UART_RX_BUFFER_SIZE >> 0);
info[1] = (uint8_t)(DAP_UART_RX_BUFFER_SIZE >> 8);
info[2] = (uint8_t)(DAP_UART_RX_BUFFER_SIZE >> 16);
info[3] = (uint8_t)(DAP_UART_RX_BUFFER_SIZE >> 24);
length = 4U;
#endif
break;
case DAP_ID_UART_TX_BUFFER_SIZE:
#if (DAP_UART != 0)
info[0] = (uint8_t)(DAP_UART_TX_BUFFER_SIZE >> 0);
info[1] = (uint8_t)(DAP_UART_TX_BUFFER_SIZE >> 8);
info[2] = (uint8_t)(DAP_UART_TX_BUFFER_SIZE >> 16);
info[3] = (uint8_t)(DAP_UART_TX_BUFFER_SIZE >> 24);
length = 4U;
#endif #endif
break; break;
case DAP_ID_SWO_BUFFER_SIZE: case DAP_ID_SWO_BUFFER_SIZE:
@ -1751,6 +1771,24 @@ uint32_t DAP_ProcessCommand(const uint8_t *request, uint8_t *response) {
break; break;
#endif #endif
#if (DAP_UART != 0)
case ID_DAP_UART_Transport:
num = UART_Transport(request, response);
break;
case ID_DAP_UART_Configure:
num = UART_Configure(request, response);
break;
case ID_DAP_UART_Control:
num = UART_Control(request, response);
break;
case ID_DAP_UART_Status:
num = UART_Status(response);
break;
case ID_DAP_UART_Transfer:
num = UART_Transfer(request, response);
break;
#endif
default: default:
*(response-1) = ID_DAP_Invalid; *(response-1) = ID_DAP_Invalid;
return ((1U << 16) | 1U); return ((1U << 16) | 1U);

View File

@ -0,0 +1,652 @@
/*
* Copyright (c) 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: 1. March 2021
* $Revision: V1.0.0
*
* Project: CMSIS-DAP Source
* Title: UART.c CMSIS-DAP UART
*
*---------------------------------------------------------------------------*/
#include "DAP_config.h"
#include "DAP.h"
#if (DAP_UART != 0)
#ifdef DAP_FW_V1
#error "UART Communication Port not supported in DAP V1!"
#endif
#include "Driver_USART.h"
#include "cmsis_os2.h"
#include <string.h>
#define UART_RX_BLOCK_SIZE 32U /* Uart Rx Block Size (must be 2^n) */
// USART Driver
#define _USART_Driver_(n) Driver_USART##n
#define USART_Driver_(n) _USART_Driver_(n)
extern ARM_DRIVER_USART USART_Driver_(DAP_UART_DRIVER);
#define pUSART (&USART_Driver_(DAP_UART_DRIVER))
// UART Configuration
#if (DAP_UART_USB_COM_PORT != 0)
static uint8_t UartTransport = DAP_UART_TRANSPORT_USB_COM_PORT;
#else
static uint8_t UartTransport = DAP_UART_TRANSPORT_NONE;
#endif
// UART Flags
static uint8_t UartConfigured = 0U;
static uint8_t UartReceiveEnabled = 0U;
static uint8_t UartTransmitEnabled = 0U;
static uint8_t UartTransmitActive = 0U;
// UART TX Buffer
static uint8_t UartTxBuf[DAP_UART_TX_BUFFER_SIZE];
static volatile uint32_t UartTxIndexI = 0U;
static volatile uint32_t UartTxIndexO = 0U;
// UART RX Buffer
static uint8_t UartRxBuf[DAP_UART_RX_BUFFER_SIZE];
static volatile uint32_t UartRxIndexI = 0U;
static volatile uint32_t UartRxIndexO = 0U;
// Uart Errors
static volatile uint8_t UartErrorRxDataLost = 0U;
static volatile uint8_t UartErrorFraming = 0U;
static volatile uint8_t UartErrorParity = 0U;
// UART Transmit
static uint32_t UartTxNum = 0U;
// Function prototypes
static uint8_t UART_Init (void);
static void UART_Uninit (void);
static uint8_t UART_Get_Status (void);
static uint8_t UART_Receive_Enable (void);
static uint8_t UART_Transmit_Enable (void);
static void UART_Receive_Disable (void);
static void UART_Transmit_Disable (void);
static void UART_Receive_Flush (void);
static void UART_Transmit_Flush (void);
static void UART_Receive (void);
static void UART_Transmit (void);
// USART Driver Callback function
// event: event mask
static void USART_Callback (uint32_t event) {
if (event & ARM_USART_EVENT_SEND_COMPLETE) {
UartTxIndexO += UartTxNum;
UartTransmitActive = 0U;
UART_Transmit();
}
if (event & ARM_USART_EVENT_RECEIVE_COMPLETE) {
UartRxIndexI += UART_RX_BLOCK_SIZE;
UART_Receive();
}
if (event & ARM_USART_EVENT_RX_OVERFLOW) {
UartErrorRxDataLost = 1U;
}
if (event & ARM_USART_EVENT_RX_FRAMING_ERROR) {
UartErrorFraming = 1U;
}
if (event & ARM_USART_EVENT_RX_PARITY_ERROR) {
UartErrorParity = 1U;
}
}
// Init UART
// return: DAP_OK or DAP_ERROR
static uint8_t UART_Init (void) {
int32_t status;
uint8_t ret = DAP_ERROR;
UartConfigured = 0U;
UartReceiveEnabled = 0U;
UartTransmitEnabled = 0U;
UartTransmitActive = 0U;
UartErrorRxDataLost = 0U;
UartErrorFraming = 0U;
UartErrorParity = 0U;
UartTxIndexI = 0U;
UartTxIndexO = 0U;
UartRxIndexI = 0U;
UartRxIndexO = 0U;
UartTxNum = 0U;
status = pUSART->Initialize(USART_Callback);
if (status == ARM_DRIVER_OK) {
status = pUSART->PowerControl(ARM_POWER_FULL);
}
if (status == ARM_DRIVER_OK) {
ret = DAP_OK;
}
return (ret);
}
// Un-Init UART
static void UART_Uninit (void) {
UartConfigured = 0U;
pUSART->PowerControl(ARM_POWER_OFF);
pUSART->Uninitialize();
}
// Get UART Status
// return: status
static uint8_t UART_Get_Status (void) {
uint8_t status = 0U;
if (UartReceiveEnabled != 0U) {
status |= DAP_UART_STATUS_RX_ENABLED;
}
if (UartErrorRxDataLost != 0U) {
UartErrorRxDataLost = 0U;
status |= DAP_UART_STATUS_RX_DATA_LOST;
}
if (UartErrorFraming != 0U) {
UartErrorFraming = 0U;
status |= DAP_UART_STATUS_FRAMING_ERROR;
}
if (UartErrorParity != 0U) {
UartErrorParity = 0U;
status |= DAP_UART_STATUS_PARITY_ERROR;
}
if (UartTransmitEnabled != 0U) {
status |= DAP_UART_STATUS_TX_ENABLED;
}
return (status);
}
// Enable UART Receive
// return: DAP_OK or DAP_ERROR
static uint8_t UART_Receive_Enable (void) {
int32_t status;
uint8_t ret = DAP_ERROR;
if (UartReceiveEnabled == 0U) {
// Flush Buffers
UartRxIndexI = 0U;
UartRxIndexO = 0U;
UART_Receive();
status = pUSART->Control(ARM_USART_CONTROL_RX, 1U);
if (status == ARM_DRIVER_OK) {
UartReceiveEnabled = 1U;
ret = DAP_OK;
}
} else {
ret = DAP_OK;
}
return (ret);
}
// Enable UART Transmit
// return: DAP_OK or DAP_ERROR
static uint8_t UART_Transmit_Enable (void) {
int32_t status;
uint8_t ret = DAP_ERROR;
if (UartTransmitEnabled == 0U) {
// Flush Buffers
UartTransmitActive = 0U;
UartTxIndexI = 0U;
UartTxIndexO = 0U;
UartTxNum = 0U;
status = pUSART->Control(ARM_USART_CONTROL_TX, 1U);
if (status == ARM_DRIVER_OK) {
UartTransmitEnabled = 1U;
ret = DAP_OK;
}
} else {
ret = DAP_OK;
}
return (ret);
}
// Disable UART Receive
static void UART_Receive_Disable (void) {
if (UartReceiveEnabled != 0U) {
pUSART->Control(ARM_USART_CONTROL_RX, 0U);
pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
UartReceiveEnabled = 0U;
}
}
// Disable UART Transmit
static void UART_Transmit_Disable (void) {
if (UartTransmitEnabled != 0U) {
pUSART->Control(ARM_USART_ABORT_SEND, 0U);
pUSART->Control(ARM_USART_CONTROL_TX, 0U);
UartTransmitActive = 0U;
UartTransmitEnabled = 0U;
}
}
// Flush UART Receive buffer
static void UART_Receive_Flush (void) {
pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
UartRxIndexI = 0U;
UartRxIndexO = 0U;
if (UartReceiveEnabled != 0U) {
UART_Receive();
}
}
// Flush UART Transmit buffer
static void UART_Transmit_Flush (void) {
pUSART->Control(ARM_USART_ABORT_SEND, 0U);
UartTransmitActive = 0U;
UartTxIndexI = 0U;
UartTxIndexO = 0U;
UartTxNum = 0U;
}
// Receive data from target via UART
static void UART_Receive (void) {
uint32_t index;
index = UartRxIndexI & (DAP_UART_RX_BUFFER_SIZE - 1U);
pUSART->Receive(&UartRxBuf[index], UART_RX_BLOCK_SIZE);
}
// Transmit available data to target via UART
static void UART_Transmit (void) {
uint32_t count;
uint32_t index;
count = UartTxIndexI - UartTxIndexO;
index = UartTxIndexO & (DAP_UART_TX_BUFFER_SIZE - 1U);
if (count != 0U) {
if ((index + count) <= DAP_UART_TX_BUFFER_SIZE) {
UartTxNum = count;
} else {
UartTxNum = DAP_UART_TX_BUFFER_SIZE - index;
}
UartTransmitActive = 1U;
pUSART->Send(&UartTxBuf[index], UartTxNum);
}
}
// Process UART Transport command and prepare response
// request: pointer to request data
// response: pointer to response data
// return: number of bytes in response (lower 16 bits)
// number of bytes in request (upper 16 bits)
uint32_t UART_Transport (const uint8_t *request, uint8_t *response) {
uint8_t transport;
uint8_t ret = DAP_ERROR;
transport = *request;
switch (transport) {
case DAP_UART_TRANSPORT_NONE:
switch (UartTransport) {
case DAP_UART_TRANSPORT_NONE:
ret = DAP_OK;
break;
case DAP_UART_TRANSPORT_USB_COM_PORT:
#if (DAP_UART_USB_COM_PORT != 0)
USB_COM_PORT_Activate(0U);
UartTransport = DAP_UART_TRANSPORT_NONE;
ret = DAP_OK;
#endif
break;
case DAP_UART_TRANSPORT_DAP_COMMAND:
UART_Receive_Disable();
UART_Transmit_Disable();
UART_Uninit();
UartTransport = DAP_UART_TRANSPORT_NONE;
ret= DAP_OK;
break;
}
break;
case DAP_UART_TRANSPORT_USB_COM_PORT:
switch (UartTransport) {
case DAP_UART_TRANSPORT_NONE:
#if (DAP_UART_USB_COM_PORT != 0)
if (USB_COM_PORT_Activate(1U) == 0U) {
UartTransport = DAP_UART_TRANSPORT_USB_COM_PORT;
ret = DAP_OK;
}
#endif
break;
case DAP_UART_TRANSPORT_USB_COM_PORT:
ret = DAP_OK;
break;
case DAP_UART_TRANSPORT_DAP_COMMAND:
UART_Receive_Disable();
UART_Transmit_Disable();
UART_Uninit();
UartTransport = DAP_UART_TRANSPORT_NONE;
#if (DAP_UART_USB_COM_PORT != 0)
if (USB_COM_PORT_Activate(1U) == 0U) {
UartTransport = DAP_UART_TRANSPORT_USB_COM_PORT;
ret = DAP_OK;
}
#endif
break;
}
break;
case DAP_UART_TRANSPORT_DAP_COMMAND:
switch (UartTransport) {
case DAP_UART_TRANSPORT_NONE:
ret = UART_Init();
if (ret == DAP_OK) {
UartTransport = DAP_UART_TRANSPORT_DAP_COMMAND;
}
break;
case DAP_UART_TRANSPORT_USB_COM_PORT:
#if (DAP_UART_USB_COM_PORT != 0)
USB_COM_PORT_Activate(0U);
UartTransport = DAP_UART_TRANSPORT_NONE;
#endif
ret = UART_Init();
if (ret == DAP_OK) {
UartTransport = DAP_UART_TRANSPORT_DAP_COMMAND;
}
break;
case DAP_UART_TRANSPORT_DAP_COMMAND:
ret = DAP_OK;
break;
}
break;
default:
break;
}
*response = ret;
return ((1U << 16) | 1U);
}
// Process UART Configure command and prepare response
// request: pointer to request data
// response: pointer to response data
// return: number of bytes in response (lower 16 bits)
// number of bytes in request (upper 16 bits)
uint32_t UART_Configure (const uint8_t *request, uint8_t *response) {
uint8_t control, status;
uint32_t baudrate;
int32_t result;
if (UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) {
status = DAP_UART_CFG_ERROR_DATA_BITS |
DAP_UART_CFG_ERROR_PARITY |
DAP_UART_CFG_ERROR_STOP_BITS;
baudrate = 0U; // baudrate error
} else {
status = 0U;
control = *request;
baudrate = (uint32_t)(*(request+1) << 0) |
(uint32_t)(*(request+2) << 8) |
(uint32_t)(*(request+3) << 16) |
(uint32_t)(*(request+4) << 24);
result = pUSART->Control(control |
ARM_USART_MODE_ASYNCHRONOUS |
ARM_USART_FLOW_CONTROL_NONE,
baudrate);
if (result == ARM_DRIVER_OK) {
UartConfigured = 1U;
} else {
UartConfigured = 0U;
switch (result) {
case ARM_USART_ERROR_BAUDRATE:
status = 0U;
baudrate = 0U;
break;
case ARM_USART_ERROR_DATA_BITS:
status = DAP_UART_CFG_ERROR_DATA_BITS;
break;
case ARM_USART_ERROR_PARITY:
status = DAP_UART_CFG_ERROR_PARITY;
break;
case ARM_USART_ERROR_STOP_BITS:
status = DAP_UART_CFG_ERROR_STOP_BITS;
break;
default:
status = DAP_UART_CFG_ERROR_DATA_BITS |
DAP_UART_CFG_ERROR_PARITY |
DAP_UART_CFG_ERROR_STOP_BITS;
baudrate = 0U;
break;
}
}
}
*response++ = status;
*response++ = (uint8_t)(baudrate >> 0);
*response++ = (uint8_t)(baudrate >> 8);
*response++ = (uint8_t)(baudrate >> 16);
*response = (uint8_t)(baudrate >> 24);
return ((5U << 16) | 5U);
}
// Process UART Control command and prepare response
// request: pointer to request data
// response: pointer to response data
// return: number of bytes in response (lower 16 bits)
// number of bytes in request (upper 16 bits)
uint32_t UART_Control (const uint8_t *request, uint8_t *response) {
uint8_t control;
uint8_t result;
uint8_t ret = DAP_OK;
if (UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) {
ret = DAP_ERROR;
} else {
control = *request;
if ((control & DAP_UART_CONTROL_RX_DISABLE) != 0U) {
// Receive disable
UART_Receive_Disable();
} else if ((control & DAP_UART_CONTROL_RX_ENABLE) != 0U) {
// Receive enable
if (UartConfigured != 0U) {
result = UART_Receive_Enable();
if (result != DAP_OK) {
ret = DAP_ERROR;
}
} else {
ret = DAP_ERROR;
}
}
if ((control & DAP_UART_CONTROL_RX_BUF_FLUSH) != 0U) {
UART_Receive_Flush();
}
if ((control & DAP_UART_CONTROL_TX_DISABLE) != 0U) {
// Transmit disable
UART_Transmit_Disable();
} else if ((control & DAP_UART_CONTROL_TX_ENABLE) != 0U) {
// Transmit enable
if (UartConfigured != 0U) {
result = UART_Transmit_Enable();
if (result != DAP_OK) {
ret = DAP_ERROR;
}
} else {
ret = DAP_ERROR;
}
}
if ((control & DAP_UART_CONTROL_TX_BUF_FLUSH) != 0U) {
UART_Transmit_Flush();
}
}
*response = ret;
return ((1U << 16) | 1U);
}
// Process UART Status command and prepare response
// response: pointer to response data
// return: number of bytes in response (lower 16 bits)
// number of bytes in request (upper 16 bits)
uint32_t UART_Status (uint8_t *response) {
uint32_t rx_cnt, tx_cnt;
uint32_t cnt;
uint8_t status;
if ((UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) ||
(UartConfigured == 0U)) {
rx_cnt = 0U;
tx_cnt = 0U;
status = 0U;
} else {
rx_cnt = UartRxIndexI - UartRxIndexO;
rx_cnt += pUSART->GetRxCount();
if (rx_cnt > (DAP_UART_RX_BUFFER_SIZE - (UART_RX_BLOCK_SIZE*2))) {
// Overflow
UartErrorRxDataLost = 1U;
rx_cnt = (DAP_UART_RX_BUFFER_SIZE - (UART_RX_BLOCK_SIZE*2));
UartRxIndexO = UartRxIndexI - rx_cnt;
}
tx_cnt = UartTxIndexI - UartTxIndexO;
cnt = pUSART->GetTxCount();
if (UartTransmitActive != 0U) {
tx_cnt -= cnt;
}
status = UART_Get_Status();
}
*response++ = status;
*response++ = (uint8_t)(rx_cnt >> 0);
*response++ = (uint8_t)(rx_cnt >> 8);
*response++ = (uint8_t)(rx_cnt >> 16);
*response++ = (uint8_t)(rx_cnt >> 24);
*response++ = (uint8_t)(tx_cnt >> 0);
*response++ = (uint8_t)(tx_cnt >> 8);
*response++ = (uint8_t)(tx_cnt >> 16);
*response = (uint8_t)(tx_cnt >> 24);
return ((0U << 16) | 9U);
}
// Process UART Transfer command and prepare response
// request: pointer to request data
// response: pointer to response data
// return: number of bytes in response (lower 16 bits)
// number of bytes in request (upper 16 bits)
uint32_t UART_Transfer (const uint8_t *request, uint8_t *response) {
uint32_t rx_cnt, tx_cnt;
uint32_t rx_num, tx_num;
uint8_t *rx_data;
const
uint8_t *tx_data;
uint32_t num;
uint32_t index;
uint8_t status;
if (UartTransport != DAP_UART_TRANSPORT_DAP_COMMAND) {
status = 0U;
rx_cnt = 0U;
tx_cnt = 0U;
} else {
// RX Data
rx_cnt = ((uint32_t)(*(request+0) << 0) |
(uint32_t)(*(request+1) << 8));
if (rx_cnt > (DAP_PACKET_SIZE - 6U)) {
rx_cnt = (DAP_PACKET_SIZE - 6U);
}
rx_num = UartRxIndexI - UartRxIndexO;
rx_num += pUSART->GetRxCount();
if (rx_num > (DAP_UART_RX_BUFFER_SIZE - (UART_RX_BLOCK_SIZE*2))) {
// Overflow
UartErrorRxDataLost = 1U;
rx_num = (DAP_UART_RX_BUFFER_SIZE - (UART_RX_BLOCK_SIZE*2));
UartRxIndexO = UartRxIndexI - rx_num;
}
if (rx_cnt > rx_num) {
rx_cnt = rx_num;
}
rx_data = (response+5);
index = UartRxIndexO & (DAP_UART_RX_BUFFER_SIZE - 1U);
if ((index + rx_cnt) <= DAP_UART_RX_BUFFER_SIZE) {
memcpy( rx_data, &UartRxBuf[index], rx_cnt);
} else {
num = DAP_UART_RX_BUFFER_SIZE - index;
memcpy( rx_data, &UartRxBuf[index], num);
memcpy(&rx_data[num], &UartRxBuf[0], rx_cnt - num);
}
UartRxIndexO += rx_cnt;
// TX Data
tx_cnt = ((uint32_t)(*(request+2) << 0) |
(uint32_t)(*(request+3) << 8));
tx_data = (request+4);
if (tx_cnt > (DAP_PACKET_SIZE - 5U)) {
tx_cnt = (DAP_PACKET_SIZE - 5U);
}
tx_num = UartTxIndexI - UartTxIndexO;
num = pUSART->GetTxCount();
if (UartTransmitActive != 0U) {
tx_num -= num;
}
if (tx_cnt > (DAP_UART_TX_BUFFER_SIZE - tx_num)) {
tx_cnt = (DAP_UART_TX_BUFFER_SIZE - tx_num);
}
index = UartTxIndexI & (DAP_UART_TX_BUFFER_SIZE - 1U);
if ((index + tx_cnt) <= DAP_UART_TX_BUFFER_SIZE) {
memcpy(&UartTxBuf[index], tx_data, tx_cnt);
} else {
num = DAP_UART_TX_BUFFER_SIZE - index;
memcpy(&UartTxBuf[index], tx_data, num);
memcpy(&UartTxBuf[0], &tx_data[num], tx_cnt - num);
}
UartTxIndexI += tx_cnt;
if (UartTransmitActive == 0U) {
UART_Transmit();
}
status = UART_Get_Status();
}
*response++ = status;
*response++ = (uint8_t)(tx_cnt >> 0);
*response++ = (uint8_t)(tx_cnt >> 8);
*response++ = (uint8_t)(rx_cnt >> 0);
*response = (uint8_t)(rx_cnt >> 8);
return (((4U + tx_cnt) << 16) | (5U + rx_cnt));
}
#endif /* DAP_UART */