0
0
Fork 0

feat: Mainly improve DAP configuration:

1. improve DAP configuration independent of specific hardware
2. add hardware timer
3. cmake configuration file simple modification
4. add some to-do items
This commit is contained in:
windowsair 2020-01-21 22:03:05 +08:00
parent ba04bf3a5b
commit 2c09346169
12 changed files with 4343 additions and 3 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
.vscode/
build/

View File

View File

@ -0,0 +1,665 @@
/*
* 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 Configuration
* Title: DAP_config.h CMSIS-DAP Configuration File (Template)
*
*---------------------------------------------------------------------------*/
#ifndef __DAP_CONFIG_H__
#define __DAP_CONFIG_H__
#include "gpio.h"
#include "gpio_struct.h"
#include "timer_struct.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 160000000U ///< Specifies the CPU Clock in Hz.
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<160MHz
/// 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.
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<1MHz
/// 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.
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<< 512 for High-speed USB WinUSB.
/// 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.
/// Maximum SWO UART Baudrate.
#define SWO_UART_MAX_BAUDRATE 50000000U ///< SWO UART Maximum Baudrate in Hz.
// <<<<<<<<<<<<<<<<<<<<<<<<<<<<< 5MHz
// TODO: uncertain value
/// 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 1 ///< 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 1 ///< 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 5000000U ///< Timestamp clock in Hz (0 = timestamps not supported).
// <<<<<<<<<<<<<<<<<<<<<5MHz
/// 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 and Device Name string is stored which
/// may be used by the debugger or IDE to configure device parameters.
#define TARGET_DEVICE_FIXED 0 ///< Target Device: 1 = known, 0 = unknown;
#if TARGET_DEVICE_FIXED
#define TARGET_DEVICE_VENDOR "ARM" ///< String indicating the Silicon Vendor
#define TARGET_DEVICE_NAME "Cortex-M4" ///< String indicating the Target Device
#endif
/**
* @brief Get Vendor ID string.
*
* @param str Pointer to buffer to store the string.
* @return String length.
*/
__STATIC_INLINE uint8_t DAP_GetVendorString(char *str)
{
//TODO: fill this
// In fact, Keil can get the corresponding information through USB
// without filling in this information.
(void)str;
return (0U);
}
/**
* @brief Get Product ID string.
*
* @param str Pointer to buffer to store the string.
* @return String length.
*/
__STATIC_INLINE uint8_t DAP_GetProductString(char *str)
{
(void)str;
return (0U);
}
/**
* @brief Get Serial Number string.
*
* @param str Pointer to buffer to store the string.
* @return String length.
*/
__STATIC_INLINE uint8_t DAP_GetSerNumString(char *str)
{
(void)str;
return (0U);
}
///@}
// Modify your pins here
// ATTENTION: DO NOT USE RTC GPIO16
#define PIN_SWDIO 2
#define PIN_SWCLK 0
#define PIN_TDO 4
#define PIN_TDI 5
#define PIN_nTRST 1 // optional
#define PIN_nRESET 16
// LED_BUILTIN
#define PIN_LED_CONNECTED 13
// LED_BUILTIN
#define PIN_LED_RUNNING 15
//**************************************************************************************************
/**
\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.
*/
/**
* @brief 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)
{
gpio_set_direction(PIN_SWCLK, GPIO_MODE_OUTPUT);
gpio_set_direction(PIN_SWDIO, GPIO_MODE_OUTPUT);
gpio_set_direction(PIN_TDO, GPIO_MODE_DEF_INPUT);
gpio_set_direction(PIN_TDI, GPIO_MODE_OUTPUT);
gpio_set_direction(PIN_nTRST, GPIO_MODE_OUTPUT_OD);
gpio_set_direction(PIN_nRESET, GPIO_MODE_OUTPUT_OD);
gpio_set_pull_mode(PIN_nTRST, GPIO_PULLUP_ONLY);
gpio_set_pull_mode(PIN_nRESET, GPIO_PULLUP_ONLY);
}
/**
* @brief 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)
{
gpio_set_direction(PIN_SWCLK, GPIO_MODE_OUTPUT);
gpio_set_direction(PIN_SWDIO, GPIO_MODE_OUTPUT);
gpio_set_direction(PIN_TDO, GPIO_MODE_DEF_INPUT);
gpio_set_direction(PIN_TDI, GPIO_MODE_OUTPUT);
gpio_set_direction(PIN_nTRST, GPIO_MODE_OUTPUT_OD);
gpio_set_direction(PIN_nRESET, GPIO_MODE_OUTPUT_OD);
gpio_set_pull_mode(PIN_nTRST, GPIO_PULLUP_ONLY);
gpio_set_pull_mode(PIN_nRESET, GPIO_PULLUP_ONLY);
}
/**
* @brief 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)
{
// Will be called when the DAP disconnected
gpio_set_direction(PIN_SWCLK, GPIO_MODE_DEF_DISABLE);
gpio_set_direction(PIN_SWDIO, GPIO_MODE_DEF_DISABLE);
gpio_set_direction(PIN_TDO, GPIO_MODE_DEF_DISABLE);
gpio_set_direction(PIN_TDI, GPIO_MODE_DEF_DISABLE);
gpio_set_direction(PIN_nTRST, GPIO_MODE_DEF_DISABLE);
gpio_set_direction(PIN_nRESET, GPIO_MODE_DEF_DISABLE);
}
// SWCLK/TCK I/O pin -------------------------------------
/**
* @brief 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)
{
// TODO : can we set to 0?
return ((GPIO.in >> PIN_SWCLK) & 0x1);
}
/**
* @brief 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)
{
GPIO.out_w1ts |= (0x1 << PIN_SWCLK);
}
/**
* @brief 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)
{
GPIO.out_w1tc |= (0x1 << PIN_SWCLK);
}
// SWDIO/TMS Pin I/O --------------------------------------
/**
* @brief 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 ((GPIO.in >> PIN_SWDIO) & 0x1);
}
/**
* @brief 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)
{
GPIO.out_w1ts |= (0x1 << PIN_SWDIO);
}
/**
* @brief 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)
{
GPIO.out_w1tc |= (0x1 << PIN_SWDIO);
}
/**
* @brief 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 ((GPIO.in >> PIN_SWDIO) & 0x1);
}
/**
* @brief 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)
{
/**
* Important: Use only one bit (bit0) of param!
* Sometimes the func "SWD_TransferFunction" of SW_DP.c will
* issue "2" as param instead of "0". Zach Lee
*/
if ((bit & 1U) == 1)
{
//set bit
GPIO.out_w1ts |= (0x1 << PIN_SWDIO);
}
else
{
//reset bit
GPIO.out_w1tc |= (0x1 << PIN_SWDIO);
}
}
/**
* @brief 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)
{
// Need fast response
// set \ref gpio_set_direction -> OUTPUT
GPIO.enable_w1ts |= (0x1 << PIN_SWDIO);
}
/**
* @brief 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)
{
// Need fast response
// set \ref gpio_set_dircetion -> INPUT
// esp8266 input is always connected
GPIO.enable_w1tc |= (0x1 << PIN_SWDIO);
}
// TDI Pin I/O ---------------------------------------------
/**
* @brief 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 ((GPIO.in >> PIN_TDI) & 0x1);
}
/**
* @brief 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)
{
if ((bit & 1U) == 1)
{
//set bit
GPIO.out_w1ts |= (0x1 << PIN_TDI);
}
else
{
//reset bit
GPIO.out_w1tc |= (0x1 << PIN_TDI);
}
}
// TDO Pin I/O ---------------------------------------------
/**
* @brief 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 ((GPIO.in >> PIN_TDO_IN) & 0x1);
}
// nTRST Pin I/O -------------------------------------------
/**
* @brief 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 ((GPIO.in >> PIN_nTRST) & 0x1);
}
/**
* @brief 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)
{
//TODO : What does this mean? ? ?
if ((bit & 1U) == 1)
{
//set bit
GPIO.out_w1ts |= (0x1 << PIN_nTRST);
}
else
{
//reset bit
GPIO.out_w1tc |= (0x1 << PIN_nTRST);
}
}
// nRESET Pin I/O------------------------------------------
/**
* @brief 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 ((GPIO.in >> PIN_nRESET) & 0x1);
}
/**
* @brief 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)
{
//TODO : What does this mean? ? ?
if ((bit & 1U) == 1)
{
//set bit
GPIO.out_w1ts |= (0x1 << PIN_nRESET);
}
else
{
//reset bit
GPIO.out_w1tc |= (0x1 << PIN_nRESET);
}
}
///@}
//**************************************************************************************************
/**
\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.
*/
/**
* @brief 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)
{
if (bit)
{
//set bit
GPIO.out_w1ts |= (0x1 << PIN_LED_CONNECTED);
}
else
{
//reset bit
GPIO.out_w1tc |= (0x1 << PIN_LED_CONNECTED);
}
}
/**
* @brief 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)
{
if (bit)
{
//set bit
GPIO.out_w1ts |= (0x1 << PIN_LED_RUNNING);
}
else
{
//reset bit
GPIO.out_w1tc |= (0x1 << PIN_LED_RUNNING);
}
}
///@}
//**************************************************************************************************
/**
\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.
*/
/**
* @brief Get timestamp of Test Domain Timer.
*
* @return Current timestamp value.
*/
__STATIC_INLINE uint32_t TIMESTAMP_GET(void)
{
// FRC1 is a 24-bit countdown timer
return (0x1000000U - 1U - (frc1.count.data));
}
///@}
//**************************************************************************************************
/**
\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)
{
// This function maybe unnecessary...
gpio_set_direction(PIN_SWCLK, GPIO_MODE_DEF_INPUT);
gpio_set_direction(PIN_SWDIO, GPIO_MODE_DEF_INPUT); //
gpio_set_direction(PIN_nRESET, GPIO_MODE_DEF_INPUT); //
gpio_set_direction(PIN_TDI, GPIO_MODE_DEF_INPUT);
gpio_set_direction(PIN_TDO, GPIO_MODE_DEF_INPUT);
// Configure: LED as output (turned off)
gpio_set_direction(PIN_LED_CONNECTED, GPIO_MODE_DEF_OUTPUT);
LED_CONNECTED_OUT(0);
gpio_set_direction(PIN_LED_RUNNING, GPIO_MODE_DEF_OUTPUT);
LED_RUNNING_OUT(0);
}
/** 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); // not available
}
///@}
#endif /* __DAP_CONFIG_H__ */

