diff --git a/.gitignore b/.gitignore
index 1d74e21..e524d79 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
.vscode/
+build/
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..45b689f
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,27 @@
+language: c
+sudo: required
+before_install:
+- sudo apt install -y gcc git wget make libncurses-dev flex bison python python-serial
+- wget https://dl.espressif.com/dl/xtensa-lx106-elf-linux64-1.22.0-100-ge567ec7-5.2.0.tar.gz
+
+install:
+- tar -xzf ./xtensa-lx106-elf-linux64-1.22.0-100-ge567ec7-5.2.0.tar.gz
+- git clone --recursive https://github.com/espressif/ESP8266_RTOS_SDK.git
+- python -m pip install --user -r ./ESP8266_RTOS_SDK/requirements.txt
+
+before_script:
+- export IDF_PATH=$PWD/ESP8266_RTOS_SDK
+- export PATH="$PATH:$PWD/xtensa-lx106-elf/bin"
+
+script:
+- python ./idf.py fullclean
+- python ./idf.py build
+
+deploy:
+ provider: releases
+ api_key: ${GITHUB_TOKEN}
+ file:
+ - ./build/esp8266_dap.bin
+ skip_cleanup: true
+ on:
+ tags: true
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3514e60..0eb1581 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,7 @@
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
+#set(COMPONENT_DIRS "${IDF_PATH}/components ${PROJECT_PATH}/components")
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
-project(tcp_server)
+project(esp8266_dap)
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..e14fa0d
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 windowsair
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/README.md b/README.md
index e69de29..b8f4a0d 100644
--- a/README.md
+++ b/README.md
@@ -0,0 +1,159 @@
+

