Initial commit
This commit is contained in:
commit
ce3dd83b9f
1470 changed files with 1054449 additions and 0 deletions
561
Drivers/CMSIS/DAP/Firmware/Config/DAP_config.h
Normal file
561
Drivers/CMSIS/DAP/Firmware/Config/DAP_config.h
Normal file
|
@ -0,0 +1,561 @@
|
|||
/*
|
||||
* 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: 16. June 2021
|
||||
* $Revision: V2.1.0
|
||||
*
|
||||
* Project: CMSIS-DAP Configuration
|
||||
* Title: DAP_config.h CMSIS-DAP Configuration File (Template)
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __DAP_CONFIG_H__
|
||||
#define __DAP_CONFIG_H__
|
||||
|
||||
|
||||
//**************************************************************************************************
|
||||
/**
|
||||
\defgroup DAP_Config_Debug_gr CMSIS-DAP Debug Unit Information
|
||||
\ingroup DAP_ConfigIO_gr
|
||||
@{
|
||||
Provides definitions about the hardware and configuration of the Debug Unit.
|
||||
|
||||
This information includes:
|
||||
- Definition of Cortex-M processor parameters used in CMSIS-DAP Debug Unit.
|
||||
- Debug Unit Identification strings (Vendor, Product, Serial Number).
|
||||
- Debug Unit communication packet size.
|
||||
- Debug Access Port supported modes and settings (JTAG/SWD and SWO).
|
||||
- Optional information about a connected Target Device (for Evaluation Boards).
|
||||
*/
|
||||
|
||||
#ifdef _RTE_
|
||||
#include "RTE_Components.h"
|
||||
#include CMSIS_device_header
|
||||
#else
|
||||
#include "device.h" // Debug Unit Cortex-M Processor Header File
|
||||
#endif
|
||||
|
||||
/// Processor Clock of the Cortex-M MCU used in the Debug Unit.
|
||||
/// This value is used to calculate the SWD/JTAG clock speed.
|
||||
#define CPU_CLOCK 100000000U ///< Specifies the CPU Clock in Hz.
|
||||
|
||||
/// Number of processor cycles for I/O Port write operations.
|
||||
/// This value is used to calculate the SWD/JTAG clock speed that is generated with I/O
|
||||
/// Port write operations in the Debug Unit by a Cortex-M MCU. Most Cortex-M processors
|
||||
/// require 2 processor cycles for a I/O Port Write operation. If the Debug Unit uses
|
||||
/// a Cortex-M0+ processor with high-speed peripheral I/O only 1 processor cycle might be
|
||||
/// required.
|
||||
#define IO_PORT_WRITE_CYCLES 2U ///< I/O Cycles: 2=default, 1=Cortex-M0+ fast I/0.
|
||||
|
||||
/// Indicate that Serial Wire Debug (SWD) communication mode is available at the Debug Access Port.
|
||||
/// This information is returned by the command \ref DAP_Info as part of <b>Capabilities</b>.
|
||||
#define DAP_SWD 1 ///< SWD Mode: 1 = available, 0 = not available.
|
||||
|
||||
/// Indicate that JTAG communication mode is available at the Debug Port.
|
||||
/// This information is returned by the command \ref DAP_Info as part of <b>Capabilities</b>.
|
||||
#define DAP_JTAG 1 ///< JTAG Mode: 1 = available, 0 = not available.
|
||||
|
||||
/// Configure maximum number of JTAG devices on the scan chain connected to the Debug Access Port.
|
||||
/// This setting impacts the RAM requirements of the Debug Unit. Valid range is 1 .. 255.
|
||||
#define DAP_JTAG_DEV_CNT 8U ///< Maximum number of JTAG devices on scan chain.
|
||||
|
||||
/// Default communication mode on the Debug Access Port.
|
||||
/// Used for the command \ref DAP_Connect when Port Default mode is selected.
|
||||
#define DAP_DEFAULT_PORT 1U ///< Default JTAG/SWJ Port Mode: 1 = SWD, 2 = JTAG.
|
||||
|
||||
/// Default communication speed on the Debug Access Port for SWD and JTAG mode.
|
||||
/// Used to initialize the default SWD/JTAG clock frequency.
|
||||
/// The command \ref DAP_SWJ_Clock can be used to overwrite this default setting.
|
||||
#define DAP_DEFAULT_SWJ_CLOCK 1000000U ///< Default SWD/JTAG clock frequency in Hz.
|
||||
|
||||
/// Maximum Package Size for Command and Response data.
|
||||
/// This configuration settings is used to optimize the communication performance with the
|
||||
/// debugger and depends on the USB peripheral. Typical vales are 64 for Full-speed USB HID or WinUSB,
|
||||
/// 1024 for High-speed USB HID and 512 for High-speed USB WinUSB.
|
||||
#define DAP_PACKET_SIZE 512U ///< Specifies Packet Size in bytes.
|
||||
|
||||
/// Maximum Package Buffers for Command and Response data.
|
||||
/// This configuration settings is used to optimize the communication performance with the
|
||||
/// debugger and depends on the USB peripheral. For devices with limited RAM or USB buffer the
|
||||
/// setting can be reduced (valid range is 1 .. 255).
|
||||
#define DAP_PACKET_COUNT 8U ///< Specifies number of packets buffered.
|
||||
|
||||
/// Indicate that UART Serial Wire Output (SWO) trace is available.
|
||||
/// This information is returned by the command \ref DAP_Info as part of <b>Capabilities</b>.
|
||||
#define SWO_UART 1 ///< 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.
|
||||
#define SWO_UART_MAX_BAUDRATE 10000000U ///< SWO UART Maximum Baudrate in Hz.
|
||||
|
||||
/// Indicate that Manchester Serial Wire Output (SWO) trace is available.
|
||||
/// This information is returned by the command \ref DAP_Info as part of <b>Capabilities</b>.
|
||||
#define SWO_MANCHESTER 0 ///< SWO Manchester: 1 = available, 0 = not available.
|
||||
|
||||
/// SWO Trace Buffer Size.
|
||||
#define SWO_BUFFER_SIZE 4096U ///< SWO Trace Buffer Size in bytes (must be 2^n).
|
||||
|
||||
/// SWO Streaming Trace.
|
||||
#define SWO_STREAM 0 ///< SWO Streaming Trace: 1 = available, 0 = not available.
|
||||
|
||||
/// Clock frequency of the Test Domain Timer. Timer value is returned with \ref TIMESTAMP_GET.
|
||||
#define TIMESTAMP_CLOCK 100000000U ///< Timestamp clock in Hz (0 = timestamps not supported).
|
||||
|
||||
/// 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 1 ///< 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 1 ///< USB COM Port: 1 = available, 0 = not available.
|
||||
|
||||
/// Debug Unit is connected to fixed Target Device.
|
||||
/// The Debug Unit may be part of an evaluation board and always connected to a fixed
|
||||
/// known device. In this case a Device Vendor, Device Name, Board Vendor and Board Name strings
|
||||
/// are stored and may be used by the debugger or IDE to configure device parameters.
|
||||
#define TARGET_FIXED 0 ///< Target: 1 = known, 0 = unknown;
|
||||
|
||||
#define TARGET_DEVICE_VENDOR "Arm" ///< String indicating the Silicon Vendor
|
||||
#define TARGET_DEVICE_NAME "Cortex-M" ///< String indicating the Target Device
|
||||
#define TARGET_BOARD_VENDOR "Arm" ///< String indicating the Board Vendor
|
||||
#define TARGET_BOARD_NAME "Arm board" ///< 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
|
||||
|
||||
/** Get Vendor 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_GetVendorString (char *str) {
|
||||
(void)str;
|
||||
return (0U);
|
||||
}
|
||||
|
||||
/** Get Product 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_GetProductString (char *str) {
|
||||
(void)str;
|
||||
return (0U);
|
||||
}
|
||||
|
||||
/** Get Serial Number 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_GetSerNumString (char *str) {
|
||||
(void)str;
|
||||
return (0U);
|
||||
}
|
||||
|
||||
/** 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
|
||||
}
|
||||
|
||||
/** 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
|
||||
}
|
||||
|
||||
/** 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
|
||||
}
|
||||
|
||||
/** 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
|
||||
}
|
||||
|
||||
/** 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);
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
|
||||
//**************************************************************************************************
|
||||
/**
|
||||
\defgroup DAP_Config_PortIO_gr CMSIS-DAP Hardware I/O Pin Access
|
||||
\ingroup DAP_ConfigIO_gr
|
||||
@{
|
||||
|
||||
Standard I/O Pins of the CMSIS-DAP Hardware Debug Port support standard JTAG mode
|
||||
and Serial Wire Debug (SWD) mode. In SWD mode only 2 pins are required to implement the debug
|
||||
interface of a device. The following I/O Pins are provided:
|
||||
|
||||
JTAG I/O Pin | SWD I/O Pin | CMSIS-DAP Hardware pin mode
|
||||
---------------------------- | -------------------- | ---------------------------------------------
|
||||
TCK: Test Clock | SWCLK: Clock | Output Push/Pull
|
||||
TMS: Test Mode Select | SWDIO: Data I/O | Output Push/Pull; Input (for receiving data)
|
||||
TDI: Test Data Input | | Output Push/Pull
|
||||
TDO: Test Data Output | | Input
|
||||
nTRST: Test Reset (optional) | | Output Open Drain with pull-up resistor
|
||||
nRESET: Device Reset | nRESET: Device Reset | Output Open Drain with pull-up resistor
|
||||
|
||||
|
||||
DAP Hardware I/O Pin Access Functions
|
||||
-------------------------------------
|
||||
The various I/O Pins are accessed by functions that implement the Read, Write, Set, or Clear to
|
||||
these I/O Pins.
|
||||
|
||||
For the SWDIO I/O Pin there are additional functions that are called in SWD I/O mode only.
|
||||
This functions are provided to achieve faster I/O that is possible with some advanced GPIO
|
||||
peripherals that can independently write/read a single I/O pin without affecting any other pins
|
||||
of the same I/O port. The following SWDIO I/O Pin functions are provided:
|
||||
- \ref PIN_SWDIO_OUT_ENABLE to enable the output mode from the DAP hardware.
|
||||
- \ref PIN_SWDIO_OUT_DISABLE to enable the input mode to the DAP hardware.
|
||||
- \ref PIN_SWDIO_IN to read from the SWDIO I/O pin with utmost possible speed.
|
||||
- \ref PIN_SWDIO_OUT to write to the SWDIO I/O pin with utmost possible speed.
|
||||
*/
|
||||
|
||||
|
||||
// Configure DAP I/O pins ------------------------------
|
||||
|
||||
/** Setup JTAG I/O pins: TCK, TMS, TDI, TDO, nTRST, and nRESET.
|
||||
Configures the DAP Hardware I/O pins for JTAG mode:
|
||||
- TCK, TMS, TDI, nTRST, nRESET to output mode and set to high level.
|
||||
- TDO to input mode.
|
||||
*/
|
||||
__STATIC_INLINE void PORT_JTAG_SETUP (void) {
|
||||
;
|
||||
}
|
||||
|
||||
/** Setup SWD I/O pins: SWCLK, SWDIO, and nRESET.
|
||||
Configures the DAP Hardware I/O pins for Serial Wire Debug (SWD) mode:
|
||||
- SWCLK, SWDIO, nRESET to output mode and set to default high level.
|
||||
- TDI, nTRST to HighZ mode (pins are unused in SWD mode).
|
||||
*/
|
||||
__STATIC_INLINE void PORT_SWD_SETUP (void) {
|
||||
;
|
||||
}
|
||||
|
||||
/** Disable JTAG/SWD I/O Pins.
|
||||
Disables the DAP Hardware I/O pins which configures:
|
||||
- TCK/SWCLK, TMS/SWDIO, TDI, TDO, nTRST, nRESET to High-Z mode.
|
||||
*/
|
||||
__STATIC_INLINE void PORT_OFF (void) {
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
// SWCLK/TCK I/O pin -------------------------------------
|
||||
|
||||
/** SWCLK/TCK I/O pin: Get Input.
|
||||
\return Current status of the SWCLK/TCK DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN (void) {
|
||||
return (0U);
|
||||
}
|
||||
|
||||
/** SWCLK/TCK I/O pin: Set Output to High.
|
||||
Set the SWCLK/TCK DAP hardware I/O pin to high level.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWCLK_TCK_SET (void) {
|
||||
;
|
||||
}
|
||||
|
||||
/** SWCLK/TCK I/O pin: Set Output to Low.
|
||||
Set the SWCLK/TCK DAP hardware I/O pin to low level.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR (void) {
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
// SWDIO/TMS Pin I/O --------------------------------------
|
||||
|
||||
/** SWDIO/TMS I/O pin: Get Input.
|
||||
\return Current status of the SWDIO/TMS DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN (void) {
|
||||
return (0U);
|
||||
}
|
||||
|
||||
/** SWDIO/TMS I/O pin: Set Output to High.
|
||||
Set the SWDIO/TMS DAP hardware I/O pin to high level.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET (void) {
|
||||
;
|
||||
}
|
||||
|
||||
/** SWDIO/TMS I/O pin: Set Output to Low.
|
||||
Set the SWDIO/TMS DAP hardware I/O pin to low level.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWDIO_TMS_CLR (void) {
|
||||
;
|
||||
}
|
||||
|
||||
/** SWDIO I/O pin: Get Input (used in SWD mode only).
|
||||
\return Current status of the SWDIO DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN (void) {
|
||||
return (0U);
|
||||
}
|
||||
|
||||
/** SWDIO I/O pin: Set Output (used in SWD mode only).
|
||||
\param bit Output value for the SWDIO DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWDIO_OUT (uint32_t bit) {
|
||||
;
|
||||
}
|
||||
|
||||
/** SWDIO I/O pin: Switch to Output mode (used in SWD mode only).
|
||||
Configure the SWDIO DAP hardware I/O pin to output mode. This function is
|
||||
called prior \ref PIN_SWDIO_OUT function calls.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWDIO_OUT_ENABLE (void) {
|
||||
;
|
||||
}
|
||||
|
||||
/** SWDIO I/O pin: Switch to Input mode (used in SWD mode only).
|
||||
Configure the SWDIO DAP hardware I/O pin to input mode. This function is
|
||||
called prior \ref PIN_SWDIO_IN function calls.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE (void) {
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
// TDI Pin I/O ---------------------------------------------
|
||||
|
||||
/** TDI I/O pin: Get Input.
|
||||
\return Current status of the TDI DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_TDI_IN (void) {
|
||||
return (0U);
|
||||
}
|
||||
|
||||
/** TDI I/O pin: Set Output.
|
||||
\param bit Output value for the TDI DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_TDI_OUT (uint32_t bit) {
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
// TDO Pin I/O ---------------------------------------------
|
||||
|
||||
/** TDO I/O pin: Get Input.
|
||||
\return Current status of the TDO DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_TDO_IN (void) {
|
||||
return (0U);
|
||||
}
|
||||
|
||||
|
||||
// nTRST Pin I/O -------------------------------------------
|
||||
|
||||
/** nTRST I/O pin: Get Input.
|
||||
\return Current status of the nTRST DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_nTRST_IN (void) {
|
||||
return (0U);
|
||||
}
|
||||
|
||||
/** nTRST I/O pin: Set Output.
|
||||
\param bit JTAG TRST Test Reset pin status:
|
||||
- 0: issue a JTAG TRST Test Reset.
|
||||
- 1: release JTAG TRST Test Reset.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_nTRST_OUT (uint32_t bit) {
|
||||
;
|
||||
}
|
||||
|
||||
// nRESET Pin I/O------------------------------------------
|
||||
|
||||
/** nRESET I/O pin: Get Input.
|
||||
\return Current status of the nRESET DAP hardware I/O pin.
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t PIN_nRESET_IN (void) {
|
||||
return (0U);
|
||||
}
|
||||
|
||||
/** nRESET I/O pin: Set Output.
|
||||
\param bit target device hardware reset pin status:
|
||||
- 0: issue a device hardware reset.
|
||||
- 1: release device hardware reset.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void PIN_nRESET_OUT (uint32_t bit) {
|
||||
;
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
|
||||
//**************************************************************************************************
|
||||
/**
|
||||
\defgroup DAP_Config_LEDs_gr CMSIS-DAP Hardware Status LEDs
|
||||
\ingroup DAP_ConfigIO_gr
|
||||
@{
|
||||
|
||||
CMSIS-DAP Hardware may provide LEDs that indicate the status of the CMSIS-DAP Debug Unit.
|
||||
|
||||
It is recommended to provide the following LEDs for status indication:
|
||||
- Connect LED: is active when the DAP hardware is connected to a debugger.
|
||||
- Running LED: is active when the debugger has put the target device into running state.
|
||||
*/
|
||||
|
||||
/** Debug Unit: Set status of Connected LED.
|
||||
\param bit status of the Connect LED.
|
||||
- 1: Connect LED ON: debugger is connected to CMSIS-DAP Debug Unit.
|
||||
- 0: Connect LED OFF: debugger is not connected to CMSIS-DAP Debug Unit.
|
||||
*/
|
||||
__STATIC_INLINE void LED_CONNECTED_OUT (uint32_t bit) {}
|
||||
|
||||
/** Debug Unit: Set status Target Running LED.
|
||||
\param bit status of the Target Running LED.
|
||||
- 1: Target Running LED ON: program execution in target started.
|
||||
- 0: Target Running LED OFF: program execution in target stopped.
|
||||
*/
|
||||
__STATIC_INLINE void LED_RUNNING_OUT (uint32_t bit) {}
|
||||
|
||||
///@}
|
||||
|
||||
|
||||
//**************************************************************************************************
|
||||
/**
|
||||
\defgroup DAP_Config_Timestamp_gr CMSIS-DAP Timestamp
|
||||
\ingroup DAP_ConfigIO_gr
|
||||
@{
|
||||
Access function for Test Domain Timer.
|
||||
|
||||
The value of the Test Domain Timer in the Debug Unit is returned by the function \ref TIMESTAMP_GET. By
|
||||
default, the DWT timer is used. The frequency of this timer is configured with \ref TIMESTAMP_CLOCK.
|
||||
|
||||
*/
|
||||
|
||||
/** Get timestamp of Test Domain Timer.
|
||||
\return Current timestamp value.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t TIMESTAMP_GET (void) {
|
||||
return (DWT->CYCCNT);
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
|
||||
//**************************************************************************************************
|
||||
/**
|
||||
\defgroup DAP_Config_Initialization_gr CMSIS-DAP Initialization
|
||||
\ingroup DAP_ConfigIO_gr
|
||||
@{
|
||||
|
||||
CMSIS-DAP Hardware I/O and LED Pins are initialized with the function \ref DAP_SETUP.
|
||||
*/
|
||||
|
||||
/** Setup of the Debug Unit I/O pins and LEDs (called when Debug Unit is initialized).
|
||||
This function performs the initialization of the CMSIS-DAP Hardware I/O Pins and the
|
||||
Status LEDs. In detail the operation of Hardware I/O and LED pins are enabled and set:
|
||||
- I/O clock system enabled.
|
||||
- all I/O pins: input buffer enabled, output pins are set to HighZ mode.
|
||||
- for nTRST, nRESET a weak pull-up (if available) is enabled.
|
||||
- LED output pins are enabled and LEDs are turned off.
|
||||
*/
|
||||
__STATIC_INLINE void DAP_SETUP (void) {
|
||||
;
|
||||
}
|
||||
|
||||
/** Reset Target Device with custom specific I/O pin or command sequence.
|
||||
This function allows the optional implementation of a device specific reset sequence.
|
||||
It is called when the command \ref DAP_ResetTarget and is for example required
|
||||
when a device needs a time-critical unlock sequence that enables the debug port.
|
||||
\return 0 = no device specific reset sequence is implemented.\n
|
||||
1 = a device specific reset sequence is implemented.
|
||||
*/
|
||||
__STATIC_INLINE uint8_t RESET_TARGET (void) {
|
||||
return (0U); // change to '1' when a device reset sequence is implemented
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
|
||||
#endif /* __DAP_CONFIG_H__ */
|
367
Drivers/CMSIS/DAP/Firmware/Include/DAP.h
Normal file
367
Drivers/CMSIS/DAP/Firmware/Include/DAP.h
Normal file
|
@ -0,0 +1,367 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2022 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: 26. April 2022
|
||||
* $Revision: V2.1.1
|
||||
*
|
||||
* Project: CMSIS-DAP Include
|
||||
* Title: DAP.h Definitions
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __DAP_H__
|
||||
#define __DAP_H__
|
||||
|
||||
|
||||
// DAP Firmware Version
|
||||
#ifdef DAP_FW_V1
|
||||
#define DAP_FW_VER "1.3.0"
|
||||
#else
|
||||
#define DAP_FW_VER "2.1.1"
|
||||
#endif
|
||||
|
||||
// DAP Command IDs
|
||||
#define ID_DAP_Info 0x00U
|
||||
#define ID_DAP_HostStatus 0x01U
|
||||
#define ID_DAP_Connect 0x02U
|
||||
#define ID_DAP_Disconnect 0x03U
|
||||
#define ID_DAP_TransferConfigure 0x04U
|
||||
#define ID_DAP_Transfer 0x05U
|
||||
#define ID_DAP_TransferBlock 0x06U
|
||||
#define ID_DAP_TransferAbort 0x07U
|
||||
#define ID_DAP_WriteABORT 0x08U
|
||||
#define ID_DAP_Delay 0x09U
|
||||
#define ID_DAP_ResetTarget 0x0AU
|
||||
#define ID_DAP_SWJ_Pins 0x10U
|
||||
#define ID_DAP_SWJ_Clock 0x11U
|
||||
#define ID_DAP_SWJ_Sequence 0x12U
|
||||
#define ID_DAP_SWD_Configure 0x13U
|
||||
#define ID_DAP_SWD_Sequence 0x1DU
|
||||
#define ID_DAP_JTAG_Sequence 0x14U
|
||||
#define ID_DAP_JTAG_Configure 0x15U
|
||||
#define ID_DAP_JTAG_IDCODE 0x16U
|
||||
#define ID_DAP_SWO_Transport 0x17U
|
||||
#define ID_DAP_SWO_Mode 0x18U
|
||||
#define ID_DAP_SWO_Baudrate 0x19U
|
||||
#define ID_DAP_SWO_Control 0x1AU
|
||||
#define ID_DAP_SWO_Status 0x1BU
|
||||
#define ID_DAP_SWO_ExtendedStatus 0x1EU
|
||||
#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_ExecuteCommands 0x7FU
|
||||
|
||||
// DAP Vendor Command IDs
|
||||
#define ID_DAP_Vendor0 0x80U
|
||||
#define ID_DAP_Vendor1 0x81U
|
||||
#define ID_DAP_Vendor2 0x82U
|
||||
#define ID_DAP_Vendor3 0x83U
|
||||
#define ID_DAP_Vendor4 0x84U
|
||||
#define ID_DAP_Vendor5 0x85U
|
||||
#define ID_DAP_Vendor6 0x86U
|
||||
#define ID_DAP_Vendor7 0x87U
|
||||
#define ID_DAP_Vendor8 0x88U
|
||||
#define ID_DAP_Vendor9 0x89U
|
||||
#define ID_DAP_Vendor10 0x8AU
|
||||
#define ID_DAP_Vendor11 0x8BU
|
||||
#define ID_DAP_Vendor12 0x8CU
|
||||
#define ID_DAP_Vendor13 0x8DU
|
||||
#define ID_DAP_Vendor14 0x8EU
|
||||
#define ID_DAP_Vendor15 0x8FU
|
||||
#define ID_DAP_Vendor16 0x90U
|
||||
#define ID_DAP_Vendor17 0x91U
|
||||
#define ID_DAP_Vendor18 0x92U
|
||||
#define ID_DAP_Vendor19 0x93U
|
||||
#define ID_DAP_Vendor20 0x94U
|
||||
#define ID_DAP_Vendor21 0x95U
|
||||
#define ID_DAP_Vendor22 0x96U
|
||||
#define ID_DAP_Vendor23 0x97U
|
||||
#define ID_DAP_Vendor24 0x98U
|
||||
#define ID_DAP_Vendor25 0x99U
|
||||
#define ID_DAP_Vendor26 0x9AU
|
||||
#define ID_DAP_Vendor27 0x9BU
|
||||
#define ID_DAP_Vendor28 0x9CU
|
||||
#define ID_DAP_Vendor29 0x9DU
|
||||
#define ID_DAP_Vendor30 0x9EU
|
||||
#define ID_DAP_Vendor31 0x9FU
|
||||
|
||||
#define ID_DAP_Invalid 0xFFU
|
||||
|
||||
// DAP Status Code
|
||||
#define DAP_OK 0U
|
||||
#define DAP_ERROR 0xFFU
|
||||
|
||||
// DAP ID
|
||||
#define DAP_ID_VENDOR 1U
|
||||
#define DAP_ID_PRODUCT 2U
|
||||
#define DAP_ID_SER_NUM 3U
|
||||
#define DAP_ID_DAP_FW_VER 4U
|
||||
#define DAP_ID_DEVICE_VENDOR 5U
|
||||
#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_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_PACKET_COUNT 0xFEU
|
||||
#define DAP_ID_PACKET_SIZE 0xFFU
|
||||
|
||||
// DAP Host Status
|
||||
#define DAP_DEBUGGER_CONNECTED 0U
|
||||
#define DAP_TARGET_RUNNING 1U
|
||||
|
||||
// DAP Port
|
||||
#define DAP_PORT_AUTODETECT 0U // Autodetect Port
|
||||
#define DAP_PORT_DISABLED 0U // Port Disabled (I/O pins in High-Z)
|
||||
#define DAP_PORT_SWD 1U // SWD Port (SWCLK, SWDIO) + nRESET
|
||||
#define DAP_PORT_JTAG 2U // JTAG Port (TCK, TMS, TDI, TDO, nTRST) + nRESET
|
||||
|
||||
// DAP SWJ Pins
|
||||
#define DAP_SWJ_SWCLK_TCK 0 // SWCLK/TCK
|
||||
#define DAP_SWJ_SWDIO_TMS 1 // SWDIO/TMS
|
||||
#define DAP_SWJ_TDI 2 // TDI
|
||||
#define DAP_SWJ_TDO 3 // TDO
|
||||
#define DAP_SWJ_nTRST 5 // nTRST
|
||||
#define DAP_SWJ_nRESET 7 // nRESET
|
||||
|
||||
// DAP Transfer Request
|
||||
#define DAP_TRANSFER_APnDP (1U<<0)
|
||||
#define DAP_TRANSFER_RnW (1U<<1)
|
||||
#define DAP_TRANSFER_A2 (1U<<2)
|
||||
#define DAP_TRANSFER_A3 (1U<<3)
|
||||
#define DAP_TRANSFER_MATCH_VALUE (1U<<4)
|
||||
#define DAP_TRANSFER_MATCH_MASK (1U<<5)
|
||||
#define DAP_TRANSFER_TIMESTAMP (1U<<7)
|
||||
|
||||
// DAP Transfer Response
|
||||
#define DAP_TRANSFER_OK (1U<<0)
|
||||
#define DAP_TRANSFER_WAIT (1U<<1)
|
||||
#define DAP_TRANSFER_FAULT (1U<<2)
|
||||
#define DAP_TRANSFER_ERROR (1U<<3)
|
||||
#define DAP_TRANSFER_MISMATCH (1U<<4)
|
||||
|
||||
// DAP SWO Trace Mode
|
||||
#define DAP_SWO_OFF 0U
|
||||
#define DAP_SWO_UART 1U
|
||||
#define DAP_SWO_MANCHESTER 2U
|
||||
|
||||
// DAP SWO Trace Status
|
||||
#define DAP_SWO_CAPTURE_ACTIVE (1U<<0)
|
||||
#define DAP_SWO_CAPTURE_PAUSED (1U<<1)
|
||||
#define DAP_SWO_STREAM_ERROR (1U<<6)
|
||||
#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
|
||||
#define DP_IDCODE 0x00U // IDCODE Register (SW Read only)
|
||||
#define DP_ABORT 0x00U // Abort Register (SW Write only)
|
||||
#define DP_CTRL_STAT 0x04U // Control & Status
|
||||
#define DP_WCR 0x04U // Wire Control Register (SW Only)
|
||||
#define DP_SELECT 0x08U // Select Register (JTAG R/W & SW W)
|
||||
#define DP_RESEND 0x08U // Resend (SW Read Only)
|
||||
#define DP_RDBUFF 0x0CU // Read Buffer (Read Only)
|
||||
|
||||
// JTAG IR Codes
|
||||
#define JTAG_ABORT 0x08U
|
||||
#define JTAG_DPACC 0x0AU
|
||||
#define JTAG_APACC 0x0BU
|
||||
#define JTAG_IDCODE 0x0EU
|
||||
#define JTAG_BYPASS 0x0FU
|
||||
|
||||
// JTAG Sequence Info
|
||||
#define JTAG_SEQUENCE_TCK 0x3FU // TCK count
|
||||
#define JTAG_SEQUENCE_TMS 0x40U // TMS value
|
||||
#define JTAG_SEQUENCE_TDO 0x80U // TDO capture
|
||||
|
||||
// SWD Sequence Info
|
||||
#define SWD_SEQUENCE_CLK 0x3FU // SWCLK count
|
||||
#define SWD_SEQUENCE_DIN 0x80U // SWDIO capture
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "cmsis_compiler.h"
|
||||
|
||||
// DAP Data structure
|
||||
typedef struct {
|
||||
uint8_t debug_port; // Debug Port
|
||||
uint8_t fast_clock; // Fast Clock Flag
|
||||
uint8_t padding[2];
|
||||
uint32_t clock_delay; // Clock Delay
|
||||
uint32_t timestamp; // Last captured Timestamp
|
||||
struct { // Transfer Configuration
|
||||
uint8_t idle_cycles; // Idle cycles after transfer
|
||||
uint8_t padding[3];
|
||||
uint16_t retry_count; // Number of retries after WAIT response
|
||||
uint16_t match_retry; // Number of retries if read value does not match
|
||||
uint32_t match_mask; // Match Mask
|
||||
} transfer;
|
||||
#if (DAP_SWD != 0)
|
||||
struct { // SWD Configuration
|
||||
uint8_t turnaround; // Turnaround period
|
||||
uint8_t data_phase; // Always generate Data Phase
|
||||
} swd_conf;
|
||||
#endif
|
||||
#if (DAP_JTAG != 0)
|
||||
struct { // JTAG Device Chain
|
||||
uint8_t count; // Number of devices
|
||||
uint8_t index; // Device index (device at TDO has index 0)
|
||||
#if (DAP_JTAG_DEV_CNT != 0)
|
||||
uint8_t ir_length[DAP_JTAG_DEV_CNT]; // IR Length in bits
|
||||
uint16_t ir_before[DAP_JTAG_DEV_CNT]; // Bits before IR
|
||||
uint16_t ir_after [DAP_JTAG_DEV_CNT]; // Bits after IR
|
||||
#endif
|
||||
} jtag_dev;
|
||||
#endif
|
||||
} DAP_Data_t;
|
||||
|
||||
extern DAP_Data_t DAP_Data; // DAP Data
|
||||
extern volatile uint8_t DAP_TransferAbort; // Transfer Abort Flag
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
// Functions
|
||||
extern void SWJ_Sequence (uint32_t count, const uint8_t *data);
|
||||
extern void SWD_Sequence (uint32_t info, const uint8_t *swdo, uint8_t *swdi);
|
||||
extern void JTAG_Sequence (uint32_t info, const uint8_t *tdi, uint8_t *tdo);
|
||||
extern void JTAG_IR (uint32_t ir);
|
||||
extern uint32_t JTAG_ReadIDCode (void);
|
||||
extern void JTAG_WriteAbort (uint32_t data);
|
||||
extern uint8_t JTAG_Transfer (uint32_t request, uint32_t *data);
|
||||
extern uint8_t SWD_Transfer (uint32_t request, uint32_t *data);
|
||||
|
||||
extern void Delayms (uint32_t delay);
|
||||
|
||||
extern uint32_t SWO_Transport (const uint8_t *request, uint8_t *response);
|
||||
extern uint32_t SWO_Mode (const uint8_t *request, uint8_t *response);
|
||||
extern uint32_t SWO_Baudrate (const uint8_t *request, uint8_t *response);
|
||||
extern uint32_t SWO_Control (const uint8_t *request, uint8_t *response);
|
||||
extern uint32_t SWO_Status (uint8_t *response);
|
||||
extern uint32_t SWO_ExtendedStatus (const uint8_t *request, uint8_t *response);
|
||||
extern uint32_t SWO_Data (const uint8_t *request, uint8_t *response);
|
||||
|
||||
extern void SWO_QueueTransfer (uint8_t *buf, uint32_t num);
|
||||
extern void SWO_AbortTransfer (void);
|
||||
extern void SWO_TransferComplete (void);
|
||||
|
||||
extern uint32_t SWO_Mode_UART (uint32_t enable);
|
||||
extern uint32_t SWO_Baudrate_UART (uint32_t baudrate);
|
||||
extern uint32_t SWO_Control_UART (uint32_t active);
|
||||
extern void SWO_Capture_UART (uint8_t *buf, uint32_t num);
|
||||
extern uint32_t SWO_GetCount_UART (void);
|
||||
|
||||
extern uint32_t SWO_Mode_Manchester (uint32_t enable);
|
||||
extern uint32_t SWO_Baudrate_Manchester (uint32_t baudrate);
|
||||
extern uint32_t SWO_Control_Manchester (uint32_t active);
|
||||
extern void SWO_Capture_Manchester (uint8_t *buf, uint32_t num);
|
||||
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_ProcessCommand (const uint8_t *request, uint8_t *response);
|
||||
extern uint32_t DAP_ExecuteCommand (const uint8_t *request, uint8_t *response);
|
||||
|
||||
extern void DAP_Setup (void);
|
||||
|
||||
// Configurable delay for clock generation
|
||||
#ifndef DELAY_SLOW_CYCLES
|
||||
#define DELAY_SLOW_CYCLES 3U // Number of cycles for one iteration
|
||||
#endif
|
||||
#if defined(__CC_ARM)
|
||||
__STATIC_FORCEINLINE void PIN_DELAY_SLOW (uint32_t delay) {
|
||||
uint32_t count = delay;
|
||||
while (--count);
|
||||
}
|
||||
#else
|
||||
__STATIC_FORCEINLINE void PIN_DELAY_SLOW (uint32_t delay) {
|
||||
__ASM volatile (
|
||||
".syntax unified\n"
|
||||
"0:\n\t"
|
||||
"subs %0,%0,#1\n\t"
|
||||
"bne 0b\n"
|
||||
: "+l" (delay) : : "cc"
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Fixed delay for fast clock generation
|
||||
#ifndef DELAY_FAST_CYCLES
|
||||
#define DELAY_FAST_CYCLES 0U // Number of cycles: 0..3
|
||||
#endif
|
||||
__STATIC_FORCEINLINE void PIN_DELAY_FAST (void) {
|
||||
#if (DELAY_FAST_CYCLES >= 1U)
|
||||
__NOP();
|
||||
#endif
|
||||
#if (DELAY_FAST_CYCLES >= 2U)
|
||||
__NOP();
|
||||
#endif
|
||||
#if (DELAY_FAST_CYCLES >= 3U)
|
||||
__NOP();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __DAP_H__ */
|
1812
Drivers/CMSIS/DAP/Firmware/Source/DAP.c
Normal file
1812
Drivers/CMSIS/DAP/Firmware/Source/DAP.c
Normal file
File diff suppressed because it is too large
Load diff
100
Drivers/CMSIS/DAP/Firmware/Source/DAP_vendor.c
Normal file
100
Drivers/CMSIS/DAP/Firmware/Source/DAP_vendor.c
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* 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: 1. December 2017
|
||||
* $Revision: V2.0.0
|
||||
*
|
||||
* Project: CMSIS-DAP Source
|
||||
* Title: DAP_vendor.c CMSIS-DAP Vendor Commands
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "DAP_config.h"
|
||||
#include "DAP.h"
|
||||
|
||||
//**************************************************************************************************
|
||||
/**
|
||||
\defgroup DAP_Vendor_Adapt_gr Adapt Vendor Commands
|
||||
\ingroup DAP_Vendor_gr
|
||||
@{
|
||||
|
||||
The file DAP_vendor.c provides template source code for extension of a Debug Unit with
|
||||
Vendor Commands. Copy this file to the project folder of the Debug Unit and add the
|
||||
file to the MDK-ARM project under the file group Configuration.
|
||||
*/
|
||||
|
||||
/** Process DAP Vendor Command and prepare Response Data
|
||||
\param request pointer to request data
|
||||
\param response pointer to response data
|
||||
\return number of bytes in response (lower 16 bits)
|
||||
number of bytes in request (upper 16 bits)
|
||||
*/
|
||||
uint32_t DAP_ProcessVendorCommand(const uint8_t *request, uint8_t *response) {
|
||||
uint32_t num = (1U << 16) | 1U;
|
||||
|
||||
*response++ = *request; // copy Command ID
|
||||
|
||||
switch (*request++) { // first byte in request is Command ID
|
||||
case ID_DAP_Vendor0:
|
||||
#if 0 // example user command
|
||||
num += 1U << 16; // increment request count
|
||||
if (*request == 1U) { // when first command data byte is 1
|
||||
*response++ = 'X'; // send 'X' as response
|
||||
num++; // increment response count
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case ID_DAP_Vendor1: break;
|
||||
case ID_DAP_Vendor2: break;
|
||||
case ID_DAP_Vendor3: break;
|
||||
case ID_DAP_Vendor4: break;
|
||||
case ID_DAP_Vendor5: break;
|
||||
case ID_DAP_Vendor6: break;
|
||||
case ID_DAP_Vendor7: break;
|
||||
case ID_DAP_Vendor8: break;
|
||||
case ID_DAP_Vendor9: break;
|
||||
case ID_DAP_Vendor10: break;
|
||||
case ID_DAP_Vendor11: break;
|
||||
case ID_DAP_Vendor12: break;
|
||||
case ID_DAP_Vendor13: break;
|
||||
case ID_DAP_Vendor14: break;
|
||||
case ID_DAP_Vendor15: break;
|
||||
case ID_DAP_Vendor16: break;
|
||||
case ID_DAP_Vendor17: break;
|
||||
case ID_DAP_Vendor18: break;
|
||||
case ID_DAP_Vendor19: break;
|
||||
case ID_DAP_Vendor20: break;
|
||||
case ID_DAP_Vendor21: break;
|
||||
case ID_DAP_Vendor22: break;
|
||||
case ID_DAP_Vendor23: break;
|
||||
case ID_DAP_Vendor24: break;
|
||||
case ID_DAP_Vendor25: break;
|
||||
case ID_DAP_Vendor26: break;
|
||||
case ID_DAP_Vendor27: break;
|
||||
case ID_DAP_Vendor28: break;
|
||||
case ID_DAP_Vendor29: break;
|
||||
case ID_DAP_Vendor30: break;
|
||||
case ID_DAP_Vendor31: break;
|
||||
}
|
||||
|
||||
return (num);
|
||||
}
|
||||
|
||||
///@}
|
370
Drivers/CMSIS/DAP/Firmware/Source/JTAG_DP.c
Normal file
370
Drivers/CMSIS/DAP/Firmware/Source/JTAG_DP.c
Normal file
|
@ -0,0 +1,370 @@
|
|||
/*
|
||||
* 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: 1. December 2017
|
||||
* $Revision: V2.0.0
|
||||
*
|
||||
* Project: CMSIS-DAP Source
|
||||
* Title: JTAG_DP.c CMSIS-DAP JTAG DP I/O
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "DAP_config.h"
|
||||
#include "DAP.h"
|
||||
|
||||
|
||||
// JTAG Macros
|
||||
|
||||
#define PIN_TCK_SET PIN_SWCLK_TCK_SET
|
||||
#define PIN_TCK_CLR PIN_SWCLK_TCK_CLR
|
||||
#define PIN_TMS_SET PIN_SWDIO_TMS_SET
|
||||
#define PIN_TMS_CLR PIN_SWDIO_TMS_CLR
|
||||
|
||||
#define JTAG_CYCLE_TCK() \
|
||||
PIN_TCK_CLR(); \
|
||||
PIN_DELAY(); \
|
||||
PIN_TCK_SET(); \
|
||||
PIN_DELAY()
|
||||
|
||||
#define JTAG_CYCLE_TDI(tdi) \
|
||||
PIN_TDI_OUT(tdi); \
|
||||
PIN_TCK_CLR(); \
|
||||
PIN_DELAY(); \
|
||||
PIN_TCK_SET(); \
|
||||
PIN_DELAY()
|
||||
|
||||
#define JTAG_CYCLE_TDO(tdo) \
|
||||
PIN_TCK_CLR(); \
|
||||
PIN_DELAY(); \
|
||||
tdo = PIN_TDO_IN(); \
|
||||
PIN_TCK_SET(); \
|
||||
PIN_DELAY()
|
||||
|
||||
#define JTAG_CYCLE_TDIO(tdi,tdo) \
|
||||
PIN_TDI_OUT(tdi); \
|
||||
PIN_TCK_CLR(); \
|
||||
PIN_DELAY(); \
|
||||
tdo = PIN_TDO_IN(); \
|
||||
PIN_TCK_SET(); \
|
||||
PIN_DELAY()
|
||||
|
||||
#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
|
||||
|
||||
|
||||
#if (DAP_JTAG != 0)
|
||||
|
||||
|
||||
// Generate JTAG Sequence
|
||||
// info: sequence information
|
||||
// tdi: pointer to TDI generated data
|
||||
// tdo: pointer to TDO captured data
|
||||
// return: none
|
||||
void JTAG_Sequence (uint32_t info, const uint8_t *tdi, uint8_t *tdo) {
|
||||
uint32_t i_val;
|
||||
uint32_t o_val;
|
||||
uint32_t bit;
|
||||
uint32_t n, k;
|
||||
|
||||
n = info & JTAG_SEQUENCE_TCK;
|
||||
if (n == 0U) {
|
||||
n = 64U;
|
||||
}
|
||||
|
||||
if (info & JTAG_SEQUENCE_TMS) {
|
||||
PIN_TMS_SET();
|
||||
} else {
|
||||
PIN_TMS_CLR();
|
||||
}
|
||||
|
||||
while (n) {
|
||||
i_val = *tdi++;
|
||||
o_val = 0U;
|
||||
for (k = 8U; k && n; k--, n--) {
|
||||
JTAG_CYCLE_TDIO(i_val, bit);
|
||||
i_val >>= 1;
|
||||
o_val >>= 1;
|
||||
o_val |= bit << 7;
|
||||
}
|
||||
o_val >>= k;
|
||||
if (info & JTAG_SEQUENCE_TDO) {
|
||||
*tdo++ = (uint8_t)o_val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// JTAG Set IR
|
||||
// ir: IR value
|
||||
// return: none
|
||||
#define JTAG_IR_Function(speed) /**/ \
|
||||
static void JTAG_IR_##speed (uint32_t ir) { \
|
||||
uint32_t n; \
|
||||
\
|
||||
PIN_TMS_SET(); \
|
||||
JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \
|
||||
JTAG_CYCLE_TCK(); /* Select-IR-Scan */ \
|
||||
PIN_TMS_CLR(); \
|
||||
JTAG_CYCLE_TCK(); /* Capture-IR */ \
|
||||
JTAG_CYCLE_TCK(); /* Shift-IR */ \
|
||||
\
|
||||
PIN_TDI_OUT(1U); \
|
||||
for (n = DAP_Data.jtag_dev.ir_before[DAP_Data.jtag_dev.index]; n; n--) { \
|
||||
JTAG_CYCLE_TCK(); /* Bypass before data */ \
|
||||
} \
|
||||
for (n = DAP_Data.jtag_dev.ir_length[DAP_Data.jtag_dev.index] - 1U; n; n--) { \
|
||||
JTAG_CYCLE_TDI(ir); /* Set IR bits (except last) */ \
|
||||
ir >>= 1; \
|
||||
} \
|
||||
n = DAP_Data.jtag_dev.ir_after[DAP_Data.jtag_dev.index]; \
|
||||
if (n) { \
|
||||
JTAG_CYCLE_TDI(ir); /* Set last IR bit */ \
|
||||
PIN_TDI_OUT(1U); \
|
||||
for (--n; n; n--) { \
|
||||
JTAG_CYCLE_TCK(); /* Bypass after data */ \
|
||||
} \
|
||||
PIN_TMS_SET(); \
|
||||
JTAG_CYCLE_TCK(); /* Bypass & Exit1-IR */ \
|
||||
} else { \
|
||||
PIN_TMS_SET(); \
|
||||
JTAG_CYCLE_TDI(ir); /* Set last IR bit & Exit1-IR */ \
|
||||
} \
|
||||
\
|
||||
JTAG_CYCLE_TCK(); /* Update-IR */ \
|
||||
PIN_TMS_CLR(); \
|
||||
JTAG_CYCLE_TCK(); /* Idle */ \
|
||||
PIN_TDI_OUT(1U); \
|
||||
}
|
||||
|
||||
|
||||
// JTAG Transfer I/O
|
||||
// request: A[3:2] RnW APnDP
|
||||
// data: DATA[31:0]
|
||||
// return: ACK[2:0]
|
||||
#define JTAG_TransferFunction(speed) /**/ \
|
||||
static uint8_t JTAG_Transfer##speed (uint32_t request, uint32_t *data) { \
|
||||
uint32_t ack; \
|
||||
uint32_t bit; \
|
||||
uint32_t val; \
|
||||
uint32_t n; \
|
||||
\
|
||||
PIN_TMS_SET(); \
|
||||
JTAG_CYCLE_TCK(); /* Select-DR-Scan */ \
|
||||
PIN_TMS_CLR(); \
|
||||
JTAG_CYCLE_TCK(); /* Capture-DR */ \
|
||||
JTAG_CYCLE_TCK(); /* Shift-DR */ \
|
||||
\
|
||||
for (n = DAP_Data.jtag_dev.index; n; n--) { \
|
||||
JTAG_CYCLE_TCK(); /* Bypass before data */ \
|
||||
} \
|
||||
\
|
||||
JTAG_CYCLE_TDIO(request >> 1, bit); /* Set RnW, Get ACK.0 */ \
|
||||
ack = bit << 1; \
|
||||
JTAG_CYCLE_TDIO(request >> 2, bit); /* Set A2, Get ACK.1 */ \
|
||||
ack |= bit << 0; \
|
||||
JTAG_CYCLE_TDIO(request >> 3, bit); /* Set A3, Get ACK.2 */ \
|
||||
ack |= bit << 2; \
|
||||
\
|
||||
if (ack != DAP_TRANSFER_OK) { \
|
||||
/* Exit on error */ \
|
||||
PIN_TMS_SET(); \
|
||||
JTAG_CYCLE_TCK(); /* Exit1-DR */ \
|
||||
goto exit; \
|
||||
} \
|
||||
\
|
||||
if (request & DAP_TRANSFER_RnW) { \
|
||||
/* Read Transfer */ \
|
||||
val = 0U; \
|
||||
for (n = 31U; n; n--) { \
|
||||
JTAG_CYCLE_TDO(bit); /* Get D0..D30 */ \
|
||||
val |= bit << 31; \
|
||||
val >>= 1; \
|
||||
} \
|
||||
n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U; \
|
||||
if (n) { \
|
||||
JTAG_CYCLE_TDO(bit); /* Get D31 */ \
|
||||
for (--n; n; n--) { \
|
||||
JTAG_CYCLE_TCK(); /* Bypass after data */ \
|
||||
} \
|
||||
PIN_TMS_SET(); \
|
||||
JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \
|
||||
} else { \
|
||||
PIN_TMS_SET(); \
|
||||
JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */ \
|
||||
} \
|
||||
val |= bit << 31; \
|
||||
if (data) { *data = val; } \
|
||||
} else { \
|
||||
/* Write Transfer */ \
|
||||
val = *data; \
|
||||
for (n = 31U; n; n--) { \
|
||||
JTAG_CYCLE_TDI(val); /* Set D0..D30 */ \
|
||||
val >>= 1; \
|
||||
} \
|
||||
n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U; \
|
||||
if (n) { \
|
||||
JTAG_CYCLE_TDI(val); /* Set D31 */ \
|
||||
for (--n; n; n--) { \
|
||||
JTAG_CYCLE_TCK(); /* Bypass after data */ \
|
||||
} \
|
||||
PIN_TMS_SET(); \
|
||||
JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */ \
|
||||
} else { \
|
||||
PIN_TMS_SET(); \
|
||||
JTAG_CYCLE_TDI(val); /* Set D31 & Exit1-DR */ \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
exit: \
|
||||
JTAG_CYCLE_TCK(); /* Update-DR */ \
|
||||
PIN_TMS_CLR(); \
|
||||
JTAG_CYCLE_TCK(); /* Idle */ \
|
||||
PIN_TDI_OUT(1U); \
|
||||
\
|
||||
/* Capture Timestamp */ \
|
||||
if (request & DAP_TRANSFER_TIMESTAMP) { \
|
||||
DAP_Data.timestamp = TIMESTAMP_GET(); \
|
||||
} \
|
||||
\
|
||||
/* Idle cycles */ \
|
||||
n = DAP_Data.transfer.idle_cycles; \
|
||||
while (n--) { \
|
||||
JTAG_CYCLE_TCK(); /* Idle */ \
|
||||
} \
|
||||
\
|
||||
return ((uint8_t)ack); \
|
||||
}
|
||||
|
||||
|
||||
#undef PIN_DELAY
|
||||
#define PIN_DELAY() PIN_DELAY_FAST()
|
||||
JTAG_IR_Function(Fast)
|
||||
JTAG_TransferFunction(Fast)
|
||||
|
||||
#undef PIN_DELAY
|
||||
#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
|
||||
JTAG_IR_Function(Slow)
|
||||
JTAG_TransferFunction(Slow)
|
||||
|
||||
|
||||
// JTAG Read IDCODE register
|
||||
// return: value read
|
||||
uint32_t JTAG_ReadIDCode (void) {
|
||||
uint32_t bit;
|
||||
uint32_t val;
|
||||
uint32_t n;
|
||||
|
||||
PIN_TMS_SET();
|
||||
JTAG_CYCLE_TCK(); /* Select-DR-Scan */
|
||||
PIN_TMS_CLR();
|
||||
JTAG_CYCLE_TCK(); /* Capture-DR */
|
||||
JTAG_CYCLE_TCK(); /* Shift-DR */
|
||||
|
||||
for (n = DAP_Data.jtag_dev.index; n; n--) {
|
||||
JTAG_CYCLE_TCK(); /* Bypass before data */
|
||||
}
|
||||
|
||||
val = 0U;
|
||||
for (n = 31U; n; n--) {
|
||||
JTAG_CYCLE_TDO(bit); /* Get D0..D30 */
|
||||
val |= bit << 31;
|
||||
val >>= 1;
|
||||
}
|
||||
PIN_TMS_SET();
|
||||
JTAG_CYCLE_TDO(bit); /* Get D31 & Exit1-DR */
|
||||
val |= bit << 31;
|
||||
|
||||
JTAG_CYCLE_TCK(); /* Update-DR */
|
||||
PIN_TMS_CLR();
|
||||
JTAG_CYCLE_TCK(); /* Idle */
|
||||
|
||||
return (val);
|
||||
}
|
||||
|
||||
|
||||
// JTAG Write ABORT register
|
||||
// data: value to write
|
||||
// return: none
|
||||
void JTAG_WriteAbort (uint32_t data) {
|
||||
uint32_t n;
|
||||
|
||||
PIN_TMS_SET();
|
||||
JTAG_CYCLE_TCK(); /* Select-DR-Scan */
|
||||
PIN_TMS_CLR();
|
||||
JTAG_CYCLE_TCK(); /* Capture-DR */
|
||||
JTAG_CYCLE_TCK(); /* Shift-DR */
|
||||
|
||||
for (n = DAP_Data.jtag_dev.index; n; n--) {
|
||||
JTAG_CYCLE_TCK(); /* Bypass before data */
|
||||
}
|
||||
|
||||
PIN_TDI_OUT(0U);
|
||||
JTAG_CYCLE_TCK(); /* Set RnW=0 (Write) */
|
||||
JTAG_CYCLE_TCK(); /* Set A2=0 */
|
||||
JTAG_CYCLE_TCK(); /* Set A3=0 */
|
||||
|
||||
for (n = 31U; n; n--) {
|
||||
JTAG_CYCLE_TDI(data); /* Set D0..D30 */
|
||||
data >>= 1;
|
||||
}
|
||||
n = DAP_Data.jtag_dev.count - DAP_Data.jtag_dev.index - 1U;
|
||||
if (n) {
|
||||
JTAG_CYCLE_TDI(data); /* Set D31 */
|
||||
for (--n; n; n--) {
|
||||
JTAG_CYCLE_TCK(); /* Bypass after data */
|
||||
}
|
||||
PIN_TMS_SET();
|
||||
JTAG_CYCLE_TCK(); /* Bypass & Exit1-DR */
|
||||
} else {
|
||||
PIN_TMS_SET();
|
||||
JTAG_CYCLE_TDI(data); /* Set D31 & Exit1-DR */
|
||||
}
|
||||
|
||||
JTAG_CYCLE_TCK(); /* Update-DR */
|
||||
PIN_TMS_CLR();
|
||||
JTAG_CYCLE_TCK(); /* Idle */
|
||||
PIN_TDI_OUT(1U);
|
||||
}
|
||||
|
||||
|
||||
// JTAG Set IR
|
||||
// ir: IR value
|
||||
// return: none
|
||||
void JTAG_IR (uint32_t ir) {
|
||||
if (DAP_Data.fast_clock) {
|
||||
JTAG_IR_Fast(ir);
|
||||
} else {
|
||||
JTAG_IR_Slow(ir);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// JTAG Transfer I/O
|
||||
// request: A[3:2] RnW APnDP
|
||||
// data: DATA[31:0]
|
||||
// return: ACK[2:0]
|
||||
uint8_t JTAG_Transfer(uint32_t request, uint32_t *data) {
|
||||
if (DAP_Data.fast_clock) {
|
||||
return JTAG_TransferFast(request, data);
|
||||
} else {
|
||||
return JTAG_TransferSlow(request, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* (DAP_JTAG != 0) */
|
798
Drivers/CMSIS/DAP/Firmware/Source/SWO.c
Normal file
798
Drivers/CMSIS/DAP/Firmware/Source/SWO.c
Normal file
|
@ -0,0 +1,798 @@
|
|||
/*
|
||||
* 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: 29. March 2021
|
||||
* $Revision: V2.0.1
|
||||
*
|
||||
* Project: CMSIS-DAP Source
|
||||
* Title: SWO.c CMSIS-DAP SWO I/O
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "DAP_config.h"
|
||||
#include "DAP.h"
|
||||
#if (SWO_UART != 0)
|
||||
#include "Driver_USART.h"
|
||||
#endif
|
||||
#if (SWO_STREAM != 0)
|
||||
#include "cmsis_os2.h"
|
||||
#define osObjectsExternal
|
||||
#include "osObjects.h"
|
||||
#endif
|
||||
|
||||
#if (SWO_STREAM != 0)
|
||||
#ifdef DAP_FW_V1
|
||||
#error "SWO Streaming Trace not supported in DAP V1!"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (SWO_UART != 0)
|
||||
|
||||
// USART Driver
|
||||
#define _USART_Driver_(n) Driver_USART##n
|
||||
#define USART_Driver_(n) _USART_Driver_(n)
|
||||
extern ARM_DRIVER_USART USART_Driver_(SWO_UART_DRIVER);
|
||||
#define pUSART (&USART_Driver_(SWO_UART_DRIVER))
|
||||
|
||||
static uint8_t USART_Ready = 0U;
|
||||
|
||||
#endif /* (SWO_UART != 0) */
|
||||
|
||||
|
||||
#if ((SWO_UART != 0) || (SWO_MANCHESTER != 0))
|
||||
|
||||
|
||||
#define SWO_STREAM_TIMEOUT 50U /* Stream timeout in ms */
|
||||
|
||||
#define USB_BLOCK_SIZE 512U /* USB Block Size */
|
||||
#define TRACE_BLOCK_SIZE 64U /* Trace Block Size (2^n: 32...512) */
|
||||
|
||||
// Trace State
|
||||
static uint8_t TraceTransport = 0U; /* Trace Transport */
|
||||
static uint8_t TraceMode = 0U; /* Trace Mode */
|
||||
static uint8_t TraceStatus = 0U; /* Trace Status without Errors */
|
||||
static uint8_t TraceError[2] = {0U, 0U}; /* Trace Error flags (banked) */
|
||||
static uint8_t TraceError_n = 0U; /* Active Trace Error bank */
|
||||
|
||||
// Trace Buffer
|
||||
static uint8_t TraceBuf[SWO_BUFFER_SIZE]; /* Trace Buffer (must be 2^n) */
|
||||
static volatile uint32_t TraceIndexI = 0U; /* Incoming Trace Index */
|
||||
static volatile uint32_t TraceIndexO = 0U; /* Outgoing Trace Index */
|
||||
static volatile uint8_t TraceUpdate; /* Trace Update Flag */
|
||||
static uint32_t TraceBlockSize; /* Current Trace Block Size */
|
||||
|
||||
#if (TIMESTAMP_CLOCK != 0U)
|
||||
// Trace Timestamp
|
||||
static volatile struct {
|
||||
uint32_t index;
|
||||
uint32_t tick;
|
||||
} TraceTimestamp;
|
||||
#endif
|
||||
|
||||
// Trace Helper functions
|
||||
static void ClearTrace (void);
|
||||
static void ResumeTrace (void);
|
||||
static uint32_t GetTraceCount (void);
|
||||
static uint8_t GetTraceStatus (void);
|
||||
static void SetTraceError (uint8_t flag);
|
||||
|
||||
#if (SWO_STREAM != 0)
|
||||
extern osThreadId_t SWO_ThreadId;
|
||||
static volatile uint8_t TransferBusy = 0U; /* Transfer Busy Flag */
|
||||
static uint32_t TransferSize; /* Current Transfer Size */
|
||||
#endif
|
||||
|
||||
|
||||
#if (SWO_UART != 0)
|
||||
|
||||
// USART Driver Callback function
|
||||
// event: event mask
|
||||
static void USART_Callback (uint32_t event) {
|
||||
uint32_t index_i;
|
||||
uint32_t index_o;
|
||||
uint32_t count;
|
||||
uint32_t num;
|
||||
|
||||
if (event & ARM_USART_EVENT_RECEIVE_COMPLETE) {
|
||||
#if (TIMESTAMP_CLOCK != 0U)
|
||||
TraceTimestamp.tick = TIMESTAMP_GET();
|
||||
#endif
|
||||
index_o = TraceIndexO;
|
||||
index_i = TraceIndexI;
|
||||
index_i += TraceBlockSize;
|
||||
TraceIndexI = index_i;
|
||||
#if (TIMESTAMP_CLOCK != 0U)
|
||||
TraceTimestamp.index = index_i;
|
||||
#endif
|
||||
num = TRACE_BLOCK_SIZE - (index_i & (TRACE_BLOCK_SIZE - 1U));
|
||||
count = index_i - index_o;
|
||||
if (count <= (SWO_BUFFER_SIZE - num)) {
|
||||
index_i &= SWO_BUFFER_SIZE - 1U;
|
||||
TraceBlockSize = num;
|
||||
pUSART->Receive(&TraceBuf[index_i], num);
|
||||
} else {
|
||||
TraceStatus = DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED;
|
||||
}
|
||||
TraceUpdate = 1U;
|
||||
#if (SWO_STREAM != 0)
|
||||
if (TraceTransport == 2U) {
|
||||
if (count >= (USB_BLOCK_SIZE - (index_o & (USB_BLOCK_SIZE - 1U)))) {
|
||||
osThreadFlagsSet(SWO_ThreadId, 1U);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (event & ARM_USART_EVENT_RX_OVERFLOW) {
|
||||
SetTraceError(DAP_SWO_BUFFER_OVERRUN);
|
||||
}
|
||||
if (event & (ARM_USART_EVENT_RX_BREAK |
|
||||
ARM_USART_EVENT_RX_FRAMING_ERROR |
|
||||
ARM_USART_EVENT_RX_PARITY_ERROR)) {
|
||||
SetTraceError(DAP_SWO_STREAM_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
// Enable or disable SWO Mode (UART)
|
||||
// enable: enable flag
|
||||
// return: 1 - Success, 0 - Error
|
||||
__WEAK uint32_t SWO_Mode_UART (uint32_t enable) {
|
||||
int32_t status;
|
||||
|
||||
USART_Ready = 0U;
|
||||
|
||||
if (enable != 0U) {
|
||||
status = pUSART->Initialize(USART_Callback);
|
||||
if (status != ARM_DRIVER_OK) {
|
||||
return (0U);
|
||||
}
|
||||
status = pUSART->PowerControl(ARM_POWER_FULL);
|
||||
if (status != ARM_DRIVER_OK) {
|
||||
pUSART->Uninitialize();
|
||||
return (0U);
|
||||
}
|
||||
} else {
|
||||
pUSART->Control(ARM_USART_CONTROL_RX, 0U);
|
||||
pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
|
||||
pUSART->PowerControl(ARM_POWER_OFF);
|
||||
pUSART->Uninitialize();
|
||||
}
|
||||
return (1U);
|
||||
}
|
||||
|
||||
// Configure SWO Baudrate (UART)
|
||||
// baudrate: requested baudrate
|
||||
// return: actual baudrate or 0 when not configured
|
||||
__WEAK uint32_t SWO_Baudrate_UART (uint32_t baudrate) {
|
||||
int32_t status;
|
||||
uint32_t index;
|
||||
uint32_t num;
|
||||
|
||||
if (baudrate > SWO_UART_MAX_BAUDRATE) {
|
||||
baudrate = SWO_UART_MAX_BAUDRATE;
|
||||
}
|
||||
|
||||
if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
|
||||
pUSART->Control(ARM_USART_CONTROL_RX, 0U);
|
||||
if (pUSART->GetStatus().rx_busy) {
|
||||
TraceIndexI += pUSART->GetRxCount();
|
||||
pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
|
||||
}
|
||||
}
|
||||
|
||||
status = pUSART->Control(ARM_USART_MODE_ASYNCHRONOUS |
|
||||
ARM_USART_DATA_BITS_8 |
|
||||
ARM_USART_PARITY_NONE |
|
||||
ARM_USART_STOP_BITS_1,
|
||||
baudrate);
|
||||
|
||||
if (status == ARM_DRIVER_OK) {
|
||||
USART_Ready = 1U;
|
||||
} else {
|
||||
USART_Ready = 0U;
|
||||
return (0U);
|
||||
}
|
||||
|
||||
if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
|
||||
if ((TraceStatus & DAP_SWO_CAPTURE_PAUSED) == 0U) {
|
||||
index = TraceIndexI & (SWO_BUFFER_SIZE - 1U);
|
||||
num = TRACE_BLOCK_SIZE - (index & (TRACE_BLOCK_SIZE - 1U));
|
||||
TraceBlockSize = num;
|
||||
pUSART->Receive(&TraceBuf[index], num);
|
||||
}
|
||||
pUSART->Control(ARM_USART_CONTROL_RX, 1U);
|
||||
}
|
||||
|
||||
return (baudrate);
|
||||
}
|
||||
|
||||
// Control SWO Capture (UART)
|
||||
// active: active flag
|
||||
// return: 1 - Success, 0 - Error
|
||||
__WEAK uint32_t SWO_Control_UART (uint32_t active) {
|
||||
int32_t status;
|
||||
|
||||
if (active) {
|
||||
if (!USART_Ready) {
|
||||
return (0U);
|
||||
}
|
||||
TraceBlockSize = 1U;
|
||||
status = pUSART->Receive(&TraceBuf[0], 1U);
|
||||
if (status != ARM_DRIVER_OK) {
|
||||
return (0U);
|
||||
}
|
||||
status = pUSART->Control(ARM_USART_CONTROL_RX, 1U);
|
||||
if (status != ARM_DRIVER_OK) {
|
||||
return (0U);
|
||||
}
|
||||
} else {
|
||||
pUSART->Control(ARM_USART_CONTROL_RX, 0U);
|
||||
if (pUSART->GetStatus().rx_busy) {
|
||||
TraceIndexI += pUSART->GetRxCount();
|
||||
pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
|
||||
}
|
||||
}
|
||||
return (1U);
|
||||
}
|
||||
|
||||
// Start SWO Capture (UART)
|
||||
// buf: pointer to buffer for capturing
|
||||
// num: number of bytes to capture
|
||||
__WEAK void SWO_Capture_UART (uint8_t *buf, uint32_t num) {
|
||||
TraceBlockSize = num;
|
||||
pUSART->Receive(buf, num);
|
||||
}
|
||||
|
||||
// Get SWO Pending Trace Count (UART)
|
||||
// return: number of pending trace data bytes
|
||||
__WEAK uint32_t SWO_GetCount_UART (void) {
|
||||
uint32_t count;
|
||||
|
||||
if (pUSART->GetStatus().rx_busy) {
|
||||
count = pUSART->GetRxCount();
|
||||
} else {
|
||||
count = 0U;
|
||||
}
|
||||
return (count);
|
||||
}
|
||||
|
||||
#endif /* (SWO_UART != 0) */
|
||||
|
||||
|
||||
#if (SWO_MANCHESTER != 0)
|
||||
|
||||
// Enable or disable SWO Mode (Manchester)
|
||||
// enable: enable flag
|
||||
// return: 1 - Success, 0 - Error
|
||||
__WEAK uint32_t SWO_Mode_Manchester (uint32_t enable) {
|
||||
return (0U);
|
||||
}
|
||||
|
||||
// Configure SWO Baudrate (Manchester)
|
||||
// baudrate: requested baudrate
|
||||
// return: actual baudrate or 0 when not configured
|
||||
__WEAK uint32_t SWO_Baudrate_Manchester (uint32_t baudrate) {
|
||||
return (0U);
|
||||
}
|
||||
|
||||
// Control SWO Capture (Manchester)
|
||||
// active: active flag
|
||||
// return: 1 - Success, 0 - Error
|
||||
__WEAK uint32_t SWO_Control_Manchester (uint32_t active) {
|
||||
return (0U);
|
||||
}
|
||||
|
||||
// Start SWO Capture (Manchester)
|
||||
// buf: pointer to buffer for capturing
|
||||
// num: number of bytes to capture
|
||||
__WEAK void SWO_Capture_Manchester (uint8_t *buf, uint32_t num) {
|
||||
}
|
||||
|
||||
// Get SWO Pending Trace Count (Manchester)
|
||||
// return: number of pending trace data bytes
|
||||
__WEAK uint32_t SWO_GetCount_Manchester (void) {
|
||||
}
|
||||
|
||||
#endif /* (SWO_MANCHESTER != 0) */
|
||||
|
||||
|
||||
// Clear Trace Errors and Data
|
||||
static void ClearTrace (void) {
|
||||
|
||||
#if (SWO_STREAM != 0)
|
||||
if (TraceTransport == 2U) {
|
||||
if (TransferBusy != 0U) {
|
||||
SWO_AbortTransfer();
|
||||
TransferBusy = 0U;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TraceError[0] = 0U;
|
||||
TraceError[1] = 0U;
|
||||
TraceError_n = 0U;
|
||||
TraceIndexI = 0U;
|
||||
TraceIndexO = 0U;
|
||||
|
||||
#if (TIMESTAMP_CLOCK != 0U)
|
||||
TraceTimestamp.index = 0U;
|
||||
TraceTimestamp.tick = 0U;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Resume Trace Capture
|
||||
static void ResumeTrace (void) {
|
||||
uint32_t index_i;
|
||||
uint32_t index_o;
|
||||
|
||||
if (TraceStatus == (DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED)) {
|
||||
index_i = TraceIndexI;
|
||||
index_o = TraceIndexO;
|
||||
if ((index_i - index_o) < SWO_BUFFER_SIZE) {
|
||||
index_i &= SWO_BUFFER_SIZE - 1U;
|
||||
switch (TraceMode) {
|
||||
#if (SWO_UART != 0)
|
||||
case DAP_SWO_UART:
|
||||
TraceStatus = DAP_SWO_CAPTURE_ACTIVE;
|
||||
SWO_Capture_UART(&TraceBuf[index_i], 1U);
|
||||
break;
|
||||
#endif
|
||||
#if (SWO_MANCHESTER != 0)
|
||||
case DAP_SWO_MANCHESTER:
|
||||
TraceStatus = DAP_SWO_CAPTURE_ACTIVE;
|
||||
SWO_Capture_Manchester(&TraceBuf[index_i], 1U);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get Trace Count
|
||||
// return: number of available data bytes in trace buffer
|
||||
static uint32_t GetTraceCount (void) {
|
||||
uint32_t count;
|
||||
|
||||
if (TraceStatus == DAP_SWO_CAPTURE_ACTIVE) {
|
||||
do {
|
||||
TraceUpdate = 0U;
|
||||
count = TraceIndexI - TraceIndexO;
|
||||
switch (TraceMode) {
|
||||
#if (SWO_UART != 0)
|
||||
case DAP_SWO_UART:
|
||||
count += SWO_GetCount_UART();
|
||||
break;
|
||||
#endif
|
||||
#if (SWO_MANCHESTER != 0)
|
||||
case DAP_SWO_MANCHESTER:
|
||||
count += SWO_GetCount_Manchester();
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} while (TraceUpdate != 0U);
|
||||
} else {
|
||||
count = TraceIndexI - TraceIndexO;
|
||||
}
|
||||
|
||||
return (count);
|
||||
}
|
||||
|
||||
// Get Trace Status (clear Error flags)
|
||||
// return: Trace Status (Active flag and Error flags)
|
||||
static uint8_t GetTraceStatus (void) {
|
||||
uint8_t status;
|
||||
uint32_t n;
|
||||
|
||||
n = TraceError_n;
|
||||
TraceError_n ^= 1U;
|
||||
status = TraceStatus | TraceError[n];
|
||||
TraceError[n] = 0U;
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
// Set Trace Error flag(s)
|
||||
// flag: error flag(s) to set
|
||||
static void SetTraceError (uint8_t flag) {
|
||||
TraceError[TraceError_n] |= flag;
|
||||
}
|
||||
|
||||
|
||||
// Process SWO 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 SWO_Transport (const uint8_t *request, uint8_t *response) {
|
||||
uint8_t transport;
|
||||
uint32_t result;
|
||||
|
||||
if ((TraceStatus & DAP_SWO_CAPTURE_ACTIVE) == 0U) {
|
||||
transport = *request;
|
||||
switch (transport) {
|
||||
case 0U:
|
||||
case 1U:
|
||||
#if (SWO_STREAM != 0)
|
||||
case 2U:
|
||||
#endif
|
||||
TraceTransport = transport;
|
||||
result = 1U;
|
||||
break;
|
||||
default:
|
||||
result = 0U;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
result = 0U;
|
||||
}
|
||||
|
||||
if (result != 0U) {
|
||||
*response = DAP_OK;
|
||||
} else {
|
||||
*response = DAP_ERROR;
|
||||
}
|
||||
|
||||
return ((1U << 16) | 1U);
|
||||
}
|
||||
|
||||
|
||||
// Process SWO Mode 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 SWO_Mode (const uint8_t *request, uint8_t *response) {
|
||||
uint8_t mode;
|
||||
uint32_t result;
|
||||
|
||||
mode = *request;
|
||||
|
||||
switch (TraceMode) {
|
||||
#if (SWO_UART != 0)
|
||||
case DAP_SWO_UART:
|
||||
SWO_Mode_UART(0U);
|
||||
break;
|
||||
#endif
|
||||
#if (SWO_MANCHESTER != 0)
|
||||
case DAP_SWO_MANCHESTER:
|
||||
SWO_Mode_Manchester(0U);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case DAP_SWO_OFF:
|
||||
result = 1U;
|
||||
break;
|
||||
#if (SWO_UART != 0)
|
||||
case DAP_SWO_UART:
|
||||
result = SWO_Mode_UART(1U);
|
||||
break;
|
||||
#endif
|
||||
#if (SWO_MANCHESTER != 0)
|
||||
case DAP_SWO_MANCHESTER:
|
||||
result = SWO_Mode_Manchester(1U);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
result = 0U;
|
||||
break;
|
||||
}
|
||||
if (result != 0U) {
|
||||
TraceMode = mode;
|
||||
} else {
|
||||
TraceMode = DAP_SWO_OFF;
|
||||
}
|
||||
|
||||
TraceStatus = 0U;
|
||||
|
||||
if (result != 0U) {
|
||||
*response = DAP_OK;
|
||||
} else {
|
||||
*response = DAP_ERROR;
|
||||
}
|
||||
|
||||
return ((1U << 16) | 1U);
|
||||
}
|
||||
|
||||
|
||||
// Process SWO Baudrate 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 SWO_Baudrate (const uint8_t *request, uint8_t *response) {
|
||||
uint32_t baudrate;
|
||||
|
||||
baudrate = (uint32_t)(*(request+0) << 0) |
|
||||
(uint32_t)(*(request+1) << 8) |
|
||||
(uint32_t)(*(request+2) << 16) |
|
||||
(uint32_t)(*(request+3) << 24);
|
||||
|
||||
switch (TraceMode) {
|
||||
#if (SWO_UART != 0)
|
||||
case DAP_SWO_UART:
|
||||
baudrate = SWO_Baudrate_UART(baudrate);
|
||||
break;
|
||||
#endif
|
||||
#if (SWO_MANCHESTER != 0)
|
||||
case DAP_SWO_MANCHESTER:
|
||||
baudrate = SWO_Baudrate_Manchester(baudrate);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
baudrate = 0U;
|
||||
break;
|
||||
}
|
||||
|
||||
if (baudrate == 0U) {
|
||||
TraceStatus = 0U;
|
||||
}
|
||||
|
||||
*response++ = (uint8_t)(baudrate >> 0);
|
||||
*response++ = (uint8_t)(baudrate >> 8);
|
||||
*response++ = (uint8_t)(baudrate >> 16);
|
||||
*response = (uint8_t)(baudrate >> 24);
|
||||
|
||||
return ((4U << 16) | 4U);
|
||||
}
|
||||
|
||||
|
||||
// Process SWO 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 SWO_Control (const uint8_t *request, uint8_t *response) {
|
||||
uint8_t active;
|
||||
uint32_t result;
|
||||
|
||||
active = *request & DAP_SWO_CAPTURE_ACTIVE;
|
||||
|
||||
if (active != (TraceStatus & DAP_SWO_CAPTURE_ACTIVE)) {
|
||||
if (active) {
|
||||
ClearTrace();
|
||||
}
|
||||
switch (TraceMode) {
|
||||
#if (SWO_UART != 0)
|
||||
case DAP_SWO_UART:
|
||||
result = SWO_Control_UART(active);
|
||||
break;
|
||||
#endif
|
||||
#if (SWO_MANCHESTER != 0)
|
||||
case DAP_SWO_MANCHESTER:
|
||||
result = SWO_Control_Manchester(active);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
result = 0U;
|
||||
break;
|
||||
}
|
||||
if (result != 0U) {
|
||||
TraceStatus = active;
|
||||
#if (SWO_STREAM != 0)
|
||||
if (TraceTransport == 2U) {
|
||||
osThreadFlagsSet(SWO_ThreadId, 1U);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
result = 1U;
|
||||
}
|
||||
|
||||
if (result != 0U) {
|
||||
*response = DAP_OK;
|
||||
} else {
|
||||
*response = DAP_ERROR;
|
||||
}
|
||||
|
||||
return ((1U << 16) | 1U);
|
||||
}
|
||||
|
||||
|
||||
// Process SWO Status command and prepare response
|
||||
// response: pointer to response data
|
||||
// return: number of bytes in response
|
||||
uint32_t SWO_Status (uint8_t *response) {
|
||||
uint8_t status;
|
||||
uint32_t count;
|
||||
|
||||
status = GetTraceStatus();
|
||||
count = GetTraceCount();
|
||||
|
||||
*response++ = status;
|
||||
*response++ = (uint8_t)(count >> 0);
|
||||
*response++ = (uint8_t)(count >> 8);
|
||||
*response++ = (uint8_t)(count >> 16);
|
||||
*response = (uint8_t)(count >> 24);
|
||||
|
||||
return (5U);
|
||||
}
|
||||
|
||||
|
||||
// Process SWO Extended Status 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 SWO_ExtendedStatus (const uint8_t *request, uint8_t *response) {
|
||||
uint8_t cmd;
|
||||
uint8_t status;
|
||||
uint32_t count;
|
||||
#if (TIMESTAMP_CLOCK != 0U)
|
||||
uint32_t index;
|
||||
uint32_t tick;
|
||||
#endif
|
||||
uint32_t num;
|
||||
|
||||
num = 0U;
|
||||
cmd = *request;
|
||||
|
||||
if (cmd & 0x01U) {
|
||||
status = GetTraceStatus();
|
||||
*response++ = status;
|
||||
num += 1U;
|
||||
}
|
||||
|
||||
if (cmd & 0x02U) {
|
||||
count = GetTraceCount();
|
||||
*response++ = (uint8_t)(count >> 0);
|
||||
*response++ = (uint8_t)(count >> 8);
|
||||
*response++ = (uint8_t)(count >> 16);
|
||||
*response++ = (uint8_t)(count >> 24);
|
||||
num += 4U;
|
||||
}
|
||||
|
||||
#if (TIMESTAMP_CLOCK != 0U)
|
||||
if (cmd & 0x04U) {
|
||||
do {
|
||||
TraceUpdate = 0U;
|
||||
index = TraceTimestamp.index;
|
||||
tick = TraceTimestamp.tick;
|
||||
} while (TraceUpdate != 0U);
|
||||
*response++ = (uint8_t)(index >> 0);
|
||||
*response++ = (uint8_t)(index >> 8);
|
||||
*response++ = (uint8_t)(index >> 16);
|
||||
*response++ = (uint8_t)(index >> 24);
|
||||
*response++ = (uint8_t)(tick >> 0);
|
||||
*response++ = (uint8_t)(tick >> 8);
|
||||
*response++ = (uint8_t)(tick >> 16);
|
||||
*response++ = (uint8_t)(tick >> 24);
|
||||
num += 4U;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ((1U << 16) | num);
|
||||
}
|
||||
|
||||
|
||||
// Process SWO Data 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 SWO_Data (const uint8_t *request, uint8_t *response) {
|
||||
uint8_t status;
|
||||
uint32_t count;
|
||||
uint32_t index;
|
||||
uint32_t n, i;
|
||||
|
||||
status = GetTraceStatus();
|
||||
count = GetTraceCount();
|
||||
|
||||
if (TraceTransport == 1U) {
|
||||
n = (uint32_t)(*(request+0) << 0) |
|
||||
(uint32_t)(*(request+1) << 8);
|
||||
if (n > (DAP_PACKET_SIZE - 4U)) {
|
||||
n = DAP_PACKET_SIZE - 4U;
|
||||
}
|
||||
if (count > n) {
|
||||
count = n;
|
||||
}
|
||||
} else {
|
||||
count = 0U;
|
||||
}
|
||||
|
||||
*response++ = status;
|
||||
*response++ = (uint8_t)(count >> 0);
|
||||
*response++ = (uint8_t)(count >> 8);
|
||||
|
||||
if (TraceTransport == 1U) {
|
||||
index = TraceIndexO;
|
||||
for (i = index, n = count; n; n--) {
|
||||
i &= SWO_BUFFER_SIZE - 1U;
|
||||
*response++ = TraceBuf[i++];
|
||||
}
|
||||
TraceIndexO = index + count;
|
||||
ResumeTrace();
|
||||
}
|
||||
|
||||
return ((2U << 16) | (3U + count));
|
||||
}
|
||||
|
||||
|
||||
#if (SWO_STREAM != 0)
|
||||
|
||||
// SWO Data Transfer complete callback
|
||||
void SWO_TransferComplete (void) {
|
||||
TraceIndexO += TransferSize;
|
||||
TransferBusy = 0U;
|
||||
ResumeTrace();
|
||||
osThreadFlagsSet(SWO_ThreadId, 1U);
|
||||
}
|
||||
|
||||
// SWO Thread
|
||||
__NO_RETURN void SWO_Thread (void *argument) {
|
||||
uint32_t timeout;
|
||||
uint32_t flags;
|
||||
uint32_t count;
|
||||
uint32_t index;
|
||||
uint32_t i, n;
|
||||
(void) argument;
|
||||
|
||||
timeout = osWaitForever;
|
||||
|
||||
for (;;) {
|
||||
flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout);
|
||||
if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) {
|
||||
timeout = SWO_STREAM_TIMEOUT;
|
||||
} else {
|
||||
timeout = osWaitForever;
|
||||
flags = osFlagsErrorTimeout;
|
||||
}
|
||||
if (TransferBusy == 0U) {
|
||||
count = GetTraceCount();
|
||||
if (count != 0U) {
|
||||
index = TraceIndexO & (SWO_BUFFER_SIZE - 1U);
|
||||
n = SWO_BUFFER_SIZE - index;
|
||||
if (count > n) {
|
||||
count = n;
|
||||
}
|
||||
if (flags != osFlagsErrorTimeout) {
|
||||
i = index & (USB_BLOCK_SIZE - 1U);
|
||||
if (i == 0U) {
|
||||
count &= ~(USB_BLOCK_SIZE - 1U);
|
||||
} else {
|
||||
n = USB_BLOCK_SIZE - i;
|
||||
if (count >= n) {
|
||||
count = n;
|
||||
} else {
|
||||
count = 0U;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count != 0U) {
|
||||
TransferSize = count;
|
||||
TransferBusy = 1U;
|
||||
SWO_QueueTransfer(&TraceBuf[index], count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* (SWO_STREAM != 0) */
|
||||
|
||||
|
||||
#endif /* ((SWO_UART != 0) || (SWO_MANCHESTER != 0)) */
|
286
Drivers/CMSIS/DAP/Firmware/Source/SW_DP.c
Normal file
286
Drivers/CMSIS/DAP/Firmware/Source/SW_DP.c
Normal file
|
@ -0,0 +1,286 @@
|
|||
/*
|
||||
* 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: 1. December 2017
|
||||
* $Revision: V2.0.0
|
||||
*
|
||||
* Project: CMSIS-DAP Source
|
||||
* Title: SW_DP.c CMSIS-DAP SW DP I/O
|
||||
*
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "DAP_config.h"
|
||||
#include "DAP.h"
|
||||
|
||||
|
||||
// SW Macros
|
||||
|
||||
#define PIN_SWCLK_SET PIN_SWCLK_TCK_SET
|
||||
#define PIN_SWCLK_CLR PIN_SWCLK_TCK_CLR
|
||||
|
||||
#define SW_CLOCK_CYCLE() \
|
||||
PIN_SWCLK_CLR(); \
|
||||
PIN_DELAY(); \
|
||||
PIN_SWCLK_SET(); \
|
||||
PIN_DELAY()
|
||||
|
||||
#define SW_WRITE_BIT(bit) \
|
||||
PIN_SWDIO_OUT(bit); \
|
||||
PIN_SWCLK_CLR(); \
|
||||
PIN_DELAY(); \
|
||||
PIN_SWCLK_SET(); \
|
||||
PIN_DELAY()
|
||||
|
||||
#define SW_READ_BIT(bit) \
|
||||
PIN_SWCLK_CLR(); \
|
||||
PIN_DELAY(); \
|
||||
bit = PIN_SWDIO_IN(); \
|
||||
PIN_SWCLK_SET(); \
|
||||
PIN_DELAY()
|
||||
|
||||
#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
|
||||
|
||||
|
||||
// Generate SWJ Sequence
|
||||
// count: sequence bit count
|
||||
// data: pointer to sequence bit data
|
||||
// return: none
|
||||
#if ((DAP_SWD != 0) || (DAP_JTAG != 0))
|
||||
void SWJ_Sequence (uint32_t count, const uint8_t *data) {
|
||||
uint32_t val;
|
||||
uint32_t n;
|
||||
|
||||
val = 0U;
|
||||
n = 0U;
|
||||
while (count--) {
|
||||
if (n == 0U) {
|
||||
val = *data++;
|
||||
n = 8U;
|
||||
}
|
||||
if (val & 1U) {
|
||||
PIN_SWDIO_TMS_SET();
|
||||
} else {
|
||||
PIN_SWDIO_TMS_CLR();
|
||||
}
|
||||
SW_CLOCK_CYCLE();
|
||||
val >>= 1;
|
||||
n--;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Generate SWD Sequence
|
||||
// info: sequence information
|
||||
// swdo: pointer to SWDIO generated data
|
||||
// swdi: pointer to SWDIO captured data
|
||||
// return: none
|
||||
#if (DAP_SWD != 0)
|
||||
void SWD_Sequence (uint32_t info, const uint8_t *swdo, uint8_t *swdi) {
|
||||
uint32_t val;
|
||||
uint32_t bit;
|
||||
uint32_t n, k;
|
||||
|
||||
n = info & SWD_SEQUENCE_CLK;
|
||||
if (n == 0U) {
|
||||
n = 64U;
|
||||
}
|
||||
|
||||
if (info & SWD_SEQUENCE_DIN) {
|
||||
while (n) {
|
||||
val = 0U;
|
||||
for (k = 8U; k && n; k--, n--) {
|
||||
SW_READ_BIT(bit);
|
||||
val >>= 1;
|
||||
val |= bit << 7;
|
||||
}
|
||||
val >>= k;
|
||||
*swdi++ = (uint8_t)val;
|
||||
}
|
||||
} else {
|
||||
while (n) {
|
||||
val = *swdo++;
|
||||
for (k = 8U; k && n; k--, n--) {
|
||||
SW_WRITE_BIT(val);
|
||||
val >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if (DAP_SWD != 0)
|
||||
|
||||
|
||||
// SWD Transfer I/O
|
||||
// request: A[3:2] RnW APnDP
|
||||
// data: DATA[31:0]
|
||||
// return: ACK[2:0]
|
||||
#define SWD_TransferFunction(speed) /**/ \
|
||||
static uint8_t SWD_Transfer##speed (uint32_t request, uint32_t *data) { \
|
||||
uint32_t ack; \
|
||||
uint32_t bit; \
|
||||
uint32_t val; \
|
||||
uint32_t parity; \
|
||||
\
|
||||
uint32_t n; \
|
||||
\
|
||||
/* Packet Request */ \
|
||||
parity = 0U; \
|
||||
SW_WRITE_BIT(1U); /* Start Bit */ \
|
||||
bit = request >> 0; \
|
||||
SW_WRITE_BIT(bit); /* APnDP Bit */ \
|
||||
parity += bit; \
|
||||
bit = request >> 1; \
|
||||
SW_WRITE_BIT(bit); /* RnW Bit */ \
|
||||
parity += bit; \
|
||||
bit = request >> 2; \
|
||||
SW_WRITE_BIT(bit); /* A2 Bit */ \
|
||||
parity += bit; \
|
||||
bit = request >> 3; \
|
||||
SW_WRITE_BIT(bit); /* A3 Bit */ \
|
||||
parity += bit; \
|
||||
SW_WRITE_BIT(parity); /* Parity Bit */ \
|
||||
SW_WRITE_BIT(0U); /* Stop Bit */ \
|
||||
SW_WRITE_BIT(1U); /* Park Bit */ \
|
||||
\
|
||||
/* Turnaround */ \
|
||||
PIN_SWDIO_OUT_DISABLE(); \
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
|
||||
SW_CLOCK_CYCLE(); \
|
||||
} \
|
||||
\
|
||||
/* Acknowledge response */ \
|
||||
SW_READ_BIT(bit); \
|
||||
ack = bit << 0; \
|
||||
SW_READ_BIT(bit); \
|
||||
ack |= bit << 1; \
|
||||
SW_READ_BIT(bit); \
|
||||
ack |= bit << 2; \
|
||||
\
|
||||
if (ack == DAP_TRANSFER_OK) { /* OK response */ \
|
||||
/* Data transfer */ \
|
||||
if (request & DAP_TRANSFER_RnW) { \
|
||||
/* Read data */ \
|
||||
val = 0U; \
|
||||
parity = 0U; \
|
||||
for (n = 32U; n; n--) { \
|
||||
SW_READ_BIT(bit); /* Read RDATA[0:31] */ \
|
||||
parity += bit; \
|
||||
val >>= 1; \
|
||||
val |= bit << 31; \
|
||||
} \
|
||||
SW_READ_BIT(bit); /* Read Parity */ \
|
||||
if ((parity ^ bit) & 1U) { \
|
||||
ack = DAP_TRANSFER_ERROR; \
|
||||
} \
|
||||
if (data) { *data = val; } \
|
||||
/* Turnaround */ \
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
|
||||
SW_CLOCK_CYCLE(); \
|
||||
} \
|
||||
PIN_SWDIO_OUT_ENABLE(); \
|
||||
} else { \
|
||||
/* Turnaround */ \
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
|
||||
SW_CLOCK_CYCLE(); \
|
||||
} \
|
||||
PIN_SWDIO_OUT_ENABLE(); \
|
||||
/* Write data */ \
|
||||
val = *data; \
|
||||
parity = 0U; \
|
||||
for (n = 32U; n; n--) { \
|
||||
SW_WRITE_BIT(val); /* Write WDATA[0:31] */ \
|
||||
parity += val; \
|
||||
val >>= 1; \
|
||||
} \
|
||||
SW_WRITE_BIT(parity); /* Write Parity Bit */ \
|
||||
} \
|
||||
/* Capture Timestamp */ \
|
||||
if (request & DAP_TRANSFER_TIMESTAMP) { \
|
||||
DAP_Data.timestamp = TIMESTAMP_GET(); \
|
||||
} \
|
||||
/* Idle cycles */ \
|
||||
n = DAP_Data.transfer.idle_cycles; \
|
||||
if (n) { \
|
||||
PIN_SWDIO_OUT(0U); \
|
||||
for (; n; n--) { \
|
||||
SW_CLOCK_CYCLE(); \
|
||||
} \
|
||||
} \
|
||||
PIN_SWDIO_OUT(1U); \
|
||||
return ((uint8_t)ack); \
|
||||
} \
|
||||
\
|
||||
if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { \
|
||||
/* WAIT or FAULT response */ \
|
||||
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) != 0U)) { \
|
||||
for (n = 32U+1U; n; n--) { \
|
||||
SW_CLOCK_CYCLE(); /* Dummy Read RDATA[0:31] + Parity */ \
|
||||
} \
|
||||
} \
|
||||
/* Turnaround */ \
|
||||
for (n = DAP_Data.swd_conf.turnaround; n; n--) { \
|
||||
SW_CLOCK_CYCLE(); \
|
||||
} \
|
||||
PIN_SWDIO_OUT_ENABLE(); \
|
||||
if (DAP_Data.swd_conf.data_phase && ((request & DAP_TRANSFER_RnW) == 0U)) { \
|
||||
PIN_SWDIO_OUT(0U); \
|
||||
for (n = 32U+1U; n; n--) { \
|
||||
SW_CLOCK_CYCLE(); /* Dummy Write WDATA[0:31] + Parity */ \
|
||||
} \
|
||||
} \
|
||||
PIN_SWDIO_OUT(1U); \
|
||||
return ((uint8_t)ack); \
|
||||
} \
|
||||
\
|
||||
/* Protocol error */ \
|
||||
for (n = DAP_Data.swd_conf.turnaround + 32U + 1U; n; n--) { \
|
||||
SW_CLOCK_CYCLE(); /* Back off data phase */ \
|
||||
} \
|
||||
PIN_SWDIO_OUT_ENABLE(); \
|
||||
PIN_SWDIO_OUT(1U); \
|
||||
return ((uint8_t)ack); \
|
||||
}
|
||||
|
||||
|
||||
#undef PIN_DELAY
|
||||
#define PIN_DELAY() PIN_DELAY_FAST()
|
||||
SWD_TransferFunction(Fast)
|
||||
|
||||
#undef PIN_DELAY
|
||||
#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay)
|
||||
SWD_TransferFunction(Slow)
|
||||
|
||||
|
||||
// SWD Transfer I/O
|
||||
// request: A[3:2] RnW APnDP
|
||||
// data: DATA[31:0]
|
||||
// return: ACK[2:0]
|
||||
uint8_t SWD_Transfer(uint32_t request, uint32_t *data) {
|
||||
if (DAP_Data.fast_clock) {
|
||||
return SWD_TransferFast(request, data);
|
||||
} else {
|
||||
return SWD_TransferSlow(request, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* (DAP_SWD != 0) */
|
652
Drivers/CMSIS/DAP/Firmware/Source/UART.c
Normal file
652
Drivers/CMSIS/DAP/Firmware/Source/UART.c
Normal 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 */
|
Loading…
Add table
Add a link
Reference in a new issue