View File

@ -0,0 +1,325 @@
/*
* Copyright (c) 2013-2019 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. November 2019
* $Revision: V2.0.0
*
* 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.2.0"
#else
#define DAP_FW_VER "2.0.0"
#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_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_FW_VER 4U
#define DAP_ID_DEVICE_VENDOR 5U
#define DAP_ID_DEVICE_NAME 6U
#define DAP_ID_CAPABILITIES 0xF0U
#define DAP_ID_TIMESTAMP_CLOCK 0xF1U
#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)
// 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 UART_SWO_Mode (uint32_t enable);
extern uint32_t UART_SWO_Baudrate (uint32_t baudrate);
extern uint32_t UART_SWO_Control (uint32_t active);
extern void UART_SWO_Capture (uint8_t *buf, uint32_t num);
extern uint32_t UART_SWO_GetCount (void);
extern uint32_t Manchester_SWO_Mode (uint32_t enable);
extern uint32_t Manchester_SWO_Baudrate (uint32_t baudrate);
extern uint32_t Manchester_SWO_Control (uint32_t active);
extern void Manchester_SWO_Capture (uint8_t *buf, uint32_t num);
extern uint32_t Manchester_SWO_GetCount (void);
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__ */

1769
components/DAP/source/DAP.c Normal file