+Wireless ESP8266 DAP
+
+[](https://travis-ci.com/windowsair/wireless-esp8266-dap) master
+[](https://travis-ci.com/windowsair/wireless-esp8266-dap) develop
+
+[](https://github.com/windowsair/wireless-esp8266-dap/LICENSE) [](https://github.com/windowsair/wireless-esp8266-dap/pulls) [](https://github.com/windowsair/wireless-esp8266-dap)
+
+
+## Introduce
+
+Wireless debugging with ***only one ESP8266*** !
+
+Realized by USBIP and CMSIS-DAP protocol stack.
+
+> 👉 5m distance, 100kb size firmware flash test:
+
+
+
+## Feature
+
+1. Debug Communication Mode
+ - [x] SWJ
+ - [x] JTAG
+
+2. USB Communication Mode
+ - [x] USB-HID
+ - [ ] WCID & WinUSB
+
+3. Debug Trace
+ - [ ] UART Serial Wire Output(SWO)
+ - [ ] SWO Streaming Trace
+
+4. More..
+ - [x] Custom maximum debug clock(more than 10MHz)
+ - [ ] ...
+
+
+
+## Link your board
+
+1. WIFI
+
+The default connected WIFI SSID is `DAP` , password `12345678`
+
+You can change `WIFI_SSID` and ` WIFI_PASS` in [wifi_configuration.h](main/wifi_configuration.h)
+
+2. Debugger
+
+- SWD
+
+| SWD | |
+|----------------|--------|
+| SWCLK | GPIO5 |
+| SWDIO | GPIO4 |
+| LED\_CONNECTED | GPIO2 |
+| LED\_RUNNING | GPIO15 |
+| TVCC | 3V3 |
+| GND | GND |
+
+- JTAG
+
+| JTAG | |
+|--------------------|---------|
+| TCK | GPIO5 |
+| TMS | GPIO4 |
+| TDI | GPIO13 |
+| TDO | GPIO12 |
+| nTRST \(optional\) | GPIO0\* |
+| nRESET | GPIO14 |
+| LED\_CONNECTED | GPIO2 |
+| LED\_RUNNING | GPIO15 |
+| TVCC | 3V3 |
+| GND | GND |
+
+You can modify these pin definitions in [DAP_config.h](components/DAP/config/DAP_config.h)
+
+> Tips: Try to avoid using `GPIO0`(working mode switch) and `GPIO16`(RTC)
+
+## Build
+
+1. Get ESP8266 RTOS Software Development Kit
+
+See: [ESP8266_RTOS_SDK](https://github.com/espressif/ESP8266_RTOS_SDK "ESP8266_RTOS_SDK")
+
+2. Build & Flash
+
+Build with ESP-IDF build system.
+More information can be found at the following link: [Build System](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html "Build System")
+
+The following example shows a possible way to build on Windows:
+
+```bash
+# Build
+python ./idf.py build
+# Flash
+python ./idf.py -p /dev/ttyS5 flash
+```
+
+> We also provided sample firmware quick evaluation. See [Releases](https://github.com/windowsair/wireless-esp8266-dap/releases)
+
+
+## Usage
+
+1. Get USBIP project
+
+- Windows: [usbip-windows](https://github.com/george-hopkins/usbip-windows "usbip-windows") . Or you can find it already built here: https://github.com/barbalion/usbip-win-client
+- Linux: Distributed as part of the kernel
+
+2. Start esp8266 and connect it to the device to be debugged
+
+3. Connect it with usbip:
+
+```bash
+.\usbip.exe -D -a 1-1
+```
+
+If all goes well, you should see your device connected.
+
+
+
+
+
+
+## Develop
+
+> Credits to:
+> - https://github.com/thevoidnn/esp8266-wifi-cmsis-dap for adapter firmware based on CMSIS-DAP v1.0
+> - https://github.com/ARM-software/CMSIS_5 for CMSIS
+
+
+In this repo you can find the complete implementation of the USB protocol stack including USB-HID, WCID, WinUSB. Although WinUSB-based mode currently does not work on USBIP :disappointed_relieved: . They are very easy and can help you quickly build your own DAP on other hardware platforms.
+
+
+Currently using USB-HID for transmission is still slightly slower, If you have any ideas, welcome:
+- [New issues](https://github.com/windowsair/wireless-esp8266-dap/issues)
+- [New pull](https://github.com/windowsair/wireless-esp8266-dap/pulls)
+
+
+### Issue
+
+2-4
+
+Due to the limitation of USB-HID (I'm not sure if this is a problem with USBIP or Windows), now each URB packet can only reach 255 bytes (About 1MBps bandwidth), which has not reached the upper limit of ESP8266 transmission bandwidth.
+
+I now have an idea to construct a Man-in-the-middle between the two to forward traffic, thereby increasing the bandwidth of each transmission.
+
+1-31
+
+At present, the adaptation to WCID, WinUSB, etc. has all been completed. However, when transmitting data on the endpoint, we received an error message from USBIP. This is most likely a problem with the USBIP project itself.
+
+Due to the completeness of the USBIP protocol document, we have not yet understood its role in the Bulk transmission process, which may also lead to errors in subsequent processes.
+
+We will continue to try to make it work on USB HID. Once the USBIP problem is solved, we will immediately transfer it to work on WinUSB
+
+
+
+## License
+[MIT LICENSE](LICENSE)
\ No newline at end of file
diff --git a/components/DAP/CMakeLists.txt b/components/DAP/CMakeLists.txt
new file mode 100644
index 0000000..3eec5a2
--- /dev/null
+++ b/components/DAP/CMakeLists.txt
@@ -0,0 +1,5 @@
+set(COMPONENT_ADD_INCLUDEDIRS "config include $ENV{IDF_PATH}/components/esp8266/include/esp8266/ $ENV{IDF_PATH}//components/esp_ringbuf/include/")
+set(COMPONENT_SRCS "./source/DAP.c ./source/DAP_vendor.c ./source/JTAG_DP.c ./source/SW_DP.c ./source/SWO.c ./source/uart_modify.c")
+
+
+register_component()
\ No newline at end of file
diff --git a/components/DAP/config/DAP_config.h b/components/DAP/config/DAP_config.h
new file mode 100644
index 0000000..7121a2e
--- /dev/null
+++ b/components/DAP/config/DAP_config.h
@@ -0,0 +1,764 @@
+/*
+ * 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
+#include
+#include "cmsis_compiler.h"
+#include "gpio.h"
+#include "gpio_struct.h"
+#include "timer_struct.h"
+#include "esp8266/pin_mux_register.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 160000000 ///< Specifies the CPU Clock in Hz.
+// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<160MHz
+
+// This value is used to replace the largest 10MHZ speed clock in Keil
+#define MAX_USER_CLOCK 10000000 ///< Specifies the max Debug 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 Capabilities.
+#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 Capabilities.
+#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 255U ///< 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 20 ///< 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 Capabilities.
+#define SWO_UART 0 ///< SWO UART: 1 = available, 0 = not available.
+
+/// Maximum SWO UART Baudrate.
+#define SWO_UART_MAX_BAUDRATE (115200U * 40U) ///< 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 Capabilities.
+#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 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;
+ strcpy(str, "windowsair");
+ return (sizeof("windowsair"));
+}
+
+/**
+ * @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;
+ strcpy(str, "CMSIS-DAP v2");
+ return (sizeof("CMSIS-DAP v2"));
+}
+
+/**
+ * @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)
+{
+ strcpy(str, "1234");
+ return (sizeof("1234"));
+}
+
+///@}
+
+// Modify your pins here
+
+// ATTENTION: DO NOT USE RTC GPIO16
+#define PIN_SWDIO 4
+#define PIN_SWCLK 5
+#define PIN_TDO 13
+#define PIN_TDI 12
+#define PIN_nTRST 0 // optional
+#define PIN_nRESET 14
+// LED_BUILTIN
+#define PIN_LED_CONNECTED 2
+// 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_pin_reg_t pin_reg;
+
+ // gpio_set_direction(PIN_SWCLK, GPIO_MODE_OUTPUT);
+ // gpio_set_direction(PIN_SWDIO, GPIO_MODE_OUTPUT);
+ GPIO.enable_w1ts |= (0x1 << PIN_SWCLK);
+ GPIO.pin[PIN_SWCLK].driver = 0;
+ pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_SWCLK));
+ pin_reg.pullup = 0;
+ WRITE_PERI_REG(GPIO_PIN_REG(PIN_SWCLK), pin_reg.val);
+ GPIO.enable_w1ts |= (0x1 << PIN_SWDIO);
+ GPIO.pin[PIN_SWDIO].driver = 0;
+ pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_SWDIO));
+ pin_reg.pullup = 0;
+ WRITE_PERI_REG(GPIO_PIN_REG(PIN_SWDIO), pin_reg.val);
+
+ // gpio_set_direction(PIN_TDO, GPIO_MODE_DEF_INPUT);
+ GPIO.enable_w1tc |= (0x1 << PIN_TDO);
+ GPIO.pin[PIN_TDO].driver = 0;
+ pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_TDO));
+ pin_reg.pullup = 0;
+ WRITE_PERI_REG(GPIO_PIN_REG(PIN_TDO), pin_reg.val);
+ // gpio_set_direction(PIN_TDI, GPIO_MODE_OUTPUT);
+ GPIO.enable_w1ts |= (0x1 << PIN_TDI);
+ GPIO.pin[PIN_TDI].driver = 0;
+ pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_TDI));
+ pin_reg.pullup = 0;
+ WRITE_PERI_REG(GPIO_PIN_REG(PIN_TDI), pin_reg.val);
+
+ // gpio_set_direction(PIN_nTRST, GPIO_MODE_OUTPUT_OD);
+ // gpio_set_direction(PIN_nRESET, GPIO_MODE_OUTPUT_OD);
+ GPIO.enable_w1tc |= (0x1 << PIN_nTRST);
+ GPIO.pin[PIN_nTRST].driver = 1;
+ GPIO.enable_w1tc |= (0x1 << PIN_nRESET);
+ GPIO.pin[PIN_nRESET].driver = 1;
+
+ // gpio_set_pull_mode(PIN_nTRST, GPIO_PULLUP_ONLY);
+ // gpio_set_pull_mode(PIN_nRESET, GPIO_PULLUP_ONLY);
+ pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_nTRST));
+ pin_reg.pullup = 1;
+ WRITE_PERI_REG(GPIO_PIN_REG(PIN_nTRST), pin_reg.val);
+ pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_nRESET));
+ pin_reg.pullup = 1;
+ WRITE_PERI_REG(GPIO_PIN_REG(PIN_nRESET), pin_reg.val);
+}
+
+/**
+ * @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_pin_reg_t pin_reg;
+
+ // gpio_set_direction(PIN_SWCLK, GPIO_MODE_OUTPUT);
+ // gpio_set_direction(PIN_SWDIO, GPIO_MODE_OUTPUT);
+ GPIO.enable_w1ts |= (0x1 << PIN_SWCLK);
+ GPIO.pin[PIN_SWCLK].driver = 0;
+ pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_SWCLK));
+ pin_reg.pullup = 0;
+ WRITE_PERI_REG(GPIO_PIN_REG(PIN_SWCLK), pin_reg.val);
+ GPIO.enable_w1ts |= (0x1 << PIN_SWDIO);
+ GPIO.pin[PIN_SWDIO].driver = 0;
+ pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_SWDIO));
+ pin_reg.pullup = 0;
+ WRITE_PERI_REG(GPIO_PIN_REG(PIN_SWDIO), pin_reg.val);
+
+ // gpio_set_direction(PIN_TDO, GPIO_MODE_DEF_INPUT);
+ GPIO.enable_w1tc |= (0x1 << PIN_TDO);
+ GPIO.pin[PIN_TDO].driver = 0;
+ pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_TDO));
+ pin_reg.pullup = 0;
+ WRITE_PERI_REG(GPIO_PIN_REG(PIN_TDO), pin_reg.val);
+ // gpio_set_direction(PIN_TDI, GPIO_MODE_OUTPUT);
+ GPIO.enable_w1ts |= (0x1 << PIN_TDI);
+ GPIO.pin[PIN_TDI].driver = 0;
+ pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_TDI));
+ pin_reg.pullup = 0;
+ WRITE_PERI_REG(GPIO_PIN_REG(PIN_TDI), pin_reg.val);
+
+ // gpio_set_direction(PIN_nTRST, GPIO_MODE_OUTPUT_OD);
+ // gpio_set_direction(PIN_nRESET, GPIO_MODE_OUTPUT_OD);
+ GPIO.enable_w1tc |= (0x1 << PIN_nTRST);
+ GPIO.pin[PIN_nTRST].driver = 1;
+ GPIO.enable_w1tc |= (0x1 << PIN_nRESET);
+ GPIO.pin[PIN_nRESET].driver = 1;
+
+ // gpio_set_pull_mode(PIN_nTRST, GPIO_PULLUP_ONLY);
+ // gpio_set_pull_mode(PIN_nRESET, GPIO_PULLUP_ONLY);
+ pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_nTRST));
+ pin_reg.pullup = 1;
+ WRITE_PERI_REG(GPIO_PIN_REG(PIN_nTRST), pin_reg.val);
+ pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_nRESET));
+ pin_reg.pullup = 1;
+ WRITE_PERI_REG(GPIO_PIN_REG(PIN_nRESET), pin_reg.val);
+}
+
+/**
+ * @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);
+ GPIO.pin[PIN_SWCLK].driver = 0;
+ GPIO.enable_w1tc |= (0x1 << PIN_SWCLK);
+
+ GPIO.pin[PIN_SWDIO].driver = 0;
+ GPIO.enable_w1tc |= (0x1 << PIN_SWDIO);
+
+ GPIO.pin[PIN_TDO].driver = 0;
+ GPIO.enable_w1tc |= (0x1 << PIN_TDO);
+
+ GPIO.pin[PIN_TDI].driver = 0;
+ GPIO.enable_w1tc |= (0x1 << PIN_TDI);
+
+ GPIO.pin[PIN_nTRST].driver = 0;
+ GPIO.enable_w1tc |= (0x1 << PIN_nTRST);
+
+ GPIO.pin[PIN_nRESET].driver = 0;
+ GPIO.enable_w1tc |= (0x1 << PIN_nRESET);
+}
+
+// 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 0;
+}
+
+/**
+ * @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) ? 1 : 0;
+}
+
+/**
+ * @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) ? 1 : 0;
+}
+
+/**
+ * @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);
+ GPIO.pin[PIN_SWDIO].driver = 0;
+}
+
+/**
+ * @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);
+ GPIO.pin[PIN_SWDIO].driver = 0;
+}
+
+// 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) ? 1 : 0;
+}
+
+/**
+ * @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) & 0x1) ? 1 : 0;
+}
+
+// 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 0; // not available
+}
+
+/**
+ * @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);
+ // }
+ ; // not available
+}
+
+// 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) ? 1 : 0;
+}
+
+/**
+ * @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 23-bit countdown timer
+ return (0x7FFFFF - (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__ */
diff --git a/components/DAP/include/DAP.h b/components/DAP/include/DAP.h
new file mode 100644
index 0000000..65e0459
--- /dev/null
+++ b/components/DAP/include/DAP.h
@@ -0,0 +1,330 @@
+/*
+ * 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
+#include
+#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
+
+#define USE_ASSEMBLY 1
+
+#if (USE_ASSEMBLY == 0)
+ __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(
+ "l_PINDELAYSLOW%=:"
+ "ADDI.N %[time], %[time], -1;"
+ "BNEZ %[time], l_PINDELAYSLOW%=;"
+ : [time] "+r"(delay));
+}
+
+#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__ */
diff --git a/components/DAP/include/cmsis_compiler.h b/components/DAP/include/cmsis_compiler.h
new file mode 100644
index 0000000..aafbe21
--- /dev/null
+++ b/components/DAP/include/cmsis_compiler.h
@@ -0,0 +1,50 @@
+#ifndef __CMSIS_COMPILER_H__
+#define __CMSIS_COMPILER_H__
+
+#ifndef __STATIC_FORCEINLINE
+ #define __STATIC_FORCEINLINE static inline __attribute__((always_inline))
+#endif
+#ifndef __STATIC_INLINE
+ #define __STATIC_INLINE static inline __attribute__((always_inline))
+#endif
+#ifndef __WEAK
+ #define __WEAK __attribute__((weak))
+#endif
+
+#define GPIO_PIN_REG_0 PERIPHS_IO_MUX_GPIO0_U
+#define GPIO_PIN_REG_1 PERIPHS_IO_MUX_U0TXD_U
+#define GPIO_PIN_REG_2 PERIPHS_IO_MUX_GPIO2_U
+#define GPIO_PIN_REG_3 PERIPHS_IO_MUX_U0RXD_U
+#define GPIO_PIN_REG_4 PERIPHS_IO_MUX_GPIO4_U
+#define GPIO_PIN_REG_5 PERIPHS_IO_MUX_GPIO5_U
+#define GPIO_PIN_REG_6 PERIPHS_IO_MUX_SD_CLK_U
+#define GPIO_PIN_REG_7 PERIPHS_IO_MUX_SD_DATA0_U
+#define GPIO_PIN_REG_8 PERIPHS_IO_MUX_SD_DATA1_U
+#define GPIO_PIN_REG_9 PERIPHS_IO_MUX_SD_DATA2_U
+#define GPIO_PIN_REG_10 PERIPHS_IO_MUX_SD_DATA3_U
+#define GPIO_PIN_REG_11 PERIPHS_IO_MUX_SD_CMD_U
+#define GPIO_PIN_REG_12 PERIPHS_IO_MUX_MTDI_U
+#define GPIO_PIN_REG_13 PERIPHS_IO_MUX_MTCK_U
+#define GPIO_PIN_REG_14 PERIPHS_IO_MUX_MTMS_U
+#define GPIO_PIN_REG_15 PERIPHS_IO_MUX_MTDO_U
+#define GPIO_PIN_REG_16 PAD_XPD_DCDC_CONF
+#define GPIO_PIN_REG(i) \
+ (i==0) ? GPIO_PIN_REG_0: \
+ (i==1) ? GPIO_PIN_REG_1: \
+ (i==2) ? GPIO_PIN_REG_2: \
+ (i==3) ? GPIO_PIN_REG_3: \
+ (i==4) ? GPIO_PIN_REG_4: \
+ (i==5) ? GPIO_PIN_REG_5: \
+ (i==6) ? GPIO_PIN_REG_6: \
+ (i==7) ? GPIO_PIN_REG_7: \
+ (i==8) ? GPIO_PIN_REG_8: \
+ (i==9) ? GPIO_PIN_REG_9: \
+ (i==10)? GPIO_PIN_REG_10: \
+ (i==11)? GPIO_PIN_REG_11: \
+ (i==12)? GPIO_PIN_REG_12: \
+ (i==13)? GPIO_PIN_REG_13: \
+ (i==14)? GPIO_PIN_REG_14: \
+ (i==15)? GPIO_PIN_REG_15: \
+ GPIO_PIN_REG_16
+
+#endif
\ No newline at end of file
diff --git a/components/DAP/include/uart_modify.h b/components/DAP/include/uart_modify.h
new file mode 100644
index 0000000..3d3a277
--- /dev/null
+++ b/components/DAP/include/uart_modify.h
@@ -0,0 +1,565 @@
+/**
+ * @brief Made some simple modifications to the official UART
+ *
+ */
+
+// Copyright 2018-2025 Espressif Systems (Shanghai) PTE LTD
+//
+// 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
+//
+// http://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.
+
+
+#ifndef _DRIVER_UART_H_
+#define _DRIVER_UART_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "esp_err.h"
+#include "esp_log.h"
+#include "freertos/queue.h"
+
+#define UART_FIFO_LEN (128) /*!< Length of the hardware FIFO buffers */
+#define UART_INTR_MASK 0x1ff /*!< Mask of all UART interrupts */
+#define UART_LINE_INV_MASK (0x3f << 19) /*!< TBD */
+
+#define UART_INVERSE_DISABLE (0x0) /*!< Disable UART signal inverse*/
+#define UART_INVERSE_RXD (BIT(19)) /*!< UART RXD input inverse*/
+#define UART_INVERSE_CTS (BIT(20)) /*!< UART CTS input inverse*/
+#define UART_INVERSE_TXD (BIT(22)) /*!< UART TXD output inverse*/
+#define UART_INVERSE_RTS (BIT(23)) /*!< UART RTS output inverse*/
+
+/**
+ * @brief UART mode selection
+ */
+typedef enum {
+ UART_MODE_UART = 0x00, /*!< mode: regular UART mode*/
+} uart_mode_t;
+
+/**
+ * @brief UART word length constants
+ */
+typedef enum {
+ UART_DATA_5_BITS = 0x0, /*!< word length: 5bits*/
+ UART_DATA_6_BITS = 0x1, /*!< word length: 6bits*/
+ UART_DATA_7_BITS = 0x2, /*!< word length: 7bits*/
+ UART_DATA_8_BITS = 0x3, /*!< word length: 8bits*/
+ UART_DATA_BITS_MAX = 0x4,
+} uart_word_length_t;
+
+/**
+ * @brief UART stop bits number
+ */
+typedef enum {
+ UART_STOP_BITS_1 = 0x1, /*!< stop bit: 1bit*/
+ UART_STOP_BITS_1_5 = 0x2, /*!< stop bit: 1.5bits*/
+ UART_STOP_BITS_2 = 0x3, /*!< stop bit: 2bits*/
+ UART_STOP_BITS_MAX = 0x4,
+} uart_stop_bits_t;
+
+/**
+ * @brief UART peripheral number
+ */
+typedef enum {
+ UART_NUM_0 = 0x0,
+ UART_NUM_1 = 0x1,
+ UART_NUM_MAX,
+} uart_port_t;
+
+/**
+ * @brief UART parity constants
+ */
+typedef enum {
+ UART_PARITY_DISABLE = 0x0, /*!< Disable UART parity*/
+ UART_PARITY_EVEN = 0x2, /*!< Enable UART even parity*/
+ UART_PARITY_ODD = 0x3 /*!< Enable UART odd parity*/
+} uart_parity_t;
+
+/**
+ * @brief UART hardware flow control modes
+ */
+typedef enum {
+ UART_HW_FLOWCTRL_DISABLE = 0x0, /*!< disable hardware flow control*/
+ UART_HW_FLOWCTRL_RTS = 0x1, /*!< enable RX hardware flow control (rts)*/
+ UART_HW_FLOWCTRL_CTS = 0x2, /*!< enable TX hardware flow control (cts)*/
+ UART_HW_FLOWCTRL_CTS_RTS = 0x3, /*!< enable hardware flow control*/
+ UART_HW_FLOWCTRL_MAX = 0x4,
+} uart_hw_flowcontrol_t;
+
+/**
+ * @brief UART configuration parameters for my_uart_param_config function
+ */
+typedef struct {
+ int baud_rate; /*!< UART baud rate*/
+ uart_word_length_t data_bits; /*!< UART byte size*/
+ uart_parity_t parity; /*!< UART parity mode*/
+ uart_stop_bits_t stop_bits; /*!< UART stop bits*/
+ uart_hw_flowcontrol_t flow_ctrl; /*!< UART HW flow control mode (cts/rts)*/
+ uint8_t rx_flow_ctrl_thresh; /*!< UART HW RTS threshold*/
+} uart_config_t;
+
+/**
+ * @brief UART interrupt configuration parameters for my_uart_intr_config function
+ */
+typedef struct {
+ uint32_t intr_enable_mask; /*!< UART interrupt enable mask, choose from UART_XXXX_INT_ENA_M under UART_INT_ENA_REG(i), connect with bit-or operator*/
+ uint8_t rx_timeout_thresh; /*!< UART timeout interrupt threshold (unit: time of sending one byte)*/
+ uint8_t txfifo_empty_intr_thresh; /*!< UART TX empty interrupt threshold.*/
+ uint8_t rxfifo_full_thresh; /*!< UART RX full interrupt threshold.*/
+} uart_intr_config_t;
+
+/**
+ * @brief UART event types used in the ring buffer
+ */
+typedef enum {
+ UART_DATA, /*!< UART data event*/
+ UART_BUFFER_FULL, /*!< UART RX buffer full event*/
+ UART_FIFO_OVF, /*!< UART FIFO overflow event*/
+ UART_FRAME_ERR, /*!< UART RX frame error event*/
+ UART_PARITY_ERR, /*!< UART RX parity event*/
+ UART_EVENT_MAX, /*!< UART event max index*/
+} uart_event_type_t;
+
+/**
+ * @brief Event structure used in UART event queue
+ */
+typedef struct {
+ uart_event_type_t type; /*!< UART event type */
+ size_t size; /*!< UART data size for UART_DATA event*/
+} uart_event_t;
+
+
+/**
+ * @brief Set UART data bits.
+ *
+ * @param uart_num Uart port number.
+ * @param data_bit Uart data bits.
+ *
+ * @return
+ * - ESP_OK success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit);
+
+/**
+ * @brief Get UART data bits.
+ *
+ * @param uart_num Uart port number.
+ * @param data_bit Pointer to accept value of UART data bits.
+ *
+ * @return
+ * - ESP_OK success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_get_word_length(uart_port_t uart_num, uart_word_length_t *data_bit);
+
+/**
+ * @brief Set UART stop bits.
+ *
+ * @param uart_num Uart port number
+ * @param stop_bits Uart stop bits
+ *
+ * @return
+ * - ESP_OK success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bits);
+
+/**
+ * @brief Get UART stop bits.
+ *
+ * @param uart_num Uart port number.
+ * @param stop_bits Pointer to accept value of UART stop bits.
+ *
+ * @return
+ * - ESP_OK success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t *stop_bits);
+
+/**
+ * @brief Set UART parity mode.
+ *
+ * @param uart_num Uart port number.
+ * @param parity_mode The enum of uart parity configuration.
+ *
+ * @return
+ * - ESP_OK success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_set_parity(uart_port_t uart_num, uart_parity_t parity_mode);
+
+/**
+ * @brief Get UART parity mode.
+ *
+ * @param uart_num Uart port number
+ * @param parity_mode Pointer to accept value of UART parity mode.
+ *
+ * @return
+ * - ESP_OK success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_get_parity(uart_port_t uart_num, uart_parity_t *parity_mode);
+
+/**
+ * @brief Set UART baud rate.
+ *
+ * @param uart_num Uart port number
+ * @param baudrate UART baud rate.
+ *
+ * @return
+ * - ESP_OK success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_set_baudrate(uart_port_t uart_num, uint32_t baudrate);
+
+/**
+ * @brief Get UART baud rate.
+ *
+ * @param uart_num Uart port number.
+ * @param baudrate Pointer to accept value of Uart baud rate.
+ *
+ * @return
+ * - ESP_OK success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_get_baudrate(uart_port_t uart_num, uint32_t *baudrate);
+
+/**
+ * @brief Set UART line inverse mode
+ *
+ * @param uart_num UART_NUM_0
+ * @param inverse_mask Choose the wires that need to be inverted.
+ * Inverse_mask should be chosen from
+ * UART_INVERSE_RXD / UART_INVERSE_TXD / UART_INVERSE_RTS / UART_INVERSE_CTS,
+ * combined with OR operation.
+ *
+ * @return
+ * - ESP_OK success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_set_line_inverse(uart_port_t uart_num, uint32_t inverse_mask);
+
+/**
+ * @brief Configure Hardware flow control.
+ *
+ * @param uart_num Uart port number.
+ * @param flow_ctrl Hardware flow control mode.
+ * @param rx_thresh Threshold of Hardware flow control.
+ *
+ * @return
+ * - ESP_OK success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_set_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t flow_ctrl, uint8_t rx_thresh);
+
+/**
+ * @brief Get hardware flow control mode
+ *
+ * @param uart_num Uart port number.
+ * @param flow_ctrl Option for different flow control mode.
+ *
+ * @return
+ * - ESP_OK Success, result will be put in (*flow_ctrl)
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_get_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t *flow_ctrl);
+
+/**
+ * @brief UART0 swap.
+ * Use MTCK as UART0 RX, MTDO as UART0 TX, so ROM log will not output from
+ * this new UART0. We also need to use MTDO (U0RTS) and MTCK (U0CTS) as UART0 in hardware.
+ *
+ * @return
+ * - ESP_OK Success
+ */
+esp_err_t my_uart_enable_swap(void);
+
+/**
+ * @brief Disable UART0 swap.
+ * Use the original UART0, not MTCK and MTDO.
+ *
+ * @return
+ * - ESP_OK Success
+ */
+esp_err_t my_uart_disable_swap(void);
+
+/**
+ * @brief Clear uart interrupts status.
+ *
+ * @param uart_num Uart port number.
+ * @param mask Uart interrupt bits mask.
+ *
+ * @return
+ * - ESP_OK success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_clear_intr_status(uart_port_t uart_num, uint32_t mask);
+
+/**
+ * @brief Set UART interrupt enable
+ *
+ * @param uart_num Uart port number
+ * @param enable_mask Bit mask of the enable bits.
+ * The bit mask should be composed from the fields of register UART_INT_ENA_REG.
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_enable_intr_mask(uart_port_t uart_num, uint32_t enable_mask);
+
+/**
+ * @brief Clear UART interrupt enable bits
+ *
+ * @param uart_num Uart port number
+ * @param disable_mask Bit mask of the disable bits.
+ * The bit mask should be composed from the fields of register UART_INT_ENA_REG.
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask);
+
+/**
+ * @brief Enable UART RX interrupt (RX_FULL & RX_TIMEOUT INTERRUPT)
+ *
+ * @param uart_num UART_NUM_0
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_enable_rx_intr(uart_port_t uart_num);
+
+/**
+ * @brief Disable UART RX interrupt (RX_FULL & RX_TIMEOUT INTERRUPT)
+ *
+ * @param uart_num UART_NUM_0
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_disable_rx_intr(uart_port_t uart_num);
+
+/**
+ * @brief Disable UART TX interrupt (TX_FULL & TX_TIMEOUT INTERRUPT)
+ *
+ * @param uart_num UART_NUM_0
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_disable_tx_intr(uart_port_t uart_num);
+
+/**
+ * @brief Enable UART TX interrupt (TX_FULL & TX_TIMEOUT INTERRUPT)
+ *
+ * @param uart_num UART_NUM_0
+ * @param enable 1: enable; 0: disable
+ * @param thresh Threshold of TX interrupt, 0 ~ UART_FIFO_LEN
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh);
+
+/**
+ * @brief Register UART interrupt handler (ISR).
+ *
+ * @param uart_num UART_NUM_0
+ * @param fn Interrupt handler function.
+ * @param arg parameter for handler function
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_isr_register(uart_port_t uart_num, void (*fn)(void *), void *arg);
+
+/**
+ * @brief Config Common parameters of serial ports.
+ *
+ * @param uart_num Uart port number.
+ * @param uart_conf Uart config parameters.
+ *
+ * @return
+ * - ESP_OK success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_param_config(uart_port_t uart_num, uart_config_t *uart_conf);
+
+/**
+ * @brief Config types of uarts.
+ *
+ * @param uart_num Uart port number.
+ * @param uart_intr_conf Uart interrupt config parameters.
+ *
+ * @return
+ * - ESP_OK success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_intr_config(uart_port_t uart_num, uart_intr_config_t *uart_intr_conf);
+
+/**
+ * @brief Install UART driver.
+ *
+ * @note Rx_buffer_size should be greater than UART_FIFO_LEN. Tx_buffer_size should be either zero or greater than UART_FIFO_LEN.
+ *
+ * @param uart_num Uart port number.
+ * @param rx_buffer_size UART RX ring buffer size.
+ * @param tx_buffer_size UART TX ring buffer size.
+ * If set to zero, driver will not use TX buffer, TX function will block task until all data have been sent out.
+ * @param queue_size UART event queue size/depth.
+ * @param uart_queue UART event queue handle (out param). On success, a new queue handle is written here to provide
+ * access to UART events. If set to NULL, driver will not use an event queue.
+ * @param no_use Invalid parameters, just to fit some modules.
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, QueueHandle_t *uart_queue, int no_use);
+
+/**
+ * @brief Uninstall UART driver.
+ *
+ * @param uart_num Uart port number.
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_driver_delete(uart_port_t uart_num);
+
+/**
+ * @brief Waiting for the last byte of data to be sent
+ *
+ * @param uart_num Uart port number.
+ * @param ticks_to_wait Timeout, count in RTOS ticks
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait);
+
+/**
+ * @brief Send data to the UART port from a given buffer and length.
+ *
+ * This function will not wait for enough space in TX FIFO. It will just fill the available TX FIFO and return when the FIFO is full.
+ * @note This function should only be used when UART TX buffer is not enabled.
+ *
+ * @param uart_num Uart port number.
+ * @param buffer data buffer address
+ * @param len data length to send
+ *
+ * @return
+ * - (-1) Parameter error
+ * - OTHERS (>=0) The number of bytes pushed to the TX FIFO
+ */
+int my_uart_tx_chars(uart_port_t uart_num, const char *buffer, uint32_t len);
+
+/**
+ * @brief Send data to the UART port from a given buffer and length,
+ *
+ * If the UART driver's parameter 'tx_buffer_size' is set to zero:
+ * This function will not return until all the data have been sent out, or at least pushed into TX FIFO.
+ *
+ * Otherwise, if the 'tx_buffer_size' > 0, this function will return after copying all the data to tx ring buffer,
+ * UART ISR will then move data from the ring buffer to TX FIFO gradually.
+ *
+ * @param uart_num Uart port number.
+ * @param src data buffer address
+ * @param size data length to send
+ *
+ * @return
+ * - (-1) Parameter error
+ * - OTHERS (>=0) The number of bytes pushed to the TX FIFO
+ */
+int my_uart_write_bytes(uart_port_t uart_num, const char *src, size_t size);
+
+/**
+ * @brief UART read bytes from UART buffer
+ *
+ * @param uart_num Uart port number.
+ * @param buf pointer to the buffer.
+ * @param length data length
+ * @param ticks_to_wait sTimeout, count in RTOS ticks
+ *
+ * @return
+ * - (-1) Error
+ * - OTHERS (>=0) The number of bytes read from UART FIFO
+ */
+int my_uart_read_bytes(uart_port_t uart_num, uint8_t *buf, uint32_t length, TickType_t ticks_to_wait);
+
+/**
+ * @brief Alias of my_uart_flush_input.
+ * UART ring buffer flush. This will discard all data in the UART RX buffer.
+ * @note Instead of waiting the data sent out, this function will clear UART rx buffer.
+ * In order to send all the data in tx FIFO, we can use my_uart_wait_tx_done function.
+ * @param uart_num UART port number.
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_flush(uart_port_t uart_num);
+
+/**
+ * @brief Clear input buffer, discard all the data is in the ring-buffer.
+ * @note In order to send all the data in tx FIFO, we can use my_uart_wait_tx_done function.
+ * @param uart_num UART port number.
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_flush_input(uart_port_t uart_num);
+
+/**
+ * @brief UART get RX ring buffer cached data length
+ *
+ * @param uart_num UART port number.
+ * @param size Pointer of size_t to accept cached data length
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_get_buffered_data_len(uart_port_t uart_num, size_t *size);
+
+/**
+ * @brief UART set threshold timeout for TOUT feature
+ *
+ * @param uart_num Uart number to configure
+ * @param tout_thresh This parameter defines timeout threshold in uart symbol periods. The maximum value of threshold is 126.
+ * tout_thresh = 1, defines TOUT interrupt timeout equal to transmission time of one symbol (~11 bit) on current baudrate.
+ * If the time is expired the UART_RXFIFO_TOUT_INT interrupt is triggered. If tout_thresh == 0,
+ * the TOUT feature is disabled.
+ *
+ * @return
+ * - ESP_OK Success
+ * - ESP_ERR_INVALID_ARG Parameter error
+ */
+esp_err_t my_uart_set_rx_timeout(uart_port_t uart_num, const uint8_t tout_thresh);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _DRIVER_UART_H_
diff --git a/components/DAP/source/DAP.c b/components/DAP/source/DAP.c
new file mode 100644
index 0000000..03f048c
--- /dev/null
+++ b/components/DAP/source/DAP.c
@@ -0,0 +1,1773 @@
+/*
+ * 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.c CMSIS-DAP Commands
+ *
+ *---------------------------------------------------------------------------*/
+
+#include
+#include "DAP_config.h"
+#include "DAP.h"
+
+
+#if (DAP_PACKET_SIZE < 64U)
+#error "Minimum Packet Size is 64!"
+#endif
+#if (DAP_PACKET_SIZE > 32768U)
+#error "Maximum Packet Size is 32768!"
+#endif
+#if (DAP_PACKET_COUNT < 1U)
+#error "Minimum Packet Count is 1!"
+#endif
+#if (DAP_PACKET_COUNT > 255U)
+#error "Maximum Packet Count is 255!"
+#endif
+
+
+// Clock Macros
+
+#define MAX_SWJ_CLOCK(delay_cycles) \
+ ((CPU_CLOCK/2U) / (IO_PORT_WRITE_CYCLES + delay_cycles))
+
+#define CLOCK_DELAY(swj_clock) \
+ (((CPU_CLOCK/2U) / swj_clock) - IO_PORT_WRITE_CYCLES)
+
+
+ DAP_Data_t DAP_Data; // DAP Data
+volatile uint8_t DAP_TransferAbort; // Transfer Abort Flag
+
+
+static const char DAP_FW_Ver [] = DAP_FW_VER;
+
+#if TARGET_DEVICE_FIXED
+static const char TargetDeviceVendor [] = TARGET_DEVICE_VENDOR;
+static const char TargetDeviceName [] = TARGET_DEVICE_NAME;
+#endif
+
+
+// Get DAP Information
+// id: info identifier
+// info: pointer to info data
+// return: number of bytes in info data
+static uint8_t DAP_Info(uint8_t id, uint8_t *info) {
+ uint8_t length = 0U;
+
+ switch (id) {
+ case DAP_ID_VENDOR:
+ length = DAP_GetVendorString((char *)info);
+ break;
+ case DAP_ID_PRODUCT:
+ length = DAP_GetProductString((char *)info);
+ break;
+ case DAP_ID_SER_NUM:
+ length = DAP_GetSerNumString((char *)info);
+ break;
+ case DAP_ID_FW_VER:
+ length = (uint8_t)sizeof(DAP_FW_Ver);
+ memcpy(info, DAP_FW_Ver, length);
+ break;
+ case DAP_ID_DEVICE_VENDOR:
+#if TARGET_DEVICE_FIXED
+ length = (uint8_t)sizeof(TargetDeviceVendor);
+ memcpy(info, TargetDeviceVendor, length);
+#endif
+ break;
+ case DAP_ID_DEVICE_NAME:
+#if TARGET_DEVICE_FIXED
+ length = (uint8_t)sizeof(TargetDeviceName);
+ memcpy(info, TargetDeviceName, length);
+#endif
+ break;
+ case DAP_ID_CAPABILITIES:
+ info[0] = ((DAP_SWD != 0) ? (1U << 0) : 0U) |
+ ((DAP_JTAG != 0) ? (1U << 1) : 0U) |
+ ((SWO_UART != 0) ? (1U << 2) : 0U) |
+ ((SWO_MANCHESTER != 0) ? (1U << 3) : 0U) |
+ /* Atomic Commands */ (1U << 4) |
+ ((TIMESTAMP_CLOCK != 0U) ? (1U << 5) : 0U) |
+ ((SWO_STREAM != 0U) ? (1U << 6) : 0U);
+ length = 1U;
+ break;
+ case DAP_ID_TIMESTAMP_CLOCK:
+#if (TIMESTAMP_CLOCK != 0U)
+ info[0] = (uint8_t)(TIMESTAMP_CLOCK >> 0);
+ info[1] = (uint8_t)(TIMESTAMP_CLOCK >> 8);
+ info[2] = (uint8_t)(TIMESTAMP_CLOCK >> 16);
+ info[3] = (uint8_t)(TIMESTAMP_CLOCK >> 24);
+ length = 4U;
+#endif
+ break;
+ case DAP_ID_SWO_BUFFER_SIZE:
+#if ((SWO_UART != 0) || (SWO_MANCHESTER != 0))
+ info[0] = (uint8_t)(SWO_BUFFER_SIZE >> 0);
+ info[1] = (uint8_t)(SWO_BUFFER_SIZE >> 8);
+ info[2] = (uint8_t)(SWO_BUFFER_SIZE >> 16);
+ info[3] = (uint8_t)(SWO_BUFFER_SIZE >> 24);
+ length = 4U;
+#endif
+ break;
+ case DAP_ID_PACKET_SIZE:
+ info[0] = (uint8_t)(DAP_PACKET_SIZE >> 0);
+ info[1] = (uint8_t)(DAP_PACKET_SIZE >> 8);
+ length = 2U;
+ break;
+ case DAP_ID_PACKET_COUNT:
+ info[0] = DAP_PACKET_COUNT;
+ length = 1U;
+ break;
+ default:
+ break;
+ }
+
+ return (length);
+}
+
+
+// Delay for specified time
+// delay: delay time in ms
+void Delayms(uint32_t delay) {
+ delay *= ((CPU_CLOCK/1000U) + (DELAY_SLOW_CYCLES-1U)) / DELAY_SLOW_CYCLES;
+ PIN_DELAY_SLOW(delay);
+}
+
+
+// Process Delay 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)
+static uint32_t DAP_Delay(const uint8_t *request, uint8_t *response) {
+ uint32_t delay;
+
+ delay = (uint32_t)(*(request+0)) |
+ (uint32_t)(*(request+1) << 8);
+ delay *= ((CPU_CLOCK/1000000U) + (DELAY_SLOW_CYCLES-1U)) / DELAY_SLOW_CYCLES;
+
+ PIN_DELAY_SLOW(delay);
+
+ *response = DAP_OK;
+ return ((2U << 16) | 1U);
+}
+
+
+// Process Host 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)
+static uint32_t DAP_HostStatus(const uint8_t *request, uint8_t *response) {
+
+ switch (*request) {
+ case DAP_DEBUGGER_CONNECTED:
+ LED_CONNECTED_OUT((*(request+1) & 1U));
+ break;
+ case DAP_TARGET_RUNNING:
+ LED_RUNNING_OUT((*(request+1) & 1U));
+ break;
+ default:
+ *response = DAP_ERROR;
+ return ((2U << 16) | 1U);
+ }
+
+ *response = DAP_OK;
+ return ((2U << 16) | 1U);
+}
+
+
+// Process Connect 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)
+static uint32_t DAP_Connect(const uint8_t *request, uint8_t *response) {
+ uint32_t port;
+
+ if (*request == DAP_PORT_AUTODETECT) {
+ port = DAP_DEFAULT_PORT;
+ } else {
+ port = *request;
+ }
+
+ switch (port) {
+#if (DAP_SWD != 0)
+ case DAP_PORT_SWD:
+ DAP_Data.debug_port = DAP_PORT_SWD;
+ PORT_SWD_SETUP();
+ break;
+#endif
+#if (DAP_JTAG != 0)
+ case DAP_PORT_JTAG:
+ DAP_Data.debug_port = DAP_PORT_JTAG;
+ PORT_JTAG_SETUP();
+ break;
+#endif
+ default:
+ port = DAP_PORT_DISABLED;
+ break;
+ }
+
+ *response = (uint8_t)port;
+ return ((1U << 16) | 1U);
+}
+
+
+// Process Disconnect command and prepare response
+// response: pointer to response data
+// return: number of bytes in response
+static uint32_t DAP_Disconnect(uint8_t *response) {
+
+ DAP_Data.debug_port = DAP_PORT_DISABLED;
+ PORT_OFF();
+
+ *response = DAP_OK;
+ return (1U);
+}
+
+
+// Process Reset Target command and prepare response
+// response: pointer to response data
+// return: number of bytes in response
+static uint32_t DAP_ResetTarget(uint8_t *response) {
+
+ *(response+1) = RESET_TARGET();
+ *(response+0) = DAP_OK;
+ return (2U);
+}
+
+
+// Process SWJ Pins 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)
+static uint32_t DAP_SWJ_Pins(const uint8_t *request, uint8_t *response) {
+#if ((DAP_SWD != 0) || (DAP_JTAG != 0))
+ uint32_t value;
+ uint32_t select;
+ uint32_t wait;
+ uint32_t timestamp;
+
+ value = (uint32_t) *(request+0);
+ select = (uint32_t) *(request+1);
+ wait = (uint32_t)(*(request+2) << 0) |
+ (uint32_t)(*(request+3) << 8) |
+ (uint32_t)(*(request+4) << 16) |
+ (uint32_t)(*(request+5) << 24);
+
+ if ((select & (1U << DAP_SWJ_SWCLK_TCK)) != 0U) {
+ if ((value & (1U << DAP_SWJ_SWCLK_TCK)) != 0U) {
+ PIN_SWCLK_TCK_SET();
+ } else {
+ PIN_SWCLK_TCK_CLR();
+ }
+ }
+ if ((select & (1U << DAP_SWJ_SWDIO_TMS)) != 0U) {
+ if ((value & (1U << DAP_SWJ_SWDIO_TMS)) != 0U) {
+ PIN_SWDIO_TMS_SET();
+ } else {
+ PIN_SWDIO_TMS_CLR();
+ }
+ }
+ if ((select & (1U << DAP_SWJ_TDI)) != 0U) {
+ PIN_TDI_OUT(value >> DAP_SWJ_TDI);
+ }
+ if ((select & (1U << DAP_SWJ_nTRST)) != 0U) {
+ PIN_nTRST_OUT(value >> DAP_SWJ_nTRST);
+ }
+ if ((select & (1U << DAP_SWJ_nRESET)) != 0U){
+ PIN_nRESET_OUT(value >> DAP_SWJ_nRESET);
+ }
+
+ if (wait != 0U) {
+#if (TIMESTAMP_CLOCK != 0U)
+ if (wait > 3000000U) {
+ wait = 3000000U;
+ }
+#if (TIMESTAMP_CLOCK >= 1000000U)
+ wait *= TIMESTAMP_CLOCK / 1000000U;
+#else
+ wait /= 1000000U / TIMESTAMP_CLOCK;
+#endif
+#else
+ wait = 1U;
+#endif
+ timestamp = TIMESTAMP_GET();
+ do {
+ if ((select & (1U << DAP_SWJ_SWCLK_TCK)) != 0U) {
+ if ((value >> DAP_SWJ_SWCLK_TCK) ^ PIN_SWCLK_TCK_IN()) {
+ continue;
+ }
+ }
+ if ((select & (1U << DAP_SWJ_SWDIO_TMS)) != 0U) {
+ if ((value >> DAP_SWJ_SWDIO_TMS) ^ PIN_SWDIO_TMS_IN()) {
+ continue;
+ }
+ }
+ if ((select & (1U << DAP_SWJ_TDI)) != 0U) {
+ if ((value >> DAP_SWJ_TDI) ^ PIN_TDI_IN()) {
+ continue;
+ }
+ }
+ if ((select & (1U << DAP_SWJ_nTRST)) != 0U) {
+ if ((value >> DAP_SWJ_nTRST) ^ PIN_nTRST_IN()) {
+ continue;
+ }
+ }
+ if ((select & (1U << DAP_SWJ_nRESET)) != 0U) {
+ if ((value >> DAP_SWJ_nRESET) ^ PIN_nRESET_IN()) {
+ continue;
+ }
+ }
+ break;
+ } while ((TIMESTAMP_GET() - timestamp) < wait);
+ }
+
+ value = (PIN_SWCLK_TCK_IN() << DAP_SWJ_SWCLK_TCK) |
+ (PIN_SWDIO_TMS_IN() << DAP_SWJ_SWDIO_TMS) |
+ (PIN_TDI_IN() << DAP_SWJ_TDI) |
+ (PIN_TDO_IN() << DAP_SWJ_TDO) |
+ (PIN_nTRST_IN() << DAP_SWJ_nTRST) |
+ (PIN_nRESET_IN() << DAP_SWJ_nRESET);
+
+ *response = (uint8_t)value;
+#else
+ *response = 0U;
+#endif
+
+ return ((6U << 16) | 1U);
+}
+
+
+// Process SWJ Clock 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)
+static uint32_t DAP_SWJ_Clock(const uint8_t *request, uint8_t *response) {
+#if ((DAP_SWD != 0) || (DAP_JTAG != 0))
+ uint32_t clock;
+ uint32_t delay;
+
+ clock = (uint32_t)(*(request+0) << 0) |
+ (uint32_t)(*(request+1) << 8) |
+ (uint32_t)(*(request+2) << 16) |
+ (uint32_t)(*(request+3) << 24);
+
+ if (clock == 0U) {
+ *response = DAP_ERROR;
+ return ((4U << 16) | 1U);
+ }
+ if(clock == 10000000){
+ clock = MAX_USER_CLOCK;
+ }
+
+
+ if (clock >= MAX_SWJ_CLOCK(DELAY_FAST_CYCLES)) {
+ DAP_Data.fast_clock = 1U;
+ DAP_Data.clock_delay = 1U;
+ } else {
+ DAP_Data.fast_clock = 0U;
+
+ delay = ((CPU_CLOCK/2U) + (clock - 1U)) / clock;
+ if (delay > IO_PORT_WRITE_CYCLES) {
+ delay -= IO_PORT_WRITE_CYCLES;
+ delay = (delay + (DELAY_SLOW_CYCLES - 1U)) / DELAY_SLOW_CYCLES;
+ } else {
+ delay = 1U;
+ }
+
+ DAP_Data.clock_delay = delay;
+ }
+
+ *response = DAP_OK;
+#else
+ *response = DAP_ERROR;
+#endif
+
+ return ((4U << 16) | 1U);
+}
+
+
+// Process SWJ Sequence 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)
+static uint32_t DAP_SWJ_Sequence(const uint8_t *request, uint8_t *response) {
+ uint32_t count;
+
+ count = *request++;
+ if (count == 0U) {
+ count = 256U;
+ }
+
+#if ((DAP_SWD != 0) || (DAP_JTAG != 0))
+ SWJ_Sequence(count, request);
+ *response = DAP_OK;
+#else
+ *response = DAP_ERROR;
+#endif
+
+ count = (count + 7U) >> 3;
+
+ return (((count + 1U) << 16) | 1U);
+}
+
+
+// Process SWD 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)
+static uint32_t DAP_SWD_Configure(const uint8_t *request, uint8_t *response) {
+#if (DAP_SWD != 0)
+ uint8_t value;
+
+ value = *request;
+ DAP_Data.swd_conf.turnaround = (value & 0x03U) + 1U;
+ DAP_Data.swd_conf.data_phase = (value & 0x04U) ? 1U : 0U;
+
+ *response = DAP_OK;
+#else
+ *response = DAP_ERROR;
+#endif
+
+ return ((1U << 16) | 1U);
+}
+
+
+// Process SWD Sequence 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)
+static uint32_t DAP_SWD_Sequence(const uint8_t *request, uint8_t *response) {
+ uint32_t sequence_info;
+ uint32_t sequence_count;
+ uint32_t request_count;
+ uint32_t response_count;
+ uint32_t count;
+
+#if (DAP_SWD != 0)
+ *response++ = DAP_OK;
+#else
+ *response++ = DAP_ERROR;
+#endif
+ request_count = 1U;
+ response_count = 1U;
+
+ sequence_count = *request++;
+ while (sequence_count--) {
+ sequence_info = *request++;
+ count = sequence_info & SWD_SEQUENCE_CLK;
+ if (count == 0U) {
+ count = 64U;
+ }
+ count = (count + 7U) / 8U;
+#if (DAP_SWD != 0)
+ if ((sequence_info & SWD_SEQUENCE_DIN) != 0U) {
+ PIN_SWDIO_OUT_DISABLE();
+ } else {
+ PIN_SWDIO_OUT_ENABLE();
+ }
+ SWD_Sequence(sequence_info, request, response);
+ if (sequence_count == 0U) {
+ PIN_SWDIO_OUT_ENABLE();
+ }
+#endif
+ if ((sequence_info & SWD_SEQUENCE_DIN) != 0U) {
+ request_count++;
+#if (DAP_SWD != 0)
+ response += count;
+ response_count += count;
+#endif
+ } else {
+ request += count;
+ request_count += count + 1U;
+ }
+ }
+
+ return ((request_count << 16) | response_count);
+}
+
+
+// Process JTAG Sequence 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)
+static uint32_t DAP_JTAG_Sequence(const uint8_t *request, uint8_t *response) {
+ uint32_t sequence_info;
+ uint32_t sequence_count;
+ uint32_t request_count;
+ uint32_t response_count;
+ uint32_t count;
+
+#if (DAP_JTAG != 0)
+ *response++ = DAP_OK;
+#else
+ *response++ = DAP_ERROR;
+#endif
+ request_count = 1U;
+ response_count = 1U;
+
+ sequence_count = *request++;
+ while (sequence_count--) {
+ sequence_info = *request++;
+ count = sequence_info & JTAG_SEQUENCE_TCK;
+ if (count == 0U) {
+ count = 64U;
+ }
+ count = (count + 7U) / 8U;
+#if (DAP_JTAG != 0)
+ JTAG_Sequence(sequence_info, request, response);
+#endif
+ request += count;
+ request_count += count + 1U;
+#if (DAP_JTAG != 0)
+ if ((sequence_info & JTAG_SEQUENCE_TDO) != 0U) {
+ response += count;
+ response_count += count;
+ }
+#endif
+ }
+
+ return ((request_count << 16) | response_count);
+}
+
+
+// Process JTAG 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)
+static uint32_t DAP_JTAG_Configure(const uint8_t *request, uint8_t *response) {
+ uint32_t count;
+#if (DAP_JTAG != 0)
+ uint32_t length;
+ uint32_t bits;
+ uint32_t n;
+
+ count = *request++;
+ DAP_Data.jtag_dev.count = (uint8_t)count;
+
+ bits = 0U;
+ for (n = 0U; n < count; n++) {
+ length = *request++;
+ DAP_Data.jtag_dev.ir_length[n] = (uint8_t)length;
+ DAP_Data.jtag_dev.ir_before[n] = (uint16_t)bits;
+ bits += length;
+ }
+ for (n = 0U; n < count; n++) {
+ bits -= DAP_Data.jtag_dev.ir_length[n];
+ DAP_Data.jtag_dev.ir_after[n] = (uint16_t)bits;
+ }
+
+ *response = DAP_OK;
+#else
+ count = *request;
+ *response = DAP_ERROR;
+#endif
+
+ return (((count + 1U) << 16) | 1U);
+}
+
+
+// Process JTAG IDCODE 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)
+static uint32_t DAP_JTAG_IDCode(const uint8_t *request, uint8_t *response) {
+#if (DAP_JTAG != 0)
+ uint32_t data;
+
+ if (DAP_Data.debug_port != DAP_PORT_JTAG) {
+ goto id_error;
+ }
+
+ // Device index (JTAP TAP)
+ DAP_Data.jtag_dev.index = *request;
+ if (DAP_Data.jtag_dev.index >= DAP_Data.jtag_dev.count) {
+ goto id_error;
+ }
+
+ // Select JTAG chain
+ JTAG_IR(JTAG_IDCODE);
+
+ // Read IDCODE register
+ data = JTAG_ReadIDCode();
+
+ // Store Data
+ *(response+0) = DAP_OK;
+ *(response+1) = (uint8_t)(data >> 0);
+ *(response+2) = (uint8_t)(data >> 8);
+ *(response+3) = (uint8_t)(data >> 16);
+ *(response+4) = (uint8_t)(data >> 24);
+
+ return ((1U << 16) | 5U);
+
+id_error:
+#endif
+ *response = DAP_ERROR;
+ return ((1U << 16) | 1U);
+}
+
+
+// Process Transfer 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)
+static uint32_t DAP_TransferConfigure(const uint8_t *request, uint8_t *response) {
+
+ DAP_Data.transfer.idle_cycles = *(request+0);
+ DAP_Data.transfer.retry_count = (uint16_t) *(request+1) |
+ (uint16_t)(*(request+2) << 8);
+ DAP_Data.transfer.match_retry = (uint16_t) *(request+3) |
+ (uint16_t)(*(request+4) << 8);
+
+ *response = DAP_OK;
+ return ((5U << 16) | 1U);
+}
+
+
+// Process SWD 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)
+#if (DAP_SWD != 0)
+static uint32_t DAP_SWD_Transfer(const uint8_t *request, uint8_t *response) {
+ const
+ uint8_t *request_head;
+ uint32_t request_count;
+ uint32_t request_value;
+ uint8_t *response_head;
+ uint32_t response_count;
+ uint32_t response_value;
+ uint32_t post_read;
+ uint32_t check_write;
+ uint32_t match_value;
+ uint32_t match_retry;
+ uint32_t retry;
+ uint32_t data;
+#if (TIMESTAMP_CLOCK != 0U)
+ uint32_t timestamp;
+#endif
+
+ request_head = request;
+
+ response_count = 0U;
+ response_value = 0U;
+ response_head = response;
+ response += 2;
+
+ DAP_TransferAbort = 0U;
+
+ post_read = 0U;
+ check_write = 0U;
+
+ request++; // Ignore DAP index
+
+ request_count = *request++;
+
+ for (; request_count != 0U; request_count--) {
+ request_value = *request++;
+ if ((request_value & DAP_TRANSFER_RnW) != 0U) {
+ // Read register
+ if (post_read) {
+ // Read was posted before
+ retry = DAP_Data.transfer.retry_count;
+ if ((request_value & (DAP_TRANSFER_APnDP | DAP_TRANSFER_MATCH_VALUE)) == DAP_TRANSFER_APnDP) {
+ // Read previous AP data and post next AP read
+ do {
+ response_value = SWD_Transfer(request_value, &data);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ } else {
+ // Read previous AP data
+ do {
+ response_value = SWD_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ post_read = 0U;
+ }
+ if (response_value != DAP_TRANSFER_OK) {
+ break;
+ }
+ // Store previous AP data
+ *response++ = (uint8_t) data;
+ *response++ = (uint8_t)(data >> 8);
+ *response++ = (uint8_t)(data >> 16);
+ *response++ = (uint8_t)(data >> 24);
+#if (TIMESTAMP_CLOCK != 0U)
+ if (post_read) {
+ // Store Timestamp of next AP read
+ if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
+ timestamp = DAP_Data.timestamp;
+ *response++ = (uint8_t) timestamp;
+ *response++ = (uint8_t)(timestamp >> 8);
+ *response++ = (uint8_t)(timestamp >> 16);
+ *response++ = (uint8_t)(timestamp >> 24);
+ }
+ }
+#endif
+ }
+ if ((request_value & DAP_TRANSFER_MATCH_VALUE) != 0U) {
+ // Read with value match
+ match_value = (uint32_t)(*(request+0) << 0) |
+ (uint32_t)(*(request+1) << 8) |
+ (uint32_t)(*(request+2) << 16) |
+ (uint32_t)(*(request+3) << 24);
+ request += 4;
+ match_retry = DAP_Data.transfer.match_retry;
+ if ((request_value & DAP_TRANSFER_APnDP) != 0U) {
+ // Post AP read
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = SWD_Transfer(request_value, NULL);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ if (response_value != DAP_TRANSFER_OK) {
+ break;
+ }
+ }
+ do {
+ // Read register until its value matches or retry counter expires
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = SWD_Transfer(request_value, &data);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ if (response_value != DAP_TRANSFER_OK) {
+ break;
+ }
+ } while (((data & DAP_Data.transfer.match_mask) != match_value) && match_retry-- && !DAP_TransferAbort);
+ if ((data & DAP_Data.transfer.match_mask) != match_value) {
+ response_value |= DAP_TRANSFER_MISMATCH;
+ }
+ if (response_value != DAP_TRANSFER_OK) {
+ break;
+ }
+ } else {
+ // Normal read
+ retry = DAP_Data.transfer.retry_count;
+ if ((request_value & DAP_TRANSFER_APnDP) != 0U) {
+ // Read AP register
+ if (post_read == 0U) {
+ // Post AP read
+ do {
+ response_value = SWD_Transfer(request_value, NULL);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ if (response_value != DAP_TRANSFER_OK) {
+ break;
+ }
+#if (TIMESTAMP_CLOCK != 0U)
+ // Store Timestamp
+ if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
+ timestamp = DAP_Data.timestamp;
+ *response++ = (uint8_t) timestamp;
+ *response++ = (uint8_t)(timestamp >> 8);
+ *response++ = (uint8_t)(timestamp >> 16);
+ *response++ = (uint8_t)(timestamp >> 24);
+ }
+#endif
+ post_read = 1U;
+ }
+ } else {
+ // Read DP register
+ do {
+ response_value = SWD_Transfer(request_value, &data);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ if (response_value != DAP_TRANSFER_OK) {
+ break;
+ }
+#if (TIMESTAMP_CLOCK != 0U)
+ // Store Timestamp
+ if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
+ timestamp = DAP_Data.timestamp;
+ *response++ = (uint8_t) timestamp;
+ *response++ = (uint8_t)(timestamp >> 8);
+ *response++ = (uint8_t)(timestamp >> 16);
+ *response++ = (uint8_t)(timestamp >> 24);
+ }
+#endif
+ // Store data
+ *response++ = (uint8_t) data;
+ *response++ = (uint8_t)(data >> 8);
+ *response++ = (uint8_t)(data >> 16);
+ *response++ = (uint8_t)(data >> 24);
+ }
+ }
+ check_write = 0U;
+ } else {
+ // Write register
+ if (post_read) {
+ // Read previous data
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = SWD_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ if (response_value != DAP_TRANSFER_OK) {
+ break;
+ }
+ // Store previous data
+ *response++ = (uint8_t) data;
+ *response++ = (uint8_t)(data >> 8);
+ *response++ = (uint8_t)(data >> 16);
+ *response++ = (uint8_t)(data >> 24);
+ post_read = 0U;
+ }
+ // Load data
+ data = (uint32_t)(*(request+0) << 0) |
+ (uint32_t)(*(request+1) << 8) |
+ (uint32_t)(*(request+2) << 16) |
+ (uint32_t)(*(request+3) << 24);
+ request += 4;
+ if ((request_value & DAP_TRANSFER_MATCH_MASK) != 0U) {
+ // Write match mask
+ DAP_Data.transfer.match_mask = data;
+ response_value = DAP_TRANSFER_OK;
+ } else {
+ // Write DP/AP register
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = SWD_Transfer(request_value, &data);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ if (response_value != DAP_TRANSFER_OK) {
+ break;
+ }
+#if (TIMESTAMP_CLOCK != 0U)
+ // Store Timestamp
+ if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
+ timestamp = DAP_Data.timestamp;
+ *response++ = (uint8_t) timestamp;
+ *response++ = (uint8_t)(timestamp >> 8);
+ *response++ = (uint8_t)(timestamp >> 16);
+ *response++ = (uint8_t)(timestamp >> 24);
+ }
+#endif
+ check_write = 1U;
+ }
+ }
+ response_count++;
+ if (DAP_TransferAbort) {
+ break;
+ }
+ }
+
+ for (; request_count != 0U; request_count--) {
+ // Process canceled requests
+ request_value = *request++;
+ if ((request_value & DAP_TRANSFER_RnW) != 0U) {
+ // Read register
+ if ((request_value & DAP_TRANSFER_MATCH_VALUE) != 0U) {
+ // Read with value match
+ request += 4;
+ }
+ } else {
+ // Write register
+ request += 4;
+ }
+ }
+
+ if (response_value == DAP_TRANSFER_OK) {
+ if (post_read) {
+ // Read previous data
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = SWD_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ if (response_value != DAP_TRANSFER_OK) {
+ goto end;
+ }
+ // Store previous data
+ *response++ = (uint8_t) data;
+ *response++ = (uint8_t)(data >> 8);
+ *response++ = (uint8_t)(data >> 16);
+ *response++ = (uint8_t)(data >> 24);
+ } else if (check_write) {
+ // Check last write
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = SWD_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, NULL);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ }
+ }
+
+end:
+ *(response_head+0) = (uint8_t)response_count;
+ *(response_head+1) = (uint8_t)response_value;
+
+ return (((uint32_t)(request - request_head) << 16) | (uint32_t)(response - response_head));
+}
+#endif
+
+
+// Process JTAG 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)
+#if (DAP_JTAG != 0)
+static uint32_t DAP_JTAG_Transfer(const uint8_t *request, uint8_t *response) {
+ const
+ uint8_t *request_head;
+ uint32_t request_count;
+ uint32_t request_value;
+ uint32_t request_ir;
+ uint8_t *response_head;
+ uint32_t response_count;
+ uint32_t response_value;
+ uint32_t post_read;
+ uint32_t match_value;
+ uint32_t match_retry;
+ uint32_t retry;
+ uint32_t data;
+ uint32_t ir;
+#if (TIMESTAMP_CLOCK != 0U)
+ uint32_t timestamp;
+#endif
+
+ request_head = request;
+
+ response_count = 0U;
+ response_value = 0U;
+ response_head = response;
+ response += 2;
+
+ DAP_TransferAbort = 0U;
+
+ ir = 0U;
+ post_read = 0U;
+
+ // Device index (JTAP TAP)
+ DAP_Data.jtag_dev.index = *request++;
+ if (DAP_Data.jtag_dev.index >= DAP_Data.jtag_dev.count) {
+ goto end;
+ }
+
+ request_count = *request++;
+
+ for (; request_count != 0U; request_count--) {
+ request_value = *request++;
+ request_ir = (request_value & DAP_TRANSFER_APnDP) ? JTAG_APACC : JTAG_DPACC;
+ if ((request_value & DAP_TRANSFER_RnW) != 0U) {
+ // Read register
+ if (post_read) {
+ // Read was posted before
+ retry = DAP_Data.transfer.retry_count;
+ if ((ir == request_ir) && ((request_value & DAP_TRANSFER_MATCH_VALUE) == 0U)) {
+ // Read previous data and post next read
+ do {
+ response_value = JTAG_Transfer(request_value, &data);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ } else {
+ // Select JTAG chain
+ if (ir != JTAG_DPACC) {
+ ir = JTAG_DPACC;
+ JTAG_IR(ir);
+ }
+ // Read previous data
+ do {
+ response_value = JTAG_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ post_read = 0U;
+ }
+ if (response_value != DAP_TRANSFER_OK) {
+ break;
+ }
+ // Store previous data
+ *response++ = (uint8_t) data;
+ *response++ = (uint8_t)(data >> 8);
+ *response++ = (uint8_t)(data >> 16);
+ *response++ = (uint8_t)(data >> 24);
+#if (TIMESTAMP_CLOCK != 0U)
+ if (post_read) {
+ // Store Timestamp of next AP read
+ if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
+ timestamp = DAP_Data.timestamp;
+ *response++ = (uint8_t) timestamp;
+ *response++ = (uint8_t)(timestamp >> 8);
+ *response++ = (uint8_t)(timestamp >> 16);
+ *response++ = (uint8_t)(timestamp >> 24);
+ }
+ }
+#endif
+ }
+ if ((request_value & DAP_TRANSFER_MATCH_VALUE) != 0U) {
+ // Read with value match
+ match_value = (uint32_t)(*(request+0) << 0) |
+ (uint32_t)(*(request+1) << 8) |
+ (uint32_t)(*(request+2) << 16) |
+ (uint32_t)(*(request+3) << 24);
+ request += 4;
+ match_retry = DAP_Data.transfer.match_retry;
+ // Select JTAG chain
+ if (ir != request_ir) {
+ ir = request_ir;
+ JTAG_IR(ir);
+ }
+ // Post DP/AP read
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = JTAG_Transfer(request_value, NULL);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ if (response_value != DAP_TRANSFER_OK) {
+ break;
+ }
+ do {
+ // Read register until its value matches or retry counter expires
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = JTAG_Transfer(request_value, &data);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ if (response_value != DAP_TRANSFER_OK) {
+ break;
+ }
+ } while (((data & DAP_Data.transfer.match_mask) != match_value) && match_retry-- && !DAP_TransferAbort);
+ if ((data & DAP_Data.transfer.match_mask) != match_value) {
+ response_value |= DAP_TRANSFER_MISMATCH;
+ }
+ if (response_value != DAP_TRANSFER_OK) {
+ break;
+ }
+ } else {
+ // Normal read
+ if (post_read == 0U) {
+ // Select JTAG chain
+ if (ir != request_ir) {
+ ir = request_ir;
+ JTAG_IR(ir);
+ }
+ // Post DP/AP read
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = JTAG_Transfer(request_value, NULL);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ if (response_value != DAP_TRANSFER_OK) {
+ break;
+ }
+#if (TIMESTAMP_CLOCK != 0U)
+ // Store Timestamp
+ if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
+ timestamp = DAP_Data.timestamp;
+ *response++ = (uint8_t) timestamp;
+ *response++ = (uint8_t)(timestamp >> 8);
+ *response++ = (uint8_t)(timestamp >> 16);
+ *response++ = (uint8_t)(timestamp >> 24);
+ }
+#endif
+ post_read = 1U;
+ }
+ }
+ } else {
+ // Write register
+ if (post_read) {
+ // Select JTAG chain
+ if (ir != JTAG_DPACC) {
+ ir = JTAG_DPACC;
+ JTAG_IR(ir);
+ }
+ // Read previous data
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = JTAG_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ if (response_value != DAP_TRANSFER_OK) {
+ break;
+ }
+ // Store previous data
+ *response++ = (uint8_t) data;
+ *response++ = (uint8_t)(data >> 8);
+ *response++ = (uint8_t)(data >> 16);
+ *response++ = (uint8_t)(data >> 24);
+ post_read = 0U;
+ }
+ // Load data
+ data = (uint32_t)(*(request+0) << 0) |
+ (uint32_t)(*(request+1) << 8) |
+ (uint32_t)(*(request+2) << 16) |
+ (uint32_t)(*(request+3) << 24);
+ request += 4;
+ if ((request_value & DAP_TRANSFER_MATCH_MASK) != 0U) {
+ // Write match mask
+ DAP_Data.transfer.match_mask = data;
+ response_value = DAP_TRANSFER_OK;
+ } else {
+ // Select JTAG chain
+ if (ir != request_ir) {
+ ir = request_ir;
+ JTAG_IR(ir);
+ }
+ // Write DP/AP register
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = JTAG_Transfer(request_value, &data);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ if (response_value != DAP_TRANSFER_OK) {
+ break;
+ }
+#if (TIMESTAMP_CLOCK != 0U)
+ // Store Timestamp
+ if ((request_value & DAP_TRANSFER_TIMESTAMP) != 0U) {
+ timestamp = DAP_Data.timestamp;
+ *response++ = (uint8_t) timestamp;
+ *response++ = (uint8_t)(timestamp >> 8);
+ *response++ = (uint8_t)(timestamp >> 16);
+ *response++ = (uint8_t)(timestamp >> 24);
+ }
+#endif
+ }
+ }
+ response_count++;
+ if (DAP_TransferAbort) {
+ break;
+ }
+ }
+
+ for (; request_count != 0U; request_count--) {
+ // Process canceled requests
+ request_value = *request++;
+ if ((request_value & DAP_TRANSFER_RnW) != 0U) {
+ // Read register
+ if ((request_value & DAP_TRANSFER_MATCH_VALUE) != 0U) {
+ // Read with value match
+ request += 4;
+ }
+ } else {
+ // Write register
+ request += 4;
+ }
+ }
+
+ if (response_value == DAP_TRANSFER_OK) {
+ // Select JTAG chain
+ if (ir != JTAG_DPACC) {
+ ir = JTAG_DPACC;
+ JTAG_IR(ir);
+ }
+ if (post_read) {
+ // Read previous data
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = JTAG_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, &data);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ if (response_value != DAP_TRANSFER_OK) {
+ goto end;
+ }
+ // Store previous data
+ *response++ = (uint8_t) data;
+ *response++ = (uint8_t)(data >> 8);
+ *response++ = (uint8_t)(data >> 16);
+ *response++ = (uint8_t)(data >> 24);
+ } else {
+ // Check last write
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = JTAG_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, NULL);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ }
+ }
+
+end:
+ *(response_head+0) = (uint8_t)response_count;
+ *(response_head+1) = (uint8_t)response_value;
+
+ return (((uint32_t)(request - request_head) << 16) | (uint32_t)(response - response_head));
+}
+#endif
+
+
+// Process Dummy 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)
+static uint32_t DAP_Dummy_Transfer(const uint8_t *request, uint8_t *response) {
+ const
+ uint8_t *request_head;
+ uint32_t request_count;
+ uint32_t request_value;
+
+ request_head = request;
+
+ request++; // Ignore DAP index
+
+ request_count = *request++;
+
+ for (; request_count != 0U; request_count--) {
+ // Process dummy requests
+ request_value = *request++;
+ if ((request_value & DAP_TRANSFER_RnW) != 0U) {
+ // Read register
+ if ((request_value & DAP_TRANSFER_MATCH_VALUE) != 0U) {
+ // Read with value match
+ request += 4;
+ }
+ } else {
+ // Write register
+ request += 4;
+ }
+ }
+
+ *(response+0) = 0U; // Response count
+ *(response+1) = 0U; // Response value
+
+ return (((uint32_t)(request - request_head) << 16) | 2U);
+}
+
+
+// Process 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)
+static uint32_t DAP_Transfer(const uint8_t *request, uint8_t *response) {
+ uint32_t num;
+
+ switch (DAP_Data.debug_port) {
+#if (DAP_SWD != 0)
+ case DAP_PORT_SWD:
+ num = DAP_SWD_Transfer(request, response);
+ break;
+#endif
+#if (DAP_JTAG != 0)
+ case DAP_PORT_JTAG:
+ num = DAP_JTAG_Transfer(request, response);
+ break;
+#endif
+ default:
+ num = DAP_Dummy_Transfer(request, response);
+ break;
+ }
+
+ return (num);
+}
+
+
+// Process SWD Transfer Block command and prepare response
+// request: pointer to request data
+// response: pointer to response data
+// return: number of bytes in response
+#if (DAP_SWD != 0)
+static uint32_t DAP_SWD_TransferBlock(const uint8_t *request, uint8_t *response) {
+ uint32_t request_count;
+ uint32_t request_value;
+ uint32_t response_count;
+ uint32_t response_value;
+ uint8_t *response_head;
+ uint32_t retry;
+ uint32_t data;
+
+ response_count = 0U;
+ response_value = 0U;
+ response_head = response;
+ response += 3;
+
+ DAP_TransferAbort = 0U;
+
+ request++; // Ignore DAP index
+
+ request_count = (uint32_t)(*(request+0) << 0) |
+ (uint32_t)(*(request+1) << 8);
+ request += 2;
+ if (request_count == 0U) {
+ goto end;
+ }
+
+ request_value = *request++;
+ if ((request_value & DAP_TRANSFER_RnW) != 0U) {
+ // Read register block
+ if ((request_value & DAP_TRANSFER_APnDP) != 0U) {
+ // Post AP read
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = SWD_Transfer(request_value, NULL);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ if (response_value != DAP_TRANSFER_OK) {
+ goto end;
+ }
+ }
+ while (request_count--) {
+ // Read DP/AP register
+ if ((request_count == 0U) && ((request_value & DAP_TRANSFER_APnDP) != 0U)) {
+ // Last AP read
+ request_value = DP_RDBUFF | DAP_TRANSFER_RnW;
+ }
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = SWD_Transfer(request_value, &data);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ if (response_value != DAP_TRANSFER_OK) {
+ goto end;
+ }
+ // Store data
+ *response++ = (uint8_t) data;
+ *response++ = (uint8_t)(data >> 8);
+ *response++ = (uint8_t)(data >> 16);
+ *response++ = (uint8_t)(data >> 24);
+ response_count++;
+ }
+ } else {
+ // Write register block
+ while (request_count--) {
+ // Load data
+ data = (uint32_t)(*(request+0) << 0) |
+ (uint32_t)(*(request+1) << 8) |
+ (uint32_t)(*(request+2) << 16) |
+ (uint32_t)(*(request+3) << 24);
+ request += 4;
+ // Write DP/AP register
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = SWD_Transfer(request_value, &data);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ if (response_value != DAP_TRANSFER_OK) {
+ goto end;
+ }
+ response_count++;
+ }
+ // Check last write
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = SWD_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, NULL);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ }
+
+end:
+ *(response_head+0) = (uint8_t)(response_count >> 0);
+ *(response_head+1) = (uint8_t)(response_count >> 8);
+ *(response_head+2) = (uint8_t) response_value;
+
+ return ((uint32_t)(response - response_head));
+}
+#endif
+
+
+// Process JTAG Transfer Block command and prepare response
+// request: pointer to request data
+// response: pointer to response data
+// return: number of bytes in response
+#if (DAP_JTAG != 0)
+static uint32_t DAP_JTAG_TransferBlock(const uint8_t *request, uint8_t *response) {
+ uint32_t request_count;
+ uint32_t request_value;
+ uint32_t response_count;
+ uint32_t response_value;
+ uint8_t *response_head;
+ uint32_t retry;
+ uint32_t data;
+ uint32_t ir;
+
+ response_count = 0U;
+ response_value = 0U;
+ response_head = response;
+ response += 3;
+
+ DAP_TransferAbort = 0U;
+
+ // Device index (JTAP TAP)
+ DAP_Data.jtag_dev.index = *request++;
+ if (DAP_Data.jtag_dev.index >= DAP_Data.jtag_dev.count) {
+ goto end;
+ }
+
+ request_count = (uint32_t)(*(request+0) << 0) |
+ (uint32_t)(*(request+1) << 8);
+ request += 2;
+ if (request_count == 0U) {
+ goto end;
+ }
+
+ request_value = *request++;
+
+ // Select JTAG chain
+ ir = (request_value & DAP_TRANSFER_APnDP) ? JTAG_APACC : JTAG_DPACC;
+ JTAG_IR(ir);
+
+ if ((request_value & DAP_TRANSFER_RnW) != 0U) {
+ // Post read
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = JTAG_Transfer(request_value, NULL);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ if (response_value != DAP_TRANSFER_OK) {
+ goto end;
+ }
+ // Read register block
+ while (request_count--) {
+ // Read DP/AP register
+ if (request_count == 0U) {
+ // Last read
+ if (ir != JTAG_DPACC) {
+ JTAG_IR(JTAG_DPACC);
+ }
+ request_value = DP_RDBUFF | DAP_TRANSFER_RnW;
+ }
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = JTAG_Transfer(request_value, &data);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ if (response_value != DAP_TRANSFER_OK) {
+ goto end;
+ }
+ // Store data
+ *response++ = (uint8_t) data;
+ *response++ = (uint8_t)(data >> 8);
+ *response++ = (uint8_t)(data >> 16);
+ *response++ = (uint8_t)(data >> 24);
+ response_count++;
+ }
+ } else {
+ // Write register block
+ while (request_count--) {
+ // Load data
+ data = (uint32_t)(*(request+0) << 0) |
+ (uint32_t)(*(request+1) << 8) |
+ (uint32_t)(*(request+2) << 16) |
+ (uint32_t)(*(request+3) << 24);
+ request += 4;
+ // Write DP/AP register
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = JTAG_Transfer(request_value, &data);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ if (response_value != DAP_TRANSFER_OK) {
+ goto end;
+ }
+ response_count++;
+ }
+ // Check last write
+ if (ir != JTAG_DPACC) {
+ JTAG_IR(JTAG_DPACC);
+ }
+ retry = DAP_Data.transfer.retry_count;
+ do {
+ response_value = JTAG_Transfer(DP_RDBUFF | DAP_TRANSFER_RnW, NULL);
+ } while ((response_value == DAP_TRANSFER_WAIT) && retry-- && !DAP_TransferAbort);
+ }
+
+end:
+ *(response_head+0) = (uint8_t)(response_count >> 0);
+ *(response_head+1) = (uint8_t)(response_count >> 8);
+ *(response_head+2) = (uint8_t) response_value;
+
+ return ((uint32_t)(response - response_head));
+}
+#endif
+
+
+// Process Transfer Block 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)
+static uint32_t DAP_TransferBlock(const uint8_t *request, uint8_t *response) {
+ uint32_t num;
+
+ switch (DAP_Data.debug_port) {
+#if (DAP_SWD != 0)
+ case DAP_PORT_SWD:
+ num = DAP_SWD_TransferBlock (request, response);
+ break;
+#endif
+#if (DAP_JTAG != 0)
+ case DAP_PORT_JTAG:
+ num = DAP_JTAG_TransferBlock(request, response);
+ break;
+#endif
+ default:
+ *(response+0) = 0U; // Response count [7:0]
+ *(response+1) = 0U; // Response count[15:8]
+ *(response+2) = 0U; // Response value
+ num = 3U;
+ break;
+ }
+
+ if ((*(request+3) & DAP_TRANSFER_RnW) != 0U) {
+ // Read register block
+ num |= 4U << 16;
+ } else {
+ // Write register block
+ num |= (4U + (((uint32_t)(*(request+1)) | (uint32_t)(*(request+2) << 8)) * 4)) << 16;
+ }
+
+ return (num);
+}
+
+
+// Process SWD Write ABORT command and prepare response
+// request: pointer to request data
+// response: pointer to response data
+// return: number of bytes in response
+#if (DAP_SWD != 0)
+static uint32_t DAP_SWD_WriteAbort(const uint8_t *request, uint8_t *response) {
+ uint32_t data;
+
+ // Load data (Ignore DAP index)
+ data = (uint32_t)(*(request+1) << 0) |
+ (uint32_t)(*(request+2) << 8) |
+ (uint32_t)(*(request+3) << 16) |
+ (uint32_t)(*(request+4) << 24);
+
+ // Write Abort register
+ SWD_Transfer(DP_ABORT, &data);
+
+ *response = DAP_OK;
+ return (1U);
+}
+#endif
+
+
+// Process JTAG Write ABORT command and prepare response
+// request: pointer to request data
+// response: pointer to response data
+// return: number of bytes in response
+#if (DAP_JTAG != 0)
+static uint32_t DAP_JTAG_WriteAbort(const uint8_t *request, uint8_t *response) {
+ uint32_t data;
+
+ // Device index (JTAP TAP)
+ DAP_Data.jtag_dev.index = *request;
+ if (DAP_Data.jtag_dev.index >= DAP_Data.jtag_dev.count) {
+ *response = DAP_ERROR;
+ return (1U);
+ }
+
+ // Select JTAG chain
+ JTAG_IR(JTAG_ABORT);
+
+ // Load data
+ data = (uint32_t)(*(request+1) << 0) |
+ (uint32_t)(*(request+2) << 8) |
+ (uint32_t)(*(request+3) << 16) |
+ (uint32_t)(*(request+4) << 24);
+
+ // Write Abort register
+ JTAG_WriteAbort(data);
+
+ *response = DAP_OK;
+ return (1U);
+}
+#endif
+
+
+// Process Write ABORT 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)
+static uint32_t DAP_WriteAbort(const uint8_t *request, uint8_t *response) {
+ uint32_t num;
+
+ switch (DAP_Data.debug_port) {
+#if (DAP_SWD != 0)
+ case DAP_PORT_SWD:
+ num = DAP_SWD_WriteAbort (request, response);
+ break;
+#endif
+#if (DAP_JTAG != 0)
+ case DAP_PORT_JTAG:
+ num = DAP_JTAG_WriteAbort(request, response);
+ break;
+#endif
+ default:
+ *response = DAP_ERROR;
+ num = 1U;
+ break;
+ }
+ return ((5U << 16) | num);
+}
+
+
+// Process DAP Vendor command request and prepare response
+// Default function (can be overridden)
+// 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)
+__WEAK uint32_t DAP_ProcessVendorCommand(const uint8_t *request, uint8_t *response) {
+ (void)request;
+ *response = ID_DAP_Invalid;
+ return ((1U << 16) | 1U);
+}
+
+
+// Process DAP command request 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 DAP_ProcessCommand(const uint8_t *request, uint8_t *response) {
+ uint32_t num;
+
+ if ((*request >= ID_DAP_Vendor0) && (*request <= ID_DAP_Vendor31)) {
+ return DAP_ProcessVendorCommand(request, response);
+ }
+
+ *response++ = *request;
+
+ switch (*request++) {
+ case ID_DAP_Info:
+ num = DAP_Info(*request, response+1);
+ *response = (uint8_t)num;
+ return ((2U << 16) + 2U + num);
+
+ case ID_DAP_HostStatus:
+ num = DAP_HostStatus(request, response);
+ break;
+
+ case ID_DAP_Connect:
+ num = DAP_Connect(request, response);
+ break;
+ case ID_DAP_Disconnect:
+ num = DAP_Disconnect(response);
+ break;
+
+ case ID_DAP_Delay:
+ num = DAP_Delay(request, response);
+ break;
+
+ case ID_DAP_ResetTarget:
+ num = DAP_ResetTarget(response);
+ break;
+
+ case ID_DAP_SWJ_Pins:
+ num = DAP_SWJ_Pins(request, response);
+ break;
+ case ID_DAP_SWJ_Clock:
+ num = DAP_SWJ_Clock(request, response);
+ break;
+ case ID_DAP_SWJ_Sequence:
+ num = DAP_SWJ_Sequence(request, response);
+ break;
+
+ case ID_DAP_SWD_Configure:
+ num = DAP_SWD_Configure(request, response);
+ break;
+ case ID_DAP_SWD_Sequence:
+ num = DAP_SWD_Sequence(request, response);
+ break;
+
+ case ID_DAP_JTAG_Sequence:
+ num = DAP_JTAG_Sequence(request, response);
+ break;
+ case ID_DAP_JTAG_Configure:
+ num = DAP_JTAG_Configure(request, response);
+ break;
+ case ID_DAP_JTAG_IDCODE:
+ num = DAP_JTAG_IDCode(request, response);
+ break;
+
+ case ID_DAP_TransferConfigure:
+ num = DAP_TransferConfigure(request, response);
+ break;
+ case ID_DAP_Transfer:
+ num = DAP_Transfer(request, response);
+ break;
+ case ID_DAP_TransferBlock:
+ num = DAP_TransferBlock(request, response);
+ break;
+
+ case ID_DAP_WriteABORT:
+ num = DAP_WriteAbort(request, response);
+ break;
+
+#if ((SWO_UART != 0) || (SWO_MANCHESTER != 0))
+ case ID_DAP_SWO_Transport:
+ num = SWO_Transport(request, response);
+ break;
+ case ID_DAP_SWO_Mode:
+ num = SWO_Mode(request, response);
+ break;
+ case ID_DAP_SWO_Baudrate:
+ num = SWO_Baudrate(request, response);
+ break;
+ case ID_DAP_SWO_Control:
+ num = SWO_Control(request, response);
+ break;
+ case ID_DAP_SWO_Status:
+ num = SWO_Status(response);
+ break;
+ case ID_DAP_SWO_ExtendedStatus:
+ num = SWO_ExtendedStatus(request, response);
+ break;
+ case ID_DAP_SWO_Data:
+ num = SWO_Data(request, response);
+ break;
+#endif
+
+ default:
+ *(response-1) = ID_DAP_Invalid;
+ return ((1U << 16) | 1U);
+ }
+
+ return ((1U << 16) + 1U + num);
+}
+
+
+// Execute DAP command (process request 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 DAP_ExecuteCommand(const uint8_t *request, uint8_t *response) {
+ uint32_t cnt, num, n;
+
+ if (*request == ID_DAP_ExecuteCommands) {
+ *response++ = *request++;
+ cnt = *request++;
+ *response++ = (uint8_t)cnt;
+ num = (2U << 16) | 2U;
+ while (cnt--) {
+ n = DAP_ProcessCommand(request, response);
+ num += n;
+ request += (uint16_t)(n >> 16);
+ response += (uint16_t) n;
+ }
+ return (num);
+ }
+
+ return DAP_ProcessCommand(request, response);
+}
+
+
+// Setup DAP
+void DAP_Setup(void) {
+
+ // Default settings
+ DAP_Data.debug_port = 0U;
+ DAP_Data.fast_clock = 0U;
+ DAP_Data.clock_delay = CLOCK_DELAY(DAP_DEFAULT_SWJ_CLOCK);
+ DAP_Data.transfer.idle_cycles = 0U;
+ DAP_Data.transfer.retry_count = 100U;
+ DAP_Data.transfer.match_retry = 0U;
+ DAP_Data.transfer.match_mask = 0x00000000U;
+#if (DAP_SWD != 0)
+ DAP_Data.swd_conf.turnaround = 1U;
+ DAP_Data.swd_conf.data_phase = 0U;
+#endif
+#if (DAP_JTAG != 0)
+ DAP_Data.jtag_dev.count = 0U;
+#endif
+
+ DAP_SETUP(); // Device specific setup
+}
diff --git a/components/DAP/source/DAP_vendor.c b/components/DAP/source/DAP_vendor.c
new file mode 100644
index 0000000..a4ae496
--- /dev/null
+++ b/components/DAP/source/DAP_vendor.c
@@ -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);
+}
+
+///@}
diff --git a/components/DAP/source/JTAG_DP.c b/components/DAP/source/JTAG_DP.c
new file mode 100644
index 0000000..24b1f3f
--- /dev/null
+++ b/components/DAP/source/JTAG_DP.c
@@ -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) */
diff --git a/components/DAP/source/SWO.c b/components/DAP/source/SWO.c
new file mode 100644
index 0000000..d331a0c
--- /dev/null
+++ b/components/DAP/source/SWO.c
@@ -0,0 +1,946 @@
+/**
+ * @brief Modify this file to fit esp8266 Uart
+ *
+ */
+
+/*
+ * 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"
+
+#include "esp_err.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/event_groups.h"
+#include "uart_modify.h"
+
+
+EventGroupHandle_t kSWO_Thread_event_group;
+EventGroupHandle_t kUART_Monitoe_event_group;
+#define SWO_GOT_DATA BIT0
+#define SWO_ERROR_TIME_OUT BIT1
+
+#define UART_GOT_DATA BIT0
+
+
+#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 UART_NUM_0 /* USART Port Number */
+#endif
+
+
+
+static uint8_t USART_Ready = 0U;
+
+#endif /* (SWO_UART != 0) */
+
+#if ((SWO_UART != 0) || (SWO_MANCHESTER != 0))
+
+#define SWO_STREAM_TIMEOUT (50 / portTICK_RATE_MS) /* 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);
+void SetTraceError(uint8_t flag);
+
+#if (SWO_STREAM != 0)
+
+static volatile uint8_t TransferBusy = 0U; /* Transfer Busy Flag */
+static uint32_t TransferSize; /* Current Transfer Size */
+#endif
+
+#if (SWO_UART != 0)
+
+
+void usart_monitor_task(void *argument)
+{
+ uint32_t index_i;
+ uint32_t index_o;
+ uint32_t count;
+ uint32_t num;
+ uint32_t flags;
+
+ kUART_Monitoe_event_group = xEventGroupCreate();
+ for (;;)
+ {
+ flags = xEventGroupWaitBits(kUART_Monitoe_event_group, UART_GOT_DATA,
+ pdTRUE, pdFALSE, portMAX_DELAY);
+ if (flags & UART_GOT_DATA)
+ {
+#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));
+ // num is the number of bytes we need to read
+ // (to achieve the size of TRACE_BLOCK_SIZE)
+ count = index_i - index_o;
+ // Amount of data that has not been processed yet
+
+ // (SWO_BUFFER_SIZE-num): the remaining usable length of the buffer after reading this data
+ if (count <= (SWO_BUFFER_SIZE - num))
+ {
+ index_i &= SWO_BUFFER_SIZE - 1U;
+ TraceBlockSize = num;
+ my_uart_read_bytes(USART_PORT, &TraceBuf[index_i], num, 20 / portTICK_RATE_MS);
+ //pUSART->Receive(&TraceBuf[index_i], num);
+ }
+ else
+ {
+ // Not enough buffers
+ 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))))
+ {
+ xEventGroupSetBits(kSWO_Thread_event_group, SWO_GOT_DATA);
+ }
+ }
+#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;
+ uart_config_t uart_config = {
+ .baud_rate = 115200,
+ .data_bits = UART_DATA_8_BITS,
+ .parity = UART_PARITY_DISABLE,
+ .stop_bits = UART_STOP_BITS_1,
+ .flow_ctrl = UART_HW_FLOWCTRL_DISABLE};
+ my_uart_param_config(USART_PORT, &uart_config);
+
+#define BUF_SIZE (1024)
+ my_uart_driver_install(USART_PORT, BUF_SIZE, 0, 0, NULL, 0);
+
+ if (enable != 0U)
+ {
+ my_uart_param_config(USART_PORT, &uart_config);
+ status = my_uart_driver_install(USART_PORT, BUF_SIZE, 0, 0, NULL, 0);
+ if (status != ESP_OK)
+ {
+ return (0U);
+ }
+ }
+ else
+ {
+ my_uart_driver_delete(USART_PORT);
+ }
+ 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)
+ {
+ size_t len = 0;
+ my_uart_get_buffered_data_len(USART_PORT, &len);
+ my_uart_flush(USART_PORT);
+ TraceIndexI += len;
+ // pUSART->Control(ARM_USART_CONTROL_RX, 0U);
+ // if (pUSART->GetStatus().rx_busy)
+ // {
+ // TraceIndexI += pUSART->GetRxCount();
+ // pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U);
+ // }
+ }
+
+ /////////////
+ status = my_uart_set_baudrate(USART_PORT, baudrate);
+
+ if (status == ESP_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);
+ my_uart_read_bytes(USART_PORT, &TraceBuf[index], num, 20 / portTICK_RATE_MS);
+ }
+ //pUSART->Control(ARM_USART_CONTROL_RX, 1U); ////TODO:
+ }
+
+ 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 = my_uart_read_bytes(USART_PORT, &TraceBuf[0], 1U, 20 / portTICK_RATE_MS);
+ if (status == ESP_FAIL)
+ {
+ return (0U);
+ }
+ // status = pUSART->Control(ARM_USART_CONTROL_RX, 1U);
+ // if (status != ARM_DRIVER_OK)
+ // {
+ // return (0U);
+ // } ////TODO:
+ }
+ else
+ {
+ size_t len = 0;
+ my_uart_get_buffered_data_len(USART_PORT, &len);
+ my_uart_flush(USART_PORT);
+ TraceIndexI += len;
+ // 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;
+ my_uart_read_bytes(USART_PORT, buf, num, 20 / portTICK_RATE_MS);
+}
+
+// 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;
+ // }
+ my_uart_get_buffered_data_len(USART_PORT, &count);
+ 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)
+{
+ return (0U);
+}
+
+#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
+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)
+ {
+ xEventGroupSetBits(kSWO_Thread_event_group, SWO_GOT_DATA);
+ }
+#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();
+ xEventGroupSetBits(kSWO_Thread_event_group, SWO_GOT_DATA);
+}
+
+// SWO Thread
+void SWO_Thread(void *argument)
+{
+ uint32_t timeout;
+ uint32_t flags;
+ uint32_t count;
+ uint32_t index;
+ uint32_t i, n;
+ (void)argument;
+
+ timeout = portMAX_DELAY;
+
+ kSWO_Thread_event_group = xEventGroupCreate();
+ for (;;)
+ {
+ flags = xEventGroupWaitBits(kSWO_Thread_event_group, SWO_GOT_DATA | SWO_ERROR_TIME_OUT,
+ pdTRUE, pdFALSE, timeout);
+ if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE)
+ {
+ timeout = SWO_STREAM_TIMEOUT;
+ }
+ else
+ {
+ timeout = portMAX_DELAY;
+ flags = SWO_ERROR_TIME_OUT;
+ }
+ 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 & SWO_ERROR_TIME_OUT) == 0)
+ {
+ i = index & (USB_BLOCK_SIZE - 1U);
+ if (i == 0U)
+ {
+ count &= ~(USB_BLOCK_SIZE - 1U);
+ // Take down to the nearest number that is a multiple of USB_BLOCK_SIZE
+ }
+ 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); //through USB
+ }
+ }
+ }
+ }
+}
+
+#endif /* (SWO_STREAM != 0) */
+
+#endif /* ((SWO_UART != 0) || (SWO_MANCHESTER != 0)) */
diff --git a/components/DAP/source/SW_DP.c b/components/DAP/source/SW_DP.c
new file mode 100644
index 0000000..803cf42
--- /dev/null
+++ b/components/DAP/source/SW_DP.c
@@ -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) */
diff --git a/components/DAP/source/uart_modify.c b/components/DAP/source/uart_modify.c
new file mode 100644
index 0000000..e485482
--- /dev/null
+++ b/components/DAP/source/uart_modify.c
@@ -0,0 +1,1256 @@
+/**
+ * @brief Made some simple modifications to the official UART
+ *
+ */
+
+// Copyright 2018-2025 Espressif Systems (Shanghai) PTE LTD
+//
+// 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
+//
+// http://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.
+
+#include
+#include
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/queue.h"
+#include "freertos/semphr.h"
+#include "freertos/ringbuf.h"
+#include "freertos/event_groups.h"
+
+#include "esp_err.h"
+#include "esp_log.h"
+#include "esp_attr.h"
+
+// SWO modify
+#include "DAP_config.h"
+#include "esp8266/uart_struct.h"
+#include "esp8266/uart_register.h"
+#include "esp8266/pin_mux_register.h"
+#include "esp8266/eagle_soc.h"
+#include "esp8266/rom_functions.h"
+
+#include "rom/ets_sys.h"
+
+#include "uart_modify.h"
+#include "driver/uart_select.h"
+
+#define portYIELD_FROM_ISR() taskYIELD()
+
+#define UART_ENTER_CRITICAL() portENTER_CRITICAL()
+#define UART_EXIT_CRITICAL() portEXIT_CRITICAL()
+
+static const char *UART_TAG = "uart";
+#define UART_CHECK(a, str, ret_val) \
+ if (!(a)) \
+ { \
+ ESP_LOGE(UART_TAG, "%s(%d): %s", __FUNCTION__, __LINE__, str); \
+ return (ret_val); \
+ }
+
+#define UART_EMPTY_THRESH_DEFAULT (10)
+#define UART_FULL_THRESH_DEFAULT (120)
+#define UART_TOUT_THRESH_DEFAULT (10)
+
+typedef struct
+{
+ uart_event_type_t type; /*!< UART TX data type */
+ struct
+ {
+ size_t size;
+ uint8_t data[0];
+ } tx_data;
+} uart_tx_data_t;
+
+typedef struct
+{
+ uart_port_t uart_num; /*!< UART port number*/
+ int queue_size; /*!< UART event queue size*/
+ QueueHandle_t xQueueUart; /*!< UART queue handler*/
+ uart_mode_t uart_mode; /*!< UART controller actual mode set by uart_set_mode() */
+
+ // rx parameters
+ int rx_buffered_len; /*!< UART cached data length */
+ SemaphoreHandle_t rx_mux; /*!< UART RX data mutex*/
+ int rx_buf_size; /*!< RX ring buffer size */
+ RingbufHandle_t rx_ring_buf; /*!< RX ring buffer handler*/
+ bool rx_buffer_full_flg; /*!< RX ring buffer full flag. */
+ int rx_cur_remain; /*!< Data number that waiting to be read out in ring buffer item*/
+ uint8_t *rx_ptr; /*!< pointer to the current data in ring buffer*/
+ uint8_t *rx_head_ptr; /*!< pointer to the head of RX item*/
+ uint8_t rx_data_buf[UART_FIFO_LEN]; /*!< Data buffer to stash FIFO data*/
+ uint8_t rx_stash_len; /*!< stashed data length.(When using flow control, after reading out FIFO data, if we fail to push to buffer, we can just stash them.) */
+
+ // tx parameters
+ SemaphoreHandle_t tx_fifo_sem; /*!< UART TX FIFO semaphore*/
+ SemaphoreHandle_t tx_done_sem; /*!< UART TX done semaphore*/
+ SemaphoreHandle_t tx_mux; /*!< UART TX mutex*/
+ int tx_buf_size; /*!< TX ring buffer size */
+ RingbufHandle_t tx_ring_buf; /*!< TX ring buffer handler*/
+ bool tx_waiting_fifo; /*!< this flag indicates that some task is waiting for FIFO empty interrupt, used to send all data without any data buffer*/
+ uint8_t *tx_ptr; /*!< TX data pointer to push to FIFO in TX buffer mode*/
+ uart_tx_data_t *tx_head; /*!< TX data pointer to head of the current buffer in TX ring buffer*/
+ uint32_t tx_len_tot; /*!< Total length of current item in ring buffer*/
+ uint32_t tx_len_cur;
+ bool wait_tx_done_flg;
+ uart_select_notif_callback_t uart_select_notif_callback; /*!< Notification about select() events */
+} uart_obj_t;
+
+static uart_obj_t *p_uart_obj[UART_NUM_MAX] = {0};
+// DRAM_ATTR is required to avoid UART array placed in flash, due to accessed from ISR
+static DRAM_ATTR uart_dev_t *const UART[UART_NUM_MAX] = {&uart0, &uart1};
+
+typedef void (*uart_isr_t)(void *);
+typedef struct
+{
+ uart_isr_t fn; /*!< isr function */
+ void *args; /*!< isr function args */
+} uart_isr_func_t;
+
+static uart_isr_func_t uart_isr_func[UART_NUM_MAX];
+
+// SWO modify
+extern EventGroupHandle_t kUART_Monitoe_event_group;
+#define UART_GOT_DATA BIT0
+extern void SetTraceError(uint8_t flag);
+#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)
+//
+
+esp_err_t my_uart_set_word_length(uart_port_t uart_num, uart_word_length_t data_bit)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+ UART_CHECK((data_bit < UART_DATA_BITS_MAX), "data bit error", ESP_ERR_INVALID_ARG);
+
+ UART_ENTER_CRITICAL();
+ UART[uart_num]->conf0.bit_num = data_bit;
+ UART_EXIT_CRITICAL();
+ return ESP_OK;
+}
+
+esp_err_t my_uart_get_word_length(uart_port_t uart_num, uart_word_length_t *data_bit)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+ UART_CHECK((data_bit), "empty pointer", ESP_FAIL);
+
+ *(data_bit) = UART[uart_num]->conf0.bit_num;
+ return ESP_OK;
+}
+
+esp_err_t my_uart_set_stop_bits(uart_port_t uart_num, uart_stop_bits_t stop_bit)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+ UART_CHECK((stop_bit < UART_STOP_BITS_MAX), "stop bit error", ESP_ERR_INVALID_ARG);
+
+ UART_ENTER_CRITICAL();
+ UART[uart_num]->conf0.stop_bit_num = stop_bit;
+ UART_EXIT_CRITICAL();
+ return ESP_OK;
+}
+
+esp_err_t my_uart_get_stop_bits(uart_port_t uart_num, uart_stop_bits_t *stop_bit)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+ UART_CHECK((stop_bit), "empty pointer", ESP_FAIL);
+
+ (*stop_bit) = UART[uart_num]->conf0.stop_bit_num;
+ return ESP_OK;
+}
+
+esp_err_t my_uart_set_parity(uart_port_t uart_num, uart_parity_t parity_mode)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+ UART_CHECK(((parity_mode == UART_PARITY_DISABLE) || (parity_mode == UART_PARITY_EVEN) || (parity_mode == UART_PARITY_ODD)),
+ "parity_mode error", ESP_ERR_INVALID_ARG);
+
+ UART_ENTER_CRITICAL();
+ UART[uart_num]->conf0.parity = (parity_mode & 0x1);
+ UART[uart_num]->conf0.parity_en = ((parity_mode >> 1) & 0x1);
+ UART_EXIT_CRITICAL();
+ return ESP_OK;
+}
+
+esp_err_t my_uart_get_parity(uart_port_t uart_num, uart_parity_t *parity_mode)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+ UART_CHECK((parity_mode), "empty pointer", ESP_ERR_INVALID_ARG);
+
+ UART_ENTER_CRITICAL();
+
+ if (UART[uart_num]->conf0.parity_en)
+ {
+ if (UART[uart_num]->conf0.parity)
+ {
+ (*parity_mode) = UART_PARITY_ODD;
+ }
+ else
+ {
+ (*parity_mode) = UART_PARITY_EVEN;
+ }
+ }
+ else
+ {
+ (*parity_mode) = UART_PARITY_DISABLE;
+ }
+
+ UART_EXIT_CRITICAL();
+ return ESP_OK;
+}
+
+esp_err_t my_uart_set_baudrate(uart_port_t uart_num, uint32_t baud_rate)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+
+ UART_ENTER_CRITICAL();
+ UART[uart_num]->clk_div.val = (uint32_t)(UART_CLK_FREQ / baud_rate) & 0xFFFFF;
+ UART_EXIT_CRITICAL();
+ return ESP_OK;
+}
+
+esp_err_t my_uart_get_baudrate(uart_port_t uart_num, uint32_t *baudrate)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+ UART_CHECK((baudrate), "empty pointer", ESP_ERR_INVALID_ARG);
+
+ (*baudrate) = (UART_CLK_FREQ / (UART[uart_num]->clk_div.val & 0xFFFFF));
+ return ESP_OK;
+}
+
+esp_err_t my_uart_set_line_inverse(uart_port_t uart_num, uint32_t inverse_mask)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+ UART_CHECK((((inverse_mask & ~UART_LINE_INV_MASK) == 0) || (inverse_mask == 0)), "inverse_mask error", ESP_ERR_INVALID_ARG);
+
+ UART_ENTER_CRITICAL();
+ UART[uart_num]->conf0.val &= ~UART_LINE_INV_MASK;
+ UART[uart_num]->conf0.val |= inverse_mask;
+ UART_EXIT_CRITICAL();
+ return ESP_OK;
+}
+
+esp_err_t my_uart_set_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t flow_ctrl, uint8_t rx_thresh)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+ UART_CHECK((flow_ctrl < UART_HW_FLOWCTRL_MAX), "uart_flow ctrl error", ESP_ERR_INVALID_ARG);
+
+ UART_ENTER_CRITICAL();
+
+ if (flow_ctrl & UART_HW_FLOWCTRL_RTS)
+ {
+ UART[uart_num]->conf1.rx_flow_thrhd = rx_thresh;
+ UART[uart_num]->conf1.rx_flow_en = 1;
+ }
+ else
+ {
+ UART[uart_num]->conf1.rx_flow_en = 0;
+ }
+
+ if (flow_ctrl & UART_HW_FLOWCTRL_CTS)
+ {
+ UART[uart_num]->conf0.tx_flow_en = 1;
+ }
+ else
+ {
+ UART[uart_num]->conf0.tx_flow_en = 0;
+ }
+
+ UART_EXIT_CRITICAL();
+ return ESP_OK;
+}
+
+esp_err_t my_uart_get_hw_flow_ctrl(uart_port_t uart_num, uart_hw_flowcontrol_t *flow_ctrl)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+
+ uart_hw_flowcontrol_t val = UART_HW_FLOWCTRL_DISABLE;
+
+ if (UART[uart_num]->conf1.rx_flow_en)
+ {
+ val |= UART_HW_FLOWCTRL_RTS;
+ }
+
+ if (UART[uart_num]->conf0.tx_flow_en)
+ {
+ val |= UART_HW_FLOWCTRL_CTS;
+ }
+
+ (*flow_ctrl) = val;
+ return ESP_OK;
+}
+
+esp_err_t my_uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+ UART_CHECK((p_uart_obj[uart_num]), "uart driver error", ESP_ERR_INVALID_ARG);
+ uint32_t baudrate;
+ uint32_t byte_delay_us = 0;
+ BaseType_t res;
+ portTickType ticks_end = xTaskGetTickCount() + ticks_to_wait;
+
+ // Take tx_mux
+ res = xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)ticks_to_wait);
+ if (res == pdFALSE)
+ {
+ return ESP_ERR_TIMEOUT;
+ }
+
+ if (false == p_uart_obj[uart_num]->wait_tx_done_flg)
+ {
+ xSemaphoreGive(p_uart_obj[uart_num]->tx_mux);
+ return ESP_OK;
+ }
+
+ my_uart_get_baudrate(uart_num, &baudrate);
+ byte_delay_us = (uint32_t)(10000000 / baudrate); // (1/baudrate)*10*1000_000 us
+
+ ticks_to_wait = ticks_end - xTaskGetTickCount();
+ // wait for tx done sem.
+ if (pdTRUE == xSemaphoreTake(p_uart_obj[uart_num]->tx_done_sem, ticks_to_wait))
+ {
+ while (1)
+ {
+ if (UART[uart_num]->status.txfifo_cnt == 0)
+ {
+ ets_delay_us(byte_delay_us); // Delay one byte time to guarantee transmission completion
+ break;
+ }
+ }
+ p_uart_obj[uart_num]->wait_tx_done_flg = false;
+ }
+ else
+ {
+ xSemaphoreGive(p_uart_obj[uart_num]->tx_mux);
+ return ESP_ERR_TIMEOUT;
+ }
+ xSemaphoreGive(p_uart_obj[uart_num]->tx_mux);
+ return ESP_OK;
+}
+
+esp_err_t my_uart_enable_swap(void)
+{
+ // wait for tx done.
+ my_uart_wait_tx_done(UART_NUM_0, portMAX_DELAY);
+
+ UART_ENTER_CRITICAL();
+ // MTCK -> UART0_CTS -> U0RXD
+ PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_UART0_CTS);
+ // MTD0 -> UART0_RTS -> U0TXD
+ PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_UART0_RTS);
+ // enable swap U0TXD <-> UART0_RTS and U0RXD <-> UART0_CTS
+ SET_PERI_REG_MASK(UART_SWAP_REG, 0x4);
+ UART_EXIT_CRITICAL();
+
+ return ESP_OK;
+}
+
+esp_err_t my_uart_disable_swap(void)
+{
+ // wait for tx done.
+ my_uart_wait_tx_done(UART_NUM_0, portMAX_DELAY);
+
+ UART_ENTER_CRITICAL();
+ // disable swap U0TXD <-> UART0_RTS and U0RXD <-> UART0_CTS
+ CLEAR_PERI_REG_MASK(UART_SWAP_REG, 0x4);
+ UART_EXIT_CRITICAL();
+
+ return ESP_OK;
+}
+
+static esp_err_t uart_reset_rx_fifo(uart_port_t uart_num)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+
+ UART_ENTER_CRITICAL();
+ UART[uart_num]->conf0.rxfifo_rst = 0x1;
+ UART[uart_num]->conf0.rxfifo_rst = 0x0;
+ UART_EXIT_CRITICAL();
+ return ESP_OK;
+}
+
+esp_err_t my_uart_clear_intr_status(uart_port_t uart_num, uint32_t mask)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+
+ UART_ENTER_CRITICAL();
+ UART[uart_num]->int_clr.val |= mask;
+ UART_EXIT_CRITICAL();
+ return ESP_OK;
+}
+
+esp_err_t my_uart_enable_intr_mask(uart_port_t uart_num, uint32_t enable_mask)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+
+ UART_ENTER_CRITICAL();
+ UART[uart_num]->int_ena.val |= enable_mask;
+ UART_EXIT_CRITICAL();
+ return ESP_OK;
+}
+
+esp_err_t my_uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+
+ UART_ENTER_CRITICAL();
+ UART[uart_num]->int_ena.val &= ~disable_mask;
+ UART_EXIT_CRITICAL();
+ return ESP_OK;
+}
+
+esp_err_t my_uart_enable_rx_intr(uart_port_t uart_num)
+{
+ return my_uart_enable_intr_mask(uart_num, UART_RXFIFO_FULL_INT_ENA | UART_RXFIFO_TOUT_INT_ENA);
+}
+
+esp_err_t my_uart_disable_rx_intr(uart_port_t uart_num)
+{
+ return my_uart_disable_intr_mask(uart_num, UART_RXFIFO_FULL_INT_ENA | UART_RXFIFO_TOUT_INT_ENA);
+}
+
+esp_err_t my_uart_disable_tx_intr(uart_port_t uart_num)
+{
+ return my_uart_disable_intr_mask(uart_num, UART_TXFIFO_EMPTY_INT_ENA);
+}
+
+esp_err_t my_uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+ UART_CHECK((thresh < UART_FIFO_LEN), "empty intr threshold error", ESP_ERR_INVALID_ARG);
+
+ UART_ENTER_CRITICAL();
+ UART[uart_num]->int_clr.txfifo_empty = 1;
+ UART[uart_num]->conf1.txfifo_empty_thrhd = thresh & 0x7f;
+ UART[uart_num]->int_ena.txfifo_empty = enable & 0x1;
+ UART_EXIT_CRITICAL();
+ return ESP_OK;
+}
+
+static void uart_intr_service(void *arg)
+{
+ // UART intr process
+ uint32_t uart_num = 0;
+ // read status to get interrupt status for UART0-1
+ uint32_t uart_intr_status = UART[uart_num]->int_st.val;
+
+ if (uart_isr_func == NULL)
+ {
+ return;
+ }
+
+ do
+ {
+ uart_intr_status = UART[uart_num]->int_st.val;
+ if (uart_intr_status != 0)
+ {
+ if (uart_isr_func[uart_num].fn != NULL)
+ {
+ uart_isr_func[uart_num].fn(uart_isr_func[uart_num].args);
+ }
+ }
+ } while (++uart_num < UART_NUM_MAX);
+}
+
+esp_err_t my_uart_isr_register(uart_port_t uart_num, void (*fn)(void *), void *arg)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+
+ UART_ENTER_CRITICAL();
+ _xt_isr_mask(1 << ETS_UART_INUM);
+ _xt_isr_attach(ETS_UART_INUM, uart_intr_service, NULL);
+ uart_isr_func[uart_num].fn = fn;
+ uart_isr_func[uart_num].args = arg;
+ _xt_isr_unmask(1 << ETS_UART_INUM);
+ UART_EXIT_CRITICAL();
+ return ESP_OK;
+}
+
+esp_err_t my_uart_param_config(uart_port_t uart_num, uart_config_t *uart_conf)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+
+ if (uart_num == UART_NUM_1)
+ {
+ PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK);
+ }
+ else
+ {
+ PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
+ PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD);
+ PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD);
+
+ if (uart_conf->flow_ctrl & UART_HW_FLOWCTRL_RTS)
+ {
+ PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS);
+ }
+
+ if (uart_conf->flow_ctrl & UART_HW_FLOWCTRL_CTS)
+ {
+ PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_UART0_CTS);
+ }
+
+ my_uart_set_hw_flow_ctrl(uart_num, uart_conf->flow_ctrl, uart_conf->rx_flow_ctrl_thresh);
+ }
+
+ my_uart_set_baudrate(uart_num, uart_conf->baud_rate);
+ my_uart_set_word_length(uart_num, uart_conf->data_bits);
+ my_uart_set_stop_bits(uart_num, uart_conf->stop_bits);
+ my_uart_set_parity(uart_num, uart_conf->parity);
+ uart_reset_rx_fifo(uart_num);
+
+ return ESP_OK;
+}
+
+esp_err_t my_uart_intr_config(uart_port_t uart_num, uart_intr_config_t *intr_conf)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+
+ my_uart_clear_intr_status(uart_num, UART_INTR_MASK);
+ UART_ENTER_CRITICAL();
+ UART[uart_num]->int_clr.val = UART_INTR_MASK;
+
+ if (intr_conf->intr_enable_mask & UART_RXFIFO_TOUT_INT_ENA_M)
+ {
+ UART[uart_num]->conf1.rx_tout_thrhd = ((intr_conf->rx_timeout_thresh) & 0x7f);
+ UART[uart_num]->conf1.rx_tout_en = 1;
+ }
+ else
+ {
+ UART[uart_num]->conf1.rx_tout_en = 0;
+ }
+
+ if (intr_conf->intr_enable_mask & UART_RXFIFO_FULL_INT_ENA_M)
+ {
+ UART[uart_num]->conf1.rxfifo_full_thrhd = intr_conf->rxfifo_full_thresh;
+ }
+
+ if (intr_conf->intr_enable_mask & UART_TXFIFO_EMPTY_INT_ENA_M)
+ {
+ UART[uart_num]->conf1.txfifo_empty_thrhd = intr_conf->txfifo_empty_intr_thresh;
+ }
+
+ // my_uart_clear_intr_status(UART[uart_num], mask);
+ UART[uart_num]->int_ena.val = intr_conf->intr_enable_mask;
+ _xt_isr_unmask(0x1 << ETS_UART_INUM);
+ UART_EXIT_CRITICAL();
+
+ return ESP_OK;
+}
+
+// internal isr handler for default driver code.
+static void uart_rx_intr_handler_default(void *param)
+{
+ uart_obj_t *p_uart = (uart_obj_t *)param;
+ uint8_t uart_num = p_uart->uart_num;
+ uart_dev_t *uart_reg = UART[uart_num];
+ int rx_fifo_len = uart_reg->status.rxfifo_cnt;
+ uint8_t buf_idx = 0;
+ uint32_t uart_intr_status = UART[uart_num]->int_st.val;
+ uart_event_t uart_event;
+ BaseType_t task_woken = 0;
+
+
+ while (uart_intr_status != 0x0)
+ {
+ uart_select_notif_t notify = UART_SELECT_ERROR_NOTIF;
+
+ buf_idx = 0;
+ uart_event.type = UART_EVENT_MAX;
+
+ if (uart_intr_status & UART_TXFIFO_EMPTY_INT_ST_M)
+ {
+ my_uart_clear_intr_status(uart_num, UART_TXFIFO_EMPTY_INT_CLR_M);
+ my_uart_disable_intr_mask(uart_num, UART_TXFIFO_EMPTY_INT_ENA_M);
+
+ // TX semaphore will only be used when tx_buf_size is zero.
+ if (p_uart->tx_waiting_fifo == true && p_uart->tx_buf_size == 0)
+ {
+ p_uart->tx_waiting_fifo = false;
+ xSemaphoreGiveFromISR(p_uart->tx_fifo_sem, &task_woken);
+
+ if (task_woken == pdTRUE)
+ {
+ portYIELD_FROM_ISR();
+ }
+ }
+ else
+ {
+ // We don't use TX ring buffer, because the size is zero.
+ if (p_uart->tx_buf_size == 0)
+ {
+ continue;
+ }
+
+ int tx_fifo_rem = UART_FIFO_LEN - UART[uart_num]->status.txfifo_cnt;
+ bool en_tx_flg = false;
+
+ // We need to put a loop here, in case all the buffer items are very short.
+ // That would cause a watch_dog reset because empty interrupt happens so often.
+ // Although this is a loop in ISR, this loop will execute at most 128 turns.
+ while (tx_fifo_rem)
+ {
+ if (p_uart->tx_len_tot == 0 || p_uart->tx_ptr == NULL || p_uart->tx_len_cur == 0)
+ {
+ size_t size;
+ p_uart->tx_head = (uart_tx_data_t *)xRingbufferReceiveFromISR(p_uart->tx_ring_buf, &size);
+
+ if (p_uart->tx_head)
+ {
+ // The first item is the data description
+ // Get the first item to get the data information
+ if (p_uart->tx_len_tot == 0)
+ {
+ p_uart->tx_ptr = NULL;
+ p_uart->tx_len_tot = p_uart->tx_head->tx_data.size;
+ // We have saved the data description from the 1st item, return buffer.
+ vRingbufferReturnItemFromISR(p_uart->tx_ring_buf, p_uart->tx_head, &task_woken);
+
+ if (task_woken == pdTRUE)
+ {
+ portYIELD_FROM_ISR();
+ }
+ }
+ else if (p_uart->tx_ptr == NULL)
+ {
+ // Update the TX item pointer, we will need this to return item to buffer.
+ p_uart->tx_ptr = (uint8_t *)p_uart->tx_head;
+ en_tx_flg = true;
+ p_uart->tx_len_cur = size;
+ }
+ }
+ else
+ {
+ // Can not get data from ring buffer, return;
+ break;
+ }
+ }
+
+ if (p_uart->tx_len_tot > 0 && p_uart->tx_ptr && p_uart->tx_len_cur > 0)
+ {
+ // To fill the TX FIFO.
+ int send_len = p_uart->tx_len_cur > tx_fifo_rem ? tx_fifo_rem : p_uart->tx_len_cur;
+
+ for (buf_idx = 0; buf_idx < send_len; buf_idx++)
+ {
+ UART[uart_num]->fifo.rw_byte = *(p_uart->tx_ptr++) & 0xff;
+ }
+
+ p_uart->tx_len_tot -= send_len;
+ p_uart->tx_len_cur -= send_len;
+ tx_fifo_rem -= send_len;
+
+ if (p_uart->tx_len_cur == 0)
+ {
+ // Return item to ring buffer.
+ vRingbufferReturnItemFromISR(p_uart->tx_ring_buf, p_uart->tx_head, &task_woken);
+
+ if (task_woken == pdTRUE)
+ {
+ portYIELD_FROM_ISR();
+ }
+
+ p_uart->tx_head = NULL;
+ p_uart->tx_ptr = NULL;
+ }
+
+ if (p_uart->tx_len_tot == 0)
+ {
+ en_tx_flg = false;
+ xSemaphoreGiveFromISR(p_uart->tx_done_sem, &task_woken);
+ if (task_woken == pdTRUE)
+ {
+ portYIELD_FROM_ISR();
+ }
+ }
+ else
+ {
+ en_tx_flg = true;
+ }
+ }
+ }
+
+ if (en_tx_flg)
+ {
+ my_uart_clear_intr_status(uart_num, UART_TXFIFO_EMPTY_INT_CLR_M);
+ my_uart_enable_intr_mask(uart_num, UART_TXFIFO_EMPTY_INT_ENA_M);
+ }
+ }
+ }
+ else if ((uart_intr_status & UART_RXFIFO_TOUT_INT_ST_M) || (uart_intr_status & UART_RXFIFO_FULL_INT_ST_M))
+ {
+ rx_fifo_len = uart_reg->status.rxfifo_cnt;
+
+ if (p_uart->rx_buffer_full_flg == false)
+ {
+ // We have to read out all data in RX FIFO to clear the interrupt signal
+ while (buf_idx < rx_fifo_len)
+ {
+ p_uart->rx_data_buf[buf_idx++] = uart_reg->fifo.rw_byte;
+ }
+
+ // Get the buffer from the FIFO
+ // After Copying the Data From FIFO ,Clear intr_status
+ my_uart_clear_intr_status(uart_num, UART_RXFIFO_TOUT_INT_CLR_M | UART_RXFIFO_FULL_INT_CLR_M);
+ uart_event.type = UART_DATA;
+ uart_event.size = rx_fifo_len;
+ p_uart->rx_stash_len = rx_fifo_len;
+
+ // If we fail to push data to ring buffer, we will have to stash the data, and send next time.
+ // Mainly for applications that uses flow control or small ring buffer.
+ if (pdFALSE == xRingbufferSendFromISR(p_uart->rx_ring_buf, p_uart->rx_data_buf, p_uart->rx_stash_len, &task_woken))
+ {
+ my_uart_disable_intr_mask(uart_num, UART_RXFIFO_TOUT_INT_ENA_M | UART_RXFIFO_FULL_INT_ENA_M);
+ uart_event.type = UART_BUFFER_FULL;
+ p_uart->rx_buffer_full_flg = true;
+ // SWO modify
+ // When we cannot write to the ring buffer, we also think that the serial port is "overflow".
+ SetTraceError(DAP_SWO_BUFFER_OVERRUN);
+ }
+ else
+ {
+ p_uart->rx_buffered_len += p_uart->rx_stash_len;
+ xEventGroupSetBitsFromISR(kUART_Monitoe_event_group, UART_GOT_DATA, pdFALSE);
+ }
+
+ notify = UART_SELECT_READ_NOTIF;
+
+ if (task_woken == pdTRUE)
+ {
+ portYIELD_FROM_ISR();
+ }
+ }
+ else
+ {
+ my_uart_disable_intr_mask(uart_num, UART_RXFIFO_FULL_INT_ENA_M | UART_RXFIFO_TOUT_INT_ENA_M);
+ my_uart_clear_intr_status(uart_num, UART_RXFIFO_FULL_INT_CLR_M | UART_RXFIFO_TOUT_INT_CLR_M);
+ }
+ }
+ else if (uart_intr_status & UART_RXFIFO_OVF_INT_ST_M)
+ {
+ // When fifo overflows, we reset the fifo.
+ uart_reset_rx_fifo(uart_num);
+ uart_reg->int_clr.rxfifo_ovf = 1;
+ uart_event.type = UART_FIFO_OVF;
+ notify = UART_SELECT_ERROR_NOTIF;
+ // SWO modify
+ // Unfortunately, Overflow occurs usually there is no flow control.
+ // Although the overflow situation often occurs,
+ // the buffer stability of the serial port is better,
+ // and there is basically no data loss.
+ ////TODO: Can we get rid of this code?
+ SetTraceError(DAP_SWO_BUFFER_OVERRUN);
+ }
+ else if (uart_intr_status & UART_FRM_ERR_INT_ST_M)
+ {
+ uart_reg->int_clr.frm_err = 1;
+ uart_event.type = UART_FRAME_ERR;
+ notify = UART_SELECT_ERROR_NOTIF;
+ // SWO modify
+ SetTraceError(DAP_SWO_STREAM_ERROR);
+ }
+ else if (uart_intr_status & UART_PARITY_ERR_INT_ST_M)
+ {
+ uart_reg->int_clr.parity_err = 1;
+ uart_event.type = UART_PARITY_ERR;
+ notify = UART_SELECT_ERROR_NOTIF;
+ // SWO modify
+ SetTraceError(DAP_SWO_STREAM_ERROR);
+ }
+ else
+ {
+ uart_reg->int_clr.val = uart_intr_status; // simply clear all other intr status
+ uart_event.type = UART_EVENT_MAX;
+ notify = UART_SELECT_ERROR_NOTIF;
+ // SWO modify
+ SetTraceError(DAP_SWO_STREAM_ERROR);
+ }
+
+#ifdef CONFIG_USING_ESP_VFS
+ if (uart_event.type != UART_EVENT_MAX && p_uart->uart_select_notif_callback)
+ {
+ p_uart->uart_select_notif_callback(uart_num, notify, &task_woken);
+ if (task_woken == pdTRUE)
+ {
+ portYIELD_FROM_ISR();
+ }
+ }
+#else
+ (void)notify;
+#endif
+
+ if (uart_event.type != UART_EVENT_MAX && p_uart->xQueueUart)
+ {
+ if (pdFALSE == xQueueSendFromISR(p_uart->xQueueUart, (void *)&uart_event, &task_woken))
+ {
+ ESP_EARLY_LOGV(UART_TAG, "UART event queue full");
+ }
+
+ if (task_woken == pdTRUE)
+ {
+ portYIELD_FROM_ISR();
+ }
+ }
+
+ uart_intr_status = uart_reg->int_st.val;
+ }
+}
+
+// Fill UART tx_fifo and return a number,
+// This function by itself is not thread-safe, always call from within a muxed section.
+static int uart_fill_fifo(uart_port_t uart_num, const char *buffer, uint32_t len)
+{
+ uint8_t i = 0;
+ uint8_t tx_fifo_cnt = UART[uart_num]->status.txfifo_cnt;
+ uint8_t tx_remain_fifo_cnt = (UART_FIFO_LEN - tx_fifo_cnt);
+ uint8_t copy_cnt = (len >= tx_remain_fifo_cnt ? tx_remain_fifo_cnt : len);
+
+ for (i = 0; i < copy_cnt; i++)
+ {
+ UART[uart_num]->fifo.rw_byte = buffer[i];
+ }
+
+ return copy_cnt;
+}
+
+int my_uart_tx_chars(uart_port_t uart_num, const char *buffer, uint32_t len)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1));
+ UART_CHECK((p_uart_obj[uart_num]), "uart driver error", (-1));
+ UART_CHECK(buffer, "buffer null", (-1));
+
+ if (len == 0)
+ {
+ return 0;
+ }
+
+ xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)portMAX_DELAY);
+ int tx_len = uart_fill_fifo(uart_num, (const char *)buffer, len);
+ xSemaphoreGive(p_uart_obj[uart_num]->tx_mux);
+ return tx_len;
+}
+
+static int uart_tx_all(uart_port_t uart_num, const char *src, size_t size)
+{
+ if (size == 0)
+ {
+ return 0;
+ }
+
+ size_t original_size = size;
+
+ // lock for uart_tx
+ xSemaphoreTake(p_uart_obj[uart_num]->tx_mux, (portTickType)portMAX_DELAY);
+ p_uart_obj[uart_num]->wait_tx_done_flg = true;
+ if (p_uart_obj[uart_num]->tx_buf_size > 0)
+ {
+ int max_size = xRingbufferGetMaxItemSize(p_uart_obj[uart_num]->tx_ring_buf);
+ int offset = 0;
+ uart_tx_data_t evt;
+ evt.tx_data.size = size;
+ evt.type = UART_DATA;
+ xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void *)&evt, sizeof(uart_tx_data_t), portMAX_DELAY);
+
+ while (size > 0)
+ {
+ int send_size = size > max_size / 2 ? max_size / 2 : size;
+ xRingbufferSend(p_uart_obj[uart_num]->tx_ring_buf, (void *)(src + offset), send_size, portMAX_DELAY);
+ size -= send_size;
+ offset += send_size;
+ my_uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT);
+ }
+ }
+ else
+ {
+ while (size)
+ {
+ // semaphore for tx_fifo available
+ if (pdTRUE == xSemaphoreTake(p_uart_obj[uart_num]->tx_fifo_sem, (portTickType)portMAX_DELAY))
+ {
+ size_t sent = uart_fill_fifo(uart_num, (char *)src, size);
+
+ if (sent < size)
+ {
+ p_uart_obj[uart_num]->tx_waiting_fifo = true;
+ my_uart_enable_tx_intr(uart_num, 1, UART_EMPTY_THRESH_DEFAULT);
+ }
+
+ size -= sent;
+ src += sent;
+ }
+ }
+
+ xSemaphoreGive(p_uart_obj[uart_num]->tx_fifo_sem);
+ xSemaphoreGive(p_uart_obj[uart_num]->tx_done_sem);
+ }
+ xSemaphoreGive(p_uart_obj[uart_num]->tx_mux);
+ return original_size;
+}
+
+int my_uart_write_bytes(uart_port_t uart_num, const char *src, size_t size)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1));
+ UART_CHECK((p_uart_obj[uart_num]), "uart driver error", (-1));
+ UART_CHECK(src, "buffer null", (-1));
+
+ return uart_tx_all(uart_num, src, size);
+}
+
+int my_uart_read_bytes(uart_port_t uart_num, uint8_t *buf, uint32_t length, TickType_t ticks_to_wait)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", (-1));
+ UART_CHECK((buf), "uart data null", (-1));
+ UART_CHECK((p_uart_obj[uart_num]), "uart driver error", (-1));
+
+ uint8_t *data = NULL;
+ size_t size;
+ size_t copy_len = 0;
+ int len_tmp;
+
+ if (xSemaphoreTake(p_uart_obj[uart_num]->rx_mux, (portTickType)ticks_to_wait) != pdTRUE)
+ {
+ return -1;
+ }
+
+ while (length)
+ {
+ if (p_uart_obj[uart_num]->rx_cur_remain == 0)
+ {
+ data = (uint8_t *)xRingbufferReceive(p_uart_obj[uart_num]->rx_ring_buf, &size, (portTickType)ticks_to_wait);
+
+ if (data)
+ {
+ p_uart_obj[uart_num]->rx_head_ptr = data;
+ p_uart_obj[uart_num]->rx_ptr = data;
+ p_uart_obj[uart_num]->rx_cur_remain = size;
+ }
+ else
+ {
+ xSemaphoreGive(p_uart_obj[uart_num]->rx_mux);
+ return copy_len;
+ }
+ }
+
+ if (p_uart_obj[uart_num]->rx_cur_remain > length)
+ {
+ len_tmp = length;
+ }
+ else
+ {
+ len_tmp = p_uart_obj[uart_num]->rx_cur_remain;
+ }
+
+ memcpy(buf + copy_len, p_uart_obj[uart_num]->rx_ptr, len_tmp);
+ UART_ENTER_CRITICAL();
+ p_uart_obj[uart_num]->rx_buffered_len -= len_tmp;
+ p_uart_obj[uart_num]->rx_ptr += len_tmp;
+ UART_EXIT_CRITICAL();
+ p_uart_obj[uart_num]->rx_cur_remain -= len_tmp;
+ copy_len += len_tmp;
+ length -= len_tmp;
+
+ if (p_uart_obj[uart_num]->rx_cur_remain == 0)
+ {
+ vRingbufferReturnItem(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_head_ptr);
+ p_uart_obj[uart_num]->rx_head_ptr = NULL;
+ p_uart_obj[uart_num]->rx_ptr = NULL;
+
+ if (p_uart_obj[uart_num]->rx_buffer_full_flg)
+ {
+ BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_data_buf, p_uart_obj[uart_num]->rx_stash_len, 1);
+
+ if (res == pdTRUE)
+ {
+ UART_ENTER_CRITICAL();
+ p_uart_obj[uart_num]->rx_buffered_len += p_uart_obj[uart_num]->rx_stash_len;
+ p_uart_obj[uart_num]->rx_buffer_full_flg = false;
+ UART_EXIT_CRITICAL();
+ my_uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num);
+ }
+ }
+ }
+ }
+
+ xSemaphoreGive(p_uart_obj[uart_num]->rx_mux);
+ return copy_len;
+}
+
+esp_err_t my_uart_get_buffered_data_len(uart_port_t uart_num, size_t *size)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+ UART_CHECK((p_uart_obj[uart_num]), "uart driver error", ESP_ERR_INVALID_ARG);
+
+ *size = p_uart_obj[uart_num]->rx_buffered_len;
+ return ESP_OK;
+}
+
+esp_err_t my_uart_flush(uart_port_t uart_num) __attribute__((alias("my_uart_flush_input")));
+
+esp_err_t my_uart_flush_input(uart_port_t uart_num)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+ UART_CHECK((p_uart_obj[uart_num]), "uart driver error", ESP_ERR_INVALID_ARG);
+ uart_obj_t *p_uart = p_uart_obj[uart_num];
+ uint8_t *data;
+ size_t size;
+
+ // rx sem protect the ring buffer read related functions
+ xSemaphoreTake(p_uart->rx_mux, (portTickType)portMAX_DELAY);
+ my_uart_disable_rx_intr(p_uart_obj[uart_num]->uart_num);
+
+ while (true)
+ {
+ if (p_uart->rx_head_ptr)
+ {
+ vRingbufferReturnItem(p_uart->rx_ring_buf, p_uart->rx_head_ptr);
+ UART_ENTER_CRITICAL();
+ p_uart_obj[uart_num]->rx_buffered_len -= p_uart->rx_cur_remain;
+ UART_EXIT_CRITICAL();
+ p_uart->rx_ptr = NULL;
+ p_uart->rx_cur_remain = 0;
+ p_uart->rx_head_ptr = NULL;
+ }
+
+ data = (uint8_t *)xRingbufferReceive(p_uart->rx_ring_buf, &size, (portTickType)0);
+
+ if (data == NULL)
+ {
+ if (p_uart_obj[uart_num]->rx_buffered_len != 0)
+ {
+ ESP_LOGE(UART_TAG, "rx_buffered_len error");
+ p_uart_obj[uart_num]->rx_buffered_len = 0;
+ }
+
+ // We also need to clear the `rx_buffer_full_flg` here.
+ UART_ENTER_CRITICAL();
+ p_uart_obj[uart_num]->rx_buffer_full_flg = false;
+ UART_EXIT_CRITICAL();
+ break;
+ }
+
+ UART_ENTER_CRITICAL();
+ p_uart_obj[uart_num]->rx_buffered_len -= size;
+ UART_EXIT_CRITICAL();
+ vRingbufferReturnItem(p_uart->rx_ring_buf, data);
+
+ if (p_uart_obj[uart_num]->rx_buffer_full_flg)
+ {
+ BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_data_buf, p_uart_obj[uart_num]->rx_stash_len, 1);
+
+ if (res == pdTRUE)
+ {
+ UART_ENTER_CRITICAL();
+ p_uart_obj[uart_num]->rx_buffered_len += p_uart_obj[uart_num]->rx_stash_len;
+ p_uart_obj[uart_num]->rx_buffer_full_flg = false;
+ UART_EXIT_CRITICAL();
+ }
+ }
+ }
+
+ p_uart->rx_ptr = NULL;
+ p_uart->rx_cur_remain = 0;
+ p_uart->rx_head_ptr = NULL;
+ uart_reset_rx_fifo(uart_num);
+ my_uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num);
+ xSemaphoreGive(p_uart->rx_mux);
+ return ESP_OK;
+}
+
+esp_err_t my_uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, QueueHandle_t *uart_queue, int no_use)
+{
+ esp_err_t r;
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+ UART_CHECK((rx_buffer_size > UART_FIFO_LEN) || ((uart_num == UART_NUM_1) && (rx_buffer_size == 0)), "uart rx buffer length error(>128)", ESP_ERR_INVALID_ARG);
+ UART_CHECK((tx_buffer_size > UART_FIFO_LEN) || (tx_buffer_size == 0), "uart tx buffer length error(>128 or 0)", ESP_ERR_INVALID_ARG);
+ UART_CHECK((queue_size >= 0), "queue_size error(>=0)", ESP_ERR_INVALID_ARG);
+
+ if (p_uart_obj[uart_num] == NULL)
+ {
+ p_uart_obj[uart_num] = (uart_obj_t *)calloc(1, sizeof(uart_obj_t));
+
+ if (p_uart_obj[uart_num] == NULL)
+ {
+ ESP_LOGE(UART_TAG, "UART driver malloc error");
+ return ESP_FAIL;
+ }
+
+ p_uart_obj[uart_num]->uart_num = uart_num;
+ p_uart_obj[uart_num]->uart_mode = UART_MODE_UART;
+ p_uart_obj[uart_num]->tx_fifo_sem = xSemaphoreCreateBinary();
+ p_uart_obj[uart_num]->tx_done_sem = xSemaphoreCreateBinary();
+ xSemaphoreGive(p_uart_obj[uart_num]->tx_fifo_sem);
+ p_uart_obj[uart_num]->tx_mux = xSemaphoreCreateMutex();
+ p_uart_obj[uart_num]->rx_mux = xSemaphoreCreateMutex();
+ p_uart_obj[uart_num]->queue_size = queue_size;
+ p_uart_obj[uart_num]->tx_ptr = NULL;
+ p_uart_obj[uart_num]->tx_head = NULL;
+ p_uart_obj[uart_num]->tx_len_tot = 0;
+ p_uart_obj[uart_num]->rx_buffered_len = 0;
+ p_uart_obj[uart_num]->wait_tx_done_flg = false;
+
+ if (uart_queue)
+ {
+ p_uart_obj[uart_num]->xQueueUart = xQueueCreate(queue_size, sizeof(uart_event_t));
+ *uart_queue = p_uart_obj[uart_num]->xQueueUart;
+ ESP_LOGI(UART_TAG, "queue free spaces: %d", (int)uxQueueSpacesAvailable(p_uart_obj[uart_num]->xQueueUart));
+ }
+ else
+ {
+ p_uart_obj[uart_num]->xQueueUart = NULL;
+ }
+
+ p_uart_obj[uart_num]->rx_buffer_full_flg = false;
+ p_uart_obj[uart_num]->tx_waiting_fifo = false;
+ p_uart_obj[uart_num]->rx_ptr = NULL;
+ p_uart_obj[uart_num]->rx_cur_remain = 0;
+ p_uart_obj[uart_num]->rx_head_ptr = NULL;
+ p_uart_obj[uart_num]->rx_ring_buf = xRingbufferCreate(rx_buffer_size, RINGBUF_TYPE_BYTEBUF);
+ p_uart_obj[uart_num]->rx_buf_size = rx_buffer_size;
+
+ if (tx_buffer_size > 0)
+ {
+ p_uart_obj[uart_num]->tx_ring_buf = xRingbufferCreate(tx_buffer_size, RINGBUF_TYPE_NOSPLIT);
+ p_uart_obj[uart_num]->tx_buf_size = tx_buffer_size;
+ }
+ else
+ {
+ p_uart_obj[uart_num]->tx_ring_buf = NULL;
+ p_uart_obj[uart_num]->tx_buf_size = 0;
+ }
+
+ p_uart_obj[uart_num]->uart_select_notif_callback = NULL;
+ }
+ else
+ {
+ ESP_LOGE(UART_TAG, "UART driver already installed");
+ return ESP_FAIL;
+ }
+
+ r = my_uart_isr_register(uart_num, uart_rx_intr_handler_default, p_uart_obj[uart_num]);
+
+ if (r != ESP_OK)
+ {
+ goto err;
+ }
+
+ uart_intr_config_t uart_intr = {
+ .intr_enable_mask = UART_RXFIFO_FULL_INT_ENA_M | UART_RXFIFO_TOUT_INT_ENA_M | UART_FRM_ERR_INT_ENA_M | UART_RXFIFO_OVF_INT_ENA_M,
+ .rxfifo_full_thresh = UART_FULL_THRESH_DEFAULT,
+ .rx_timeout_thresh = UART_TOUT_THRESH_DEFAULT,
+ .txfifo_empty_intr_thresh = UART_EMPTY_THRESH_DEFAULT};
+ r = my_uart_intr_config(uart_num, &uart_intr);
+
+ if (r != ESP_OK)
+ {
+ goto err;
+ }
+
+ return r;
+
+err:
+ ESP_LOGE(UART_TAG, "driver install error");
+ my_uart_driver_delete(uart_num);
+ return r;
+}
+
+// Make sure no other tasks are still using UART before you call this function
+esp_err_t my_uart_driver_delete(uart_port_t uart_num)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+
+ if (p_uart_obj[uart_num] == NULL)
+ {
+ ESP_LOGI(UART_TAG, "ALREADY NULL");
+ return ESP_OK;
+ }
+
+ my_uart_disable_rx_intr(uart_num);
+ my_uart_disable_tx_intr(uart_num);
+ _xt_isr_mask(0x1 << ETS_UART_INUM);
+
+ if (p_uart_obj[uart_num]->tx_fifo_sem)
+ {
+ vSemaphoreDelete(p_uart_obj[uart_num]->tx_fifo_sem);
+ p_uart_obj[uart_num]->tx_fifo_sem = NULL;
+ }
+
+ if (p_uart_obj[uart_num]->tx_done_sem)
+ {
+ vSemaphoreDelete(p_uart_obj[uart_num]->tx_done_sem);
+ p_uart_obj[uart_num]->tx_done_sem = NULL;
+ }
+
+ if (p_uart_obj[uart_num]->tx_mux)
+ {
+ vSemaphoreDelete(p_uart_obj[uart_num]->tx_mux);
+ p_uart_obj[uart_num]->tx_mux = NULL;
+ }
+
+ if (p_uart_obj[uart_num]->rx_mux)
+ {
+ vSemaphoreDelete(p_uart_obj[uart_num]->rx_mux);
+ p_uart_obj[uart_num]->rx_mux = NULL;
+ }
+
+ if (p_uart_obj[uart_num]->xQueueUart)
+ {
+ vQueueDelete(p_uart_obj[uart_num]->xQueueUart);
+ p_uart_obj[uart_num]->xQueueUart = NULL;
+ }
+
+ if (p_uart_obj[uart_num]->rx_ring_buf)
+ {
+ vRingbufferDelete(p_uart_obj[uart_num]->rx_ring_buf);
+ p_uart_obj[uart_num]->rx_ring_buf = NULL;
+ }
+
+ if (p_uart_obj[uart_num]->tx_ring_buf)
+ {
+ vRingbufferDelete(p_uart_obj[uart_num]->tx_ring_buf);
+ p_uart_obj[uart_num]->tx_ring_buf = NULL;
+ }
+
+ free(p_uart_obj[uart_num]);
+ p_uart_obj[uart_num] = NULL;
+
+ return ESP_OK;
+}
+
+void uart_set_select_notif_callback(uart_port_t uart_num, uart_select_notif_callback_t uart_select_notif_callback)
+{
+ if (uart_num < UART_NUM_MAX && p_uart_obj[uart_num])
+ {
+ p_uart_obj[uart_num]->uart_select_notif_callback = (uart_select_notif_callback_t)uart_select_notif_callback;
+ }
+}
+
+esp_err_t my_uart_set_rx_timeout(uart_port_t uart_num, const uint8_t tout_thresh)
+{
+ UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_ERR_INVALID_ARG);
+ UART_CHECK((tout_thresh < 127), "tout_thresh max value is 126", ESP_ERR_INVALID_ARG);
+
+ UART_ENTER_CRITICAL();
+
+ // The tout_thresh = 1, defines TOUT interrupt timeout equal to
+ // transmission time of one symbol (~11 bit) on current baudrate
+ if (tout_thresh > 0)
+ {
+ UART[uart_num]->conf1.rx_tout_thrhd = (tout_thresh & 0x7f);
+ UART[uart_num]->conf1.rx_tout_en = 1;
+ }
+ else
+ {
+ UART[uart_num]->conf1.rx_tout_en = 0;
+ }
+
+ UART_EXIT_CRITICAL();
+ return ESP_OK;
+}
diff --git a/components/README.md b/components/README.md
new file mode 100644
index 0000000..3fc0da1
--- /dev/null
+++ b/components/README.md
@@ -0,0 +1,2 @@
+# TODO
+1. USB
\ No newline at end of file
diff --git a/components/USBIP/CMakeLists.txt b/components/USBIP/CMakeLists.txt
new file mode 100644
index 0000000..3aeba6c
--- /dev/null
+++ b/components/USBIP/CMakeLists.txt
@@ -0,0 +1,4 @@
+set(COMPONENT_ADD_INCLUDEDIRS ". ../../main")
+set(COMPONENT_SRCS "MSOS20Descriptors.c USB_handle.c USBd_config.c")
+
+register_component()
\ No newline at end of file
diff --git a/components/USBIP/MSOS20Descriptors.c b/components/USBIP/MSOS20Descriptors.c
new file mode 100644
index 0000000..6621557
--- /dev/null
+++ b/components/USBIP/MSOS20Descriptors.c
@@ -0,0 +1,84 @@
+/**
+ * @file MSOS20Descriptors.c
+ * @author windowsair
+ * @brief Store related data of Microsoft OS 2.0 descriptor
+ * @version 0.1
+ * @date 2019-11-21
+ *
+ * @copyright Copyright (c) 2019
+ *
+ */
+
+ ////TODO: refactoring into structure
+
+#include
+#include "MSOS20Descriptors.h"
+
+#define USBShort(ui16Value) ((ui16Value) & 0xff), ((ui16Value) >> 8) //((ui16Value) & 0xFF),(((ui16Value) >> 8) & 0xFF)
+
+
+
+// Microsoft OS 2.0 descriptor set header
+const uint8_t msOs20DescriptorSetHeader[kLengthOfMsOS20] =
+{
+ // Microsoft OS 2.0 Descriptor Set header (Table 10)
+ 0x0A, 0x00, // wLength (Shall be set to 0x0A)
+ MS_OS_20_SET_HEADER_DESCRIPTOR, 0x00,
+ 0x00, 0x00, 0x03, 0x06, // dwWindowsVersion: Windows 8.1 (NTDDI_WINBLUE)
+ USBShort(kLengthOfMsOS20), // wTotalLength
+
+ // Support WinUSB
+ // See https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/automatic-installation-of-winusb
+
+ // Microsoft OS 2.0 compatible ID descriptor (Table 13)
+ 0x14, 0x00, // wLength
+ USBShort(MS_OS_20_FEATURE_COMPATIBLE_ID), // wDescriptorType
+ 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, // compatibleID
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // subCompatibleID
+
+ // Microsoft OS 2.0 registry property descriptor (Table 14)
+ 0x84, 0x00, // wLength
+ USBShort(MS_OS_20_FEATURE_REG_PROPERTY),
+ 0x07, 0x00, // wPropertyDataType: REG_MULTI_SZ (Unicode Strings)
+ 0x2A, 0x00, // wPropertyNameLength
+ 'D',0,'e',0,'v',0,'i',0,'c',0,'e',0,'I',0,'n',0,'t',0,'e',0,'r',0,
+ 'f',0,'a',0,'c',0,'e',0,'G',0,'U',0,'I',0,'D',0,'s',0,0,0,
+ // Set to "DeviceInterfaceGUID" to support WinUSB
+ 0x50, 0x00, // wPropertyDataLength
+ // WinUSB GUID
+ '{',0,'C',0,'D',0,'B',0,'3',0,'B',0,'5',0,'A',0,'D',0,'-',0,
+ '2',0,'9',0,'3',0,'B',0,'-',0,'4',0,'6',0,'6',0,'3',0,'-',0,
+ 'A',0,'A',0,'3',0,'6',0,'-',0,'1',0,'A',0,'A',0,'E',0,'4',0,
+ '6',0,'4',0,'6',0,'3',0,'7',0,'7',0,'6',0,'}',0,0,0,0,0,
+ // identify a CMSIS-DAP V2 configuration,
+ // must set to "{CDB3B5AD-293B-4663-AA36-1AAE46463776}"
+
+};
+
+const uint8_t bosDescriptor[kLengthOfBos] =
+{
+ // Universal Serial Bus 3.0 Specification, Table 9-9.
+ 0x05, // bLength of this descriptor
+ USB_DESCRIPTOR_TYPE_BOS, // BOS Descriptor type(Constant)
+ USBShort(kLengthOfBos), // wLength
+ 0x01, // bNumDeviceCaps
+
+ // Microsoft OS 2.0 platform capability descriptor header (Table 4)
+ // See also:
+ // Universal Serial Bus 3.0 Specification : Format of a Device Capability Descriptor, Table 9-10.
+
+ 0x1C, // bLength of this first device capability descriptor
+ // bLength -> The total length of the remaining arrays containing this field
+ USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY, // bDescriptorType
+ USB_DEVICE_CAPABILITY_TYPE_PLATFORM, // bDevCapabilityType
+
+ // Capability-Dependent (See USB3.0 Specification Table 9-10.)
+ 0x00, // bReserved
+ USB_DEVICE_CAPABILITY_UUID, // MS_OS_20_Platform_Capability_ID
+
+ 0x00, 0x00, 0x03, 0x06, // dwWindowsVersion: Windows 8.1 (NTDDI_WINBLUE)
+ USBShort(kLengthOfMsOS20), // wMSOSDescriptorSetTotalLength(length of descriptor set header)
+ kValueOfbMS_VendorCode, // bMS_VendorCode (0x01 will be ok)
+ ////TODO:change this
+ 0, // bAltEnumCode
+};
\ No newline at end of file
diff --git a/components/USBIP/MSOS20Descriptors.h b/components/USBIP/MSOS20Descriptors.h
new file mode 100644
index 0000000..51bbcb1
--- /dev/null
+++ b/components/USBIP/MSOS20Descriptors.h
@@ -0,0 +1,81 @@
+/**
+ * @file MSOS20Descriptors.h
+ * @author windowsair
+ * @brief
+ * @version 0.1
+ * @date 2019-11-21
+ *
+ * @copyright Copyright (c) 2019
+ *
+ */
+
+#ifndef __MSOS20DESCRIPTORS_H__
+#define __MSOS20DESCRIPTORS_H__
+
+#define kLengthOfMsOS20 0xA2
+#define kLengthOfBos 0x21
+#define kValueOfbMS_VendorCode 0x01// Just set to 0x01
+extern const uint8_t bosDescriptor[kLengthOfBos];
+extern const uint8_t msOs20DescriptorSetHeader[kLengthOfMsOS20];
+
+/* Microsoft OS 2.0 Descriptors BEGIN */
+
+// Platform capability BOS descriptor, Table 1.
+#define USB_DEVICE_CAPABILITY_TYPE_PLATFORM 5
+
+// Platform capability UUID, Table 3.
+// {D8DD60DF-4589-4CC7-9CD2-659D9E648A9F}
+#define USB_DEVICE_CAPABILITY_UUID 0xDF, 0x60, 0xDD, 0xD8, 0x89, 0x45, 0xC7, 0x4C, 0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F
+
+
+// Microsoft OS 2.0 descriptor wIndex values enum, Table 8.
+#define MS_OS_20_DESCRIPTOR_INDEX 7
+#define MS_OS_20_SET_ALT_ENUMERATION 8
+
+
+// Microsoft OS 2.0 descriptor types enum for wDescriptorType values, Table 9.
+#define MS_OS_20_SET_HEADER_DESCRIPTOR 0x00
+#define MS_OS_20_SUBSET_HEADER_CONFIGURATION 0x01
+#define MS_OS_20_SUBSET_HEADER_FUNCTION 0x02
+#define MS_OS_20_FEATURE_COMPATIBLE_ID 0x03
+#define MS_OS_20_FEATURE_REG_PROPERTY 0x04
+#define MS_OS_20_FEATURE_MIN_RESUME_TIME 0x05
+#define MS_OS_20_FEATURE_MODEL_ID 0x06
+#define MS_OS_20_FEATURE_CCGP_DEVICE 0x07
+
+/* Microsoft OS 2.0 Descriptors END */
+
+
+
+/* Wireless USB Standard Extension Descriptor Types BEGIN */
+
+// Wireless USB Specification 1.1 revison 1.1, Table 7-21.
+#define USB_DESCRIPTOR_TYPE_SECURITY 12
+#define USB_DESCRIPTOR_TYPE_KEY 13
+#define USB_DESCRIPTOR_TYPE_ENCRYPTION_TYPE 14
+#define USB_DESCRIPTOR_TYPE_BOS 15
+#define USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY 16
+#define USB_DESCRIPTOR_TYPE_WIRELESS_ENDPOINT_COMPANION 17
+
+/* Wireless USB Standard Extension Descriptor Types END */
+
+
+/* Microsoft Extended Compat ID OS Feature Descriptor BEGIN */
+
+#define USB_MS_EXTENDED_COMPAT_ID_VERSION 0x0100
+#define USB_MS_EXTENDED_COMPAT_ID_TYPE 0x04
+
+#define USB_COMPATID_NONE {0}
+#define USB_SUBCOMPATID_NONE {0}
+#define USB_COMPATID_WINUSB "WINUSB\0"
+#define USB_COMPATID_RNDIS "RNDIS\0\0"
+#define USB_COMPATID_PTP "PTP\0\0\0\0"
+#define USB_COMPATID_MTP "MTP\0\0\0\0"
+#define USB_COMPATID_BLUETOOTH "BLUTUTH"
+#define USB_SUBCOMPATID_BT_V11 "11\0\0\0\0\0"
+#define USB_SUBCOMPATID_BT_V12 "12\0\0\0\0\0"
+#define USB_SUBCOMPATID_BT_V20EDR "EDR\0\0\0\0"
+
+/* Microsoft Extended Compat ID OS Feature Descriptor END */
+
+#endif
\ No newline at end of file
diff --git a/components/USBIP/USB_handle.c b/components/USBIP/USB_handle.c
new file mode 100644
index 0000000..f9fe76a
--- /dev/null
+++ b/components/USBIP/USB_handle.c
@@ -0,0 +1,333 @@
+/**
+ * @file USB_handle.c
+ * @brief Handle all Standard Device Requests on endpoint 0
+ * @version 0.1
+ * @date 2020-01-23
+ *
+ * @copyright Copyright (c) 2020
+ *
+ */
+#include
+#include
+#include "lwip/err.h"
+#include "lwip/sockets.h"
+#include "lwip/sys.h"
+#include
+#include "USB_handle.h"
+#include "USBd_config.h"
+#include "usbip_server.h"
+#include "usb_defs.h"
+#include "MSOS20Descriptors.h"
+
+// const char *strings_list[] = {
+// 0, // reserved: available languages
+// "windowsair",
+// "CMSIS-DAP v2",
+// "1234",
+// };
+
+const char *strings_list[] = {
+ 0, // reserved: available languages
+ "windowsair",
+ "esp8266 CMSIS-DAP",
+ "1234",
+};
+// handle functions
+static void handleGetDescriptor(usbip_stage2_header *header);
+
+////TODO: may be ok
+void handleUSBControlRequest(usbip_stage2_header *header)
+{
+ // Table 9-3. Standard Device Requests
+
+ switch (header->u.cmd_submit.request.bmRequestType)
+ {
+ case 0x00: // ignore..
+ switch (header->u.cmd_submit.request.bRequest)
+ {
+ case USB_REQ_CLEAR_FEATURE:
+ os_printf("* CLEAR FEATURE\r\n");
+ send_stage2_submit_data(header, 0, 0, 0);
+ break;
+ case USB_REQ_SET_FEATURE:
+ os_printf("* SET FEATURE\r\n");
+ send_stage2_submit_data(header, 0, 0, 0);
+ break;
+ case USB_REQ_SET_ADDRESS:
+ os_printf("* SET ADDRESS\r\n");
+ send_stage2_submit_data(header, 0, 0, 0);
+ break;
+ case USB_REQ_SET_DESCRIPTOR:
+ os_printf("* SET DESCRIPTOR\r\n");
+ send_stage2_submit_data(header, 0, 0, 0);
+ break;
+ case USB_REQ_SET_CONFIGURATION:
+ os_printf("* SET CONFIGURATION\r\n");
+ send_stage2_submit_data(header, 0, 0, 0);
+ break;
+ default:
+ os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
+ header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
+ break;
+ }
+ break;
+ case 0x01: // ignore...
+ switch (header->u.cmd_submit.request.bRequest)
+ {
+ case USB_REQ_CLEAR_FEATURE:
+ os_printf("* CLEAR FEATURE\r\n");
+ send_stage2_submit_data(header, 0, 0, 0);
+ break;
+ case USB_REQ_SET_FEATURE:
+ os_printf("* SET FEATURE\r\n");
+ send_stage2_submit_data(header, 0, 0, 0);
+ break;
+ case USB_REQ_SET_INTERFACE:
+ os_printf("* SET INTERFACE\r\n");
+ send_stage2_submit_data(header, 0, 0, 0);
+ break;
+
+ default:
+ os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
+ header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
+ break;
+ }
+ break;
+ case 0x02: // ignore..
+ switch (header->u.cmd_submit.request.bRequest)
+ {
+ case USB_REQ_CLEAR_FEATURE:
+ os_printf("* CLEAR FEATURE\r\n");
+ send_stage2_submit_data(header, 0, 0, 0);
+ break;
+ case USB_REQ_SET_FEATURE:
+ os_printf("* SET INTERFACE\r\n");
+ send_stage2_submit_data(header, 0, 0, 0);
+ break;
+
+ default:
+ os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
+ header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
+ break;
+ }
+ break;
+
+ case 0x80: // *IMPORTANT*
+#if (USE_WINUSB == 0)
+ case 0x81:
+#endif
+ {
+ switch (header->u.cmd_submit.request.bRequest)
+ {
+ case USB_REQ_GET_CONFIGURATION:
+ os_printf("* GET CONIFGTRATION\r\n");
+ send_stage2_submit_data(header, 0, 0, 0);
+ break;
+ case USB_REQ_GET_DESCRIPTOR:
+ handleGetDescriptor(header); ////TODO: device_qualifier
+ break;
+ case USB_REQ_GET_STATUS:
+ os_printf("* GET STATUS\r\n");
+ send_stage2_submit_data(header, 0, 0, 0);
+ break;
+ default:
+ os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
+ header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
+ break;
+ }
+ break;
+ }
+#if (USE_WINUSB == 1)
+ case 0x81: // ignore...
+ switch (header->u.cmd_submit.request.bRequest)
+ {
+ case USB_REQ_GET_INTERFACE:
+ os_printf("* GET INTERFACE\r\n");
+ send_stage2_submit_data(header, 0, 0, 0);
+ break;
+ case USB_REQ_SET_SYNCH_FRAME:
+ os_printf("* SET SYNCH FRAME\r\n");
+ send_stage2_submit_data(header, 0, 0, 0);
+ break;
+ case USB_REQ_GET_STATUS:
+ os_printf("* GET STATUS\r\n");
+ send_stage2_submit_data(header, 0, 0, 0);
+ break;
+
+ default:
+ os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
+ header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
+ break;
+ }
+ break;
+#endif
+ case 0x82: // ignore...
+ switch (header->u.cmd_submit.request.bRequest)
+ {
+ case USB_REQ_GET_STATUS:
+ os_printf("* GET STATUS\r\n");
+ send_stage2_submit_data(header, 0, 0, 0);
+ break;
+
+ default:
+ os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
+ header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
+ break;
+ }
+ break;
+ case 0xC0: // Microsoft OS 2.0 vendor-specific descriptor
+ {
+ uint16_t *wIndex = (uint16_t *)(&(header->u.cmd_submit.request.wIndex));
+ switch (*wIndex)
+ {
+ case MS_OS_20_DESCRIPTOR_INDEX:
+ os_printf("* GET MSOS 2.0 vendor-specific descriptor\r\n");
+ send_stage2_submit_data(header, 0, msOs20DescriptorSetHeader, sizeof(msOs20DescriptorSetHeader));
+ break;
+ case MS_OS_20_SET_ALT_ENUMERATION:
+ // set alternate enumeration command
+ // bAltEnumCode set to 0
+ os_printf("Set alternate enumeration.This should not happen.\r\n");
+ break;
+
+ default:
+ os_printf("USB unknown request, bmRequestType:%d,bRequest:%d,wIndex:%d\r\n",
+ header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest, *wIndex);
+ break;
+ }
+ break;
+ }
+ case 0x21: // Set_Idle for HID
+ switch (header->u.cmd_submit.request.bRequest)
+ {
+ case USB_REQ_SET_IDLE:
+ os_printf("* SET IDLE\r\n");
+ send_stage2_submit(header, 0, 0);
+ break;
+
+ default:
+ os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
+ header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
+ break;
+ }
+ break;
+ default:
+ os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n",
+ header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest);
+ break;
+ }
+}
+
+static void handleGetDescriptor(usbip_stage2_header *header)
+{
+ // 9.4.3 Get Descriptor
+ switch (header->u.cmd_submit.request.wValue.u8hi)
+ {
+ case USB_DT_DEVICE: // get device descriptor
+ os_printf("* GET 0x01 DEVICE DESCRIPTOR\r\n");
+ send_stage2_submit_data(header, 0, &kUSBd0DeviceDescriptor[0], sizeof(kUSBd0DeviceDescriptor));
+ break;
+
+ case USB_DT_CONFIGURATION: // get configuration descriptor
+ os_printf("* GET 0x02 CONFIGURATION DESCRIPTOR\r\n");
+ ////TODO: ?
+ if (header->u.cmd_submit.data_length == USB_DT_CONFIGURATION_SIZE)
+ {
+ os_printf("Sending only first part of CONFIG\r\n");
+
+ send_stage2_submit(header, 0, header->u.cmd_submit.data_length);
+ send(kSock, kUSBd0ConfigDescriptor, sizeof(kUSBd0ConfigDescriptor), 0);
+ }
+ else
+ {
+ os_printf("Sending ALL CONFIG\r\n");
+
+ send_stage2_submit(header, 0, header->u.cmd_submit.data_length);
+ send(kSock, kUSBd0ConfigDescriptor, sizeof(kUSBd0ConfigDescriptor), 0);
+ send(kSock, kUSBd0InterfaceDescriptor, sizeof(kUSBd0InterfaceDescriptor), 0);
+ }
+ break;
+
+ case USB_DT_STRING:
+ //os_printf("* GET 0x03 STRING DESCRIPTOR\r\n");
+
+ if (header->u.cmd_submit.request.wValue.u8lo == 0)
+ {
+ os_printf("** REQUESTED list of supported languages\r\n");
+ send_stage2_submit_data(header, 0, kLangDescriptor, sizeof(kLangDescriptor));
+ }
+ else if (header->u.cmd_submit.request.wValue.u8lo != 0xee)
+ {
+ //os_printf("low bit : %d\r\n", (int)header->u.cmd_submit.request.wValue.u8lo);
+ //os_printf("high bit : %d\r\n", (int)header->u.cmd_submit.request.wValue.u8hi);
+ int slen = strlen(strings_list[header->u.cmd_submit.request.wValue.u8lo]);
+ int wslen = slen * 2;
+ int buff_len = sizeof(usb_string_descriptor) + wslen;
+ char temp_buff[64];
+ usb_string_descriptor *desc = (usb_string_descriptor *)temp_buff;
+ desc->bLength = buff_len;
+ desc->bDescriptorType = USB_DT_STRING;
+ for (int i = 0; i < slen; i++)
+ {
+ desc->wData[i] = strings_list[header->u.cmd_submit.request.wValue.u8lo][i];
+
+ }
+ send_stage2_submit_data(header, 0, (uint8_t *)temp_buff, buff_len);
+ }
+ else
+ {
+ os_printf("low bit : %d\r\n", (int)header->u.cmd_submit.request.wValue.u8lo);
+ os_printf("high bit : %d\r\n", (int)header->u.cmd_submit.request.wValue.u8hi);
+ os_printf("***Unsupported String descriptor***\r\n");
+ }
+ break;
+
+ case USB_DT_INTERFACE:
+ os_printf("* GET 0x04 INTERFACE DESCRIPTOR (UNIMPLEMENTED)\r\n");
+ ////TODO:UNIMPLEMENTED
+ send_stage2_submit(header, 0, 0);
+ break;
+
+ case USB_DT_ENDPOINT:
+ os_printf("* GET 0x05 ENDPOINT DESCRIPTOR (UNIMPLEMENTED)\r\n");
+ ////TODO:UNIMPLEMENTED
+ send_stage2_submit(header, 0, 0);
+ break;
+
+ case USB_DT_DEVICE_QUALIFIER:
+ os_printf("* GET 0x06 DEVICE QUALIFIER DESCRIPTOR\r\n");
+
+ usb_device_qualifier_descriptor desc;
+
+ memset(&desc, 0, sizeof(usb_device_qualifier_descriptor));
+
+ send_stage2_submit_data(header, 0, &desc, sizeof(usb_device_qualifier_descriptor));
+ break;
+
+ case USB_DT_OTHER_SPEED_CONFIGURATION:
+ os_printf("GET 0x07 [UNIMPLEMENTED] USB_DT_OTHER_SPEED_CONFIGURATION\r\n");
+ ////TODO:UNIMPLEMENTED
+ send_stage2_submit(header, 0, 0);
+ break;
+
+ case USB_DT_INTERFACE_POWER:
+ os_printf("GET 0x08 [UNIMPLEMENTED] USB_DT_INTERFACE_POWER\r\n");
+ ////TODO:UNIMPLEMENTED
+ send_stage2_submit(header, 0, 0);
+ break;
+
+ case USB_DT_BOS:
+ os_printf("* GET 0x0F BOS DESCRIPTOR\r\n");
+ send_stage2_submit_data(header, 0, bosDescriptor, sizeof(bosDescriptor));
+ break;
+ case USB_DT_HID_REPORT:
+ os_printf("* GET 0x22 HID REPORT DESCRIPTOR\r\n");
+ send_stage2_submit_data(header, 0, (void *)kHidReportDescriptor, sizeof(kHidReportDescriptor));
+ break;
+ default:
+ os_printf("USB unknown Get Descriptor requested:%d\r\n", header->u.cmd_submit.request.wValue.u8lo);
+ os_printf("low bit :%d\r\n",header->u.cmd_submit.request.wValue.u8lo);
+ os_printf("high bit :%d\r\n",header->u.cmd_submit.request.wValue.u8hi);
+ break;
+ }
+}
diff --git a/components/USBIP/USB_handle.h b/components/USBIP/USB_handle.h
new file mode 100644
index 0000000..ac4eeec
--- /dev/null
+++ b/components/USBIP/USB_handle.h
@@ -0,0 +1,7 @@
+#ifndef __USB_HANDLE_H__
+#define __USB_HANDLE_H__
+
+#include "usbip_defs.h"
+void handleUSBControlRequest(usbip_stage2_header *header);
+
+#endif
\ No newline at end of file
diff --git a/components/USBIP/USBd_config.c b/components/USBIP/USBd_config.c
new file mode 100644
index 0000000..0061a8b
--- /dev/null
+++ b/components/USBIP/USBd_config.c
@@ -0,0 +1,310 @@
+ ////TODO: refactoring into structure
+/**
+ * @file USBd_config.c
+ * @brief Standard USB Descriptor Definitions
+ fix bugs 2020-1-23
+ * @version 0.2
+ * @date 2020-1-23
+ *
+ *
+ */
+#include
+#include
+#include "USBd_config.h"
+#include "usb_defs.h"
+
+#define USBShort(ui16Value) ((ui16Value) & 0xff), ((ui16Value) >> 8) //((ui16Value) & 0xFF),(((ui16Value) >> 8) & 0xFF)
+
+
+/**
+ * @brief step 1. Build Standard Device Descriptor
+ *
+ */
+
+// Standard Device Descriptor
+const uint8_t kUSBd0DeviceDescriptor[0x12] =
+{
+ 0x12, // bLength
+ USB_DT_DEVICE, // bDescriptorType
+ USBShort(0x0210), // bcdUSB
+ ////TODO: Is it also available elsewhere?
+
+ // We need to use a device other than the USB-IF standard, set to 0x00
+ 0x00, // bDeviceClass
+ 0x00, // bDeviceSubClass
+ 0x00, // bDeviceProtocol
+
+ USBD0_MAX_PACKET0, // bMaxPacketSize0 Maximum packet size for default pipe.
+ USBShort(USBD0_DEV_DESC_IDVENDOR), // idVendor Vendor ID (VID).
+ USBShort(USBD0_DEV_DESC_IDPRODUCT), // idProduct Product ID (PID).
+ USBShort(USBD0_DEV_DESC_BCDDEVICE), // bcdDevice Device Version BCD.
+ 0x01, // iManufacturer Index of Manufacturer string identifier.
+ 0x02, // iProduct Index of Product string identifier.
+ 0x03 * USBD0_STR_DESC_SER_EN, // iSerialNumber Index of Product serial number.
+ 0x01 // bNumConfigurations Number of configurations.
+};
+
+
+
+
+/**
+ * @brief step 2. Buid Standard Configuration Descriptor
+ *
+ */
+
+
+// Standard Interface Descriptor
+
+#if (USE_WINUSB ==1)
+const uint8_t kUSBd0InterfaceDescriptor[0x1E]=
+{
+ 0x09, // bLength
+ USB_DT_INTERFACE, // bDescriptorType
+ USBD_CUSTOM_CLASS0_IF0_NUM, // bInterfaceNumber
+ USBD_CUSTOM_CLASS0_IF0_ALT, // bAlternateSetting
+ 0x03, // bNumEndpoints(we will use 3 endpoints)
+ //
+ USBD_CUSTOM_CLASS0_IF0_CLASS, // bInterfaceClass
+ USBD_CUSTOM_CLASS0_IF0_SUBCLASS, // bInterfaceSubClass
+ USBD_CUSTOM_CLASS0_IF0_PROTOCOL, // bInterfaceProtocol
+ 0x00, // iInterface
+ // Index of string descriptor describing this interface
+ ////TODO: fix this 0x04 ?
+
+
+ // Standard Endpoint Descriptor
+
+ // Endpoint 1: Bulk Out – used for commands received from host PC.
+ // Endpoint 2: Bulk In – used for responses send to host PC.
+ // Endpoint 3: Bulk In (optional) – used for streaming SWO trace
+
+ // ATTENTION:
+ // physical endpoint 1 indeed included two "endpoints": Bulk OUT and Bulk IN
+ // physical endpoint 1 -> Endpoint 1 & Endpoint 2
+ // physical endpoint 2 -> Endpoint 3
+
+ // See also :
+ // http://www.keil.com/pack/doc/CMSIS/DAP/html/group__DAP__ConfigUSB__gr.html
+
+ /* Pysical endpoint 1 */
+
+ // "Endpoint 1: Bulk Out – used for commands received from host PC." PC -> Device
+ 0x07, // bLength
+ USB_DT_ENDPOINT, // bDescriptorType
+ 0x01, // bEndpointAddress
+ USB_ENDPOINT_ATTR_BULK, // bmAttributes
+ USBShort(512), // wMaxPacketSize
+ // We assume that it always runs in High Speed.
+ 0x00, // bInterval
+
+ /* Pysical endpoint 1 */
+
+ // "Endpoint 2: Bulk In – used for responses send to host PC." Device -> PC
+ 0x07, // bLength
+ USB_DT_ENDPOINT, // bDescriptorType
+ 0x81, // bEndpointAddress
+ USB_ENDPOINT_ATTR_BULK, // bmAttributes
+ USBShort(512), // wMaxPacketSize
+ 0x00, // bInterval
+
+ /* Pysical endpoint 2 */
+
+ // "Endpoint 3: Bulk In (optional) – used for streaming SWO trace" Device -> PC
+ 0x07, // bLength
+ USB_DT_ENDPOINT, // bDescriptorType
+ 0x82, // bEndpointAddress
+ USB_ENDPOINT_ATTR_BULK, // bmAttributes
+ USBShort(512), // wMaxPacketSize
+ 0x00, // bInterval
+
+
+};
+
+#else
+const uint8_t kUSBd0InterfaceDescriptor[0x20]=
+{
+ 0x09, // bLength
+ USB_DT_INTERFACE, // bDescriptorType
+ USBD_CUSTOM_CLASS0_IF0_NUM, // bInterfaceNumber
+ USBD_CUSTOM_CLASS0_IF0_ALT, // bAlternateSetting
+ 0x02, // bNumEndpoints ----> 2 endpoint for USB HID
+ //
+ USBD_CUSTOM_CLASS0_IF0_CLASS, // bInterfaceClass
+ USBD_CUSTOM_CLASS0_IF0_SUBCLASS, // bInterfaceSubClass
+ USBD_CUSTOM_CLASS0_IF0_PROTOCOL, // bInterfaceProtocol
+ 0x00, // iInterface
+ // Index of string descriptor describing this interface
+
+ // HID Descriptor
+ 0x09, // bLength
+ 0x21, // bDescriptorType
+ 0x11, 0x01, // bcdHID
+ 0x00, // bCountryCode
+ 0x01, // bNumDescriptors
+ 0x22, // bDescriptorType1
+ 0x21, 0x00, // wDescriptorLength1
+
+ // Standard Endpoint Descriptor
+
+ // We perform all transfer operations on Pysical endpoint 1.
+
+ /* Pysical endpoint 1 */
+
+ 0x07, // bLength
+ USB_DT_ENDPOINT, // bDescriptorType
+ 0x81, // bEndpointAddress
+ USB_ENDPOINT_ATTR_INTERRUPT, // bmAttributes
+ USBShort(64), // wMaxPacketSize
+ 0x01, // bInterval
+
+ /* Pysical endpoint 1 */
+
+ 0x07, // bLength
+ USB_DT_ENDPOINT, // bDescriptorType
+ 0x01, // bEndpointAddress
+ USB_ENDPOINT_ATTR_INTERRUPT, // bmAttributes
+ USBShort(64), // wMaxPacketSize
+ 0x01, // bInterval
+};
+#endif
+
+// Standard Configuration Descriptor
+#define LENGTHOFCONFIGDESCRIPTOR 9
+
+#if (USE_WINUSB == 1)
+const uint8_t kUSBd0ConfigDescriptor[LENGTHOFCONFIGDESCRIPTOR] =
+{
+ // Configuration descriptor header.
+
+ 0x09, // bLength
+ USB_DT_CONFIGURATION, // bDescriptorType
+
+ USBShort((sizeof(kUSBd0InterfaceDescriptor)) + (LENGTHOFCONFIGDESCRIPTOR)),
+ // wTotalLength
+
+ 0x01, // bNumInterfaces
+ // There is only one interface in the CMSIS-DAP project
+ 0x01, // bConfigurationValue: 0x01 is used to select this configuration */
+ 0x00, // iConfiguration: no string to describe this configuration */
+ USBD0_CFG_DESC_BMATTRIBUTES, // bmAttributes
+
+ USBD0_CFG_DESC_BMAXPOWER, // bMaxPower
+};
+
+#else
+const uint8_t kUSBd0ConfigDescriptor[LENGTHOFCONFIGDESCRIPTOR] =
+{
+ // Configuration descriptor header.
+
+ 0x09, // bLength
+ USB_DT_CONFIGURATION, // bDescriptorType
+
+ USBShort((sizeof(kUSBd0InterfaceDescriptor)) + (LENGTHOFCONFIGDESCRIPTOR)),
+ // wTotalLength
+
+ 0x01, // bNumInterfaces
+ // There is only one interface in the CMSIS-DAP project
+ 0x01, // bConfigurationValue: 0x01 is used to select this configuration */
+ 0x00, // iConfiguration: no string to describe this configuration */
+ USBD0_CFG_DESC_BMATTRIBUTES, // bmAttributes
+
+ USBD0_CFG_DESC_BMAXPOWER, // bMaxPower
+};
+#endif
+
+
+// USB HID Report Descriptor
+const uint8_t kHidReportDescriptor[0x21] = {
+ 0x06, 0x00, 0xFF, // Usage Page (Vendor Defined 0xFF00)
+ 0x09, 0x01, // Usage (0x01)
+ 0xA1, 0x01, // Collection (Application)
+ 0x15, 0x00, // Logical Minimum (0)
+ 0x26, 0xFF, 0x00, // Logical Maximum (255)
+ 0x75, 0x08, // Report Size (8)
+ 0x95, 0xFF, // Report Count (64)
+ 0x09, 0x01, // Usage (0x01)
+ 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
+ 0x95, 0xFF, // Report Count (64)
+ 0x09, 0x01, // Usage (0x01)
+ 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
+ 0x95, 0x01, // Report Count (1)
+ 0x09, 0x01, // Usage (0x01)
+ 0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
+ 0xC0, // End Collection
+ // 33 bytes
+};
+
+
+
+
+
+
+/**
+ * @brief step 3. Build String Descriptor
+ *
+ */
+
+
+const uint8_t kLangDescriptor[0x04] =
+{
+ 4,
+ USB_DT_STRING,
+ USBShort(USB_LANGID_ENGLISH_US)
+};
+
+
+/**
+ * @brief We will use these string descriptor:
+ * 1. Manufacturer string -> "KEIL - Tools By ARM"
+ * 2. Product string -> "LPC-Link-II"
+ * 3. Serial number string -> "0001A0000000"
+ * 4. Interface string -> "LPC-Link-II CMSIS-DAP"
+ *
+ *
+ */
+
+const uint8_t kManufacturerString[0x28] =
+{
+ 0x28, // bLength
+ 0x03, // bDescriptorType
+ // "KEIL - Tools By ARM"
+ 'K', 0, 'E', 0, 'I', 0, 'L', 0, ' ', 0, '-', 0, ' ', 0, 'T', 0, 'o', 0, 'o', 0,
+ 'l', 0, 's', 0, ' ', 0, 'B', 0, 'y', 0, ' ', 0, 'A', 0, 'R', 0, 'M', 0
+};
+
+const uint8_t kProductString[0x18] =
+{
+ 0x18, // bLength
+ 0x03, // bDescriptorType
+ // "LPC-Link-II"
+ 'L', 0, 'P', 0, 'C', 0, '-', 0, 'L', 0, 'i', 0, 'n', 0, 'k', 0, '-', 0, 'I', 0,
+ 'I', 0
+};
+
+const uint8_t kSerialNumberString[0x1A] =
+{
+ 0x1A, // bLength
+ 0x03, // bDescriptorType
+ // "0001A0000000"
+ '0', 0, '0', 0, '0', 0, '1', 0, 'A', 0, '0', 0, '0', 0, '0', 0, '0', 0, '0', 0,
+ '0', 0, '0', 0
+};
+
+const uint8_t kInterfaceString[0x2C] =
+{
+ 0x2C, // bLength
+ 0x03, // bDescriptorType
+ // "LPC-Link-II CMSIS-DAP"
+ 'L', 0, 'P', 0, 'C', 0, '-', 0, 'L', 0, 'i', 0, 'n', 0, 'k', 0, '-', 0, 'I', 0,
+ 'I', 0, ' ', 0, 'C', 0, 'M', 0, 'S', 0, 'I', 0, 'S', 0, '-', 0, 'D', 0, 'A', 0,
+ 'P', 0
+};
+
+const uint8_t * const kUSBd0StringDescriptorsSet[0x05] =
+{
+ kLangDescriptor,
+ kManufacturerString,
+ kProductString,
+ kSerialNumberString,
+ kInterfaceString
+};
\ No newline at end of file
diff --git a/components/USBIP/USBd_config.h b/components/USBIP/USBd_config.h
new file mode 100644
index 0000000..dc3a3e2
--- /dev/null
+++ b/components/USBIP/USBd_config.h
@@ -0,0 +1,66 @@
+#ifndef __USBD_CONFIG_H__
+#define __USBD_CONFIG_H__
+
+#define USE_WINUSB 0
+
+// Vendor ID assigned by USB-IF (idVendor).
+#define USBD0_DEV_DESC_IDVENDOR 0xC251
+// Product ID assigned by manufacturer (idProduct).
+#define USBD0_DEV_DESC_IDPRODUCT 0xF00A
+// Device Release Number in binary-coded decimal (bcdDevice).
+#define USBD0_DEV_DESC_BCDDEVICE 0x0100
+
+// Maximum packet size for Endpoint 0 (bMaxPacketSize0).
+#define USBD0_MAX_PACKET0 64
+
+// If disabled Serial Number String will not be assigned to USB Device.
+#define USBD0_STR_DESC_SER_EN 1
+
+// bmAttributes
+#define USBD0_CFG_DESC_BMATTRIBUTES 0x80
+
+// bMaxPower
+#define USBD0_CFG_DESC_BMAXPOWER 250
+
+// Interface Number
+#define USBD_CUSTOM_CLASS0_IF0_NUM 0
+
+// Alternate Setting
+#define USBD_CUSTOM_CLASS0_IF0_ALT 0
+
+// Class Code
+#if (USE_WINUSB == 1)
+#define USBD_CUSTOM_CLASS0_IF0_CLASS 0xFF // 0xFF: Vendor Specific
+#else
+#define USBD_CUSTOM_CLASS0_IF0_CLASS 0x03 // 0x03: HID class
+#endif
+
+// Subclass Code
+#define USBD_CUSTOM_CLASS0_IF0_SUBCLASS 0x00
+
+// Protocol Code
+#define USBD_CUSTOM_CLASS0_IF0_PROTOCOL 0x00
+
+/////////////////////////////////////////////
+
+// common part
+extern const uint8_t kUSBd0DeviceDescriptor[0x12];
+extern const uint8_t kLangDescriptor[0x04];
+extern const uint8_t kManufacturerString[0x28];
+extern const uint8_t kProductString[0x18];
+extern const uint8_t kSerialNumberString[0x1A];
+
+#if (USE_WINUSB == 1)
+extern const uint8_t kUSBd0InterfaceDescriptor[0x1E];
+extern const uint8_t kUSBd0ConfigDescriptor[0x09];
+extern const uint8_t kInterfaceString[0x2C];
+
+#else
+extern const uint8_t kUSBd0InterfaceDescriptor[0x20];
+extern const uint8_t kUSBd0ConfigDescriptor[0x09];
+extern const uint8_t kInterfaceString[0x2C];
+extern const uint8_t kHidReportDescriptor[0x21];
+
+#endif
+
+#endif
\ No newline at end of file
diff --git a/components/USBIP/usb_defs.h b/components/USBIP/usb_defs.h
new file mode 100644
index 0000000..0377dc4
--- /dev/null
+++ b/components/USBIP/usb_defs.h
@@ -0,0 +1,308 @@
+/**
+ * @file usb_defs.h
+ * @brief Modify
+ * @version 0.1
+ * @date 2020-01-22
+ *
+ * @copyright Copyright (c) 2020
+ *
+ */
+
+//
+// Created by thevoidnn on 10/25/17.
+//
+
+#ifndef __USB_DEFS_H__
+#define __USB_DEFS_H__
+
+#include
+
+#define USB_CLASS_MISCELLANEOUS_DEVICE 0xef
+#define USB_MISC_SUBCLASS_COMMON 0x02
+#define USB_MISC_PROTOCOL_INTERFACE_ASSOCIATION_DESCRIPTOR 0x01
+
+typedef union {
+ struct
+ {
+ uint8_t u8lo;
+ uint8_t u8hi;
+ } __attribute__((packed));
+ uint16_t u16;
+} word_t;
+
+typedef struct
+{
+ uint8_t bmRequestType;
+ uint8_t bRequest;
+ word_t wValue; // 16bit
+ word_t wIndex;
+ word_t wLength;
+} __attribute__((packed)) usb_standard_request;
+
+//#define USB_CLASS_HID 3
+
+#define USB_DT_HID 0x21
+#define USB_DT_REPORT 0x22
+
+//struct usb_hid_descriptor {
+// uint8_t bLength;
+// uint8_t bDescriptorType;
+// uint16_t bcdHID;
+// uint8_t bCountryCode;
+// uint8_t bNumDescriptors;
+//} __attribute__((packed));
+//#define USB_DT_HID_SIZE sizeof(struct usb_hid_descriptor)
+
+//struct usb_hid_report_descriptor {
+// uint8_t bDescriptorType;
+// uint16_t wReportLength;
+//} __attribute__((packed));
+
+#define USB_DT_REPORT_SIZE sizeof(struct usb_hid_report_descriptor)
+
+/* Class Definition */
+#define USB_CLASS_VENDOR 0xFF
+
+///////////////////////////////////////////////////////////////
+/* Table 9-2. Format of Setup Data */
+/* bmRequestType bit definitions */
+
+/* bit 7 : Direction */
+#define USB_REQ_TYPE_OUT 0x00 // Host-to-device
+#define USB_REQ_TYPE_IN 0x80 // Device-to-host
+/* bits 6..5 : Type */
+#define USB_REQ_TYPE_STANDARD 0x00
+#define USB_REQ_TYPE_CLASS 0x20
+#define USB_REQ_TYPE_VENDOR 0x40
+//#define USB_REQ_TYPE_RESERVED 0x60
+/* bits 4..0 : Recipient */
+#define USB_REQ_TYPE_DEVICE 0x00
+#define USB_REQ_TYPE_INTERFACE 0x01
+#define USB_REQ_TYPE_ENDPOINT 0x02
+#define USB_REQ_TYPE_OTHER 0x03
+//#define USB_REQ_TYPE_RESERVED 0x1F
+///////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////
+/* USB Standard Request Codes - Table 9-4 */
+#define USB_REQ_GET_STATUS 0
+#define USB_REQ_CLEAR_FEATURE 1
+/* Reserved for future use: 2 */
+#define USB_REQ_SET_FEATURE 3
+/* Reserved for future use: 3 */
+#define USB_REQ_SET_ADDRESS 5
+#define USB_REQ_GET_DESCRIPTOR 6
+#define USB_REQ_SET_DESCRIPTOR 7
+#define USB_REQ_GET_CONFIGURATION 8
+#define USB_REQ_SET_CONFIGURATION 9
+#define USB_REQ_GET_INTERFACE 10
+#define USB_REQ_SET_INTERFACE 11
+#define USB_REQ_SET_SYNCH_FRAME 12
+
+// USB HID Request
+#define USB_REQ_GET_REPORT 0x01
+#define USB_REQ_GET_IDLE 0x02
+#define USB_REQ_GET_PROTOCOL 0x03
+#define USB_REQ_SET_REPORT 0x09
+#define USB_REQ_SET_IDLE 0X0A
+#define USB_REQ_SET_PROTOCOL 0X0B
+///////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////
+/* USB Descriptor Types - Table 9-5 */
+#define USB_DT_DEVICE 1
+#define USB_DT_CONFIGURATION 2
+#define USB_DT_STRING 3
+#define USB_DT_INTERFACE 4
+#define USB_DT_ENDPOINT 5
+#define USB_DT_DEVICE_QUALIFIER 6
+#define USB_DT_OTHER_SPEED_CONFIGURATION 7
+#define USB_DT_INTERFACE_POWER 8
+#define USB_DT_BOS 15
+/* From ECNs */
+#define USB_DT_OTG 9
+#define USB_DT_DEBUG 10
+#define USB_DT_INTERFACE_ASSOCIATION 11
+/* USB HID */
+#define USB_DT_HID 0x21
+#define USB_DT_HID_REPORT 0x22
+///////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////
+/* USB Standard Feature Selectors - Table 9-6 */
+#define USB_FEAT_ENDPOINT_HALT 0 // Recipient: Device
+#define USB_FEAT_DEVICE_REMOTE_WAKEUP 1 // Recipient: Endpoint
+#define USB_FEAT_TEST_MODE 2 // Recipient: Device
+
+/* Information Returned by a GetStatus() Request to a Device - Figure 9-4 */
+#define USB_DEV_STATUS_SELF_POWERED 0x01
+#define USB_DEV_STATUS_REMOTE_WAKEUP 0x02
+///////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////
+/* USB Standard Device Descriptor - Table 9-8 */
+typedef struct
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bcdUSB;
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ uint8_t bMaxPacketSize0;
+ uint16_t idVendor;
+ uint16_t idProduct;
+ uint16_t bcdDevice;
+ uint8_t iManufacturer;
+ uint8_t iProduct;
+ uint8_t iSerialNumber;
+ uint8_t bNumConfigurations;
+} __attribute__((packed)) usb_device_descriptor;
+#define USB_DT_DEVICE_SIZE sizeof(usb_device_descriptor)
+///////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////
+/* USB Device_Qualifier Descriptor - Table 9-9
+ * Not used in this implementation.
+ */
+typedef struct
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t bcdUSB;
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+ uint8_t bMaxPacketSize0;
+ uint8_t bNumConfigurations;
+ uint8_t bReserved;
+} __attribute__((packed)) usb_device_qualifier_descriptor;
+///////////////////////////////////////////////////////////////
+
+/* This is only defined as a top level named struct to improve c++
+ * compatibility. You should never need to instance this struct
+ * in user code! */
+typedef struct
+{
+ uint8_t *cur_altsetting;
+ uint8_t num_altsetting;
+ const struct usb_iface_assoc_descriptor *iface_assoc;
+ const struct usb_interface_descriptor *altsetting;
+} __attribute__((packed)) usb_interface;
+
+///////////////////////////////////////////////////////////////
+/* USB Standard Configuration Descriptor - Table 9-10 */
+typedef struct
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t wTotalLength;
+ uint8_t bNumInterfaces;
+ uint8_t bConfigurationValue;
+ uint8_t iConfiguration;
+ uint8_t bmAttributes;
+ uint8_t bMaxPower;
+} __attribute__((packed)) usb_config_descriptor;
+#define USB_DT_CONFIGURATION_SIZE sizeof(usb_config_descriptor)
+///////////////////////////////////////////////////////////////
+
+/* USB Configuration Descriptor *bmAttributes* bit definitions */
+#define USB_CONFIG_ATTR_DEFAULT 0x80 /** always required (USB2.0 table 9-10) */
+#define USB_CONFIG_ATTR_SELF_POWERED 0x40
+#define USB_CONFIG_ATTR_REMOTE_WAKEUP 0x20
+
+/* Other Speed Configuration is the same as Configuration Descriptor.
+ * - Table 9-11
+ */
+
+///////////////////////////////////////////////////////////////
+/* USB Standard Interface Descriptor - Table 9-12 */
+typedef struct
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bInterfaceNumber;
+ uint8_t bAlternateSetting;
+ uint8_t bNumEndpoints;
+ uint8_t bInterfaceClass;
+ uint8_t bInterfaceSubClass;
+ uint8_t bInterfaceProtocol;
+ uint8_t iInterface;
+} __attribute__((packed)) usb_interface_descriptor;
+#define USB_DT_INTERFACE_SIZE sizeof(usb_interface_descriptor)
+///////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////
+/* USB Standard Endpoint Descriptor - Table 9-13 */
+typedef struct
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bEndpointAddress;
+ uint8_t bmAttributes;
+ uint16_t wMaxPacketSize;
+ uint8_t bInterval;
+} __attribute__((packed))usb_endpoint_descriptor;
+#define USB_DT_ENDPOINT_SIZE sizeof(usb_endpoint_descriptor)
+///////////////////////////////////////////////////////////////
+
+/* USB bEndpointAddress helper macros */
+#define USB_ENDPOINT_ADDR_OUT(x) (x)
+#define USB_ENDPOINT_ADDR_IN(x) (0x80 | (x))
+
+///////////////////////////////////////////////////////////////
+/* USB Endpoint Descriptor bmAttributes bit definitions - Table 9-13 */
+/* bits 1..0 : Transfer type */
+#define USB_ENDPOINT_ATTR_CONTROL 0x00
+#define USB_ENDPOINT_ATTR_ISOCHRONOUS 0x01
+#define USB_ENDPOINT_ATTR_BULK 0x02
+#define USB_ENDPOINT_ATTR_INTERRUPT 0x03
+#define USB_ENDPOINT_ATTR_TYPE 0x03
+// If not an isochronous endpoint, bits 5..2 are reserved
+// and must be set to zero.
+/* bits 3..2 : Sync type (only if ISOCHRONOUS) */
+#define USB_ENDPOINT_ATTR_NOSYNC 0x00
+#define USB_ENDPOINT_ATTR_ASYNC 0x04
+#define USB_ENDPOINT_ATTR_ADAPTIVE 0x08
+#define USB_ENDPOINT_ATTR_SYNC 0x0C
+#define USB_ENDPOINT_ATTR_SYNCTYPE 0x0C
+/* bits 5..4 : Usage type (only if ISOCHRONOUS) */
+#define USB_ENDPOINT_ATTR_DATA 0x00
+#define USB_ENDPOINT_ATTR_FEEDBACK 0x10
+#define USB_ENDPOINT_ATTR_IMPLICIT_FEEDBACK_DATA 0x20
+#define USB_ENDPOINT_ATTR_USAGETYPE 0x30
+///////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////
+/* Table 9-15 specifies String Descriptor Zero.
+ * Table 9-16 specified UNICODE String Descriptor.
+ */
+typedef struct
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint16_t wData[];
+} __attribute__((packed)) usb_string_descriptor;
+
+/* From ECN: Interface Association Descriptors, Table 9-Z */
+typedef struct
+{
+ uint8_t bLength;
+ uint8_t bDescriptorType;
+ uint8_t bFirstInterface;
+ uint8_t bInterfaceCount;
+ uint8_t bFunctionClass;
+ uint8_t bFunctionSubClass;
+ uint8_t bFunctionProtocol;
+ uint8_t iFunction;
+} __attribute__((packed)) usb_iface_assoc_descriptor;
+#define USB_DT_INTERFACE_ASSOCIATION_SIZE \
+ sizeof(usb_iface_assoc_descriptor)
+
+enum usb_language_id
+{
+ USB_LANGID_ENGLISH_US = 0x409,
+};
+///////////////////////////////////////////////////////////////
+
+#endif
diff --git a/components/USBIP/usbip_defs.h b/components/USBIP/usbip_defs.h
new file mode 100644
index 0000000..d36d16e
--- /dev/null
+++ b/components/USBIP/usbip_defs.h
@@ -0,0 +1,210 @@
+/**
+ * @file usbip_defs.h
+ * @brief Simple modification
+ * @version 0.1
+ * @date 2020-01-22
+ *
+ * @copyright Copyright (c) 2020
+ *
+ */
+
+// Focus on the following structures in this file:
+// usbip_stage2_header
+// usbip_stage1_response_devlist
+
+//
+// Created by thevoidnn on 10/25/17.
+//
+
+#ifndef __USBIP_DEFS_H__
+#define __USBIP_DEFS_H__
+
+#include
+#include "usb_defs.h"
+
+#define USBIP_SYSFS_PATH_SIZE 256
+#define USBIP_BUSID_SIZE 32
+
+enum usbip_stage1_command
+{
+ // Offset 2
+ USBIP_STAGE1_CMD_DEVICE_LIST = 0x05, // OP_REQ_DEVLIST
+ USBIP_STAGE1_CMD_DEVICE_ATTACH = 0x03, // OP_REQ_IMPORT
+};
+
+enum usbip_stager2_command
+{
+ //Offset 0
+ USBIP_STAGE2_REQ_SUBMIT = 0x0001,
+ USBIP_STAGE2_REQ_UNLINK = 0x0002,
+ USBIP_STAGE2_RSP_SUBMIT = 0x0003,
+ USBIP_STAGE2_RSP_UNLINK = 0x0004,
+};
+
+enum usbip_stage2_direction
+{
+ USBIP_DIR_OUT = 0x00,
+ USBIP_DIR_IN = 0x01,
+};
+
+typedef struct
+{
+ uint16_t version;
+ uint16_t command;
+ uint32_t status;
+} __attribute__((__packed__)) usbip_stage1_header;
+/////////////////////////////////////////////////////////////
+
+// Device description
+typedef struct
+{
+ char path[USBIP_SYSFS_PATH_SIZE];
+ char busid[USBIP_BUSID_SIZE];
+
+ uint32_t busnum;
+ uint32_t devnum;
+ uint32_t speed;
+
+ uint16_t idVendor;
+ uint16_t idProduct;
+ uint16_t bcdDevice;
+
+ uint8_t bDeviceClass;
+ uint8_t bDeviceSubClass;
+ uint8_t bDeviceProtocol;
+
+ uint8_t bConfigurationValue;
+ uint8_t bNumConfigurations;
+ uint8_t bNumInterfaces;
+} __attribute__((packed)) usbip_stage1_usb_device;
+
+// Interface description
+typedef struct
+{
+ uint8_t bInterfaceClass;
+ uint8_t bInterfaceSubClass;
+ uint8_t bInterfaceProtocol;
+ uint8_t padding;
+} __attribute__((packed)) usbip_stage1_usb_interface;
+
+typedef struct
+{
+ usbip_stage1_usb_device udev;
+ usbip_stage1_usb_interface uinf[];
+} __attribute__((packed)) usbip_stage1_response_devlist_entry;
+
+typedef struct
+{
+ uint32_t list_size;
+ usbip_stage1_response_devlist_entry devices[];
+} __attribute__((__packed__)) usbip_stage1_response_devlist;
+
+///////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////
+
+/**
+ * struct usbip_header_basic - data pertinent to every URB request
+ * RESPONSE & REQUEST
+ *
+ * @command: the usbip request type
+ * @seqnum: sequential number that identifies requests; incremented per
+ * connection
+ * @devid: specifies a remote USB device uniquely instead of busnum and devnum;
+ * in the stub driver, this value is ((busnum << 16) | devnum)
+ * @direction: direction of the transfer
+ * @ep: endpoint number
+ */
+typedef struct
+{
+ uint32_t command;
+ uint32_t seqnum;
+ uint32_t devid;
+ uint32_t direction;
+ uint32_t ep;
+} __attribute__((packed)) usbip_stage2_header_basic;
+
+/**
+ * struct usbip_header_cmd_submit - USBIP_CMD_SUBMIT packet header
+ * >>>REQUEST
+ *
+ * @transfer_flags: URB flags
+ * @transfer_buffer_length: the data size for (in) or (out) transfer
+ * @start_frame: initial frame for isochronous or interrupt transfers
+ * @number_of_packets: number of isochronous packets
+ * @interval: maximum time for the request on the server-side host controller
+ * @setup: setup data for a control request
+ */
+typedef struct
+{
+ uint32_t transfer_flags;
+ int32_t data_length;
+
+ /* it is difficult for usbip to sync frames (reserved only?) */
+ int32_t start_frame;
+ int32_t number_of_packets;
+ int32_t interval;
+
+ union {
+ uint8_t setup[8];
+ usb_standard_request request;
+ };
+} __attribute__((packed)) usbip_stage2_header_cmd_submit;
+
+/**
+ * struct usbip_header_ret_submit - USBIP_RET_SUBMIT packet header
+ * <<>>REQUEST
+ * @seqnum: the URB seqnum to unlink
+ */
+typedef struct
+{
+ uint32_t seqnum;
+} __attribute__((packed)) usbip_stage2_header_cmd_unlink;
+
+/**
+ * struct usbip_header_ret_unlink - USBIP_RET_UNLINK packet header
+ * <<
+#include
+#include "usbip_server.h"
+#include "DAP_handle.h"
+#include "DAP.h"
+#include "esp_libc.h"
+#include "USBd_config.h"
+
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/ringbuf.h"
+#include "freertos/semphr.h"
+
+#include "lwip/err.h"
+#include "lwip/sockets.h"
+#include "lwip/sys.h"
+#include
+
+extern int kSock;
+extern TaskHandle_t kDAPTaskHandle;
+////TODO: Merge this
+#define DAP_PACKET_SIZE 255
+
+static uint8_t data_out[DAP_PACKET_SIZE];
+static int dap_respond = 0;
+
+// SWO Trace
+static int swo_trace_respond = 0;
+static uint8_t *swo_data_to_send;
+static uint32_t num_swo_data;
+
+static RingbufHandle_t dap_dataIN_handle = NULL;
+static RingbufHandle_t dap_dataOUT_handle = NULL;
+static SemaphoreHandle_t data_response_mux = NULL;
+
+static void unpack(void *data, int size);
+
+void handle_dap_data_request(usbip_stage2_header *header, uint32_t length)
+{
+ uint8_t *data_in = (uint8_t *)header;
+ data_in = &(data_in[sizeof(usbip_stage2_header)]);
+ // Point to the beginning of the URB packet
+
+#if (USE_WINUSB == 1)
+ dap_respond = DAP_ProcessCommand((uint8_t *)data_in, (uint8_t *)data_out);
+ //handle_dap_data_response(header);
+ send_stage2_submit(header, 0, 0);
+#else
+ xRingbufferSend(dap_dataIN_handle, data_in, length - sizeof(usbip_stage2_header), portMAX_DELAY);
+ //os_printf("LENGTH: %d\r\n", length - sizeof(usbip_stage2_header));
+ xTaskNotifyGive(kDAPTaskHandle);
+ send_stage2_submit(header, 0, 0);
+
+#endif
+}
+
+void handle_dap_data_response(usbip_stage2_header *header)
+{
+ if (dap_respond)
+ {
+ send_stage2_submit_data(header, 0, data_out, DAP_PACKET_SIZE);
+ dap_respond = 0;
+ }
+ else
+ {
+ send_stage2_submit(header, 0, 0);
+ }
+}
+
+void handle_swo_trace_response(usbip_stage2_header *header)
+{
+ if (swo_trace_respond)
+ {
+ swo_trace_respond = 0;
+ send_stage2_submit_data(header, 0, data_out, DAP_PACKET_SIZE);
+ }
+ else
+ {
+ send_stage2_submit(header, 0, 0);
+ }
+}
+
+// SWO Data Queue Transfer
+// buf: pointer to buffer with data
+// num: number of bytes to transfer
+void SWO_QueueTransfer(uint8_t *buf, uint32_t num)
+{
+ swo_data_to_send = buf;
+ num_swo_data = num;
+ swo_trace_respond = 1;
+}
+
+// SWO Data Abort Transfer
+void SWO_AbortTransfer(void)
+{
+ //USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U));
+ ////TODO: unlink might be useful ...
+}
+
+void DAP_Thread(void *argument)
+{
+ dap_dataIN_handle = xRingbufferCreate(DAP_PACKET_SIZE * 20, RINGBUF_TYPE_BYTEBUF);
+ dap_dataOUT_handle = xRingbufferCreate(DAP_PACKET_SIZE * 10, RINGBUF_TYPE_BYTEBUF);
+ data_response_mux = xSemaphoreCreateMutex();
+ size_t packetSize;
+ uint8_t *item;
+
+ if (dap_dataIN_handle == NULL || dap_dataIN_handle == NULL ||
+ data_response_mux == NULL)
+ {
+ os_printf("Can not create DAP ringbuf/mux!\r\n");
+ vTaskDelete(NULL);
+ }
+ for (;;)
+ {
+
+ while (1)
+ {
+ ulTaskNotifyTake(pdFALSE, portMAX_DELAY);
+ packetSize = 0;
+ item = (uint8_t *)xRingbufferReceiveUpTo(dap_dataIN_handle, &packetSize,
+ (1 / portTICK_RATE_MS), DAP_PACKET_SIZE);
+ if (packetSize == 0)
+ {
+ break;
+ }
+
+ else if (packetSize < DAP_PACKET_SIZE)
+ {
+ os_printf("Wrong data in packet size:%d , data in remain: %d\r\n", packetSize, (int)xRingbufferGetMaxItemSize(dap_dataIN_handle));
+ vRingbufferReturnItem(dap_dataIN_handle, (void *)item);
+ break;
+ // This may not happen because there is a semaphore acquisition
+ }
+
+ if (item[0] == ID_DAP_QueueCommands)
+ item[0] = ID_DAP_ExecuteCommands;
+ DAP_ProcessCommand(item, data_out);
+
+ vRingbufferReturnItem(dap_dataIN_handle, (void *)item);
+ xRingbufferSend(dap_dataOUT_handle, data_out, DAP_PACKET_SIZE, portMAX_DELAY);
+ if (xSemaphoreTake(data_response_mux, portMAX_DELAY) == pdTRUE)
+ {
+ ++dap_respond;
+ xSemaphoreGive(data_response_mux);
+ }
+ }
+ }
+}
+
+int fast_reply(uint8_t *buf, uint32_t length)
+{
+ if (length == 48 && buf[3] == 1 && buf[15] == 1 && buf[19] == 1)
+ {
+ if (dap_respond > 0)
+ {
+ uint8_t *item;
+ size_t packetSize = 0;
+ item = (uint8_t *)xRingbufferReceiveUpTo(dap_dataOUT_handle, &packetSize,
+ (10 / portTICK_RATE_MS), DAP_PACKET_SIZE);
+ if (packetSize == DAP_PACKET_SIZE)
+ {
+ unpack((uint32_t *)buf, sizeof(usbip_stage2_header));
+ send_stage2_submit_data((usbip_stage2_header *)buf, 0, item, DAP_PACKET_SIZE);
+ if (xSemaphoreTake(data_response_mux, portMAX_DELAY) == pdTRUE)
+ {
+ --dap_respond;
+ xSemaphoreGive(data_response_mux);
+ }
+ vRingbufferReturnItem(dap_dataOUT_handle, (void *)item);
+ return 1;
+ }
+ else if (packetSize > 0)
+ {
+ os_printf("Wrong data out packet size:%d!\r\n", packetSize);
+ }
+ ////TODO: fast reply
+ }
+ else
+ {
+ buf[3] = 0x3; // command
+ buf[15] = 0; // direction
+ buf[0x16] = 0;
+ buf[0x17] = 0;
+ buf[27] = 0;
+ buf[39] = 0;
+ send(kSock, buf, 48, 0);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static void unpack(void *data, int size)
+{
+
+ // Ignore the setup field
+ int sz = (size / sizeof(uint32_t)) - 2;
+ uint32_t *ptr = (uint32_t *)data;
+
+ for (int i = 0; i < sz; i++)
+ {
+ ptr[i] = ntohl(ptr[i]);
+ }
+}
\ No newline at end of file
diff --git a/main/DAP_handle.h b/main/DAP_handle.h
new file mode 100644
index 0000000..2d71be2
--- /dev/null
+++ b/main/DAP_handle.h
@@ -0,0 +1,12 @@
+#ifndef __DAP_HANDLE_H__
+#define __DAP_HANDLE_H__
+
+#include "usbip_defs.h"
+
+void handle_dap_data_request(usbip_stage2_header *header, uint32_t length);
+void handle_dap_data_response(usbip_stage2_header *header);
+void handle_swo_trace_response(usbip_stage2_header *header);
+
+int fast_reply(uint8_t *buf, uint32_t length);
+
+#endif
\ No newline at end of file
diff --git a/main/Kconfig.projbuild b/main/Kconfig.projbuild
deleted file mode 100644
index c1209ac..0000000
--- a/main/Kconfig.projbuild
+++ /dev/null
@@ -1,37 +0,0 @@
-menu "Example Configuration"
-
-config WIFI_SSID
- string "WiFi SSID"
- default "myssid"
- help
- SSID (network name) for the example to connect to.
-
-config WIFI_PASSWORD
- string "WiFi Password"
- default "mypassword"
- help
- WiFi password (WPA or WPA2) for the example to use.
- Can be left blank if the network has no security set.
-
-choice EXAMPLE_IP_MODE
- prompt "IP Version"
- help
- Example can use either IPV4 or IPV6.
-
-config EXAMPLE_IPV4
- bool "IPV4"
-
-config EXAMPLE_IPV6
- bool "IPV6"
- select LWIP_IPV6
-
-endchoice
-
-config EXAMPLE_PORT
- int "Port"
- range 0 65535
- default 3333
- help
- Local port the example server will listen on.
-
-endmenu
diff --git a/main/component.mk b/main/component.mk
deleted file mode 100644
index a98f634..0000000
--- a/main/component.mk
+++ /dev/null
@@ -1,4 +0,0 @@
-#
-# "main" pseudo-component makefile.
-#
-# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
diff --git a/main/main.c b/main/main.c
new file mode 100644
index 0000000..bc92117
--- /dev/null
+++ b/main/main.c
@@ -0,0 +1,148 @@
+/* BSD Socket API Example
+
+ This example code is in the Public Domain (or CC0 licensed, at your option.)
+
+ Unless required by applicable law or agreed to in writing, this
+ software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+ CONDITIONS OF ANY KIND, either express or implied.
+*/
+#include
+#include
+#include
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/event_groups.h"
+#include "esp_system.h"
+#include "esp_wifi.h"
+#include "esp_event_loop.h"
+#include "esp_log.h"
+#include "nvs_flash.h"
+
+#include "lwip/err.h"
+#include "lwip/sockets.h"
+#include "lwip/sys.h"
+#include
+
+#include "tcp_server.h"
+#include "timer.h"
+#include "wifi_configuration.h"
+
+
+
+extern void SWO_Thread(void *argument);
+extern void usart_monitor_task(void *argument);
+extern void DAP_Setup(void);
+extern void DAP_Thread(void *argument);
+
+/* FreeRTOS event group to signal when we are connected & ready to make a request */
+static EventGroupHandle_t wifi_event_group;
+TaskHandle_t kDAPTaskHandle = NULL;
+
+const int IPV4_GOTIP_BIT = BIT0;
+#ifdef CONFIG_EXAMPLE_IPV6
+const int IPV6_GOTIP_BIT = BIT1;
+#endif
+
+
+static esp_err_t event_handler(void *ctx, system_event_t *event)
+{
+ /* For accessing reason codes in case of disconnection */
+ system_event_info_t *info = &event->event_info;
+
+ switch (event->event_id)
+ {
+ case SYSTEM_EVENT_STA_START:
+ esp_wifi_connect();
+ os_printf("SYSTEM_EVENT_STA_START\r\n");
+ break;
+ case SYSTEM_EVENT_STA_CONNECTED:
+#ifdef CONFIG_EXAMPLE_IPV6
+ /* enable ipv6 */
+ tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA);
+#endif
+ break;
+ case SYSTEM_EVENT_STA_GOT_IP:
+ xEventGroupSetBits(wifi_event_group, IPV4_GOTIP_BIT);
+ os_printf("SYSTEM_EVENT_STA_GOT_IP\r\n");
+ break;
+ case SYSTEM_EVENT_STA_DISCONNECTED:
+ os_printf("Disconnect reason : %d\r\n", info->disconnected.reason);
+ if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT)
+ {
+ /*Switch to 802.11 bgn mode */
+ esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
+ }
+ esp_wifi_connect();
+ xEventGroupClearBits(wifi_event_group, IPV4_GOTIP_BIT);
+#ifdef CONFIG_EXAMPLE_IPV6
+ xEventGroupClearBits(wifi_event_group, IPV6_GOTIP_BIT);
+#endif
+ break;
+ case SYSTEM_EVENT_AP_STA_GOT_IP6:
+#ifdef CONFIG_EXAMPLE_IPV6
+ xEventGroupSetBits(wifi_event_group, IPV6_GOTIP_BIT);
+ os_printf("SYSTEM_EVENT_STA_GOT_IP6\r\n");
+
+ char *ip6 = ip6addr_ntoa(&event->event_info.got_ip6.ip6_info.ip);
+ os_printf("IPv6: %s\r\n", ip6);
+#endif
+ default:
+ break;
+ }
+ return ESP_OK;
+}
+
+static void initialise_wifi(void)
+{
+ tcpip_adapter_init();
+ wifi_event_group = xEventGroupCreate();
+
+ ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
+ wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
+ ESP_ERROR_CHECK(esp_wifi_init(&cfg));
+ ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
+ wifi_config_t wifi_config = {
+ .sta = {
+ .ssid = WIFI_SSID,
+ .password = WIFI_PASS,
+ },
+ };
+ os_printf("Setting WiFi configuration SSID %s...\r\n", wifi_config.sta.ssid);
+ 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()
+{
+#ifdef CONFIG_EXAMPLE_IPV6
+ uint32_t bits = IPV4_GOTIP_BIT | IPV6_GOTIP_BIT;
+#else
+ uint32_t bits = IPV4_GOTIP_BIT;
+#endif
+
+ os_printf("Waiting for AP connection...\r\n");
+ xEventGroupWaitBits(wifi_event_group, bits, false, true, portMAX_DELAY);
+ os_printf("Connected to AP\r\n");
+}
+
+
+
+
+
+void app_main()
+{
+ ESP_ERROR_CHECK(nvs_flash_init());
+ initialise_wifi();
+ wait_for_ip();
+ DAP_Setup(); // DAP Setup
+
+ xTaskCreate(timer_create_task, "timer_create", 512, NULL, 10, NULL);
+ xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 20, NULL);
+ xTaskCreate(DAP_Thread, "DAP_Task", 2048, NULL, 22, &kDAPTaskHandle);
+ // SWO Trace Task
+ //xTaskCreate(SWO_Thread, "swo_task", 1024, NULL, 6, NULL);
+ //xTaskCreate(usart_monitor_task, "uart_task", 512, NULL, 6, NULL);
+
+}
diff --git a/main/tcp_server.c b/main/tcp_server.c
index 1930626..99e9fe8 100644
--- a/main/tcp_server.c
+++ b/main/tcp_server.c
@@ -1,12 +1,16 @@
-/* BSD Socket API Example
+/**
+ * @file tcp_server.c
+ * @brief Handle main tcp tasks
+ * @version 0.1
+ * @date 2020-01-22
+ *
+ * @copyright Copyright (c) 2020
+ *
+ */
+#include "tcp_server.h"
- This example code is in the Public Domain (or CC0 licensed, at your option.)
-
- Unless required by applicable law or agreed to in writing, this
- software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- CONDITIONS OF ANY KIND, either express or implied.
-*/
#include
+#include
#include
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
@@ -22,110 +26,15 @@
#include "lwip/sys.h"
#include
-/* 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
- the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
-*/
-#define EXAMPLE_WIFI_SSID "DAP"
-#define EXAMPLE_WIFI_PASS "12345678"
+#include "wifi_configuration.h"
+#include "usbip_server.h"
-#define PORT 22350
+uint8_t kState = ACCEPTING;
+int kSock = -1;
-/* FreeRTOS event group to signal when we are connected & ready to make a request */
-static EventGroupHandle_t wifi_event_group;
-
-const int IPV4_GOTIP_BIT = BIT0;
-#ifdef CONFIG_EXAMPLE_IPV6
-const int IPV6_GOTIP_BIT = BIT1;
-#endif
-
-static const char *TAG = "example";
-
-static esp_err_t event_handler(void *ctx, system_event_t *event)
+void tcp_server_task(void *pvParameters)
{
- /* For accessing reason codes in case of disconnection */
- system_event_info_t *info = &event->event_info;
-
- switch (event->event_id)
- {
- case SYSTEM_EVENT_STA_START:
- esp_wifi_connect();
- os_printf("SYSTEM_EVENT_STA_START\r\n");
- break;
- case SYSTEM_EVENT_STA_CONNECTED:
-#ifdef CONFIG_EXAMPLE_IPV6
- /* enable ipv6 */
- tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA);
-#endif
- break;
- case SYSTEM_EVENT_STA_GOT_IP:
- xEventGroupSetBits(wifi_event_group, IPV4_GOTIP_BIT);
- os_printf("SYSTEM_EVENT_STA_GOT_IP\r\n");
- break;
- case SYSTEM_EVENT_STA_DISCONNECTED:
- os_printf("Disconnect reason : %d\r\n", info->disconnected.reason);
- if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT)
- {
- /*Switch to 802.11 bgn mode */
- esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCAL_11B | WIFI_PROTOCAL_11G | WIFI_PROTOCAL_11N);
- }
- esp_wifi_connect();
- xEventGroupClearBits(wifi_event_group, IPV4_GOTIP_BIT);
-#ifdef CONFIG_EXAMPLE_IPV6
- xEventGroupClearBits(wifi_event_group, IPV6_GOTIP_BIT);
-#endif
- break;
- case SYSTEM_EVENT_AP_STA_GOT_IP6:
-#ifdef CONFIG_EXAMPLE_IPV6
- xEventGroupSetBits(wifi_event_group, IPV6_GOTIP_BIT);
- os_printf("SYSTEM_EVENT_STA_GOT_IP6\r\n");
-
- char *ip6 = ip6addr_ntoa(&event->event_info.got_ip6.ip6_info.ip);
- os_printf("IPv6: %s\r\n", ip6);
-#endif
- default:
- break;
- }
- return ESP_OK;
-}
-
-static void initialise_wifi(void)
-{
- tcpip_adapter_init();
- wifi_event_group = xEventGroupCreate();
- ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));
- wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
- ESP_ERROR_CHECK(esp_wifi_init(&cfg));
- ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
- wifi_config_t wifi_config = {
- .sta = {
- .ssid = EXAMPLE_WIFI_SSID,
- .password = EXAMPLE_WIFI_PASS,
- },
- };
- os_printf("Setting WiFi configuration SSID %s...\r\n", wifi_config.sta.ssid);
- 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()
-{
-#ifdef CONFIG_EXAMPLE_IPV6
- uint32_t bits = IPV4_GOTIP_BIT | IPV6_GOTIP_BIT;
-#else
- uint32_t bits = IPV4_GOTIP_BIT;
-#endif
-
- os_printf("Waiting for AP connection...\r\n");
- xEventGroupWaitBits(wifi_event_group, bits, false, true, portMAX_DELAY);
- os_printf("Connected to AP");
-}
-
-static void tcp_server_task(void *pvParameters)
-{
- char rx_buffer[2048];
+ uint8_t tcp_rx_buffer[305];
char addr_str[128];
int addr_family;
int ip_protocol;
@@ -157,7 +66,7 @@ static void tcp_server_task(void *pvParameters)
os_printf("Unable to create socket: errno %d\r\n", errno);
break;
}
- os_printf("Socket created");
+ os_printf("Socket created\r\n");
int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr));
if (err != 0)
@@ -165,7 +74,7 @@ static void tcp_server_task(void *pvParameters)
os_printf("Socket unable to bind: errno %d\r\n", errno);
break;
}
- os_printf("Socket binded");
+ os_printf("Socket binded\r\n");
err = listen(listen_sock, 1);
if (err != 0)
@@ -173,86 +82,87 @@ static void tcp_server_task(void *pvParameters)
os_printf("Error occured during listen: errno %d\r\n", errno);
break;
}
- os_printf("Socket listening");
+ os_printf("Socket listening\r\n");
#ifdef CONFIG_EXAMPLE_IPV6
struct sockaddr_in6 sourceAddr; // Large enough for both IPv4 or IPv6
#else
struct sockaddr_in sourceAddr;
#endif
- uint addrLen = sizeof(sourceAddr);
- int sock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen);
- if (sock < 0)
- {
- os_printf("Unable to accept connection: errno %d\r\n", errno);
- break;
- }
- os_printf("Socket accepted");
-
+ uint32_t addrLen = sizeof(sourceAddr);
while (1)
{
- int len = recv(sock, rx_buffer, 2047, 0);
- // Error occured during receiving
- if (len < 0)
+ kSock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen);
+ if (kSock < 0)
{
- os_printf("recv failed: errno %d\r\n", errno);
+ os_printf("Unable to accept connection: errno %d\r\n", errno);
break;
}
- // Connection closed
- else if (len == 0)
- {
- os_printf("Connection closed\r\n");
- break;
- }
- // Data received
- else
- {
-#ifdef CONFIG_EXAMPLE_IPV6
- // Get the sender's ip address as string
- if (sourceAddr.sin6_family == PF_INET)
- {
- inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
- }
- else if (sourceAddr.sin6_family == PF_INET6)
- {
- inet6_ntoa_r(sourceAddr.sin6_addr, addr_str, sizeof(addr_str) - 1);
- }
-#else
- inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
-#endif
+ os_printf("Socket accepted\r\n");
- rx_buffer[len] = 0; // Null-terminate whatever we received and treat like a string
- //os_printf("Received %d bytes from %s:\r\n", len, addr_str);
- // os_printf("%s", rx_buffer);
-
- int err = send(sock, rx_buffer, len, 0);
- if (err < 0)
+ while (1)
+ {
+ int len = recv(kSock, tcp_rx_buffer, sizeof(tcp_rx_buffer), 0);
+ // Error occured during receiving
+ if (len < 0)
{
- os_printf("Error occured during sending: errno %d\r\n", errno);
+ os_printf("recv failed: errno %d\r\n", errno);
break;
}
+ // Connection closed
+ else if (len == 0)
+ {
+ os_printf("Connection closed\r\n");
+ break;
+ }
+ // Data received
+ else
+ {
+ // #ifdef CONFIG_EXAMPLE_IPV6
+ // // Get the sender's ip address as string
+ // if (sourceAddr.sin6_family == PF_INET)
+ // {
+ // inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
+ // }
+ // else if (sourceAddr.sin6_family == PF_INET6)
+ // {
+ // inet6_ntoa_r(sourceAddr.sin6_addr, addr_str, sizeof(addr_str) - 1);
+ // }
+ // #else
+ // inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1);
+ // #endif
+
+ switch (kState)
+ {
+ case ACCEPTING:
+ kState = ATTACHING;
+
+ case ATTACHING:
+ attach(tcp_rx_buffer, len);
+ break;
+
+ case EMULATING:
+ emulate(tcp_rx_buffer, len);
+ break;
+ default:
+ os_printf("unkonw kstate!\r\n");
+ }
+ }
}
- }
+ // kState = ACCEPTING;
+ if (kSock != -1)
+ {
+ os_printf("Shutting down socket and restarting...\r\n");
+ //shutdown(kSock, 0);
+ close(kSock);
+ if (kState == EMULATING)
+ kState = ACCEPTING;
- if (sock != -1)
- {
- os_printf("Shutting down socket and restarting...\r\n");
- shutdown(sock, 0);
- close(sock);
-
- shutdown(listen_sock, 0);
- close(listen_sock);
- vTaskDelay(5);
+ //shutdown(listen_sock, 0);
+ //close(listen_sock);
+ //vTaskDelay(5);
+ }
}
}
vTaskDelete(NULL);
-}
-
-void app_main()
-{
- ESP_ERROR_CHECK(nvs_flash_init());
- initialise_wifi();
- wait_for_ip();
-
- xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 5, NULL);
-}
+}
\ No newline at end of file
diff --git a/main/tcp_server.h b/main/tcp_server.h
new file mode 100644
index 0000000..877ab2a
--- /dev/null
+++ b/main/tcp_server.h
@@ -0,0 +1,6 @@
+#ifndef __TCP_SERVER_H__
+#define __TCP_SERVER_H__
+
+void tcp_server_task(void *pvParameters);
+
+#endif
\ No newline at end of file
diff --git a/main/timer.c b/main/timer.c
new file mode 100644
index 0000000..6fbe6b7
--- /dev/null
+++ b/main/timer.c
@@ -0,0 +1,29 @@
+/**
+ * @file timer.c
+ * @brief Hardware timer for DAP timestamp
+ * @version 0.1
+ * @date 2020-01-22
+ *
+ * @copyright Copyright (c) 2020
+ *
+ */
+#include
+#include
+#include "timer.h"
+#include "hw_timer.h"
+#include "timer_struct.h"
+#include "freertos/FreeRTOS.h"
+#include "freertos/task.h"
+#include "freertos/event_groups.h"
+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 = 0x7FFFFF; // 23bit??
+ frc1.ctrl.en = 0x01;
+ vPortExitCritical();
+ vTaskDelete(NULL);
+}
\ No newline at end of file
diff --git a/main/timer.h b/main/timer.h
new file mode 100644
index 0000000..bc569a9
--- /dev/null
+++ b/main/timer.h
@@ -0,0 +1,6 @@
+#ifndef __TIMER_H__
+#define __TIMER_H__
+
+void timer_create_task();
+
+#endif
\ No newline at end of file
diff --git a/main/usbip_server.c b/main/usbip_server.c
new file mode 100644
index 0000000..1eb2b75
--- /dev/null
+++ b/main/usbip_server.c
@@ -0,0 +1,376 @@
+#include
+#include
+#include "lwip/err.h"
+#include "lwip/sockets.h"
+#include "lwip/sys.h"
+#include
+
+#include "usbip_server.h"
+#include "usbip_defs.h"
+#include "usb_defs.h"
+#include "USBd_config.h"
+#include "DAP_handle.h"
+#include "USB_handle.h"
+#include "USBd_config.h"
+
+// attach helper function
+static int read_stage1_command(uint8_t *buffer, uint32_t length);
+static void handle_device_list(uint8_t *buffer, uint32_t length);
+static void handle_device_attach(uint8_t *buffer, uint32_t length);
+static void send_stage1_header(uint16_t command, uint32_t status);
+static void send_device_list();
+static void send_device_info();
+static void send_interface_info();
+
+// emulate helper function
+static void pack(void *data, int size);
+static void unpack(void *data, int size);
+static int handle_submit(usbip_stage2_header *header, uint32_t length);
+static int read_stage2_command(usbip_stage2_header *header, uint32_t length);
+
+static void handle_unlink(usbip_stage2_header *header);
+// unlink helper function
+static void send_stage2_unlink(usbip_stage2_header *req_header);
+
+
+
+int attach(uint8_t *buffer, uint32_t length)
+{
+ int command = read_stage1_command(buffer, length);
+ if (command < 0)
+ {
+ return -1;
+ }
+
+ switch (command)
+ {
+ case USBIP_STAGE1_CMD_DEVICE_LIST: // OP_REQ_DEVLIST
+ handle_device_list(buffer, length);
+ break;
+
+ case USBIP_STAGE1_CMD_DEVICE_ATTACH: // OP_REQ_IMPORT
+ handle_device_attach(buffer, length);
+ break;
+
+ default:
+ os_printf("attach Unknown command: %d\r\n", command);
+ break;
+ }
+ return 0;
+}
+
+static int read_stage1_command(uint8_t *buffer, uint32_t length)
+{
+ if (length < sizeof(usbip_stage1_header))
+ {
+ return -1;
+ }
+ usbip_stage1_header *req = (usbip_stage1_header *)buffer;
+ return (ntohs(req->command) & 0xFF); // 0x80xx low bit
+}
+
+static void handle_device_list(uint8_t *buffer, uint32_t length)
+{
+ os_printf("Handling dev list request...\r\n");
+ send_stage1_header(USBIP_STAGE1_CMD_DEVICE_LIST, 0);
+ send_device_list();
+}
+
+static void handle_device_attach(uint8_t *buffer, uint32_t length)
+{
+ os_printf("Handling dev attach request...\r\n");
+
+ //char bus[USBIP_BUSID_SIZE];
+ if (length < sizeof(USBIP_BUSID_SIZE))
+ {
+ os_printf("handle device attach failed!\r\n");
+ return;
+ }
+ //client.readBytes((uint8_t *)bus, USBIP_BUSID_SIZE);
+
+ send_stage1_header(USBIP_STAGE1_CMD_DEVICE_ATTACH, 0);
+
+ send_device_info();
+
+ kState = EMULATING;
+}
+
+static void send_stage1_header(uint16_t command, uint32_t status)
+{
+ os_printf("Sending header...\r\n");
+ usbip_stage1_header header;
+ header.version = htons(273); ////TODO: 273???
+ // may be : https://github.com/Oxalin/usbip_windows/issues/4
+
+ header.command = htons(command);
+ header.status = htonl(status);
+
+ send(kSock, (uint8_t *)&header, sizeof(usbip_stage1_header), 0);
+}
+
+static void send_device_list()
+{
+ os_printf("Sending device list...\r\n");
+
+ // send device list size:
+ os_printf("Sending device list size...\r\n");
+ usbip_stage1_response_devlist response_devlist;
+
+ // we have only 1 device, so:
+ response_devlist.list_size = htonl(1);
+
+ send(kSock, (uint8_t *)&response_devlist, sizeof(usbip_stage1_response_devlist), 0);
+
+ // may be foreach:
+
+ {
+ // send device info:
+ send_device_info();
+ // send device interfaces: // (1)
+ send_interface_info();
+ }
+}
+
+static void send_device_info()
+{
+ os_printf("Sending device info...\r\n");
+ usbip_stage1_usb_device device;
+
+ strcpy(device.path, "/sys/devices/pci0000:00/0000:00:01.2/usb1/1-1");
+ strcpy(device.busid, "1-1");
+
+ device.busnum = htonl(1);
+ device.devnum = htonl(1);
+ device.speed = htonl(3); // See usb_device_speed enum
+
+ device.idVendor = htons(USBD0_DEV_DESC_IDVENDOR);
+ device.idProduct = htons(USBD0_DEV_DESC_IDPRODUCT);
+ device.bcdDevice = htons(USBD0_DEV_DESC_BCDDEVICE);
+
+ device.bDeviceClass = 0x00; // We need to use a device other than the USB-IF standard, set to 0x00
+ device.bDeviceSubClass = 0x00;
+ device.bDeviceProtocol = 0x00;
+
+ device.bConfigurationValue = 1;
+ device.bNumConfigurations = 1;
+ device.bNumInterfaces = 1;
+
+ send(kSock, (uint8_t *)&device, sizeof(usbip_stage1_usb_device), 0);
+}
+
+static void send_interface_info()
+{
+ os_printf("Sending interface info...\r\n");
+ usbip_stage1_usb_interface interface;
+ interface.bInterfaceClass = USBD_CUSTOM_CLASS0_IF0_CLASS;
+ interface.bInterfaceSubClass = USBD_CUSTOM_CLASS0_IF0_SUBCLASS;
+ interface.bInterfaceProtocol = USBD_CUSTOM_CLASS0_IF0_PROTOCOL;
+ interface.padding = 0; // shall be set to zero
+
+ send(kSock, (uint8_t *)&interface, sizeof(usbip_stage1_usb_interface), 0);
+}
+
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////
+
+int emulate(uint8_t *buffer, uint32_t length)
+{
+ // usbip_stage2_header header;
+ #if (USE_WINUSB == 0)
+ if(fast_reply(buffer, length))
+ {
+ return 0;
+ }
+ #endif
+ int command = read_stage2_command((usbip_stage2_header *)buffer, length);
+ if (command < 0)
+ {
+ return -1;
+ }
+
+ switch (command)
+ {
+ case USBIP_STAGE2_REQ_SUBMIT:
+ handle_submit((usbip_stage2_header *)buffer , length);
+ break;
+
+ case USBIP_STAGE2_REQ_UNLINK:
+ handle_unlink((usbip_stage2_header *)buffer);
+ break;
+
+ default:
+ os_printf("emulate unknown command:%d\r\n", command);
+ //handle_submit((usbip_stage2_header *)buffer, length);
+ return -1;
+ }
+ return 0;
+}
+
+static int read_stage2_command(usbip_stage2_header *header, uint32_t length)
+{
+ if (length < sizeof(usbip_stage2_header))
+ {
+ return -1;
+ }
+
+ //client.readBytes((uint8_t *)&header, sizeof(usbip_stage2_header));
+ unpack((uint32_t *)header, sizeof(usbip_stage2_header));
+ return header->base.command;
+}
+
+/**
+ * @brief Pack the following packets(Offset 0x00 - 0x28):
+ * - cmd_submit
+ * - ret_submit
+ * - cmd_unlink
+ * - ret_unlink
+ *
+ * @param data Point to packets header
+ * @param size Packets header size
+ */
+static void pack(void *data, int size)
+{
+
+ // Ignore the setup field
+ int sz = (size / sizeof(uint32_t)) - 2;
+ uint32_t *ptr = (uint32_t *)data;
+
+ for (int i = 0; i < sz; i++)
+ {
+
+ ptr[i] = htonl(ptr[i]);
+ }
+}
+
+/**
+ * @brief Unack the following packets(Offset 0x00 - 0x28):
+ * - cmd_submit
+ * - ret_submit
+ * - cmd_unlink
+ * - ret_unlink
+ *
+ * @param data Point to packets header
+ * @param size packets header size
+ */
+static void unpack(void *data, int size)
+{
+
+ // Ignore the setup field
+ int sz = (size / sizeof(uint32_t)) - 2;
+ uint32_t *ptr = (uint32_t *)data;
+
+ for (int i = 0; i < sz; i++)
+ {
+ ptr[i] = ntohl(ptr[i]);
+ }
+}
+
+/**
+ * @brief USB transaction processing
+ *
+ */
+static int handle_submit(usbip_stage2_header *header, uint32_t length)
+{
+ switch (header->base.ep)
+ {
+ // control endpoint(endpoint 0)
+ case 0x00:
+ handleUSBControlRequest(header);
+ break;
+
+ // endpoint 1 data receicve and response
+ case 0x01:
+ if (header->base.direction == 0)
+ {
+ //os_printf("EP 01 DATA FROM HOST");
+ handle_dap_data_request(header ,length);
+ }
+ else
+ {
+ // os_printf("EP 01 DATA TO HOST\r\n");
+ handle_dap_data_response(header);
+ }
+ break;
+ // endpoint 2 for SWO trace
+ case 0x02:
+ if (header->base.direction == 0)
+ {
+ // os_printf("EP 02 DATA FROM HOST");
+ send_stage2_submit(header, 0, 0);
+ }
+ else
+ {
+ // os_printf("EP 02 DATA TO HOST");
+ handle_swo_trace_response(header);
+ }
+ break;
+ // request to save data to device
+ case 0x81:
+ if (header->base.direction == 0)
+ {
+ os_printf("*** WARN! EP 81 DATA TX");
+ }
+ else
+ {
+ os_printf("*** WARN! EP 81 DATA RX");
+ }
+ return -1;
+
+ default:
+ os_printf("*** WARN ! UNKNOWN ENDPOINT: %d\r\n", (int)header->base.ep);
+ return -1;
+ }
+ return 0;
+}
+
+void send_stage2_submit(usbip_stage2_header *req_header, int32_t status, int32_t data_length)
+{
+
+ req_header->base.command = USBIP_STAGE2_RSP_SUBMIT;
+ req_header->base.direction = !(req_header->base.direction);
+
+ memset(&(req_header->u.ret_submit), 0, sizeof(usbip_stage2_header_ret_submit));
+
+ req_header->u.ret_submit.status = status;
+ req_header->u.ret_submit.data_length = data_length;
+
+ pack(req_header, sizeof(usbip_stage2_header));
+ send(kSock, req_header, sizeof(usbip_stage2_header), 0);
+}
+
+void send_stage2_submit_data(usbip_stage2_header *req_header, int32_t status, const void *const data, int32_t data_length)
+{
+
+ send_stage2_submit(req_header, status, data_length);
+
+ if (data_length)
+ {
+ send(kSock, data, data_length, 0);
+ }
+}
+
+static void handle_unlink(usbip_stage2_header *header)
+{
+ os_printf("s2 handling cmd unlink...\r\n");
+ send_stage2_unlink(header);
+}
+static void send_stage2_unlink(usbip_stage2_header *req_header)
+{
+
+ req_header->base.command = USBIP_STAGE2_RSP_UNLINK;
+ req_header->base.direction = USBIP_DIR_OUT;
+
+ memset(&(req_header->u.ret_unlink), 0, sizeof(usbip_stage2_header_ret_unlink));
+
+ // req_header.u.ret_unlink.status = 0;
+
+ pack(req_header, sizeof(usbip_stage2_header));
+
+ send(kSock, req_header, sizeof(usbip_stage2_header), 0);
+}
\ No newline at end of file
diff --git a/main/usbip_server.h b/main/usbip_server.h
new file mode 100644
index 0000000..2d0effd
--- /dev/null
+++ b/main/usbip_server.h
@@ -0,0 +1,19 @@
+#ifndef __USBIP_SERVER_H__
+#define __USBIP_SERVER_H__
+#include
+#include "usbip_defs.h"
+enum state_t
+{
+ ACCEPTING,
+ ATTACHING,
+ EMULATING
+};
+extern uint8_t kState;
+extern int kSock;
+
+int attach(uint8_t *buffer, uint32_t length);
+int emulate(uint8_t *buffer, uint32_t length);
+void send_stage2_submit_data(usbip_stage2_header *req_header, int32_t status, const void * const data, int32_t data_length);
+void send_stage2_submit(usbip_stage2_header *req_header, int32_t status, int32_t data_length);
+
+#endif
\ No newline at end of file
diff --git a/main/wifi_configuration.h b/main/wifi_configuration.h
new file mode 100644
index 0000000..5f84b6d
--- /dev/null
+++ b/main/wifi_configuration.h
@@ -0,0 +1,20 @@
+/**
+ * @file wifi_configuration.h
+ * @brief Fill in your wifi configuration information here.
+ * @version 0.1
+ * @date 2020-01-22
+ *
+ * @copyright Copyright (c) 2020
+ *
+ */
+#ifndef __WIFI_CONFIGURATION__
+#define __WIFI_CONFIGURATION__
+
+#define WIFI_SSID "DAP"
+#define WIFI_PASS "12345678"
+
+#define PORT 3240
+
+#define CONFIG_EXAMPLE_IPV4 1
+
+#endif
\ No newline at end of file
diff --git a/sdkconfig b/sdkconfig
index 0b1692e..e20f324 100644
--- a/sdkconfig
+++ b/sdkconfig
@@ -33,19 +33,19 @@ CONFIG_ESPTOOLPY_FLASHMODE_QIO=y
# CONFIG_ESPTOOLPY_FLASHMODE_DOUT is not set
CONFIG_ESPTOOLPY_FLASHMODE="dio"
CONFIG_SPI_FLASH_MODE=0x0
-# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set
-CONFIG_ESPTOOLPY_FLASHFREQ_40M=y
+CONFIG_ESPTOOLPY_FLASHFREQ_80M=y
+# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set
# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set
# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set
-CONFIG_ESPTOOLPY_FLASHFREQ="40m"
-CONFIG_SPI_FLASH_FREQ=0x0
+CONFIG_ESPTOOLPY_FLASHFREQ="80m"
+CONFIG_SPI_FLASH_FREQ=0xf
# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set
# CONFIG_ESPTOOLPY_FLASHSIZE_4MB is not set
-CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
-# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
-CONFIG_ESPTOOLPY_FLASHSIZE="8MB"
-CONFIG_SPI_FLASH_SIZE=0x800000
+# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
+CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
+CONFIG_ESPTOOLPY_FLASHSIZE="16MB"
+CONFIG_SPI_FLASH_SIZE=0x1000000
CONFIG_ESPTOOLPY_BEFORE_RESET=y
# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
CONFIG_ESPTOOLPY_BEFORE="default_reset"
@@ -69,16 +69,11 @@ CONFIG_PARTITION_TABLE_SINGLE_APP=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_OFFSET=0x8000
CONFIG_PARTITION_TABLE_FILENAME="partitions_singleapp.csv"
-CONFIG_WIFI_SSID="myssid"
-CONFIG_WIFI_PASSWORD="mypassword"
-CONFIG_EXAMPLE_IPV4=y
-# CONFIG_EXAMPLE_IPV6 is not set
-CONFIG_EXAMPLE_PORT=3333
# CONFIG_COMPILER_OPTIMIZATION_LEVEL_DEBUG is not set
CONFIG_COMPILER_OPTIMIZATION_LEVEL_RELEASE=y
-CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE=y
+# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_ENABLE is not set
# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT is not set
-# CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE is not set
+CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y
# CONFIG_COMPILER_CXX_EXCEPTIONS is not set
CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y
# CONFIG_COMPILER_STACK_CHECK_MODE_NORM is not set
@@ -87,7 +82,7 @@ CONFIG_COMPILER_STACK_CHECK_MODE_NONE=y
# CONFIG_COMPILER_STACK_CHECK is not set
# CONFIG_COMPILER_WARN_WRITE_STRINGS is not set
CONFIG_APP_UPDATE_CHECK_APP_SUM=y
-# CONFIG_APP_UPDATE_CHECK_APP_HASH is not set
+CONFIG_APP_UPDATE_CHECK_APP_HASH=y
# CONFIG_AWS_IOT_SDK is not set
# CONFIG_USING_ESP_CONSOLE is not set
CONFIG_ESP_TLS_USING_MBEDTLS=y
@@ -107,8 +102,8 @@ CONFIG_ESP_FILENAME_MACRO_NO_PATH=y
# CONFIG_ESP_FILENAME_MACRO_NULL is not set
CONFIG_USING_NEW_ETS_VPRINTF=y
# CONFIG_LINK_ETS_PRINTF_TO_IRAM is not set
-# CONFIG_SOC_FULL_ICACHE is not set
-CONFIG_SOC_IRAM_SIZE=0xC000
+CONFIG_SOC_FULL_ICACHE=y
+CONFIG_SOC_IRAM_SIZE=0x8000
CONFIG_CONSOLE_UART_DEFAULT=y
# CONFIG_CONSOLE_UART_CUSTOM is not set
# CONFIG_CONSOLE_UART_NONE is not set
@@ -130,7 +125,6 @@ CONFIG_TASK_WDT_TIMEOUT_S=15
CONFIG_RESET_REASON=y
CONFIG_WIFI_PPT_TASKSTACK_SIZE=2048
CONFIG_EVENT_LOOP_STACK_SIZE=2048
-CONFIG_ESP8266_CORE_GLOBAL_DATA_LINK_IRAM=y
# CONFIG_ESP8266_OTA_FROM_OLD is not set
# CONFIG_ESP8266_BOOT_COPY_APP is not set
CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
@@ -141,7 +135,7 @@ CONFIG_WIFI_TX_RATE_SEQUENCE_FROM_HIGH=y
# CONFIG_ESP8266_WIFI_QOS_ENABLED is not set
# CONFIG_ESP8266_WIFI_AMPDU_RX_ENABLED is not set
# CONFIG_ESP8266_WIFI_AMSDU_ENABLED is not set
-CONFIG_ESP8266_WIFI_RX_BUFFER_NUM=16
+CONFIG_ESP8266_WIFI_RX_BUFFER_NUM=26
CONFIG_ESP8266_WIFI_LEFT_CONTINUOUS_RX_BUFFER_NUM=4
CONFIG_ESP8266_WIFI_RX_PKT_NUM=7
CONFIG_ESP8266_WIFI_TX_PKT_NUM=6
@@ -151,8 +145,8 @@ CONFIG_ESP8266_WIFI_CONNECT_OPEN_ROUTER_WHEN_PWD_IS_SET=y
CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE=y
# CONFIG_ESP_PHY_INIT_DATA_IN_PARTITION is not set
CONFIG_ESP_PHY_INIT_DATA_VDD33_CONST=33
-CONFIG_ESP8266_PHY_MAX_WIFI_TX_POWER=20
-# CONFIG_ESP8266_HSPI_HIGH_THROUGHPUT is not set
+CONFIG_ESP8266_PHY_MAX_WIFI_TX_POWER=21
+CONFIG_ESP8266_HSPI_HIGH_THROUGHPUT=y
CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y
CONFIG_HTTP_BUF_SIZE=512
CONFIG_HTTPD_MAX_REQ_HDR_LEN=512
@@ -166,33 +160,31 @@ CONFIG_FREERTOS_MAX_HOOK=2
CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1024
CONFIG_FREERTOS_ISR_STACKSIZE=512
# CONFIG_FREERTOS_EXTENED_HOOKS is not set
-CONFIG_FREERTOS_GLOBAL_DATA_LINK_IRAM=y
-# CONFIG_FREERTOS_CODE_LINK_TO_IRAM is not set
+CONFIG_FREERTOS_CODE_LINK_TO_IRAM=y
CONFIG_FREERTOS_TIMER_STACKSIZE=2048
CONFIG_TASK_SWITCH_FASTER=y
# CONFIG_USE_QUEUE_SETS is not set
# CONFIG_ENABLE_FREERTOS_SLEEP is not set
# CONFIG_FREERTOS_USE_TRACE_FACILITY is not set
# CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS is not set
-# CONFIG_HEAP_DISABLE_IRAM is not set
+CONFIG_HEAP_DISABLE_IRAM=y
# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set
-# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set
+CONFIG_LOG_DEFAULT_LEVEL_ERROR=y
# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set
-CONFIG_LOG_DEFAULT_LEVEL_INFO=y
+# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set
# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set
# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set
-CONFIG_LOG_DEFAULT_LEVEL=3
+CONFIG_LOG_DEFAULT_LEVEL=1
CONFIG_LOG_COLORS=y
# CONFIG_LOG_SET_LEVEL is not set
-# CONFIG_LWIP_USE_IRAM is not set
-# CONFIG_LWIP_HIGH_THROUGHPUT is not set
-CONFIG_LWIP_GLOBAL_DATA_LINK_IRAM=y
-CONFIG_TCPIP_RECVMBOX_SIZE=32
+CONFIG_LWIP_USE_IRAM=y
+CONFIG_LWIP_HIGH_THROUGHPUT=y
+CONFIG_TCPIP_RECVMBOX_SIZE=64
CONFIG_LWIP_ARP_TABLE_SIZE=10
CONFIG_LWIP_ARP_MAXAGE=300
# CONFIG_LWIP_ESP_GRATUITOUS_ARP is not set
CONFIG_LWIP_SOCKET_MULTITHREAD=y
-# CONFIG_ENABLE_NONBLOCK_SPEEDUP is not set
+CONFIG_ENABLE_NONBLOCK_SPEEDUP=y
CONFIG_SET_SOLINGER_DEFAULT=y
CONFIG_ESP_UDP_SYNC_SEND=y
CONFIG_ESP_UDP_SYNC_RETRY_MAX=5
@@ -202,8 +194,8 @@ CONFIG_LWIP_SO_REUSE_RXTOALL=y
# CONFIG_LWIP_SO_RCVBUF is not set
CONFIG_LWIP_RECV_BUFSIZE_DEFAULT=11680
CONFIG_LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT=10000
-# CONFIG_LWIP_IP_FRAG is not set
-# CONFIG_LWIP_IP_REASSEMBLY is not set
+CONFIG_LWIP_IP_FRAG=y
+CONFIG_LWIP_IP_REASSEMBLY=y
CONFIG_LWIP_IP_REASS_MAX_PBUFS=10
# CONFIG_LWIP_IP_SOF_BROADCAST is not set
# CONFIG_LWIP_IP_SOF_BROADCAST_RECV is not set
@@ -221,7 +213,7 @@ CONFIG_LWIP_IGMP=y
CONFIG_ESP_DNS=y
CONFIG_DNS_MAX_SERVERS=3
# CONFIG_LWIP_NETIF_LOOPBACK is not set
-# CONFIG_TCP_HIGH_SPEED_RETRANSMISSION is not set
+CONFIG_TCP_HIGH_SPEED_RETRANSMISSION=y
CONFIG_LWIP_MAX_ACTIVE_TCP=5
CONFIG_LWIP_MAX_LISTENING_TCP=8
CONFIG_TCP_MAXRTX=12
@@ -229,7 +221,7 @@ CONFIG_TCP_SYNMAXRTX=6
CONFIG_TCP_MSS=1460
CONFIG_TCP_SND_BUF_DEFAULT=2920
CONFIG_TCP_WND_DEFAULT=5840
-CONFIG_TCP_RECVMBOX_SIZE=6
+CONFIG_TCP_RECVMBOX_SIZE=16
CONFIG_TCP_QUEUE_OOSEQ=y
CONFIG_TCP_OVERSIZE_MSS=y
# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set
@@ -237,7 +229,7 @@ CONFIG_TCP_OVERSIZE_MSS=y
# CONFIG_LWIP_TCP_TIMESTAMPS is not set
CONFIG_LWIP_MAX_UDP_PCBS=4
CONFIG_UDP_RECVMBOX_SIZE=6
-CONFIG_TCPIP_TASK_STACK_SIZE=2048
+CONFIG_TCPIP_TASK_STACK_SIZE=4096
CONFIG_LWIP_MAX_RAW_PCBS=4
# CONFIG_LWIP_IPV6 is not set
# CONFIG_LWIP_STATS is not set
@@ -343,7 +335,6 @@ CONFIG_OPENSSL_ASSERT_DO_NOTHING=y
# CONFIG_ENABLE_PTHREAD is not set
# CONFIG_USING_SPIFFS is not set
CONFIG_IP_LOST_TIMER_INTERVAL=120
-CONFIG_TCPIP_ADAPTER_GLOBAL_DATA_LINK_IRAM=y
# CONFIG_util_assert is not set
CONFIG_ESP_SHA=y
CONFIG_ESP_AES=y
@@ -372,9 +363,9 @@ CONFIG_MONITOR_BAUD_OTHER_VAL=74880
CONFIG_MONITOR_BAUD=74880
# CONFIG_OPTIMIZATION_LEVEL_DEBUG is not set
CONFIG_OPTIMIZATION_LEVEL_RELEASE=y
-CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y
+# CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED is not set
# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set
-# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set
+CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED=y
# CONFIG_CXX_EXCEPTIONS is not set
CONFIG_STACK_CHECK_NONE=y
# CONFIG_STACK_CHECK_NORM is not set