File diff suppressed because it is too large Load Diff

View 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);
}
///@}

View 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) */

800
components/DAP/source/SWO.c Normal file
View File

@ -0,0 +1,800 @@
/*
* 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: 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"
#endif
#if (SWO_STREAM != 0)
#ifdef DAP_FW_V1
#error "SWO Streaming Trace not supported in DAP V1!"
#endif
#endif
#if (SWO_UART != 0)
#ifndef USART_PORT
#define USART_PORT 0 /* USART Port Number */
#endif
// USART Driver
#define _USART_Driver_(n) Driver_USART##n
#define USART_Driver_(n) _USART_Driver_(n)
extern ARM_DRIVER_USART USART_Driver_(USART_PORT);
#define pUSART (&USART_Driver_(USART_PORT))
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 UART SWO Mode
// enable: enable flag
// return: 1 - Success, 0 - Error
__WEAK uint32_t UART_SWO_Mode (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 UART SWO Baudrate
// baudrate: requested baudrate
// return: actual baudrate or 0 when not configured
__WEAK uint32_t UART_SWO_Baudrate (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 UART SWO Capture
// active: active flag
// return: 1 - Success, 0 - Error
__WEAK uint32_t UART_SWO_Control (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 UART SWO Capture
// buf: pointer to buffer for capturing
// num: number of bytes to capture
__WEAK void UART_SWO_Capture (uint8_t *buf, uint32_t num) {
TraceBlockSize = num;
pUSART->Receive(buf, num);
}
// Get UART SWO Pending Trace Count
// return: number of pending trace data bytes
__WEAK uint32_t UART_SWO_GetCount (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 Manchester SWO Mode
// enable: enable flag
// return: 1 - Success, 0 - Error
__WEAK uint32_t Manchester_SWO_Mode (uint32_t enable) {
return (0U);
}
// Configure Manchester SWO Baudrate
// baudrate: requested baudrate
// return: actual baudrate or 0 when not configured
__WEAK uint32_t Manchester_SWO_Baudrate (uint32_t baudrate) {
return (0U);
}
// Control Manchester SWO Capture
// active: active flag
// return: 1 - Success, 0 - Error
__WEAK uint32_t Manchester_SWO_Control (uint32_t active) {
return (0U);
}
// Start Manchester SWO Capture
// buf: pointer to buffer for capturing
// num: number of bytes to capture
__WEAK void Manchester_SWO_Capture (uint8_t *buf, uint32_t num) {
}
// Get Manchester SWO Pending Trace Count
// return: number of pending trace data bytes
__WEAK uint32_t Manchester_SWO_GetCount (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;
UART_SWO_Capture(&TraceBuf[index_i], 1U);
break;
#endif
#if (SWO_MANCHESTER != 0)
case DAP_SWO_MANCHESTER:
TraceStatus = DAP_SWO_CAPTURE_ACTIVE;
Manchester_SWO_Capture(&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 += UART_SWO_GetCount();
break;
#endif
#if (SWO_MANCHESTER != 0)
case DAP_SWO_MANCHESTER:
count += Manchester_SWO_GetCount();
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:
UART_SWO_Mode(0U);
break;
#endif
#if (SWO_MANCHESTER != 0)
case DAP_SWO_MANCHESTER:
Manchester_SWO_Mode(0U);
break;
#endif
default:
break;
}
switch (mode) {
case DAP_SWO_OFF:
result = 1U;
break;
#if (SWO_UART != 0)
case DAP_SWO_UART:
result = UART_SWO_Mode(1U);
break;
#endif
#if (SWO_MANCHESTER != 0)
case DAP_SWO_MANCHESTER:
result = Manchester_SWO_Mode(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 = UART_SWO_Baudrate(baudrate);
break;
#endif
#if (SWO_MANCHESTER != 0)
case DAP_SWO_MANCHESTER:
baudrate = Manchester_SWO_Baudrate(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 = UART_SWO_Control(active);
break;
#endif
#if (SWO_MANCHESTER != 0)
case DAP_SWO_MANCHESTER:
result = Manchester_SWO_Control(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)) */

View 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) */

3
components/README.md Normal file
View File

@ -0,0 +1,3 @@
# TODO
1. adapt to special hardware
2. USB

View File

@ -1,4 +1,4 @@
set(COMPONENT_SRCS "tcp_server.c")
set(COMPONENT_ADD_INCLUDEDIRS ".")
set(COMPONENT_ADD_INCLUDEDIRS ". $ENV{IDF_PATH}/components/esp8266/include/esp8266/")
register_component()

View File

@ -7,6 +7,7 @@
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include <stdint.h>
#include <sys/param.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
@ -22,6 +23,11 @@
#include "lwip/sys.h"
#include <lwip/netdb.h>
#include "gpio.h"
#include "hw_timer.h"
#include "timer_struct.h"
/* The examples use simple WiFi configuration that you can set via
'make menuconfig'.
If you'd rather not, just change the below entries to strings with
@ -108,6 +114,7 @@ static void initialise_wifi(void)
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
}
static void wait_for_ip()
@ -180,7 +187,7 @@ static void tcp_server_task(void *pvParameters)
#else
struct sockaddr_in sourceAddr;
#endif
uint addrLen = sizeof(sourceAddr);
uint32_t addrLen = sizeof(sourceAddr);
int sock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen);
if (sock < 0)
{
@ -248,11 +255,25 @@ static void tcp_server_task(void *pvParameters)
vTaskDelete(NULL);
}
void timer_create_task()
{
// FRC1 frequency 80MHz
vPortEnterCritical();
frc1.ctrl.div = TIMER_CLKDIV_16; // 80MHz / 16 = 5MHz
frc1.ctrl.intr_type = TIMER_EDGE_INT;
frc1.ctrl.reload = 0x01;
frc1.load.data = 0x1000000U - 1U;
frc1.ctrl.en = 0x01;
vPortExitCritical();
vTaskDelete(NULL);
}
void app_main()
{
ESP_ERROR_CHECK(nvs_flash_init());
initialise_wifi();
wait_for_ip();
xTaskCreate(timer_create_task, "timer_create", 2048, NULL, 10, NULL);
xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 5, NULL);
}