From 2c09346169d11c4f40f4c7000f02b91c5955182d Mon Sep 17 00:00:00 2001 From: windowsair Date: Tue, 21 Jan 2020 22:03:05 +0800 Subject: [PATCH 01/15] feat: Mainly improve DAP configuration: 1. improve DAP configuration independent of specific hardware 2. add hardware timer 3. cmake configuration file simple modification 4. add some to-do items --- .gitignore | 1 + components/CMakeLists.txt | 0 components/DAP/config/DAP_config.h | 665 +++++++++++ components/DAP/include/DAP.h | 325 +++++ components/DAP/source/DAP.c | 1769 ++++++++++++++++++++++++++++ components/DAP/source/DAP_vendor.c | 100 ++ components/DAP/source/JTAG_DP.c | 370 ++++++ components/DAP/source/SWO.c | 800 +++++++++++++ components/DAP/source/SW_DP.c | 286 +++++ components/README.md | 3 + main/CMakeLists.txt | 2 +- main/tcp_server.c | 25 +- 12 files changed, 4343 insertions(+), 3 deletions(-) create mode 100644 components/CMakeLists.txt create mode 100644 components/DAP/config/DAP_config.h create mode 100644 components/DAP/include/DAP.h create mode 100644 components/DAP/source/DAP.c create mode 100644 components/DAP/source/DAP_vendor.c create mode 100644 components/DAP/source/JTAG_DP.c create mode 100644 components/DAP/source/SWO.c create mode 100644 components/DAP/source/SW_DP.c create mode 100644 components/README.md diff --git a/.gitignore b/.gitignore index 1d74e21..e524d79 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .vscode/ +build/ diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt new file mode 100644 index 0000000..e69de29 diff --git a/components/DAP/config/DAP_config.h b/components/DAP/config/DAP_config.h new file mode 100644 index 0000000..048d766 --- /dev/null +++ b/components/DAP/config/DAP_config.h @@ -0,0 +1,665 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ---------------------------------------------------------------------- + * + * $Date: 1. December 2017 + * $Revision: V2.0.0 + * + * Project: CMSIS-DAP Configuration + * Title: DAP_config.h CMSIS-DAP Configuration File (Template) + * + *---------------------------------------------------------------------------*/ + +#ifndef __DAP_CONFIG_H__ +#define __DAP_CONFIG_H__ + +#include "gpio.h" +#include "gpio_struct.h" +#include "timer_struct.h" + +//************************************************************************************************** +/** +\defgroup DAP_Config_Debug_gr CMSIS-DAP Debug Unit Information +\ingroup DAP_ConfigIO_gr +@{ +Provides definitions about the hardware and configuration of the Debug Unit. + +This information includes: + - Definition of Cortex-M processor parameters used in CMSIS-DAP Debug Unit. + - Debug Unit Identification strings (Vendor, Product, Serial Number). + - Debug Unit communication packet size. + - Debug Access Port supported modes and settings (JTAG/SWD and SWO). + - Optional information about a connected Target Device (for Evaluation Boards). +*/ + +//#ifdef _RTE_ +//#include "RTE_Components.h" +//#include CMSIS_device_header +//#else +//#include "device.h" // Debug Unit Cortex-M Processor Header File +//#endif + +/// Processor Clock of the Cortex-M MCU used in the Debug Unit. +/// This value is used to calculate the SWD/JTAG clock speed. +#define CPU_CLOCK 160000000U ///< Specifies the CPU Clock in Hz. +// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<160MHz + +/// Number of processor cycles for I/O Port write operations. +/// This value is used to calculate the SWD/JTAG clock speed that is generated with I/O +/// Port write operations in the Debug Unit by a Cortex-M MCU. Most Cortex-M processors +/// require 2 processor cycles for a I/O Port Write operation. If the Debug Unit uses +/// a Cortex-M0+ processor with high-speed peripheral I/O only 1 processor cycle might be +/// required. +#define IO_PORT_WRITE_CYCLES 2U ///< I/O Cycles: 2=default, 1=Cortex-M0+ fast I/0. + +/// Indicate that Serial Wire Debug (SWD) communication mode is available at the Debug Access Port. +/// This information is returned by the command \ref DAP_Info as part of 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 512U ///< Specifies Packet Size in bytes. +// <<<<<<<<<<<<<<<<<<<<<<<<<<<<< 512 for High-speed USB WinUSB. + +/// Maximum Package Buffers for Command and Response data. +/// This configuration settings is used to optimize the communication performance with the +/// debugger and depends on the USB peripheral. For devices with limited RAM or USB buffer the +/// setting can be reduced (valid range is 1 .. 255). +#define DAP_PACKET_COUNT 8U ///< Specifies number of packets buffered. + +/// Indicate that UART Serial Wire Output (SWO) trace is available. +/// This information is returned by the command \ref DAP_Info as part of Capabilities. +#define SWO_UART 1 ///< SWO UART: 1 = available, 0 = not available. + +/// Maximum SWO UART Baudrate. +#define SWO_UART_MAX_BAUDRATE 50000000U ///< SWO UART Maximum Baudrate in Hz. +// <<<<<<<<<<<<<<<<<<<<<<<<<<<<< 5MHz +// TODO: uncertain value + +/// Indicate that Manchester Serial Wire Output (SWO) trace is available. +/// This information is returned by the command \ref DAP_Info as part of Capabilities. +#define SWO_MANCHESTER 1 ///< SWO Manchester: 1 = available, 0 = not available. + +/// SWO Trace Buffer Size. +#define SWO_BUFFER_SIZE 4096U ///< SWO Trace Buffer Size in bytes (must be 2^n). + +/// SWO Streaming Trace. +#define SWO_STREAM 1 ///< SWO Streaming Trace: 1 = available, 0 = not available. + +/// Clock frequency of the Test Domain Timer. Timer value is returned with \ref TIMESTAMP_GET. +#define TIMESTAMP_CLOCK 5000000U ///< Timestamp clock in Hz (0 = timestamps not supported). +// <<<<<<<<<<<<<<<<<<<<<5MHz + +/// Debug Unit is connected to fixed Target Device. +/// The Debug Unit may be part of an evaluation board and always connected to a fixed +/// known device. In this case a Device Vendor and Device Name string is stored which +/// may be used by the debugger or IDE to configure device parameters. +#define TARGET_DEVICE_FIXED 0 ///< Target Device: 1 = known, 0 = unknown; + +#if TARGET_DEVICE_FIXED +#define TARGET_DEVICE_VENDOR "ARM" ///< String indicating the Silicon Vendor +#define TARGET_DEVICE_NAME "Cortex-M4" ///< String indicating the Target Device +#endif + +/** + * @brief Get Vendor ID string. + * + * @param str Pointer to buffer to store the string. + * @return String length. + */ +__STATIC_INLINE uint8_t DAP_GetVendorString(char *str) +{ + //TODO: fill this + // In fact, Keil can get the corresponding information through USB + // without filling in this information. + (void)str; + return (0U); +} + +/** + * @brief Get Product ID string. + * + * @param str Pointer to buffer to store the string. + * @return String length. + */ +__STATIC_INLINE uint8_t DAP_GetProductString(char *str) +{ + (void)str; + return (0U); +} + +/** + * @brief Get Serial Number string. + * + * @param str Pointer to buffer to store the string. + * @return String length. + */ +__STATIC_INLINE uint8_t DAP_GetSerNumString(char *str) +{ + (void)str; + return (0U); +} + +///@} + +// Modify your pins here + +// ATTENTION: DO NOT USE RTC GPIO16 +#define PIN_SWDIO 2 +#define PIN_SWCLK 0 +#define PIN_TDO 4 +#define PIN_TDI 5 +#define PIN_nTRST 1 // optional +#define PIN_nRESET 16 +// LED_BUILTIN +#define PIN_LED_CONNECTED 13 +// LED_BUILTIN +#define PIN_LED_RUNNING 15 + +//************************************************************************************************** +/** +\defgroup DAP_Config_PortIO_gr CMSIS-DAP Hardware I/O Pin Access +\ingroup DAP_ConfigIO_gr +@{ + +Standard I/O Pins of the CMSIS-DAP Hardware Debug Port support standard JTAG mode +and Serial Wire Debug (SWD) mode. In SWD mode only 2 pins are required to implement the debug +interface of a device. The following I/O Pins are provided: + +JTAG I/O Pin | SWD I/O Pin | CMSIS-DAP Hardware pin mode +---------------------------- | -------------------- | --------------------------------------------- +TCK: Test Clock | SWCLK: Clock | Output Push/Pull +TMS: Test Mode Select | SWDIO: Data I/O | Output Push/Pull; Input (for receiving data) +TDI: Test Data Input | | Output Push/Pull +TDO: Test Data Output | | Input +nTRST: Test Reset (optional) | | Output Open Drain with pull-up resistor +nRESET: Device Reset | nRESET: Device Reset | Output Open Drain with pull-up resistor + + +DAP Hardware I/O Pin Access Functions +------------------------------------- +The various I/O Pins are accessed by functions that implement the Read, Write, Set, or Clear to +these I/O Pins. + +For the SWDIO I/O Pin there are additional functions that are called in SWD I/O mode only. +This functions are provided to achieve faster I/O that is possible with some advanced GPIO +peripherals that can independently write/read a single I/O pin without affecting any other pins +of the same I/O port. The following SWDIO I/O Pin functions are provided: + - \ref PIN_SWDIO_OUT_ENABLE to enable the output mode from the DAP hardware. + - \ref PIN_SWDIO_OUT_DISABLE to enable the input mode to the DAP hardware. + - \ref PIN_SWDIO_IN to read from the SWDIO I/O pin with utmost possible speed. + - \ref PIN_SWDIO_OUT to write to the SWDIO I/O pin with utmost possible speed. +*/ + +/** + * @brief Setup JTAG I/O pins: TCK, TMS, TDI, TDO, nTRST, and nRESET. + * Configures the DAP Hardware I/O pins for JTAG mode: + * - TCK, TMS, TDI, nTRST, nRESET to ***output*** mode and set to high level. + * - TDO to ***input*** mode. + * + */ +__STATIC_INLINE void PORT_JTAG_SETUP(void) +{ + gpio_set_direction(PIN_SWCLK, GPIO_MODE_OUTPUT); + gpio_set_direction(PIN_SWDIO, GPIO_MODE_OUTPUT); + + gpio_set_direction(PIN_TDO, GPIO_MODE_DEF_INPUT); + gpio_set_direction(PIN_TDI, GPIO_MODE_OUTPUT); + + gpio_set_direction(PIN_nTRST, GPIO_MODE_OUTPUT_OD); + gpio_set_direction(PIN_nRESET, GPIO_MODE_OUTPUT_OD); + gpio_set_pull_mode(PIN_nTRST, GPIO_PULLUP_ONLY); + gpio_set_pull_mode(PIN_nRESET, GPIO_PULLUP_ONLY); +} + +/** + * @brief Setup SWD I/O pins: SWCLK, SWDIO, and nRESET. + * Configures the DAP Hardware I/O pins for Serial Wire Debug (SWD) mode: + * - SWCLK, SWDIO, nRESET to output mode and set to default high level. + * - TDI, nTRST to HighZ mode (pins are unused in SWD mode). + * + */ +__STATIC_INLINE void PORT_SWD_SETUP(void) +{ + gpio_set_direction(PIN_SWCLK, GPIO_MODE_OUTPUT); + gpio_set_direction(PIN_SWDIO, GPIO_MODE_OUTPUT); + + gpio_set_direction(PIN_TDO, GPIO_MODE_DEF_INPUT); + gpio_set_direction(PIN_TDI, GPIO_MODE_OUTPUT); + + gpio_set_direction(PIN_nTRST, GPIO_MODE_OUTPUT_OD); + gpio_set_direction(PIN_nRESET, GPIO_MODE_OUTPUT_OD); + gpio_set_pull_mode(PIN_nTRST, GPIO_PULLUP_ONLY); + gpio_set_pull_mode(PIN_nRESET, GPIO_PULLUP_ONLY); +} + +/** + * @brief Disable JTAG/SWD I/O Pins. + * Disables the DAP Hardware I/O pins which configures: + * - TCK/SWCLK, TMS/SWDIO, TDI, TDO, nTRST, nRESET to High-Z mode. + * + */ +__STATIC_INLINE void PORT_OFF(void) +{ + // Will be called when the DAP disconnected + gpio_set_direction(PIN_SWCLK, GPIO_MODE_DEF_DISABLE); + gpio_set_direction(PIN_SWDIO, GPIO_MODE_DEF_DISABLE); + + gpio_set_direction(PIN_TDO, GPIO_MODE_DEF_DISABLE); + gpio_set_direction(PIN_TDI, GPIO_MODE_DEF_DISABLE); + + gpio_set_direction(PIN_nTRST, GPIO_MODE_DEF_DISABLE); + gpio_set_direction(PIN_nRESET, GPIO_MODE_DEF_DISABLE); +} + +// SWCLK/TCK I/O pin ------------------------------------- + +/** + * @brief SWCLK/TCK I/O pin: Get Input. + * + * @return Current status of the SWCLK/TCK DAP hardware I/O pin. + */ +__STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN(void) +{ + // TODO : can we set to 0? + return ((GPIO.in >> PIN_SWCLK) & 0x1); +} + +/** + * @brief SWCLK/TCK I/O pin: Set Output to High. + * + * Set the SWCLK/TCK DAP hardware I/O pin to high level. + */ +__STATIC_FORCEINLINE void PIN_SWCLK_TCK_SET(void) +{ + GPIO.out_w1ts |= (0x1 << PIN_SWCLK); +} + +/** + * @brief SWCLK/TCK I/O pin: Set Output to Low. + * + * Set the SWCLK/TCK DAP hardware I/O pin to low level. + */ +__STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR(void) +{ + GPIO.out_w1tc |= (0x1 << PIN_SWCLK); +} + +// SWDIO/TMS Pin I/O -------------------------------------- + +/** + * @brief SWDIO/TMS I/O pin: Get Input. + * + * @return Current status of the SWDIO/TMS DAP hardware I/O pin. + */ +__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN(void) +{ + return ((GPIO.in >> PIN_SWDIO) & 0x1); +} + +/** + * @brief SWDIO/TMS I/O pin: Set Output to High. + * + * Set the SWDIO/TMS DAP hardware I/O pin to high level. + */ +__STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET(void) +{ + GPIO.out_w1ts |= (0x1 << PIN_SWDIO); +} + +/** + * @brief SWDIO/TMS I/O pin: Set Output to Low. + * + * Set the SWDIO/TMS DAP hardware I/O pin to low level. + */ +__STATIC_FORCEINLINE void PIN_SWDIO_TMS_CLR(void) +{ + GPIO.out_w1tc |= (0x1 << PIN_SWDIO); +} + +/** + * @brief SWDIO I/O pin: Get Input (used in SWD mode only). + * + * @return Current status of the SWDIO DAP hardware I/O pin. + */ +__STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN(void) +{ + return ((GPIO.in >> PIN_SWDIO) & 0x1); +} + +/** + * @brief SWDIO I/O pin: Set Output (used in SWD mode only). + * + * @param bit Output value for the SWDIO DAP hardware I/O pin. + * + */ +__STATIC_FORCEINLINE void PIN_SWDIO_OUT(uint32_t bit) +{ + /** + * Important: Use only one bit (bit0) of param! + * Sometimes the func "SWD_TransferFunction" of SW_DP.c will + * issue "2" as param instead of "0". Zach Lee + */ + if ((bit & 1U) == 1) + { + //set bit + GPIO.out_w1ts |= (0x1 << PIN_SWDIO); + } + else + { + //reset bit + GPIO.out_w1tc |= (0x1 << PIN_SWDIO); + } +} + +/** + * @brief SWDIO I/O pin: Switch to Output mode (used in SWD mode only). + * Configure the SWDIO DAP hardware I/O pin to output mode. This function is + * called prior \ref PIN_SWDIO_OUT function calls. + */ +__STATIC_FORCEINLINE void PIN_SWDIO_OUT_ENABLE(void) +{ + // Need fast response + + // set \ref gpio_set_direction -> OUTPUT + GPIO.enable_w1ts |= (0x1 << PIN_SWDIO); +} + +/** + * @brief SWDIO I/O pin: Switch to Input mode (used in SWD mode only). + * Configure the SWDIO DAP hardware I/O pin to input mode. This function is + * called prior \ref PIN_SWDIO_IN function calls. + */ +__STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE(void) +{ + // Need fast response + // set \ref gpio_set_dircetion -> INPUT + // esp8266 input is always connected + GPIO.enable_w1tc |= (0x1 << PIN_SWDIO); +} + +// TDI Pin I/O --------------------------------------------- + +/** + * @brief TDI I/O pin: Get Input. + * + * @return Current status of the TDI DAP hardware I/O pin. + */ +__STATIC_FORCEINLINE uint32_t PIN_TDI_IN(void) +{ + return ((GPIO.in >> PIN_TDI) & 0x1); +} + +/** + * @brief TDI I/O pin: Set Output. + * + * @param bit Output value for the TDI DAP hardware I/O pin. + * + */ +__STATIC_FORCEINLINE void PIN_TDI_OUT(uint32_t bit) +{ + if ((bit & 1U) == 1) + { + //set bit + GPIO.out_w1ts |= (0x1 << PIN_TDI); + } + else + { + //reset bit + GPIO.out_w1tc |= (0x1 << PIN_TDI); + } +} + +// TDO Pin I/O --------------------------------------------- + +/** + * @brief TDO I/O pin: Get Input. + * + * @return Current status of the TDO DAP hardware I/O pin. + */ +__STATIC_FORCEINLINE uint32_t PIN_TDO_IN(void) +{ + return ((GPIO.in >> PIN_TDO_IN) & 0x1); +} + +// nTRST Pin I/O ------------------------------------------- + +/** + * @brief nTRST I/O pin: Get Input. + * + * @return Current status of the nTRST DAP hardware I/O pin. + */ +__STATIC_FORCEINLINE uint32_t PIN_nTRST_IN(void) +{ + return ((GPIO.in >> PIN_nTRST) & 0x1); +} + +/** + * @brief nTRST I/O pin: Set Output. + * + * @param bit JTAG TRST Test Reset pin status: + * - 0: issue a JTAG TRST Test Reset. + - 1: release JTAG TRST Test Reset. + */ +__STATIC_FORCEINLINE void PIN_nTRST_OUT(uint32_t bit) +{ + //TODO : What does this mean? ? ? + if ((bit & 1U) == 1) + { + //set bit + GPIO.out_w1ts |= (0x1 << PIN_nTRST); + } + else + { + //reset bit + GPIO.out_w1tc |= (0x1 << PIN_nTRST); + } +} + +// nRESET Pin I/O------------------------------------------ + +/** + * @brief nRESET I/O pin: Get Input. + * + * @return Current status of the nRESET DAP hardware I/O pin. + */ +__STATIC_FORCEINLINE uint32_t PIN_nRESET_IN(void) +{ + return ((GPIO.in >> PIN_nRESET) & 0x1); +} + +/** + * @brief nRESET I/O pin: Set Output. + * + * @param bit target device hardware reset pin status: + * - 0: issue a device hardware reset. + * - 1: release device hardware reset. + */ +__STATIC_FORCEINLINE void PIN_nRESET_OUT(uint32_t bit) +{ + //TODO : What does this mean? ? ? + if ((bit & 1U) == 1) + { + //set bit + GPIO.out_w1ts |= (0x1 << PIN_nRESET); + } + else + { + //reset bit + GPIO.out_w1tc |= (0x1 << PIN_nRESET); + } +} + +///@} + +//************************************************************************************************** +/** +\defgroup DAP_Config_LEDs_gr CMSIS-DAP Hardware Status LEDs +\ingroup DAP_ConfigIO_gr +@{ + +CMSIS-DAP Hardware may provide LEDs that indicate the status of the CMSIS-DAP Debug Unit. + +It is recommended to provide the following LEDs for status indication: + - Connect LED: is active when the DAP hardware is connected to a debugger. + - Running LED: is active when the debugger has put the target device into running state. +*/ + +/** Debug Unit: Set status of Connected LED. +\param bit status of the Connect LED. + - 1: Connect LED ON: debugger is connected to CMSIS-DAP Debug Unit. + - 0: Connect LED OFF: debugger is not connected to CMSIS-DAP Debug Unit. +*/ + +/** + * @brief Debug Unit: Set status of Connected LED. + * + * @param bit status of the Connect LED. + * - 1: Connect LED ON: debugger is connected to CMSIS-DAP Debug Unit. + * - 0: Connect LED OFF: debugger is not connected to CMSIS-DAP Debug Unit. + */ +__STATIC_INLINE void LED_CONNECTED_OUT(uint32_t bit) +{ + if (bit) + { + //set bit + GPIO.out_w1ts |= (0x1 << PIN_LED_CONNECTED); + } + else + { + //reset bit + GPIO.out_w1tc |= (0x1 << PIN_LED_CONNECTED); + } +} + +/** + * @brief Debug Unit: Set status Target Running LED. + * + * @param bit status of the Target Running LED. + * - 1: Target Running LED ON: program execution in target started. + * - 0: Target Running LED OFF: program execution in target stopped. + */ +__STATIC_INLINE void LED_RUNNING_OUT(uint32_t bit) +{ + if (bit) + { + //set bit + GPIO.out_w1ts |= (0x1 << PIN_LED_RUNNING); + } + else + { + //reset bit + GPIO.out_w1tc |= (0x1 << PIN_LED_RUNNING); + } +} + +///@} + +//************************************************************************************************** +/** +\defgroup DAP_Config_Timestamp_gr CMSIS-DAP Timestamp +\ingroup DAP_ConfigIO_gr +@{ +Access function for Test Domain Timer. + +The value of the Test Domain Timer in the Debug Unit is returned by the function \ref TIMESTAMP_GET. By +default, the DWT timer is used. The frequency of this timer is configured with \ref TIMESTAMP_CLOCK. + +*/ + +/** + * @brief Get timestamp of Test Domain Timer. + * + * @return Current timestamp value. + */ +__STATIC_INLINE uint32_t TIMESTAMP_GET(void) +{ + // FRC1 is a 24-bit countdown timer + return (0x1000000U - 1U - (frc1.count.data)); +} + +///@} + +//************************************************************************************************** +/** +\defgroup DAP_Config_Initialization_gr CMSIS-DAP Initialization +\ingroup DAP_ConfigIO_gr +@{ + +CMSIS-DAP Hardware I/O and LED Pins are initialized with the function \ref DAP_SETUP. +*/ + +/** Setup of the Debug Unit I/O pins and LEDs (called when Debug Unit is initialized). +This function performs the initialization of the CMSIS-DAP Hardware I/O Pins and the +Status LEDs. In detail the operation of Hardware I/O and LED pins are enabled and set: + - I/O clock system enabled. + - all I/O pins: input buffer enabled, output pins are set to HighZ mode. + - for nTRST, nRESET a weak pull-up (if available) is enabled. + - LED output pins are enabled and LEDs are turned off. +*/ +__STATIC_INLINE void DAP_SETUP(void) +{ + // This function maybe unnecessary... + gpio_set_direction(PIN_SWCLK, GPIO_MODE_DEF_INPUT); + gpio_set_direction(PIN_SWDIO, GPIO_MODE_DEF_INPUT); // + gpio_set_direction(PIN_nRESET, GPIO_MODE_DEF_INPUT); // + gpio_set_direction(PIN_TDI, GPIO_MODE_DEF_INPUT); + gpio_set_direction(PIN_TDO, GPIO_MODE_DEF_INPUT); + + // Configure: LED as output (turned off) + gpio_set_direction(PIN_LED_CONNECTED, GPIO_MODE_DEF_OUTPUT); + LED_CONNECTED_OUT(0); + gpio_set_direction(PIN_LED_RUNNING, GPIO_MODE_DEF_OUTPUT); + LED_RUNNING_OUT(0); +} + +/** Reset Target Device with custom specific I/O pin or command sequence. +This function allows the optional implementation of a device specific reset sequence. +It is called when the command \ref DAP_ResetTarget and is for example required +when a device needs a time-critical unlock sequence that enables the debug port. +\return 0 = no device specific reset sequence is implemented.\n + 1 = a device specific reset sequence is implemented. +*/ +__STATIC_INLINE uint8_t RESET_TARGET(void) +{ + return (0U); // not available +} + +///@} + +#endif /* __DAP_CONFIG_H__ */ diff --git a/components/DAP/include/DAP.h b/components/DAP/include/DAP.h new file mode 100644 index 0000000..4194005 --- /dev/null +++ b/components/DAP/include/DAP.h @@ -0,0 +1,325 @@ +/* + * Copyright (c) 2013-2019 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ---------------------------------------------------------------------- + * + * $Date: 26. November 2019 + * $Revision: V2.0.0 + * + * Project: CMSIS-DAP Include + * Title: DAP.h Definitions + * + *---------------------------------------------------------------------------*/ + +#ifndef __DAP_H__ +#define __DAP_H__ + + +// DAP Firmware Version +#ifdef DAP_FW_V1 +#define DAP_FW_VER "1.2.0" +#else +#define DAP_FW_VER "2.0.0" +#endif + +// DAP Command IDs +#define ID_DAP_Info 0x00U +#define ID_DAP_HostStatus 0x01U +#define ID_DAP_Connect 0x02U +#define ID_DAP_Disconnect 0x03U +#define ID_DAP_TransferConfigure 0x04U +#define ID_DAP_Transfer 0x05U +#define ID_DAP_TransferBlock 0x06U +#define ID_DAP_TransferAbort 0x07U +#define ID_DAP_WriteABORT 0x08U +#define ID_DAP_Delay 0x09U +#define ID_DAP_ResetTarget 0x0AU +#define ID_DAP_SWJ_Pins 0x10U +#define ID_DAP_SWJ_Clock 0x11U +#define ID_DAP_SWJ_Sequence 0x12U +#define ID_DAP_SWD_Configure 0x13U +#define ID_DAP_SWD_Sequence 0x1DU +#define ID_DAP_JTAG_Sequence 0x14U +#define ID_DAP_JTAG_Configure 0x15U +#define ID_DAP_JTAG_IDCODE 0x16U +#define ID_DAP_SWO_Transport 0x17U +#define ID_DAP_SWO_Mode 0x18U +#define ID_DAP_SWO_Baudrate 0x19U +#define ID_DAP_SWO_Control 0x1AU +#define ID_DAP_SWO_Status 0x1BU +#define ID_DAP_SWO_ExtendedStatus 0x1EU +#define ID_DAP_SWO_Data 0x1CU + +#define ID_DAP_QueueCommands 0x7EU +#define ID_DAP_ExecuteCommands 0x7FU + +// DAP Vendor Command IDs +#define ID_DAP_Vendor0 0x80U +#define ID_DAP_Vendor1 0x81U +#define ID_DAP_Vendor2 0x82U +#define ID_DAP_Vendor3 0x83U +#define ID_DAP_Vendor4 0x84U +#define ID_DAP_Vendor5 0x85U +#define ID_DAP_Vendor6 0x86U +#define ID_DAP_Vendor7 0x87U +#define ID_DAP_Vendor8 0x88U +#define ID_DAP_Vendor9 0x89U +#define ID_DAP_Vendor10 0x8AU +#define ID_DAP_Vendor11 0x8BU +#define ID_DAP_Vendor12 0x8CU +#define ID_DAP_Vendor13 0x8DU +#define ID_DAP_Vendor14 0x8EU +#define ID_DAP_Vendor15 0x8FU +#define ID_DAP_Vendor16 0x90U +#define ID_DAP_Vendor17 0x91U +#define ID_DAP_Vendor18 0x92U +#define ID_DAP_Vendor19 0x93U +#define ID_DAP_Vendor20 0x94U +#define ID_DAP_Vendor21 0x95U +#define ID_DAP_Vendor22 0x96U +#define ID_DAP_Vendor23 0x97U +#define ID_DAP_Vendor24 0x98U +#define ID_DAP_Vendor25 0x99U +#define ID_DAP_Vendor26 0x9AU +#define ID_DAP_Vendor27 0x9BU +#define ID_DAP_Vendor28 0x9CU +#define ID_DAP_Vendor29 0x9DU +#define ID_DAP_Vendor30 0x9EU +#define ID_DAP_Vendor31 0x9FU + +#define ID_DAP_Invalid 0xFFU + +// DAP Status Code +#define DAP_OK 0U +#define DAP_ERROR 0xFFU + +// DAP ID +#define DAP_ID_VENDOR 1U +#define DAP_ID_PRODUCT 2U +#define DAP_ID_SER_NUM 3U +#define DAP_ID_FW_VER 4U +#define DAP_ID_DEVICE_VENDOR 5U +#define DAP_ID_DEVICE_NAME 6U +#define DAP_ID_CAPABILITIES 0xF0U +#define DAP_ID_TIMESTAMP_CLOCK 0xF1U +#define DAP_ID_SWO_BUFFER_SIZE 0xFDU +#define DAP_ID_PACKET_COUNT 0xFEU +#define DAP_ID_PACKET_SIZE 0xFFU + +// DAP Host Status +#define DAP_DEBUGGER_CONNECTED 0U +#define DAP_TARGET_RUNNING 1U + +// DAP Port +#define DAP_PORT_AUTODETECT 0U // Autodetect Port +#define DAP_PORT_DISABLED 0U // Port Disabled (I/O pins in High-Z) +#define DAP_PORT_SWD 1U // SWD Port (SWCLK, SWDIO) + nRESET +#define DAP_PORT_JTAG 2U // JTAG Port (TCK, TMS, TDI, TDO, nTRST) + nRESET + +// DAP SWJ Pins +#define DAP_SWJ_SWCLK_TCK 0 // SWCLK/TCK +#define DAP_SWJ_SWDIO_TMS 1 // SWDIO/TMS +#define DAP_SWJ_TDI 2 // TDI +#define DAP_SWJ_TDO 3 // TDO +#define DAP_SWJ_nTRST 5 // nTRST +#define DAP_SWJ_nRESET 7 // nRESET + +// DAP Transfer Request +#define DAP_TRANSFER_APnDP (1U<<0) +#define DAP_TRANSFER_RnW (1U<<1) +#define DAP_TRANSFER_A2 (1U<<2) +#define DAP_TRANSFER_A3 (1U<<3) +#define DAP_TRANSFER_MATCH_VALUE (1U<<4) +#define DAP_TRANSFER_MATCH_MASK (1U<<5) +#define DAP_TRANSFER_TIMESTAMP (1U<<7) + +// DAP Transfer Response +#define DAP_TRANSFER_OK (1U<<0) +#define DAP_TRANSFER_WAIT (1U<<1) +#define DAP_TRANSFER_FAULT (1U<<2) +#define DAP_TRANSFER_ERROR (1U<<3) +#define DAP_TRANSFER_MISMATCH (1U<<4) + +// DAP SWO Trace Mode +#define DAP_SWO_OFF 0U +#define DAP_SWO_UART 1U +#define DAP_SWO_MANCHESTER 2U + +// DAP SWO Trace Status +#define DAP_SWO_CAPTURE_ACTIVE (1U<<0) +#define DAP_SWO_CAPTURE_PAUSED (1U<<1) +#define DAP_SWO_STREAM_ERROR (1U<<6) +#define DAP_SWO_BUFFER_OVERRUN (1U<<7) + + +// Debug Port Register Addresses +#define DP_IDCODE 0x00U // IDCODE Register (SW Read only) +#define DP_ABORT 0x00U // Abort Register (SW Write only) +#define DP_CTRL_STAT 0x04U // Control & Status +#define DP_WCR 0x04U // Wire Control Register (SW Only) +#define DP_SELECT 0x08U // Select Register (JTAG R/W & SW W) +#define DP_RESEND 0x08U // Resend (SW Read Only) +#define DP_RDBUFF 0x0CU // Read Buffer (Read Only) + +// JTAG IR Codes +#define JTAG_ABORT 0x08U +#define JTAG_DPACC 0x0AU +#define JTAG_APACC 0x0BU +#define JTAG_IDCODE 0x0EU +#define JTAG_BYPASS 0x0FU + +// JTAG Sequence Info +#define JTAG_SEQUENCE_TCK 0x3FU // TCK count +#define JTAG_SEQUENCE_TMS 0x40U // TMS value +#define JTAG_SEQUENCE_TDO 0x80U // TDO capture + +// SWD Sequence Info +#define SWD_SEQUENCE_CLK 0x3FU // SWCLK count +#define SWD_SEQUENCE_DIN 0x80U // SWDIO capture + + +#include +#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 +#if defined(__CC_ARM) +__STATIC_FORCEINLINE void PIN_DELAY_SLOW (uint32_t delay) { + uint32_t count = delay; + while (--count); +} +#else +__STATIC_FORCEINLINE void PIN_DELAY_SLOW (uint32_t delay) { + __ASM volatile ( + ".syntax unified\n" + "0:\n\t" + "subs %0,%0,#1\n\t" + "bne 0b\n" + : "+l" (delay) : : "cc" + ); +} +#endif + +// Fixed delay for fast clock generation +#ifndef DELAY_FAST_CYCLES +#define DELAY_FAST_CYCLES 0U // Number of cycles: 0..3 +#endif +__STATIC_FORCEINLINE void PIN_DELAY_FAST (void) { +#if (DELAY_FAST_CYCLES >= 1U) + __NOP(); +#endif +#if (DELAY_FAST_CYCLES >= 2U) + __NOP(); +#endif +#if (DELAY_FAST_CYCLES >= 3U) + __NOP(); +#endif +} + +#ifdef __cplusplus +} +#endif + + +#endif /* __DAP_H__ */ diff --git a/components/DAP/source/DAP.c b/components/DAP/source/DAP.c new file mode 100644 index 0000000..9e1f620 --- /dev/null +++ b/components/DAP/source/DAP.c @@ -0,0 +1,1769 @@ +/* + * 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 >= 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..1093bfb --- /dev/null +++ b/components/DAP/source/SWO.c @@ -0,0 +1,800 @@ +/* + * Copyright (c) 2013-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ---------------------------------------------------------------------- + * + * $Date: 1. December 2017 + * $Revision: V2.0.0 + * + * Project: CMSIS-DAP Source + * Title: SWO.c CMSIS-DAP SWO I/O + * + *---------------------------------------------------------------------------*/ + +#include "DAP_config.h" +#include "DAP.h" +#if (SWO_UART != 0) +#include "Driver_USART.h" +#endif +#if (SWO_STREAM != 0) +#include "cmsis_os2.h" +#endif + +#if (SWO_STREAM != 0) +#ifdef DAP_FW_V1 +#error "SWO Streaming Trace not supported in DAP V1!" +#endif +#endif + +#if (SWO_UART != 0) + +#ifndef USART_PORT +#define USART_PORT 0 /* USART Port Number */ +#endif + +// USART Driver +#define _USART_Driver_(n) Driver_USART##n +#define USART_Driver_(n) _USART_Driver_(n) +extern ARM_DRIVER_USART USART_Driver_(USART_PORT); +#define pUSART (&USART_Driver_(USART_PORT)) + +static uint8_t USART_Ready = 0U; + +#endif /* (SWO_UART != 0) */ + + +#if ((SWO_UART != 0) || (SWO_MANCHESTER != 0)) + + +#define SWO_STREAM_TIMEOUT 50U /* Stream timeout in ms */ + +#define USB_BLOCK_SIZE 512U /* USB Block Size */ +#define TRACE_BLOCK_SIZE 64U /* Trace Block Size (2^n: 32...512) */ + +// Trace State +static uint8_t TraceTransport = 0U; /* Trace Transport */ +static uint8_t TraceMode = 0U; /* Trace Mode */ +static uint8_t TraceStatus = 0U; /* Trace Status without Errors */ +static uint8_t TraceError[2] = {0U, 0U}; /* Trace Error flags (banked) */ +static uint8_t TraceError_n = 0U; /* Active Trace Error bank */ + +// Trace Buffer +static uint8_t TraceBuf[SWO_BUFFER_SIZE]; /* Trace Buffer (must be 2^n) */ +static volatile uint32_t TraceIndexI = 0U; /* Incoming Trace Index */ +static volatile uint32_t TraceIndexO = 0U; /* Outgoing Trace Index */ +static volatile uint8_t TraceUpdate; /* Trace Update Flag */ +static uint32_t TraceBlockSize; /* Current Trace Block Size */ + +#if (TIMESTAMP_CLOCK != 0U) +// Trace Timestamp +static volatile struct { + uint32_t index; + uint32_t tick; +} TraceTimestamp; +#endif + +// Trace Helper functions +static void ClearTrace (void); +static void ResumeTrace (void); +static uint32_t GetTraceCount (void); +static uint8_t GetTraceStatus (void); +static void SetTraceError (uint8_t flag); + +#if (SWO_STREAM != 0) +extern osThreadId_t SWO_ThreadId; +static volatile uint8_t TransferBusy = 0U; /* Transfer Busy Flag */ +static uint32_t TransferSize; /* Current Transfer Size */ +#endif + + +#if (SWO_UART != 0) + +// USART Driver Callback function +// event: event mask +static void USART_Callback (uint32_t event) { + uint32_t index_i; + uint32_t index_o; + uint32_t count; + uint32_t num; + + if (event & ARM_USART_EVENT_RECEIVE_COMPLETE) { +#if (TIMESTAMP_CLOCK != 0U) + TraceTimestamp.tick = TIMESTAMP_GET(); +#endif + index_o = TraceIndexO; + index_i = TraceIndexI; + index_i += TraceBlockSize; + TraceIndexI = index_i; +#if (TIMESTAMP_CLOCK != 0U) + TraceTimestamp.index = index_i; +#endif + num = TRACE_BLOCK_SIZE - (index_i & (TRACE_BLOCK_SIZE - 1U)); + count = index_i - index_o; + if (count <= (SWO_BUFFER_SIZE - num)) { + index_i &= SWO_BUFFER_SIZE - 1U; + TraceBlockSize = num; + pUSART->Receive(&TraceBuf[index_i], num); + } else { + TraceStatus = DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED; + } + TraceUpdate = 1U; +#if (SWO_STREAM != 0) + if (TraceTransport == 2U) { + if (count >= (USB_BLOCK_SIZE - (index_o & (USB_BLOCK_SIZE - 1U)))) { + osThreadFlagsSet(SWO_ThreadId, 1U); + } + } +#endif + } + if (event & ARM_USART_EVENT_RX_OVERFLOW) { + SetTraceError(DAP_SWO_BUFFER_OVERRUN); + } + if (event & (ARM_USART_EVENT_RX_BREAK | + ARM_USART_EVENT_RX_FRAMING_ERROR | + ARM_USART_EVENT_RX_PARITY_ERROR)) { + SetTraceError(DAP_SWO_STREAM_ERROR); + } +} + +// Enable or disable UART SWO Mode +// enable: enable flag +// return: 1 - Success, 0 - Error +__WEAK uint32_t UART_SWO_Mode (uint32_t enable) { + int32_t status; + + USART_Ready = 0U; + + if (enable != 0U) { + status = pUSART->Initialize(USART_Callback); + if (status != ARM_DRIVER_OK) { + return (0U); + } + status = pUSART->PowerControl(ARM_POWER_FULL); + if (status != ARM_DRIVER_OK) { + pUSART->Uninitialize(); + return (0U); + } + } else { + pUSART->Control(ARM_USART_CONTROL_RX, 0U); + pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U); + pUSART->PowerControl(ARM_POWER_OFF); + pUSART->Uninitialize(); + } + return (1U); +} + +// Configure UART SWO Baudrate +// baudrate: requested baudrate +// return: actual baudrate or 0 when not configured +__WEAK uint32_t UART_SWO_Baudrate (uint32_t baudrate) { + int32_t status; + uint32_t index; + uint32_t num; + + if (baudrate > SWO_UART_MAX_BAUDRATE) { + baudrate = SWO_UART_MAX_BAUDRATE; + } + + if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) { + pUSART->Control(ARM_USART_CONTROL_RX, 0U); + if (pUSART->GetStatus().rx_busy) { + TraceIndexI += pUSART->GetRxCount(); + pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U); + } + } + + status = pUSART->Control(ARM_USART_MODE_ASYNCHRONOUS | + ARM_USART_DATA_BITS_8 | + ARM_USART_PARITY_NONE | + ARM_USART_STOP_BITS_1, + baudrate); + + if (status == ARM_DRIVER_OK) { + USART_Ready = 1U; + } else { + USART_Ready = 0U; + return (0U); + } + + if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) { + if ((TraceStatus & DAP_SWO_CAPTURE_PAUSED) == 0U) { + index = TraceIndexI & (SWO_BUFFER_SIZE - 1U); + num = TRACE_BLOCK_SIZE - (index & (TRACE_BLOCK_SIZE - 1U)); + TraceBlockSize = num; + pUSART->Receive(&TraceBuf[index], num); + } + pUSART->Control(ARM_USART_CONTROL_RX, 1U); + } + + return (baudrate); +} + +// Control UART SWO Capture +// active: active flag +// return: 1 - Success, 0 - Error +__WEAK uint32_t UART_SWO_Control (uint32_t active) { + int32_t status; + + if (active) { + if (!USART_Ready) { + return (0U); + } + TraceBlockSize = 1U; + status = pUSART->Receive(&TraceBuf[0], 1U); + if (status != ARM_DRIVER_OK) { + return (0U); + } + status = pUSART->Control(ARM_USART_CONTROL_RX, 1U); + if (status != ARM_DRIVER_OK) { + return (0U); + } + } else { + pUSART->Control(ARM_USART_CONTROL_RX, 0U); + if (pUSART->GetStatus().rx_busy) { + TraceIndexI += pUSART->GetRxCount(); + pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U); + } + } + return (1U); +} + +// Start UART SWO Capture +// buf: pointer to buffer for capturing +// num: number of bytes to capture +__WEAK void UART_SWO_Capture (uint8_t *buf, uint32_t num) { + TraceBlockSize = num; + pUSART->Receive(buf, num); +} + +// Get UART SWO Pending Trace Count +// return: number of pending trace data bytes +__WEAK uint32_t UART_SWO_GetCount (void) { + uint32_t count; + + if (pUSART->GetStatus().rx_busy) { + count = pUSART->GetRxCount(); + } else { + count = 0U; + } + return (count); +} + +#endif /* (SWO_UART != 0) */ + + +#if (SWO_MANCHESTER != 0) + +// Enable or disable Manchester SWO Mode +// enable: enable flag +// return: 1 - Success, 0 - Error +__WEAK uint32_t Manchester_SWO_Mode (uint32_t enable) { + return (0U); +} + +// Configure Manchester SWO Baudrate +// baudrate: requested baudrate +// return: actual baudrate or 0 when not configured +__WEAK uint32_t Manchester_SWO_Baudrate (uint32_t baudrate) { + return (0U); +} + +// Control Manchester SWO Capture +// active: active flag +// return: 1 - Success, 0 - Error +__WEAK uint32_t Manchester_SWO_Control (uint32_t active) { + return (0U); +} + +// Start Manchester SWO Capture +// buf: pointer to buffer for capturing +// num: number of bytes to capture +__WEAK void Manchester_SWO_Capture (uint8_t *buf, uint32_t num) { +} + +// Get Manchester SWO Pending Trace Count +// return: number of pending trace data bytes +__WEAK uint32_t Manchester_SWO_GetCount (void) { +} + +#endif /* (SWO_MANCHESTER != 0) */ + + +// Clear Trace Errors and Data +static void ClearTrace (void) { + +#if (SWO_STREAM != 0) + if (TraceTransport == 2U) { + if (TransferBusy != 0U) { + SWO_AbortTransfer(); + TransferBusy = 0U; + } + } +#endif + + TraceError[0] = 0U; + TraceError[1] = 0U; + TraceError_n = 0U; + TraceIndexI = 0U; + TraceIndexO = 0U; + +#if (TIMESTAMP_CLOCK != 0U) + TraceTimestamp.index = 0U; + TraceTimestamp.tick = 0U; +#endif +} + +// Resume Trace Capture +static void ResumeTrace (void) { + uint32_t index_i; + uint32_t index_o; + + if (TraceStatus == (DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED)) { + index_i = TraceIndexI; + index_o = TraceIndexO; + if ((index_i - index_o) < SWO_BUFFER_SIZE) { + index_i &= SWO_BUFFER_SIZE - 1U; + switch (TraceMode) { +#if (SWO_UART != 0) + case DAP_SWO_UART: + TraceStatus = DAP_SWO_CAPTURE_ACTIVE; + UART_SWO_Capture(&TraceBuf[index_i], 1U); + break; +#endif +#if (SWO_MANCHESTER != 0) + case DAP_SWO_MANCHESTER: + TraceStatus = DAP_SWO_CAPTURE_ACTIVE; + Manchester_SWO_Capture(&TraceBuf[index_i], 1U); + break; +#endif + default: + break; + } + } + } +} + +// Get Trace Count +// return: number of available data bytes in trace buffer +static uint32_t GetTraceCount (void) { + uint32_t count; + + if (TraceStatus == DAP_SWO_CAPTURE_ACTIVE) { + do { + TraceUpdate = 0U; + count = TraceIndexI - TraceIndexO; + switch (TraceMode) { +#if (SWO_UART != 0) + case DAP_SWO_UART: + count += UART_SWO_GetCount(); + break; +#endif +#if (SWO_MANCHESTER != 0) + case DAP_SWO_MANCHESTER: + count += Manchester_SWO_GetCount(); + break; +#endif + default: + break; + } + } while (TraceUpdate != 0U); + } else { + count = TraceIndexI - TraceIndexO; + } + + return (count); +} + +// Get Trace Status (clear Error flags) +// return: Trace Status (Active flag and Error flags) +static uint8_t GetTraceStatus (void) { + uint8_t status; + uint32_t n; + + n = TraceError_n; + TraceError_n ^= 1U; + status = TraceStatus | TraceError[n]; + TraceError[n] = 0U; + + return (status); +} + +// Set Trace Error flag(s) +// flag: error flag(s) to set +static void SetTraceError (uint8_t flag) { + TraceError[TraceError_n] |= flag; +} + + +// Process SWO Transport command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t SWO_Transport (const uint8_t *request, uint8_t *response) { + uint8_t transport; + uint32_t result; + + if ((TraceStatus & DAP_SWO_CAPTURE_ACTIVE) == 0U) { + transport = *request; + switch (transport) { + case 0U: + case 1U: +#if (SWO_STREAM != 0) + case 2U: +#endif + TraceTransport = transport; + result = 1U; + break; + default: + result = 0U; + break; + } + } else { + result = 0U; + } + + if (result != 0U) { + *response = DAP_OK; + } else { + *response = DAP_ERROR; + } + + return ((1U << 16) | 1U); +} + + +// Process SWO Mode command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t SWO_Mode (const uint8_t *request, uint8_t *response) { + uint8_t mode; + uint32_t result; + + mode = *request; + + switch (TraceMode) { +#if (SWO_UART != 0) + case DAP_SWO_UART: + UART_SWO_Mode(0U); + break; +#endif +#if (SWO_MANCHESTER != 0) + case DAP_SWO_MANCHESTER: + Manchester_SWO_Mode(0U); + break; +#endif + default: + break; + } + + switch (mode) { + case DAP_SWO_OFF: + result = 1U; + break; +#if (SWO_UART != 0) + case DAP_SWO_UART: + result = UART_SWO_Mode(1U); + break; +#endif +#if (SWO_MANCHESTER != 0) + case DAP_SWO_MANCHESTER: + result = Manchester_SWO_Mode(1U); + break; +#endif + default: + result = 0U; + break; + } + if (result != 0U) { + TraceMode = mode; + } else { + TraceMode = DAP_SWO_OFF; + } + + TraceStatus = 0U; + + if (result != 0U) { + *response = DAP_OK; + } else { + *response = DAP_ERROR; + } + + return ((1U << 16) | 1U); +} + + +// Process SWO Baudrate command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t SWO_Baudrate (const uint8_t *request, uint8_t *response) { + uint32_t baudrate; + + baudrate = (uint32_t)(*(request+0) << 0) | + (uint32_t)(*(request+1) << 8) | + (uint32_t)(*(request+2) << 16) | + (uint32_t)(*(request+3) << 24); + + switch (TraceMode) { +#if (SWO_UART != 0) + case DAP_SWO_UART: + baudrate = UART_SWO_Baudrate(baudrate); + break; +#endif +#if (SWO_MANCHESTER != 0) + case DAP_SWO_MANCHESTER: + baudrate = Manchester_SWO_Baudrate(baudrate); + break; +#endif + default: + baudrate = 0U; + break; + } + + if (baudrate == 0U) { + TraceStatus = 0U; + } + + *response++ = (uint8_t)(baudrate >> 0); + *response++ = (uint8_t)(baudrate >> 8); + *response++ = (uint8_t)(baudrate >> 16); + *response = (uint8_t)(baudrate >> 24); + + return ((4U << 16) | 4U); +} + + +// Process SWO Control command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t SWO_Control (const uint8_t *request, uint8_t *response) { + uint8_t active; + uint32_t result; + + active = *request & DAP_SWO_CAPTURE_ACTIVE; + + if (active != (TraceStatus & DAP_SWO_CAPTURE_ACTIVE)) { + if (active) { + ClearTrace(); + } + switch (TraceMode) { +#if (SWO_UART != 0) + case DAP_SWO_UART: + result = UART_SWO_Control(active); + break; +#endif +#if (SWO_MANCHESTER != 0) + case DAP_SWO_MANCHESTER: + result = Manchester_SWO_Control(active); + break; +#endif + default: + result = 0U; + break; + } + if (result != 0U) { + TraceStatus = active; +#if (SWO_STREAM != 0) + if (TraceTransport == 2U) { + osThreadFlagsSet(SWO_ThreadId, 1U); + } +#endif + } + } else { + result = 1U; + } + + if (result != 0U) { + *response = DAP_OK; + } else { + *response = DAP_ERROR; + } + + return ((1U << 16) | 1U); +} + + +// Process SWO Status command and prepare response +// response: pointer to response data +// return: number of bytes in response +uint32_t SWO_Status (uint8_t *response) { + uint8_t status; + uint32_t count; + + status = GetTraceStatus(); + count = GetTraceCount(); + + *response++ = status; + *response++ = (uint8_t)(count >> 0); + *response++ = (uint8_t)(count >> 8); + *response++ = (uint8_t)(count >> 16); + *response = (uint8_t)(count >> 24); + + return (5U); +} + + +// Process SWO Extended Status command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t SWO_ExtendedStatus (const uint8_t *request, uint8_t *response) { + uint8_t cmd; + uint8_t status; + uint32_t count; +#if (TIMESTAMP_CLOCK != 0U) + uint32_t index; + uint32_t tick; +#endif + uint32_t num; + + num = 0U; + cmd = *request; + + if (cmd & 0x01U) { + status = GetTraceStatus(); + *response++ = status; + num += 1U; + } + + if (cmd & 0x02U) { + count = GetTraceCount(); + *response++ = (uint8_t)(count >> 0); + *response++ = (uint8_t)(count >> 8); + *response++ = (uint8_t)(count >> 16); + *response++ = (uint8_t)(count >> 24); + num += 4U; + } + +#if (TIMESTAMP_CLOCK != 0U) + if (cmd & 0x04U) { + do { + TraceUpdate = 0U; + index = TraceTimestamp.index; + tick = TraceTimestamp.tick; + } while (TraceUpdate != 0U); + *response++ = (uint8_t)(index >> 0); + *response++ = (uint8_t)(index >> 8); + *response++ = (uint8_t)(index >> 16); + *response++ = (uint8_t)(index >> 24); + *response++ = (uint8_t)(tick >> 0); + *response++ = (uint8_t)(tick >> 8); + *response++ = (uint8_t)(tick >> 16); + *response++ = (uint8_t)(tick >> 24); + num += 4U; + } +#endif + + return ((1U << 16) | num); +} + + +// Process SWO Data command and prepare response +// request: pointer to request data +// response: pointer to response data +// return: number of bytes in response (lower 16 bits) +// number of bytes in request (upper 16 bits) +uint32_t SWO_Data (const uint8_t *request, uint8_t *response) { + uint8_t status; + uint32_t count; + uint32_t index; + uint32_t n, i; + + status = GetTraceStatus(); + count = GetTraceCount(); + + if (TraceTransport == 1U) { + n = (uint32_t)(*(request+0) << 0) | + (uint32_t)(*(request+1) << 8); + if (n > (DAP_PACKET_SIZE - 4U)) { + n = DAP_PACKET_SIZE - 4U; + } + if (count > n) { + count = n; + } + } else { + count = 0U; + } + + *response++ = status; + *response++ = (uint8_t)(count >> 0); + *response++ = (uint8_t)(count >> 8); + + if (TraceTransport == 1U) { + index = TraceIndexO; + for (i = index, n = count; n; n--) { + i &= SWO_BUFFER_SIZE - 1U; + *response++ = TraceBuf[i++]; + } + TraceIndexO = index + count; + ResumeTrace(); + } + + return ((2U << 16) | (3U + count)); +} + + +#if (SWO_STREAM != 0) + +// SWO Data Transfer complete callback +void SWO_TransferComplete (void) { + TraceIndexO += TransferSize; + TransferBusy = 0U; + ResumeTrace(); + osThreadFlagsSet(SWO_ThreadId, 1U); +} + +// SWO Thread +__NO_RETURN void SWO_Thread (void *argument) { + uint32_t timeout; + uint32_t flags; + uint32_t count; + uint32_t index; + uint32_t i, n; + (void) argument; + + timeout = osWaitForever; + + for (;;) { + flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout); + if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) { + timeout = SWO_STREAM_TIMEOUT; + } else { + timeout = osWaitForever; + flags = osFlagsErrorTimeout; + } + if (TransferBusy == 0U) { + count = GetTraceCount(); + if (count != 0U) { + index = TraceIndexO & (SWO_BUFFER_SIZE - 1U); + n = SWO_BUFFER_SIZE - index; + if (count > n) { + count = n; + } + if (flags != osFlagsErrorTimeout) { + i = index & (USB_BLOCK_SIZE - 1U); + if (i == 0U) { + count &= ~(USB_BLOCK_SIZE - 1U); + } else { + n = USB_BLOCK_SIZE - i; + if (count >= n) { + count = n; + } else { + count = 0U; + } + } + } + if (count != 0U) { + TransferSize = count; + TransferBusy = 1U; + SWO_QueueTransfer(&TraceBuf[index], count); + } + } + } + } +} + +#endif /* (SWO_STREAM != 0) */ + + +#endif /* ((SWO_UART != 0) || (SWO_MANCHESTER != 0)) */ 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/README.md b/components/README.md new file mode 100644 index 0000000..474ac22 --- /dev/null +++ b/components/README.md @@ -0,0 +1,3 @@ +# TODO +1. adapt to special hardware +2. USB \ No newline at end of file diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 844a715..0671f1b 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,4 +1,4 @@ set(COMPONENT_SRCS "tcp_server.c") -set(COMPONENT_ADD_INCLUDEDIRS ".") +set(COMPONENT_ADD_INCLUDEDIRS ". $ENV{IDF_PATH}/components/esp8266/include/esp8266/") register_component() diff --git a/main/tcp_server.c b/main/tcp_server.c index 1930626..ad58f76 100644 --- a/main/tcp_server.c +++ b/main/tcp_server.c @@ -7,6 +7,7 @@ CONDITIONS OF ANY KIND, either express or implied. */ #include +#include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -22,6 +23,11 @@ #include "lwip/sys.h" #include +#include "gpio.h" +#include "hw_timer.h" +#include "timer_struct.h" + + /* The examples use simple WiFi configuration that you can set via 'make menuconfig'. If you'd rather not, just change the below entries to strings with @@ -108,6 +114,7 @@ static void initialise_wifi(void) ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); ESP_ERROR_CHECK(esp_wifi_start()); + } static void wait_for_ip() @@ -180,7 +187,7 @@ static void tcp_server_task(void *pvParameters) #else struct sockaddr_in sourceAddr; #endif - uint addrLen = sizeof(sourceAddr); + uint32_t addrLen = sizeof(sourceAddr); int sock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen); if (sock < 0) { @@ -248,11 +255,25 @@ static void tcp_server_task(void *pvParameters) vTaskDelete(NULL); } +void timer_create_task() +{ + // FRC1 frequency 80MHz + vPortEnterCritical(); + frc1.ctrl.div = TIMER_CLKDIV_16; // 80MHz / 16 = 5MHz + frc1.ctrl.intr_type = TIMER_EDGE_INT; + frc1.ctrl.reload = 0x01; + frc1.load.data = 0x1000000U - 1U; + frc1.ctrl.en = 0x01; + vPortExitCritical(); + vTaskDelete(NULL); +} + void app_main() { ESP_ERROR_CHECK(nvs_flash_init()); initialise_wifi(); wait_for_ip(); - + + xTaskCreate(timer_create_task, "timer_create", 2048, NULL, 10, NULL); xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 5, NULL); } From 2037ba6392f359d6f621f0c90befedca0779ae36 Mon Sep 17 00:00:00 2001 From: windowsair Date: Wed, 22 Jan 2020 10:29:15 +0800 Subject: [PATCH 02/15] fix: project name & main.c file --- CMakeLists.txt | 2 +- main/{tcp_server.c => main.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename main/{tcp_server.c => main.c} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3514e60..afc306e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,4 +3,4 @@ cmake_minimum_required(VERSION 3.5) include($ENV{IDF_PATH}/tools/cmake/project.cmake) -project(tcp_server) +project(esp8266_dap) diff --git a/main/tcp_server.c b/main/main.c similarity index 100% rename from main/tcp_server.c rename to main/main.c From a15f87374465c0600af9ebf04f18a8bc552f9186 Mon Sep 17 00:00:00 2001 From: windowsair Date: Wed, 22 Jan 2020 22:06:29 +0800 Subject: [PATCH 03/15] feat: Add USBIP component (partially completed) --- README.md | 5 + components/USBIP/usb_defs.h | 320 ++++++++++++++++++++++++++++++++++ components/USBIP/usbip_defs.h | 223 +++++++++++++++++++++++ main/CMakeLists.txt | 4 +- main/component.mk | 4 - main/main.c | 147 +--------------- main/tcp_server.c | 171 ++++++++++++++++++ main/tcp_server.h | 6 + main/timer.c | 29 +++ main/timer.h | 6 + main/usbip_server.c | 132 ++++++++++++++ main/usbip_server.h | 16 ++ main/wifi_configuration.h | 18 ++ 13 files changed, 932 insertions(+), 149 deletions(-) create mode 100644 components/USBIP/usb_defs.h create mode 100644 components/USBIP/usbip_defs.h delete mode 100644 main/component.mk create mode 100644 main/tcp_server.c create mode 100644 main/tcp_server.h create mode 100644 main/timer.c create mode 100644 main/timer.h create mode 100644 main/usbip_server.c create mode 100644 main/usbip_server.h create mode 100644 main/wifi_configuration.h diff --git a/README.md b/README.md index e69de29..e00d592 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,5 @@ +# Setup +1. DAP_Setup() +2. Server begin + +# Loop \ 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..d75f317 --- /dev/null +++ b/components/USBIP/usb_defs.h @@ -0,0 +1,320 @@ +/** + * @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 + + + + + + +union word_t { + struct { + uint8_t u8lo; + uint8_t u8hi; + } __attribute__((packed)); + uint16_t u16; +}; + +struct usb_standard_request +{ + uint8_t bmRequestType; + uint8_t bRequest; + word_t wValue; + word_t wIndex; + word_t wLength; +} __attribute__((packed)); + + + + + +//#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 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 +/* From ECNs */ +#define USB_DT_OTG 9 +#define USB_DT_DEBUG 10 +#define USB_DT_INTERFACE_ASSOCIATION 11 +/////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////// +/* 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 */ +struct usb_device_descriptor { + 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)); +#define USB_DT_DEVICE_SIZE sizeof(struct usb_device_descriptor) +/////////////////////////////////////////////////////////////// + + + +/////////////////////////////////////////////////////////////// +/* USB Device_Qualifier Descriptor - Table 9-9 + * Not used in this implementation. + */ +struct usb_device_qualifier_descriptor { + 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)); +/////////////////////////////////////////////////////////////// + + +/* 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! */ +struct usb_interface { + uint8_t *cur_altsetting; + uint8_t num_altsetting; + const struct usb_iface_assoc_descriptor *iface_assoc; + const struct usb_interface_descriptor *altsetting; +}; + + + +/////////////////////////////////////////////////////////////// +/* USB Standard Configuration Descriptor - Table 9-10 */ +struct usb_config_descriptor { + 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)); +#define USB_DT_CONFIGURATION_SIZE sizeof(struct 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 */ +struct usb_interface_descriptor { + 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)); +#define USB_DT_INTERFACE_SIZE sizeof(struct usb_interface_descriptor) +/////////////////////////////////////////////////////////////// + + + +/////////////////////////////////////////////////////////////// +/* USB Standard Endpoint Descriptor - Table 9-13 */ +struct usb_endpoint_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; +} __attribute__((packed)); +#define USB_DT_ENDPOINT_SIZE sizeof(struct 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. + */ +struct usb_string_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wData[]; +} __attribute__((packed)); + +/* From ECN: Interface Association Descriptors, Table 9-Z */ +struct usb_iface_assoc_descriptor { + 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)); +#define USB_DT_INTERFACE_ASSOCIATION_SIZE \ + sizeof(struct 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..943989a --- /dev/null +++ b/components/USBIP/usbip_defs.h @@ -0,0 +1,223 @@ +/** + * @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 { ////TODO: change to stage2 + //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, +}; + +struct usbip_stage1_header { + uint16_t version; + uint16_t command; + uint32_t status; +} __attribute__ ((__packed__)); +///////////////////////////////////////////////////////////// + + + +// Device description +struct usbip_stage1_usb_device { + 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)); + +// Interface description +struct usbip_stage1_usb_interface { + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t padding; +} __attribute__((packed)); + + + + +struct usbip_stage1_response_devlist_entry { + struct usbip_stage1_usb_device udev; + struct usbip_stage1_usb_interface uinf[]; +} __attribute__((packed)); + +struct usbip_stage1_response_devlist { + uint32_t list_size; + usbip_stage1_response_devlist_entry devices[]; +} __attribute__ ((__packed__)); + + + + + +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////// + + + +/** + * 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 + */ +struct usbip_stage2_header_basic { + uint32_t command; + uint32_t seqnum; + uint32_t devid; + uint32_t direction; + uint32_t ep; +} __attribute__((packed)); + +/** + * 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 + */ +struct usbip_stage2_header_cmd_submit { + 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)); + +/** + * struct usbip_header_ret_submit - USBIP_RET_SUBMIT packet header + * <<>>REQUEST + * @seqnum: the URB seqnum to unlink + */ +struct usbip_stage2_header_cmd_unlink { + uint32_t seqnum; +} __attribute__((packed)); + +/** + * struct usbip_header_ret_unlink - USBIP_RET_UNLINK packet header + * << -#include "gpio.h" -#include "hw_timer.h" -#include "timer_struct.h" - +#include "tcp_server.h" +#include "timer.h" +#include "wifi_configuration.h" /* The examples use simple WiFi configuration that you can set via 'make menuconfig'. If you'd rather not, just change the below entries to strings with the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" */ -#define EXAMPLE_WIFI_SSID "DAP" -#define EXAMPLE_WIFI_PASS "12345678" -#define PORT 22350 /* FreeRTOS event group to signal when we are connected & ready to make a request */ static EventGroupHandle_t wifi_event_group; @@ -46,7 +42,6 @@ const int IPV4_GOTIP_BIT = BIT0; const int IPV6_GOTIP_BIT = BIT1; #endif -static const char *TAG = "example"; static esp_err_t event_handler(void *ctx, system_event_t *event) { @@ -130,143 +125,9 @@ static void wait_for_ip() os_printf("Connected to AP"); } -static void tcp_server_task(void *pvParameters) -{ - char rx_buffer[2048]; - char addr_str[128]; - int addr_family; - int ip_protocol; - while (1) - { -#ifdef CONFIG_EXAMPLE_IPV4 - struct sockaddr_in destAddr; - destAddr.sin_addr.s_addr = htonl(INADDR_ANY); - destAddr.sin_family = AF_INET; - destAddr.sin_port = htons(PORT); - addr_family = AF_INET; - ip_protocol = IPPROTO_IP; - inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1); -#else // IPV6 - struct sockaddr_in6 destAddr; - bzero(&destAddr.sin6_addr.un, sizeof(destAddr.sin6_addr.un)); - destAddr.sin6_family = AF_INET6; - destAddr.sin6_port = htons(PORT); - addr_family = AF_INET6; - ip_protocol = IPPROTO_IPV6; - inet6_ntoa_r(destAddr.sin6_addr, addr_str, sizeof(addr_str) - 1); -#endif - int listen_sock = socket(addr_family, SOCK_STREAM, ip_protocol); - if (listen_sock < 0) - { - os_printf("Unable to create socket: errno %d\r\n", errno); - break; - } - os_printf("Socket created"); - - int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr)); - if (err != 0) - { - os_printf("Socket unable to bind: errno %d\r\n", errno); - break; - } - os_printf("Socket binded"); - - err = listen(listen_sock, 1); - if (err != 0) - { - os_printf("Error occured during listen: errno %d\r\n", errno); - break; - } - os_printf("Socket listening"); - -#ifdef CONFIG_EXAMPLE_IPV6 - struct sockaddr_in6 sourceAddr; // Large enough for both IPv4 or IPv6 -#else - struct sockaddr_in sourceAddr; -#endif - uint32_t 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"); - - while (1) - { - int len = recv(sock, rx_buffer, 2047, 0); - // Error occured during receiving - if (len < 0) - { - 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 - - 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) - { - os_printf("Error occured during sending: errno %d\r\n", errno); - break; - } - } - } - - 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); - } - } - vTaskDelete(NULL); -} - -void timer_create_task() -{ - // FRC1 frequency 80MHz - vPortEnterCritical(); - frc1.ctrl.div = TIMER_CLKDIV_16; // 80MHz / 16 = 5MHz - frc1.ctrl.intr_type = TIMER_EDGE_INT; - frc1.ctrl.reload = 0x01; - frc1.load.data = 0x1000000U - 1U; - frc1.ctrl.en = 0x01; - vPortExitCritical(); - vTaskDelete(NULL); -} void app_main() { @@ -274,6 +135,6 @@ void app_main() initialise_wifi(); wait_for_ip(); - xTaskCreate(timer_create_task, "timer_create", 2048, NULL, 10, NULL); + xTaskCreate(timer_create_task, "timer_create", 1024, NULL, 10, NULL); xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 5, NULL); } diff --git a/main/tcp_server.c b/main/tcp_server.c new file mode 100644 index 0000000..f28213b --- /dev/null +++ b/main/tcp_server.c @@ -0,0 +1,171 @@ +/** + * @file tcp_server.c + * @brief Handle main tcp tasks + * @version 0.1 + * @date 2020-01-22 + * + * @copyright Copyright (c) 2020 + * + */ +#include "tcp_server.h" + +#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 "wifi_configuration.h" +#include "usbip_server.h" + +uint8_t state = ACCEPTING; +int sock = -1; +void tcp_server_task(void *pvParameters) +{ + char rx_buffer[2048]; + char addr_str[128]; + int addr_family; + int ip_protocol; + + while (1) + { + +#ifdef CONFIG_EXAMPLE_IPV4 + struct sockaddr_in destAddr; + destAddr.sin_addr.s_addr = htonl(INADDR_ANY); + destAddr.sin_family = AF_INET; + destAddr.sin_port = htons(PORT); + addr_family = AF_INET; + ip_protocol = IPPROTO_IP; + inet_ntoa_r(destAddr.sin_addr, addr_str, sizeof(addr_str) - 1); +#else // IPV6 + struct sockaddr_in6 destAddr; + bzero(&destAddr.sin6_addr.un, sizeof(destAddr.sin6_addr.un)); + destAddr.sin6_family = AF_INET6; + destAddr.sin6_port = htons(PORT); + addr_family = AF_INET6; + ip_protocol = IPPROTO_IPV6; + inet6_ntoa_r(destAddr.sin6_addr, addr_str, sizeof(addr_str) - 1); +#endif + + int listen_sock = socket(addr_family, SOCK_STREAM, ip_protocol); + if (listen_sock < 0) + { + os_printf("Unable to create socket: errno %d\r\n", errno); + break; + } + os_printf("Socket created"); + + int err = bind(listen_sock, (struct sockaddr *)&destAddr, sizeof(destAddr)); + if (err != 0) + { + os_printf("Socket unable to bind: errno %d\r\n", errno); + break; + } + os_printf("Socket binded"); + + err = listen(listen_sock, 1); + if (err != 0) + { + os_printf("Error occured during listen: errno %d\r\n", errno); + break; + } + os_printf("Socket listening"); + +#ifdef CONFIG_EXAMPLE_IPV6 + struct sockaddr_in6 sourceAddr; // Large enough for both IPv4 or IPv6 +#else + struct sockaddr_in sourceAddr; +#endif + uint32_t addrLen = sizeof(sourceAddr); + 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"); + + while (1) + { + int len = recv(sock, rx_buffer, 2047, 0); + // Error occured during receiving + if (len < 0) + { + 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 + + 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); + switch (state) + { + case ACCEPTING: + state = ATTACHING; + break; + + case ATTACHING: + attach(rx_buffer, len); + break; + + case EMULATING: + emulate(rx_buffer, len); + break; + } + + // int err = send(sock, rx_buffer, len, 0); + // if (err < 0) + // { + // os_printf("Error occured during sending: errno %d\r\n", errno); + // break; + // } + } + } + state = 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); + } + } + vTaskDelete(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..18be76f --- /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 = 0x1000000U - 1U; + 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..56b3b06 --- /dev/null +++ b/main/usbip_server.c @@ -0,0 +1,132 @@ +#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" + +static int read_stage1_command(uint8_t *buffer, uint32_t length); +static int handle_device_list(uint8_t *buffer, uint32_t length); +static int 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(); + + + +int attach(uint8_t *buffer, uint32_t length) +{ + uint32_t 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("s1 unknown command: %d\r\n", command); + break; + } +} + +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 int 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 int handle_device_attach(uint8_t *buffer, uint32_t length) +{ + int +} + +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); // 273??? + header.command = htons(command); + header.status = htonl(status); + + send(socket, (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(socket, (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(); + } +} + +void send_device_info() +{ + //// TODO:fill this + os_printf("Sending device info..."); + 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(2); + device.speed = htonl(2); // what is this??? + //// TODO: 0200H for USB2.0 + + //// TODO: fill Vendor Product Device-version + device.idVendor = htons(USB_DEVICE_VENDOR_ID); + device.idProduct = htons(USB_DEVICE_PRODUCT_ID); + device.bcdDevice = htons(USB_DEVICE_VERSION); + + device.bDeviceClass = 0x00; // + device.bDeviceSubClass = 0x00; + device.bDeviceProtocol = 0x00; + + device.bConfigurationValue = 1; + device.bNumConfigurations = 1; + device.bNumInterfaces = 1; + + write(&device, sizeof(usbip_stage1_usb_device)); +} + +int emulate(uint8_t *buffer, uint32_t length) +{ +} \ No newline at end of file diff --git a/main/usbip_server.h b/main/usbip_server.h new file mode 100644 index 0000000..e1c05f3 --- /dev/null +++ b/main/usbip_server.h @@ -0,0 +1,16 @@ +#ifndef __USBIP_SERVER_H__ +#define __USBIP_SERVER_H__ +#include +enum state_t +{ + ACCEPTING, + ATTACHING, + EMULATING +}; +extern uint32_t state; +extern int socket; + +int attach(uint8_t *buffer, uint32_t length); +int emulate(uint8_t *buffer, uint32_t 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..cb2701c --- /dev/null +++ b/main/wifi_configuration.h @@ -0,0 +1,18 @@ +/** + * @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 EXAMPLE_WIFI_SSID "DAP" +#define EXAMPLE_WIFI_PASS "12345678" + +#define PORT 22350 + +#endif \ No newline at end of file From a6a5e6ec0cb2e0833b3de101648702a8b36aef90 Mon Sep 17 00:00:00 2001 From: windowsair Date: Thu, 23 Jan 2020 21:55:51 +0800 Subject: [PATCH 04/15] feat: USBIP & Standard USB Descriptor Definitions 1. Add Standard USB Descriptor Definitions 2. USBIP stage1 completed --- components/README.md | 3 +- components/USBIP/USB_handle.c | 221 +++++++++++++++++++++++++++++++ components/USBIP/USB_handle.h | 5 + components/USBIP/USBd_config.c | 220 +++++++++++++++++++++++++++++++ components/USBIP/USBd_config.h | 41 ++++++ components/USBIP/usb_defs.h | 6 +- components/USBIP/usbip_defs.h | 2 +- main/main.c | 2 +- main/tcp_server.c | 14 +- main/usbip_server.c | 229 ++++++++++++++++++++++++++++++--- main/usbip_server.h | 2 +- 11 files changed, 713 insertions(+), 32 deletions(-) create mode 100644 components/USBIP/USB_handle.c create mode 100644 components/USBIP/USB_handle.h create mode 100644 components/USBIP/USBd_config.c create mode 100644 components/USBIP/USBd_config.h diff --git a/components/README.md b/components/README.md index 474ac22..e52e5e9 100644 --- a/components/README.md +++ b/components/README.md @@ -1,3 +1,4 @@ # TODO 1. adapt to special hardware -2. USB \ No newline at end of file +2. USB +3. Significant Bit is difficult to judge, may need to dive into the details of usbip \ 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..8b0cd44 --- /dev/null +++ b/components/USBIP/USB_handle.c @@ -0,0 +1,221 @@ +/** + * @file USB_handle.c + * @brief Handle all Standard Device Requests + * @version 0.1 + * @date 2020-01-23 + * + * @copyright Copyright (c) 2020 + * + */ +#include +#include "USB_handle.h" + +// handle functions +static void handleGetDescriptor(usbip_stage2_header *header); +static void handle_get_device_descriptor(usbip_stage2_header *header); + +////TODO: fill this +int handleUSBControlRequest(usbip_stage2_header *header) +{ + // Table 9-3. Standard Device Requests + + switch (header->u.cmd_submit.request.bmRequestType) + { + case 0x00: + switch (header->u.cmd_submit.request.bRequest) + { + case USB_REQ_CLEAR_FEATURE: + /* code */ + break; + case USB_REQ_SET_FEATURE: + /* code */ + break; + case USB_REQ_SET_ADDRESS: + /* code */ + break; + case USB_REQ_SET_DESCRIPTOR: + /* code */ + break; + case USB_REQ_SET_CONFIGURATION: + /* code */ + 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: + switch (header->u.cmd_submit.request.bRequest) + { + case USB_REQ_CLEAR_FEATURE: + /* code */ + break; + case USB_REQ_SET_FEATURE: + /* code */ + break; + case USB_REQ_SET_INTERFACE: + /* code */ + 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: + switch (header->u.cmd_submit.request.bRequest) + { + case USB_REQ_CLEAR_FEATURE: + /* code */ + break; + case USB_REQ_SET_FEATURE: + /* code */ + 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: + switch (header->u.cmd_submit.request.bRequest) + { + case USB_REQ_GET_CONFIGURATION: + handleGetDescriptor(header); + break; + case USB_REQ_GET_DESCRIPTOR: + /* code */ + break; + case USB_REQ_GET_STATUS: + /* code */ + 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 0x81: + switch (header->u.cmd_submit.request.bRequest) + { + case USB_REQ_GET_INTERFACE: + /* code */ + break; + case USB_REQ_SET_SYNCH_FRAME: + /* code */ + break; + case USB_REQ_GET_STATUS: + /* code */ + 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 0x82: + switch (header->u.cmd_submit.request.bRequest) + { + case USB_REQ_GET_STATUS: + /* code */ + 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; + } +} + +////TODO: fill this +static void handleGetDescriptor(usbip_stage2_header *header) +{ + // 9.4.3 Get Descriptor + switch (header->u.cmd_submit.request.wValue.u8hi) + { + case USB_DT_DEVICE: + handleGetDeviceDescriptor(header); + break; + + case USB_DT_CONFIGURATION: + handleGetConfigurationDescriptor(header); + break; + + case USB_DT_STRING: + handleGetStringDescriptor(header); + break; + + case USB_DT_INTERFACE: + handleGetInterfaceDescriptor(header); + break; + + case USB_DT_ENDPOINT: + handleGetEndpointDescriptor(header); + break; + + case USB_DT_DEVICE_QUALIFIER: + handleGetDeviceQualifierDescriptor(header); + break; + + case USB_DT_OTHER_SPEED_CONFIGURATION: + os_printf("GET 0x07 [UNIMPLEMENTED] USB_DT_OTHER_SPEED_CONFIGURATION"); + break; + + case USB_DT_INTERFACE_POWER: + os_printf("GET 0x08 [UNIMPLEMENTED] USB_DT_INTERFACE_POWER"); + break; + + case USB_DT_REPORT: + handle_get_hid_report_descriptor(header); + break; + + default: + os_printf("USB unknown Get Descriptor requested:%d", header->u.cmd_submit.request.wValue.u8lo); + break; + } +} + +static void handle_get_device_descriptor(usbip_stage2_header *header) +{ + os_printf("* GET 0x01 DEVICE DESCRIPTOR\r\n"); + + usb_device_descriptor desc; + + desc.bLength = USB_DT_DEVICE_SIZE; + desc.bDescriptorType = USB_DT_DEVICE; + + desc.bcdUSB = 0x0110; + + // defined at interface level + desc.bDeviceClass = 0x0; + desc.bDeviceSubClass = 0x0; + desc.bDeviceProtocol = 0x0; + + desc.bMaxPacketSize0 = USB_HID_MAX_PACKET_SIZE; + + desc.idVendor = USB_DEVICE_VENDOR_ID; + desc.idProduct = USB_DEVICE_PRODUCT_ID; + desc.bcdDevice = USB_DEVICE_VERSION; + + desc.iManufacturer = STR_IMANUFACTURER; + desc.iProduct = STR_IPRODUCT; + desc.iSerialNumber = STR_ISERIAL; + + desc.bNumConfigurations = 1; + + send_stage2_submit_data(header, 0, &desc, sizeof(usb_device_descriptor)); +} \ No newline at end of file diff --git a/components/USBIP/USB_handle.h b/components/USBIP/USB_handle.h new file mode 100644 index 0000000..d23789d --- /dev/null +++ b/components/USBIP/USB_handle.h @@ -0,0 +1,5 @@ +#ifndef __USB_HANDLE_H__ +#define __USB_HANDLE_H__ +#include "usbip_defs.h" +int 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..c857de3 --- /dev/null +++ b/components/USBIP/USBd_config.c @@ -0,0 +1,220 @@ + ////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" +#include "USBd_config_CustomClass_0.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 (constant) + USBShort(0x0200), // bcdUSB (2.00) + + // We need to use a device other than the USB-IF standard, set to 0x00 + 0x00, // bDeviceClass + 0x00, // bDeviceSubClass + 0x00, // bDeviceProtocol + + USBD0_MAX_PACKET0, // Maximum packet size for default pipe. + USBShort(USBD0_DEV_DESC_IDVENDOR), // Vendor ID (VID). + USBShort(USBD0_DEV_DESC_IDPRODUCT), // Product ID (PID). + USBShort(USBD0_DEV_DESC_BCDDEVICE), // Device Version BCD. + 0x01, // Index of Manufacturer string identifier. + 0x02, // Index of Product string identifier. + 0x03 * USBD0_STR_DESC_SER_EN, // Index of Product serial number. + 0x01 // Number of configurations. +}; + + + + +/** + * @brief step 2. Buid Standard Configuration Descriptor + * + */ + + +// Standard Interface Descriptor +const uint8_t kUSBd0InterfaceDescriptor[]= +{ + 0x09, // bLength + USB_DT_INTERFACE, // bDescriptorType + USBD_CUSTOM_CLASS0_IF0_NUM, // bInterfaceNumber + USBD_CUSTOM_CLASS0_IF0_ALT, // bAlternateSetting + 0x03, // bNumEndpoints(we will use three 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 + + 0x07, // bLength + USB_DTYPE_ENDPOINT, // bDescriptorType + USBD_CUSTOM_CLASS0_IF0_EP0_BENDPOINTADDRESS, // bEndpointAddress -> set 0x01 for endpoint 0 + USB_EP_ATTR_BULK, // bmAttributes -> Endpoint is a bulk endpoint. + USBShort(USBD_CUSTOM_CLASS0_IF0_EP0_HS_WMAXPACKETSIZE), + // wMaxPacketSize -> The maximum packet size: 512 bytes + // We assume that it always runs in High Speed. + USBD_CUSTOM_CLASS0_IF0_EP0_HS_BINTERVAL, // bInterval + + + // 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_DTYPE_ENDPOINT, // bDescriptorType + 0x01, // bEndpointAddress + USB_ENDPOINT_ATTR_BULK, // bmAttributes + USBShort(USBD_CUSTOM_CLASS0_IF0_EP1_HS_WMAXPACKETSIZE), // wMaxPacketSize + USBD_CUSTOM_CLASS0_IF0_EP1_HS_BINTERVAL, // bInterval + + /* Pysical endpoint 1 */ + + // "Endpoint 2: Bulk In – used for responses send to host PC." Device -> PC + 0x07, // bLength + USB_DTYPE_ENDPOINT, // bDescriptorType + 0x81, // bEndpointAddress + USB_ENDPOINT_ATTR_BULK, // bmAttributes + USBShort(USBD_CUSTOM_CLASS0_IF0_EP2_HS_WMAXPACKETSIZE), // wMaxPacketSize + USBD_CUSTOM_CLASS0_IF0_EP2_HS_BINTERVAL, // bInterval + + /* Pysical endpoint 2 */ + // "Endpoint 3: Bulk In (optional) – used for streaming SWO trace" Device -> PC + 0x07, // bLength + USB_DTYPE_ENDPOINT, // bDescriptorType + 0x82, // bEndpointAddress + USB_ENDPOINT_ATTR_BULK, // bmAttributes + USBShort(USBD_CUSTOM_CLASS0_IF0_EP3_HS_WMAXPACKETSIZE), // wMaxPacketSize + USBD_CUSTOM_CLASS0_IF0_EP3_HS_BINTERVAL, // bInterval + + +}; + +// Standard Configuration Descriptor +const uint8_t kUSBd0ConfigDescriptor[] = +{ + // Configuration descriptor header. + + 0x09, // bLength -> 0x09?? may be ok... 1-23 + 0x03, // bDescriptorType + // constant, set to 0x03 + + USBShort((sizeof(kUSBd0InterfaceDescriptor)) + (sizeof(kUSBd0ConfigDescriptor))), + // 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 +}; + + + +/** + * @brief step 3. Build String Descriptor + * + */ + + +const uint8_t kLangDescriptor[] = +{ + 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[] = +{ + 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..88e213a --- /dev/null +++ b/components/USBIP/USBd_config.h @@ -0,0 +1,41 @@ +#ifndef __USBD_CONFIG_H__ +#define __USBD_CONFIG_H__ + +// 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 +#define USBD_CUSTOM_CLASS0_IF0_CLASS 0xFF // 0xFF: Vendor Specific + +// Subclass Code +#define USBD_CUSTOM_CLASS0_IF0_SUBCLASS 0x00 + +// Protocol Code +#define USBD_CUSTOM_CLASS0_IF0_PROTOCOL 0x00 + + + +#endif \ No newline at end of file diff --git a/components/USBIP/usb_defs.h b/components/USBIP/usb_defs.h index d75f317..995a97e 100644 --- a/components/USBIP/usb_defs.h +++ b/components/USBIP/usb_defs.h @@ -23,10 +23,6 @@ #define USB_MISC_PROTOCOL_INTERFACE_ASSOCIATION_DESCRIPTOR 0x01 - - - - union word_t { struct { uint8_t u8lo; @@ -39,7 +35,7 @@ struct usb_standard_request { uint8_t bmRequestType; uint8_t bRequest; - word_t wValue; + word_t wValue; // 16bit word_t wIndex; word_t wLength; } __attribute__((packed)); diff --git a/components/USBIP/usbip_defs.h b/components/USBIP/usbip_defs.h index 943989a..eb3935c 100644 --- a/components/USBIP/usbip_defs.h +++ b/components/USBIP/usbip_defs.h @@ -165,7 +165,7 @@ struct usbip_stage2_header_cmd_submit { */ struct usbip_stage2_header_ret_submit { int32_t status; - int32_t data_length; + int32_t data_length;//actual_length int32_t start_frame; int32_t number_of_packets; int32_t error_count; diff --git a/main/main.c b/main/main.c index ea82251..03f5354 100644 --- a/main/main.c +++ b/main/main.c @@ -122,7 +122,7 @@ static void wait_for_ip() os_printf("Waiting for AP connection...\r\n"); xEventGroupWaitBits(wifi_event_group, bits, false, true, portMAX_DELAY); - os_printf("Connected to AP"); + os_printf("Connected to AP\r\n"); } diff --git a/main/tcp_server.c b/main/tcp_server.c index f28213b..7e6f870 100644 --- a/main/tcp_server.c +++ b/main/tcp_server.c @@ -30,7 +30,7 @@ #include "usbip_server.h" uint8_t state = ACCEPTING; -int sock = -1; +int kSock = -1; void tcp_server_task(void *pvParameters) { char rx_buffer[2048]; @@ -89,8 +89,8 @@ void tcp_server_task(void *pvParameters) struct sockaddr_in sourceAddr; #endif uint32_t addrLen = sizeof(sourceAddr); - sock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen); - if (sock < 0) + kSock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen); + if (kSock < 0) { os_printf("Unable to accept connection: errno %d\r\n", errno); break; @@ -99,7 +99,7 @@ void tcp_server_task(void *pvParameters) while (1) { - int len = recv(sock, rx_buffer, 2047, 0); + int len = recv(kSock, rx_buffer, 2047, 0); // Error occured during receiving if (len < 0) { @@ -156,11 +156,11 @@ void tcp_server_task(void *pvParameters) } } state = ACCEPTING; - if (sock != -1) + if (kSock != -1) { os_printf("Shutting down socket and restarting...\r\n"); - shutdown(sock, 0); - close(sock); + shutdown(kSock, 0); + close(kSock); shutdown(listen_sock, 0); close(listen_sock); diff --git a/main/usbip_server.c b/main/usbip_server.c index 56b3b06..38faf78 100644 --- a/main/usbip_server.c +++ b/main/usbip_server.c @@ -8,18 +8,25 @@ #include "usbip_defs.h" #include "usb_defs.h" +// attach helper function static int read_stage1_command(uint8_t *buffer, uint32_t length); static int handle_device_list(uint8_t *buffer, uint32_t length); static int 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); +static int handle_control_request(usbip_stage2_header *header); +static void send_stage2_submit(usbip_stage2_header *req_header, int32_t status, int32_t data_length); int attach(uint8_t *buffer, uint32_t length) { - uint32_t command = read_stage1_command(buffer, length); + int command = read_stage1_command(buffer, length); if (command < 0) { return -1; @@ -31,12 +38,12 @@ int attach(uint8_t *buffer, uint32_t length) handle_device_list(buffer, length); break; - case USBIP_STAGE1_CMD_DEVICE_ATTACH: // OP_REQ_IMPORT - handle_device_attach(buffer, length); + case USBIP_STAGE1_CMD_DEVICE_ATTACH: // OP_REQ_IMPORT + handle_device_attach(buffer, length); ////TODO: fill this break; default: - os_printf("s1 unknown command: %d\r\n", command); + os_printf("attach Unknown command: %d\r\n", command); break; } } @@ -48,7 +55,7 @@ static int read_stage1_command(uint8_t *buffer, uint32_t length) return -1; } usbip_stage1_header *req = (usbip_stage1_header *)buffer; - return ntohs(req->command) & 0xFF; // 0x80xx low bit + return (ntohs(req->command) & 0xFF); // 0x80xx low bit } static int handle_device_list(uint8_t *buffer, uint32_t length) @@ -60,18 +67,33 @@ static int handle_device_list(uint8_t *buffer, uint32_t length) static int handle_device_attach(uint8_t *buffer, uint32_t length) { - int + os_printf("Handling dev attach request...\r\n"); + + //char bus[USBIP_BUSID_SIZE]; + if (length < sizeof(USBIP_BUSID_SIZE)) + { + return -1; + } + //client.readBytes((uint8_t *)bus, USBIP_BUSID_SIZE); + + send_stage1_header(USBIP_STAGE1_CMD_DEVICE_ATTACH, 0); + + send_device_info(); + + state = 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); // 273??? + 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(socket, (uint8_t *)&header, sizeof(usbip_stage1_header), 0); + send(kSock, (uint8_t *)&header, sizeof(usbip_stage1_header), 0); } static void send_device_list() @@ -97,7 +119,7 @@ static void send_device_list() } } -void send_device_info() +static void send_device_info() { //// TODO:fill this os_printf("Sending device info..."); @@ -111,12 +133,11 @@ void send_device_info() device.speed = htonl(2); // what is this??? //// TODO: 0200H for USB2.0 - //// TODO: fill Vendor Product Device-version - device.idVendor = htons(USB_DEVICE_VENDOR_ID); - device.idProduct = htons(USB_DEVICE_PRODUCT_ID); - device.bcdDevice = htons(USB_DEVICE_VERSION); + device.idVendor = htons(USBD0_DEV_DESC_IDVENDOR); + device.idProduct = htons(USBD0_DEV_DESC_IDPRODUCT); + device.bcdDevice = htons(USBD0_DEV_DESC_BCDDEVICE); - device.bDeviceClass = 0x00; // + device.bDeviceClass = 0x00; // We need to use a device other than the USB-IF standard, set to 0x00 device.bDeviceSubClass = 0x00; device.bDeviceProtocol = 0x00; @@ -124,9 +145,185 @@ void send_device_info() device.bNumConfigurations = 1; device.bNumInterfaces = 1; - write(&device, sizeof(usbip_stage1_usb_device)); + 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; + int command = read_stage2_command((usbip_stage2_header *)buffer); ////TODO: fill this + if (command < 0) + { + return -1; + } + + switch (command) + { + case USBIP_STAGE2_REQ_SUBMIT: + handle_submit((usbip_stage2_header *)buffer); + break; + + case USBIP_STAGE2_REQ_UNLINK: + handle_unlink((usbip_stage2_header *)buffer); + break; + + default: + os_printf("emulate unknown command:%d\r\n", command); + return -1; + } + return 0; +} + +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 size = (size / sizeof(uint32_t)) - 2; + uint32_t *ptr = (uint32_t *)data; + + for (int i = 0; i < size; 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 size = (size / sizeof(uint32_t)) - 2; + uint32_t *ptr = (uint32_t *)data; + + for (int i = 0; i < size; i++) + { + ptr[i] = ntohl(ptr[i]); + } +} + +////TODO: fill this +/** + * @brief + * + */ +static int handle_submit(usbip_stage2_header *header) +{ + switch (header->base.ep) + { + // control endpoint(endpoint 0) + case 0x00: + handle_control_request(header); + break; + + // data + case 0x01: + if (header->base.direction == 0) + { + // Serial.println("EP 01 DATA FROM HOST"); + handle_data_request(header); + } + else + { + // Serial.println("EP 01 DATA TO HOST"); + handle_data_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: "); + os_printf((int)header.base.ep); + return -1; + } + return 0; +} + +static 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, void *data, int32_t data_length) +{ + + send_stage2_submit(req_header, status, data_length); + + if (data_length) + { + send(kSock, data, data_length, 0); + } } \ No newline at end of file diff --git a/main/usbip_server.h b/main/usbip_server.h index e1c05f3..c085c28 100644 --- a/main/usbip_server.h +++ b/main/usbip_server.h @@ -8,7 +8,7 @@ enum state_t EMULATING }; extern uint32_t state; -extern int socket; +extern int kSock; int attach(uint8_t *buffer, uint32_t length); int emulate(uint8_t *buffer, uint32_t length); From 957cc01656335450f46b72f3b7ad2d3263ce4885 Mon Sep 17 00:00:00 2001 From: windowsair Date: Fri, 24 Jan 2020 16:41:15 +0800 Subject: [PATCH 05/15] fix: C-style structure definition & other details improvements --- components/USBIP/USB_handle.c | 106 +++++++++------- components/USBIP/USBd_config.c | 47 +++----- components/USBIP/USBd_config.h | 13 ++ components/USBIP/usb_defs.h | 214 +++++++++++++++------------------ components/USBIP/usbip_defs.h | 117 ++++++++---------- main/usbip_server.c | 8 +- main/usbip_server.h | 3 + 7 files changed, 248 insertions(+), 260 deletions(-) diff --git a/components/USBIP/USB_handle.c b/components/USBIP/USB_handle.c index 8b0cd44..56207a2 100644 --- a/components/USBIP/USB_handle.c +++ b/components/USBIP/USB_handle.c @@ -8,14 +8,21 @@ * */ #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" + // handle functions -static void handleGetDescriptor(usbip_stage2_header *header); -static void handle_get_device_descriptor(usbip_stage2_header *header); +static void handleGetDescriptor(struct usbip_stage2_header *header); ////TODO: fill this -int handleUSBControlRequest(usbip_stage2_header *header) +int handleUSBControlRequest(struct usbip_stage2_header *header) { // Table 9-3. Standard Device Requests @@ -142,80 +149,87 @@ int handleUSBControlRequest(usbip_stage2_header *header) } ////TODO: fill this -static void handleGetDescriptor(usbip_stage2_header *header) +static void handleGetDescriptor(struct usbip_stage2_header *header) { // 9.4.3 Get Descriptor switch (header->u.cmd_submit.request.wValue.u8hi) { - case USB_DT_DEVICE: - handleGetDeviceDescriptor(header); + case USB_DT_DEVICE: // get device descriptor + os_printf("* GET 0x01 DEVICE DESCRIPTOR\r\n"); + send_stage2_submit_data(header, 0, kUSBd0DeviceDescriptor, sizeof(kUSBd0DeviceDescriptor)); break; - case USB_DT_CONFIGURATION: - handleGetConfigurationDescriptor(header); + 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: - handleGetStringDescriptor(header); + 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{ + os_printf("***Unsupported operation***\r\n"); + } break; case USB_DT_INTERFACE: - handleGetInterfaceDescriptor(header); + os_printf("* GET 0x04 INTERFACE DESCRIPTOR (UNIMPLEMENTED)\r\n"); + ////TODO:UNIMPLEMENTED + send_stage2_submit(header, 0, 0); break; case USB_DT_ENDPOINT: - handleGetEndpointDescriptor(header); + os_printf("* GET 0x05 ENDPOINT DESCRIPTOR (UNIMPLEMENTED)\r\n"); + ////TODO:UNIMPLEMENTED + send_stage2_submit(header, 0, 0); break; case USB_DT_DEVICE_QUALIFIER: - handleGetDeviceQualifierDescriptor(header); + os_printf("* GET 0x06 DEVICE QUALIFIER DESCRIPTOR"); + + 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"); + ////TODO:UNIMPLEMENTED + send_stage2_submit(header, 0, 0); break; case USB_DT_INTERFACE_POWER: os_printf("GET 0x08 [UNIMPLEMENTED] USB_DT_INTERFACE_POWER"); + ////TODO:UNIMPLEMENTED + send_stage2_submit(header, 0, 0); break; - case USB_DT_REPORT: - handle_get_hid_report_descriptor(header); - break; default: os_printf("USB unknown Get Descriptor requested:%d", header->u.cmd_submit.request.wValue.u8lo); break; } } - -static void handle_get_device_descriptor(usbip_stage2_header *header) -{ - os_printf("* GET 0x01 DEVICE DESCRIPTOR\r\n"); - - usb_device_descriptor desc; - - desc.bLength = USB_DT_DEVICE_SIZE; - desc.bDescriptorType = USB_DT_DEVICE; - - desc.bcdUSB = 0x0110; - - // defined at interface level - desc.bDeviceClass = 0x0; - desc.bDeviceSubClass = 0x0; - desc.bDeviceProtocol = 0x0; - - desc.bMaxPacketSize0 = USB_HID_MAX_PACKET_SIZE; - - desc.idVendor = USB_DEVICE_VENDOR_ID; - desc.idProduct = USB_DEVICE_PRODUCT_ID; - desc.bcdDevice = USB_DEVICE_VERSION; - - desc.iManufacturer = STR_IMANUFACTURER; - desc.iProduct = STR_IPRODUCT; - desc.iSerialNumber = STR_ISERIAL; - - desc.bNumConfigurations = 1; - - send_stage2_submit_data(header, 0, &desc, sizeof(usb_device_descriptor)); -} \ No newline at end of file diff --git a/components/USBIP/USBd_config.c b/components/USBIP/USBd_config.c index c857de3..e0f57ab 100644 --- a/components/USBIP/USBd_config.c +++ b/components/USBIP/USBd_config.c @@ -12,7 +12,6 @@ #include #include "USBd_config.h" #include "usb_defs.h" -#include "USBd_config_CustomClass_0.h" #define USBShort(ui16Value) ((ui16Value) & 0xff), ((ui16Value) >> 8) //((ui16Value) & 0xFF),(((ui16Value) >> 8) & 0xFF) @@ -54,7 +53,7 @@ const uint8_t kUSBd0DeviceDescriptor[0x12] = // Standard Interface Descriptor -const uint8_t kUSBd0InterfaceDescriptor[]= +const uint8_t kUSBd0InterfaceDescriptor[0x1E]= { 0x09, // bLength USB_DT_INTERFACE, // bDescriptorType @@ -72,16 +71,6 @@ const uint8_t kUSBd0InterfaceDescriptor[]= // Standard Endpoint Descriptor - 0x07, // bLength - USB_DTYPE_ENDPOINT, // bDescriptorType - USBD_CUSTOM_CLASS0_IF0_EP0_BENDPOINTADDRESS, // bEndpointAddress -> set 0x01 for endpoint 0 - USB_EP_ATTR_BULK, // bmAttributes -> Endpoint is a bulk endpoint. - USBShort(USBD_CUSTOM_CLASS0_IF0_EP0_HS_WMAXPACKETSIZE), - // wMaxPacketSize -> The maximum packet size: 512 bytes - // We assume that it always runs in High Speed. - USBD_CUSTOM_CLASS0_IF0_EP0_HS_BINTERVAL, // bInterval - - // 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 @@ -98,36 +87,38 @@ const uint8_t kUSBd0InterfaceDescriptor[]= // "Endpoint 1: Bulk Out – used for commands received from host PC." PC -> Device 0x07, // bLength - USB_DTYPE_ENDPOINT, // bDescriptorType + USB_DT_ENDPOINT, // bDescriptorType 0x01, // bEndpointAddress - USB_ENDPOINT_ATTR_BULK, // bmAttributes - USBShort(USBD_CUSTOM_CLASS0_IF0_EP1_HS_WMAXPACKETSIZE), // wMaxPacketSize - USBD_CUSTOM_CLASS0_IF0_EP1_HS_BINTERVAL, // bInterval + 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_DTYPE_ENDPOINT, // bDescriptorType + USB_DT_ENDPOINT, // bDescriptorType 0x81, // bEndpointAddress - USB_ENDPOINT_ATTR_BULK, // bmAttributes - USBShort(USBD_CUSTOM_CLASS0_IF0_EP2_HS_WMAXPACKETSIZE), // wMaxPacketSize - USBD_CUSTOM_CLASS0_IF0_EP2_HS_BINTERVAL, // bInterval + 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_DTYPE_ENDPOINT, // bDescriptorType + USB_DT_ENDPOINT, // bDescriptorType 0x82, // bEndpointAddress - USB_ENDPOINT_ATTR_BULK, // bmAttributes - USBShort(USBD_CUSTOM_CLASS0_IF0_EP3_HS_WMAXPACKETSIZE), // wMaxPacketSize - USBD_CUSTOM_CLASS0_IF0_EP3_HS_BINTERVAL, // bInterval + USB_ENDPOINT_ATTR_BULK, // bmAttributes + USBShort(512), // wMaxPacketSize + 0x00, // bInterval }; // Standard Configuration Descriptor -const uint8_t kUSBd0ConfigDescriptor[] = +#define LENGTHOFCONFIGDESCRIPTOR 9 +const uint8_t kUSBd0ConfigDescriptor[LENGTHOFCONFIGDESCRIPTOR] = { // Configuration descriptor header. @@ -135,7 +126,7 @@ const uint8_t kUSBd0ConfigDescriptor[] = 0x03, // bDescriptorType // constant, set to 0x03 - USBShort((sizeof(kUSBd0InterfaceDescriptor)) + (sizeof(kUSBd0ConfigDescriptor))), + USBShort((sizeof(kUSBd0InterfaceDescriptor)) + (LENGTHOFCONFIGDESCRIPTOR)), // wTotalLength 0x01, // bNumInterfaces @@ -155,7 +146,7 @@ const uint8_t kUSBd0ConfigDescriptor[] = */ -const uint8_t kLangDescriptor[] = +const uint8_t kLangDescriptor[0x04] = { 4, USB_DT_STRING, @@ -210,7 +201,7 @@ const uint8_t kInterfaceString[0x2C] = 'P', 0 }; -const uint8_t * const kUSBd0StringDescriptorsSet[] = +const uint8_t * const kUSBd0StringDescriptorsSet[0x05] = { kLangDescriptor, kManufacturerString, diff --git a/components/USBIP/USBd_config.h b/components/USBIP/USBd_config.h index 88e213a..6af8944 100644 --- a/components/USBIP/USBd_config.h +++ b/components/USBIP/USBd_config.h @@ -38,4 +38,17 @@ + + +///////////////////////////////////////////// +extern const uint8_t kUSBd0DeviceDescriptor[0x12]; +extern const uint8_t kUSBd0InterfaceDescriptor[0x1E]; +extern const uint8_t kUSBd0ConfigDescriptor[0x09]; +extern const uint8_t kLangDescriptor[0x04]; +extern const uint8_t kManufacturerString[0x28]; +extern const uint8_t kProductString[0x18]; +extern const uint8_t kSerialNumberString[0x1A]; +extern const uint8_t kInterfaceString[0x2C]; + + #endif \ No newline at end of file diff --git a/components/USBIP/usb_defs.h b/components/USBIP/usb_defs.h index 995a97e..31898da 100644 --- a/components/USBIP/usb_defs.h +++ b/components/USBIP/usb_defs.h @@ -17,37 +17,32 @@ #include - -#define USB_CLASS_MISCELLANEOUS_DEVICE 0xef -#define USB_MISC_SUBCLASS_COMMON 0x02 +#define USB_CLASS_MISCELLANEOUS_DEVICE 0xef +#define USB_MISC_SUBCLASS_COMMON 0x02 #define USB_MISC_PROTOCOL_INTERFACE_ASSOCIATION_DESCRIPTOR 0x01 - -union word_t { - struct { +typedef union { + struct + { uint8_t u8lo; uint8_t u8hi; } __attribute__((packed)); uint16_t u16; -}; +} word_t; -struct usb_standard_request +typedef struct { - uint8_t bmRequestType; - uint8_t bRequest; + uint8_t bmRequestType; + uint8_t bRequest; word_t wValue; // 16bit word_t wIndex; word_t wLength; -} __attribute__((packed)); - - - - +} __attribute__((packed)) usb_standard_request; //#define USB_CLASS_HID 3 -#define USB_DT_HID 0x21 -#define USB_DT_REPORT 0x22 +#define USB_DT_HID 0x21 +#define USB_DT_REPORT 0x22 //struct usb_hid_descriptor { // uint8_t bLength; @@ -63,84 +58,79 @@ struct usb_standard_request // uint16_t wReportLength; //} __attribute__((packed)); - #define USB_DT_REPORT_SIZE sizeof(struct usb_hid_report_descriptor) - /* Class Definition */ -#define USB_CLASS_VENDOR 0xFF +#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 +#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 +#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 +#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 +#define USB_REQ_GET_STATUS 0 +#define USB_REQ_CLEAR_FEATURE 1 /* Reserved for future use: 2 */ -#define USB_REQ_SET_FEATURE 3 +#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 +#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 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_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 /* From ECNs */ -#define USB_DT_OTG 9 -#define USB_DT_DEBUG 10 -#define USB_DT_INTERFACE_ASSOCIATION 11 +#define USB_DT_OTG 9 +#define USB_DT_DEBUG 10 +#define USB_DT_INTERFACE_ASSOCIATION 11 /////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////// /* 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 +#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 +#define USB_DEV_STATUS_SELF_POWERED 0x01 +#define USB_DEV_STATUS_REMOTE_WAKEUP 0x02 /////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////// /* USB Standard Device Descriptor - Table 9-8 */ -struct usb_device_descriptor { +typedef struct +{ uint8_t bLength; uint8_t bDescriptorType; uint16_t bcdUSB; @@ -155,17 +145,16 @@ struct usb_device_descriptor { uint8_t iProduct; uint8_t iSerialNumber; uint8_t bNumConfigurations; -} __attribute__((packed)); -#define USB_DT_DEVICE_SIZE sizeof(struct usb_device_descriptor) +} __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. */ -struct usb_device_qualifier_descriptor { +typedef struct +{ uint8_t bLength; uint8_t bDescriptorType; uint16_t bcdUSB; @@ -175,25 +164,24 @@ struct usb_device_qualifier_descriptor { uint8_t bMaxPacketSize0; uint8_t bNumConfigurations; uint8_t bReserved; -} __attribute__((packed)); +} __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! */ -struct usb_interface { +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 */ -struct usb_config_descriptor { +typedef struct +{ uint8_t bLength; uint8_t bDescriptorType; uint16_t wTotalLength; @@ -202,25 +190,23 @@ struct usb_config_descriptor { uint8_t iConfiguration; uint8_t bmAttributes; uint8_t bMaxPower; -} __attribute__((packed)); -#define USB_DT_CONFIGURATION_SIZE sizeof(struct usb_config_descriptor) +} __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 +#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 */ -struct usb_interface_descriptor { +typedef struct +{ uint8_t bLength; uint8_t bDescriptorType; uint8_t bInterfaceNumber; @@ -230,15 +216,14 @@ struct usb_interface_descriptor { uint8_t bInterfaceSubClass; uint8_t bInterfaceProtocol; uint8_t iInterface; -} __attribute__((packed)); -#define USB_DT_INTERFACE_SIZE sizeof(struct usb_interface_descriptor) +} __attribute__((packed)) usb_interface_descriptor; +#define USB_DT_INTERFACE_SIZE sizeof(usb_interface_descriptor) /////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////// /* USB Standard Endpoint Descriptor - Table 9-13 */ -struct usb_endpoint_descriptor { +typedef struct usb_endpoint_descriptor +{ uint8_t bLength; uint8_t bDescriptorType; uint8_t bEndpointAddress; @@ -246,52 +231,50 @@ struct usb_endpoint_descriptor { uint16_t wMaxPacketSize; uint8_t bInterval; } __attribute__((packed)); -#define USB_DT_ENDPOINT_SIZE sizeof(struct 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 +#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 +#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_DATA 0x00 +#define USB_ENDPOINT_ATTR_FEEDBACK 0x10 #define USB_ENDPOINT_ATTR_IMPLICIT_FEEDBACK_DATA 0x20 -#define USB_ENDPOINT_ATTR_USAGETYPE 0x30 +#define USB_ENDPOINT_ATTR_USAGETYPE 0x30 /////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////// /* Table 9-15 specifies String Descriptor Zero. * Table 9-16 specified UNICODE String Descriptor. */ -struct usb_string_descriptor { +typedef struct +{ uint8_t bLength; uint8_t bDescriptorType; uint16_t wData[]; -} __attribute__((packed)); +} __attribute__((packed)) usb_string_descriptor; /* From ECN: Interface Association Descriptors, Table 9-Z */ -struct usb_iface_assoc_descriptor { +typedef struct +{ uint8_t bLength; uint8_t bDescriptorType; uint8_t bFirstInterface; @@ -300,17 +283,14 @@ struct usb_iface_assoc_descriptor { uint8_t bFunctionSubClass; uint8_t bFunctionProtocol; uint8_t iFunction; -} __attribute__((packed)); +} __attribute__((packed)) usb_iface_assoc_descriptor; #define USB_DT_INTERFACE_ASSOCIATION_SIZE \ - sizeof(struct usb_iface_assoc_descriptor) + sizeof(usb_iface_assoc_descriptor) -enum usb_language_id { +enum usb_language_id +{ USB_LANGID_ENGLISH_US = 0x409, }; /////////////////////////////////////////////////////////////// - - - - #endif diff --git a/components/USBIP/usbip_defs.h b/components/USBIP/usbip_defs.h index eb3935c..c977914 100644 --- a/components/USBIP/usbip_defs.h +++ b/components/USBIP/usbip_defs.h @@ -12,7 +12,6 @@ // usbip_stage2_header // usbip_stage1_response_devlist - // // Created by thevoidnn on 10/25/17. // @@ -26,36 +25,39 @@ #define USBIP_SYSFS_PATH_SIZE 256 #define USBIP_BUSID_SIZE 32 -enum usbip_stage1_command { +enum usbip_stage1_command +{ // Offset 2 - USBIP_STAGE1_CMD_DEVICE_LIST = 0x05, // OP_REQ_DEVLIST + USBIP_STAGE1_CMD_DEVICE_LIST = 0x05, // OP_REQ_DEVLIST USBIP_STAGE1_CMD_DEVICE_ATTACH = 0x03, // OP_REQ_IMPORT }; -enum usbip_stager2_command { ////TODO: change to stage2 - //Offset 0 - USBIP_STAGE2_REQ_SUBMIT = 0x0001, +enum usbip_stager2_command +{ ////TODO: change to stage2 + //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 { +enum usbip_stage2_direction +{ USBIP_DIR_OUT = 0x00, - USBIP_DIR_IN = 0x01, + USBIP_DIR_IN = 0x01, }; -struct usbip_stage1_header { +typedef struct +{ uint16_t version; uint16_t command; - uint32_t status; -} __attribute__ ((__packed__)); + uint32_t status; +} __attribute__((__packed__)) usbip_stage1_header; ///////////////////////////////////////////////////////////// - - // Device description -struct usbip_stage1_usb_device { +typedef struct +{ char path[USBIP_SYSFS_PATH_SIZE]; char busid[USBIP_BUSID_SIZE]; @@ -74,39 +76,33 @@ struct usbip_stage1_usb_device { uint8_t bConfigurationValue; uint8_t bNumConfigurations; uint8_t bNumInterfaces; -} __attribute__((packed)); +} __attribute__((packed)) usbip_stage1_usb_device; // Interface description -struct usbip_stage1_usb_interface { +typedef struct +{ uint8_t bInterfaceClass; uint8_t bInterfaceSubClass; uint8_t bInterfaceProtocol; uint8_t padding; -} __attribute__((packed)); +} __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; - - -struct usbip_stage1_response_devlist_entry { - struct usbip_stage1_usb_device udev; - struct usbip_stage1_usb_interface uinf[]; -} __attribute__((packed)); - -struct usbip_stage1_response_devlist { - uint32_t list_size; +typedef struct +{ + uint32_t list_size; usbip_stage1_response_devlist_entry devices[]; -} __attribute__ ((__packed__)); - - - - +} __attribute__((__packed__)) usbip_stage1_response_devlist; /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// - - /** * struct usbip_header_basic - data pertinent to every URB request * RESPONSE & REQUEST @@ -119,13 +115,14 @@ struct usbip_stage1_response_devlist { * @direction: direction of the transfer * @ep: endpoint number */ -struct usbip_stage2_header_basic { +typedef struct +{ uint32_t command; uint32_t seqnum; uint32_t devid; uint32_t direction; uint32_t ep; -} __attribute__((packed)); +} __attribute__((packed)) usbip_stage2_header_basic; /** * struct usbip_header_cmd_submit - USBIP_CMD_SUBMIT packet header @@ -138,7 +135,8 @@ struct usbip_stage2_header_basic { * @interval: maximum time for the request on the server-side host controller * @setup: setup data for a control request */ -struct usbip_stage2_header_cmd_submit { +typedef struct +{ uint32_t transfer_flags; int32_t data_length; @@ -151,7 +149,7 @@ struct usbip_stage2_header_cmd_submit { uint8_t setup[8]; usb_standard_request request; }; -} __attribute__((packed)); +} __attribute__((packed)) usbip_stage2_header_cmd_submit; /** * struct usbip_header_ret_submit - USBIP_RET_SUBMIT packet header @@ -163,61 +161,50 @@ struct usbip_stage2_header_cmd_submit { * @number_of_packets: number of isochronous packets * @error_count: number of errors for isochronous transfers */ -struct usbip_stage2_header_ret_submit { +typedef struct +{ int32_t status; - int32_t data_length;//actual_length + int32_t data_length; //actual_length int32_t start_frame; int32_t number_of_packets; int32_t error_count; -} __attribute__((packed)); - - - +} __attribute__((packed)) usbip_stage2_header_ret_submit; /** * struct usbip_header_cmd_unlink - USBIP_CMD_UNLINK packet header * >>>REQUEST * @seqnum: the URB seqnum to unlink */ -struct usbip_stage2_header_cmd_unlink { +typedef struct +{ uint32_t seqnum; -} __attribute__((packed)); +} __attribute__((packed)) usbip_stage2_header_cmd_unlink; /** * struct usbip_header_ret_unlink - USBIP_RET_UNLINK packet header * <<base.ep); return -1; } return 0; } -static void send_stage2_submit(usbip_stage2_header *req_header, int32_t status, int32_t data_length) +void send_stage2_submit(usbip_stage2_header *req_header, int32_t status, int32_t data_length) { req_header->base.command = USBIP_STAGE2_RSP_SUBMIT; diff --git a/main/usbip_server.h b/main/usbip_server.h index c085c28..12df7d6 100644 --- a/main/usbip_server.h +++ b/main/usbip_server.h @@ -1,6 +1,7 @@ #ifndef __USBIP_SERVER_H__ #define __USBIP_SERVER_H__ #include +#include "usbip_defs.h" enum state_t { ACCEPTING, @@ -12,5 +13,7 @@ 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, void *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 From 529e0a375f7a84c134be33c4e6ec374326b2ecd2 Mon Sep 17 00:00:00 2001 From: windowsair Date: Sat, 25 Jan 2020 21:45:24 +0800 Subject: [PATCH 06/15] feat: URB packet processing & DAP command push --- components/DAP/config/DAP_config.h | 12 ++--- components/USBIP/USB_handle.c | 83 +++++++++++++++++------------- components/USBIP/USBd_config.c | 3 +- components/USBIP/usbip_defs.h | 10 ++-- main/CMakeLists.txt | 2 +- main/DAP_handle.c | 45 ++++++++++++++++ main/DAP_handle.h | 8 +++ main/usbip_server.c | 11 ++-- 8 files changed, 120 insertions(+), 54 deletions(-) create mode 100644 main/DAP_handle.c create mode 100644 main/DAP_handle.h diff --git a/components/DAP/config/DAP_config.h b/components/DAP/config/DAP_config.h index 048d766..cc272fe 100644 --- a/components/DAP/config/DAP_config.h +++ b/components/DAP/config/DAP_config.h @@ -100,7 +100,7 @@ This information includes: /// This configuration settings is used to optimize the communication performance with the /// debugger and depends on the USB peripheral. For devices with limited RAM or USB buffer the /// setting can be reduced (valid range is 1 .. 255). -#define DAP_PACKET_COUNT 8U ///< Specifies number of packets buffered. +#define DAP_PACKET_COUNT 1U ///< 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. @@ -109,7 +109,7 @@ This information includes: /// Maximum SWO UART Baudrate. #define SWO_UART_MAX_BAUDRATE 50000000U ///< SWO UART Maximum Baudrate in Hz. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<< 5MHz -// TODO: uncertain value +//// 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. @@ -144,7 +144,7 @@ This information includes: */ __STATIC_INLINE uint8_t DAP_GetVendorString(char *str) { - //TODO: fill this + ////TODO: fill this // In fact, Keil can get the corresponding information through USB // without filling in this information. (void)str; @@ -296,7 +296,7 @@ __STATIC_INLINE void PORT_OFF(void) */ __STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN(void) { - // TODO : can we set to 0? + ////TODO: can we set to 0? return ((GPIO.in >> PIN_SWCLK) & 0x1); } @@ -478,7 +478,7 @@ __STATIC_FORCEINLINE uint32_t PIN_nTRST_IN(void) */ __STATIC_FORCEINLINE void PIN_nTRST_OUT(uint32_t bit) { - //TODO : What does this mean? ? ? + ////TODO: What does this mean? ? ? if ((bit & 1U) == 1) { //set bit @@ -512,7 +512,7 @@ __STATIC_FORCEINLINE uint32_t PIN_nRESET_IN(void) */ __STATIC_FORCEINLINE void PIN_nRESET_OUT(uint32_t bit) { - //TODO : What does this mean? ? ? + ////TODO: What does this mean? ? ? if ((bit & 1U) == 1) { //set bit diff --git a/components/USBIP/USB_handle.c b/components/USBIP/USB_handle.c index 56207a2..b8807db 100644 --- a/components/USBIP/USB_handle.c +++ b/components/USBIP/USB_handle.c @@ -1,6 +1,6 @@ /** * @file USB_handle.c - * @brief Handle all Standard Device Requests + * @brief Handle all Standard Device Requests on endpoint 0 * @version 0.1 * @date 2020-01-23 * @@ -17,34 +17,38 @@ #include "usbip_server.h" #include "usb_defs.h" - // handle functions -static void handleGetDescriptor(struct usbip_stage2_header *header); +static void handleGetDescriptor(usbip_stage2_header *header); ////TODO: fill this -int handleUSBControlRequest(struct usbip_stage2_header *header) +int handleUSBControlRequest(usbip_stage2_header *header) { // Table 9-3. Standard Device Requests switch (header->u.cmd_submit.request.bmRequestType) { - case 0x00: + case 0x00: // ignore.. switch (header->u.cmd_submit.request.bRequest) { case USB_REQ_CLEAR_FEATURE: - /* code */ + os_printf("* CLEAR FEATURE\r\n"); + send_stage2_submit_data(header, 0, 0, 0); break; case USB_REQ_SET_FEATURE: - /* code */ + os_printf("* SET FEATURE\r\n"); + send_stage2_submit_data(header, 0, 0, 0); break; case USB_REQ_SET_ADDRESS: - /* code */ + os_printf("* SET ADDRESS\r\n"); + send_stage2_submit_data(header, 0, 0, 0); break; case USB_REQ_SET_DESCRIPTOR: - /* code */ + os_printf("* SET DESCRIPTOR\r\n"); + send_stage2_submit_data(header, 0, 0, 0); break; case USB_REQ_SET_CONFIGURATION: - /* code */ + 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", @@ -52,17 +56,20 @@ int handleUSBControlRequest(struct usbip_stage2_header *header) break; } break; - case 0x01: + case 0x01: // ignore... switch (header->u.cmd_submit.request.bRequest) { case USB_REQ_CLEAR_FEATURE: - /* code */ + os_printf("* CLEAR FEATURE\r\n"); + send_stage2_submit_data(header, 0, 0, 0); break; case USB_REQ_SET_FEATURE: - /* code */ + os_printf("* SET FEATURE\r\n"); + send_stage2_submit_data(header, 0, 0, 0); break; case USB_REQ_SET_INTERFACE: - /* code */ + os_printf("* SET INTERFACE\r\n"); + send_stage2_submit_data(header, 0, 0, 0); break; default: @@ -71,14 +78,16 @@ int handleUSBControlRequest(struct usbip_stage2_header *header) break; } break; - case 0x02: + case 0x02: // ignore.. switch (header->u.cmd_submit.request.bRequest) { case USB_REQ_CLEAR_FEATURE: - /* code */ + os_printf("* CLEAR FEATURE\r\n"); + send_stage2_submit_data(header, 0, 0, 0); break; case USB_REQ_SET_FEATURE: - /* code */ + os_printf("* SET INTERFACE\r\n"); + send_stage2_submit_data(header, 0, 0, 0); break; default: @@ -88,17 +97,19 @@ int handleUSBControlRequest(struct usbip_stage2_header *header) } break; - case 0x80: + case 0x80: // *IMPORTANT* switch (header->u.cmd_submit.request.bRequest) { case USB_REQ_GET_CONFIGURATION: - handleGetDescriptor(header); + os_printf("* GET CONIFGTRATION\r\n"); + send_stage2_submit_data(header, 0, 0, 0); break; case USB_REQ_GET_DESCRIPTOR: - /* code */ + handleGetDescriptor(header); ////TODO: device_qualifier break; case USB_REQ_GET_STATUS: - /* code */ + 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", @@ -106,17 +117,20 @@ int handleUSBControlRequest(struct usbip_stage2_header *header) break; } break; - case 0x81: + case 0x81: // ignore... switch (header->u.cmd_submit.request.bRequest) { case USB_REQ_GET_INTERFACE: - /* code */ + os_printf("* GET INTERFACE\r\n"); + send_stage2_submit_data(header, 0, 0, 0); break; case USB_REQ_SET_SYNCH_FRAME: - /* code */ + os_printf("* SET SYNCH FRAME\r\n"); + send_stage2_submit_data(header, 0, 0, 0); break; case USB_REQ_GET_STATUS: - /* code */ + os_printf("* GET STATUS\r\n"); + send_stage2_submit_data(header, 0, 0, 0); break; default: @@ -126,11 +140,12 @@ int handleUSBControlRequest(struct usbip_stage2_header *header) } break; - case 0x82: + case 0x82: // ignore... switch (header->u.cmd_submit.request.bRequest) { case USB_REQ_GET_STATUS: - /* code */ + os_printf("* GET STATUS\r\n"); + send_stage2_submit_data(header, 0, 0, 0); break; default: @@ -139,7 +154,6 @@ int handleUSBControlRequest(struct usbip_stage2_header *header) break; } break; - ///////// default: os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n", @@ -148,8 +162,8 @@ int handleUSBControlRequest(struct usbip_stage2_header *header) } } -////TODO: fill this -static void handleGetDescriptor(struct usbip_stage2_header *header) +////TODO: BOS descriptor +static void handleGetDescriptor(usbip_stage2_header *header) { // 9.4.3 Get Descriptor switch (header->u.cmd_submit.request.wValue.u8hi) @@ -168,7 +182,6 @@ static void handleGetDescriptor(struct usbip_stage2_header *header) send_stage2_submit(header, 0, header->u.cmd_submit.data_length); send(kSock, kUSBd0ConfigDescriptor, sizeof(kUSBd0ConfigDescriptor), 0); - } else { @@ -177,18 +190,19 @@ static void handleGetDescriptor(struct usbip_stage2_header *header) 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) { + 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{ + else + { os_printf("***Unsupported operation***\r\n"); } break; @@ -227,7 +241,6 @@ static void handleGetDescriptor(struct usbip_stage2_header *header) send_stage2_submit(header, 0, 0); break; - default: os_printf("USB unknown Get Descriptor requested:%d", header->u.cmd_submit.request.wValue.u8lo); break; diff --git a/components/USBIP/USBd_config.c b/components/USBIP/USBd_config.c index e0f57ab..c266c16 100644 --- a/components/USBIP/USBd_config.c +++ b/components/USBIP/USBd_config.c @@ -26,7 +26,8 @@ const uint8_t kUSBd0DeviceDescriptor[0x12] = { 0x12, // bLength USB_DT_DEVICE, // bDescriptorType (constant) - USBShort(0x0200), // bcdUSB (2.00) + 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 diff --git a/components/USBIP/usbip_defs.h b/components/USBIP/usbip_defs.h index c977914..84904c6 100644 --- a/components/USBIP/usbip_defs.h +++ b/components/USBIP/usbip_defs.h @@ -197,13 +197,13 @@ typedef struct */ typedef struct { - struct usbip_stage2_header_basic base; + usbip_stage2_header_basic base; union { - struct usbip_stage2_header_cmd_submit cmd_submit; - struct usbip_stage2_header_ret_submit ret_submit; - struct usbip_stage2_header_cmd_unlink cmd_unlink; - struct usbip_stage2_header_ret_unlink ret_unlink; + usbip_stage2_header_cmd_submit cmd_submit; + usbip_stage2_header_ret_submit ret_submit; + usbip_stage2_header_cmd_unlink cmd_unlink; + usbip_stage2_header_ret_unlink ret_unlink; } u; } __attribute__((packed)) usbip_stage2_header; diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 6619874..b961c72 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,4 +1,4 @@ -set(COMPONENT_SRCS "main.c timer.c tcp_server.c usbip_server.c") +set(COMPONENT_SRCS "main.c timer.c tcp_server.c usbip_server.c DAP_handle.c") set(COMPONENT_ADD_INCLUDEDIRS ". $ENV{IDF_PATH}/components/esp8266/include/esp8266/ ../components/USBIP") register_component() diff --git a/main/DAP_handle.c b/main/DAP_handle.c new file mode 100644 index 0000000..98d26c8 --- /dev/null +++ b/main/DAP_handle.c @@ -0,0 +1,45 @@ +/** + * @file DAP_handle.c + * @brief Handle DAP packets and transaction push + * @version 0.1 + * @date 2020-01-25 + * + * @copyright Copyright (c) 2020 + * + */ + +#include +#include "usbip_server.h" +#include "DAP_handle.h" +#include "DAP.h" + +////TODO: Merge this +#define DAP_PACKET_SIZE 512 + + +uint8_t data_out[DAP_PACKET_SIZE]; +int respond = 0; + + +void handle_dap_data_request(usbip_stage2_header *header) +{ + uint8_t * data_in = (uint8_t *)header; + data_in = &(data_in[sizeof(usbip_stage2_header)]); + // Point to the beginning of the URB packet + respond = DAP_ProcessCommand((uint8_t *)data_in, (uint8_t *)data_out); + send_stage2_submit(header, 0, 0); + +} +void handle_dap_data_response(usbip_stage2_header *header) +{ + if (respond) { + respond = 0; + //os_printf("*** Will respond"); + send_stage2_submit_data(header, 0, data_out, DAP_PACKET_SIZE); + + //os_printf("*** RESPONDED ***"); + } else { + //os_printf("*** Will NOT respond"); + send_stage2_submit(header, 0, 0); + } +} \ No newline at end of file diff --git a/main/DAP_handle.h b/main/DAP_handle.h new file mode 100644 index 0000000..903bc58 --- /dev/null +++ b/main/DAP_handle.h @@ -0,0 +1,8 @@ +#ifndef __DAP_HANDLE_H__ +#define __DAP_HANDLE_H__ + +#include "usbip_defs.h" + +void handle_dap_data_request(usbip_stage2_header *header); +void handle_dap_data_response(usbip_stage2_header *header); +#endif \ No newline at end of file diff --git a/main/usbip_server.c b/main/usbip_server.c index b18d235..034975d 100644 --- a/main/usbip_server.c +++ b/main/usbip_server.c @@ -121,7 +121,6 @@ static void send_device_list() static void send_device_info() { - //// TODO:fill this os_printf("Sending device info..."); usbip_stage1_usb_device device; @@ -172,7 +171,7 @@ static void send_interface_info() int emulate(uint8_t *buffer, uint32_t length) { // usbip_stage2_header header; - int command = read_stage2_command((usbip_stage2_header *)buffer); ////TODO: fill this + int command = read_stage2_command((usbip_stage2_header *)buffer, length); ////TODO: fill this if (command < 0) { return -1; @@ -272,13 +271,13 @@ static int handle_submit(usbip_stage2_header *header) case 0x01: if (header->base.direction == 0) { - // Serial.println("EP 01 DATA FROM HOST"); - handle_data_request(header); + // os_printf("EP 01 DATA FROM HOST"); + handle_dap_data_request(header); } else { - // Serial.println("EP 01 DATA TO HOST"); - handle_data_response(header); + // os_printf("EP 01 DATA TO HOST"); + handle_dap_data_response(header); } break; From 8cfb843951be031252cb739217b0b17978cdb270 Mon Sep 17 00:00:00 2001 From: windowsair Date: Sun, 26 Jan 2020 15:54:57 +0800 Subject: [PATCH 07/15] feat: Add Microsoft OS 2.0 Descriptors and WinUSB Support. --- components/USBIP/MSOS20Descriptors.c | 84 ++++++++++++++++++++++++++++ components/USBIP/MSOS20Descriptors.h | 81 +++++++++++++++++++++++++++ components/USBIP/USB_handle.c | 28 +++++++++- components/USBIP/usb_defs.h | 1 + components/USBIP/usbip_defs.h | 2 +- main/usbip_server.c | 6 +- 6 files changed, 196 insertions(+), 6 deletions(-) create mode 100644 components/USBIP/MSOS20Descriptors.c create mode 100644 components/USBIP/MSOS20Descriptors.h diff --git a/components/USBIP/MSOS20Descriptors.c b/components/USBIP/MSOS20Descriptors.c new file mode 100644 index 0000000..4337076 --- /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..61a7ea3 --- /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 index b8807db..d7ef3b2 100644 --- a/components/USBIP/USB_handle.c +++ b/components/USBIP/USB_handle.c @@ -16,11 +16,12 @@ #include "USBd_config.h" #include "usbip_server.h" #include "usb_defs.h" +#include "MSOS20Descriptors.h" // handle functions static void handleGetDescriptor(usbip_stage2_header *header); -////TODO: fill this +////TODO: may be ok int handleUSBControlRequest(usbip_stage2_header *header) { // Table 9-3. Standard Device Requests @@ -154,7 +155,26 @@ int handleUSBControlRequest(usbip_stage2_header *header) 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; default: os_printf("USB unknown request, bmRequestType:%d,bRequest:%d\r\n", header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest); @@ -162,7 +182,7 @@ int handleUSBControlRequest(usbip_stage2_header *header) } } -////TODO: BOS descriptor + static void handleGetDescriptor(usbip_stage2_header *header) { // 9.4.3 Get Descriptor @@ -241,6 +261,10 @@ static void handleGetDescriptor(usbip_stage2_header *header) 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; default: os_printf("USB unknown Get Descriptor requested:%d", header->u.cmd_submit.request.wValue.u8lo); break; diff --git a/components/USBIP/usb_defs.h b/components/USBIP/usb_defs.h index 31898da..39add9b 100644 --- a/components/USBIP/usb_defs.h +++ b/components/USBIP/usb_defs.h @@ -110,6 +110,7 @@ typedef struct #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 diff --git a/components/USBIP/usbip_defs.h b/components/USBIP/usbip_defs.h index 84904c6..d36d16e 100644 --- a/components/USBIP/usbip_defs.h +++ b/components/USBIP/usbip_defs.h @@ -33,7 +33,7 @@ enum usbip_stage1_command }; enum usbip_stager2_command -{ ////TODO: change to stage2 +{ //Offset 0 USBIP_STAGE2_REQ_SUBMIT = 0x0001, USBIP_STAGE2_REQ_UNLINK = 0x0002, diff --git a/main/usbip_server.c b/main/usbip_server.c index 034975d..1fb7e0e 100644 --- a/main/usbip_server.c +++ b/main/usbip_server.c @@ -39,7 +39,7 @@ int attach(uint8_t *buffer, uint32_t length) break; case USBIP_STAGE1_CMD_DEVICE_ATTACH: // OP_REQ_IMPORT - handle_device_attach(buffer, length); ////TODO: fill this + handle_device_attach(buffer, length); break; default: @@ -171,7 +171,7 @@ static void send_interface_info() int emulate(uint8_t *buffer, uint32_t length) { // usbip_stage2_header header; - int command = read_stage2_command((usbip_stage2_header *)buffer, length); ////TODO: fill this + int command = read_stage2_command((usbip_stage2_header *)buffer, length); if (command < 0) { return -1; @@ -253,7 +253,7 @@ static void unpack(void *data, int size) } } -////TODO: fill this + /** * @brief * From 822aa0b6adc6ff5eddda537596da78b2cd2e7a87 Mon Sep 17 00:00:00 2001 From: windowsair Date: Sun, 26 Jan 2020 16:29:52 +0800 Subject: [PATCH 08/15] chore: Add cmake file for components --- CMakeLists.txt | 1 + components/CMakeLists.txt | 0 components/DAP/CMakeLists.txt | 4 ++++ components/USBIP/CMakeLists.txt | 4 ++++ main/CMakeLists.txt | 2 +- 5 files changed, 10 insertions(+), 1 deletion(-) delete mode 100644 components/CMakeLists.txt create mode 100644 components/DAP/CMakeLists.txt create mode 100644 components/USBIP/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index afc306e..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(esp8266_dap) diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt deleted file mode 100644 index e69de29..0000000 diff --git a/components/DAP/CMakeLists.txt b/components/DAP/CMakeLists.txt new file mode 100644 index 0000000..83bea91 --- /dev/null +++ b/components/DAP/CMakeLists.txt @@ -0,0 +1,4 @@ +set(COMPONENT_ADD_INCLUDEDIRS "config include") +set(COMPONENT_SRCS "./source/DAP.c ./source/DAP_vendor.c ./source/JTAG_DP.c ./source/SW_DP.c ./source/SWO.c") + +register_component() \ No newline at end of file diff --git a/components/USBIP/CMakeLists.txt b/components/USBIP/CMakeLists.txt new file mode 100644 index 0000000..d8f96b0 --- /dev/null +++ b/components/USBIP/CMakeLists.txt @@ -0,0 +1,4 @@ +set(COMPONENT_ADD_INCLUDEDIRS ".") +set(COMPONENT_SRCS "MSOS20Descriptors.c USB_handle.c USBd_config.c") + +register_component() \ No newline at end of file diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index b961c72..d6ae4a1 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -1,4 +1,4 @@ -set(COMPONENT_SRCS "main.c timer.c tcp_server.c usbip_server.c DAP_handle.c") set(COMPONENT_ADD_INCLUDEDIRS ". $ENV{IDF_PATH}/components/esp8266/include/esp8266/ ../components/USBIP") +set(COMPONENT_SRCS "main.c timer.c tcp_server.c usbip_server.c DAP_handle.c") register_component() From 50079136ab7c8324b227b9ee15782fb15c890194 Mon Sep 17 00:00:00 2001 From: windowsair Date: Mon, 27 Jan 2020 10:42:21 +0800 Subject: [PATCH 09/15] fix: Fix some simple bugs (spelling errors, etc.) --- components/DAP/CMakeLists.txt | 5 ++-- components/DAP/config/DAP_config.h | 12 ++++++--- components/DAP/include/DAP.h | 5 +++- components/DAP/include/cmsis_compiler.h | 15 +++++++++++ components/DAP/source/SWO.c | 2 ++ components/USBIP/CMakeLists.txt | 2 +- components/USBIP/USB_handle.c | 10 ++++--- components/USBIP/USB_handle.h | 4 ++- components/USBIP/usb_defs.h | 8 +++--- main/tcp_server.c | 10 +++---- main/timer.c | 2 +- main/usbip_server.c | 36 ++++++++++++++----------- main/usbip_server.h | 4 +-- 13 files changed, 75 insertions(+), 40 deletions(-) create mode 100644 components/DAP/include/cmsis_compiler.h diff --git a/components/DAP/CMakeLists.txt b/components/DAP/CMakeLists.txt index 83bea91..59f8ce1 100644 --- a/components/DAP/CMakeLists.txt +++ b/components/DAP/CMakeLists.txt @@ -1,4 +1,5 @@ -set(COMPONENT_ADD_INCLUDEDIRS "config include") -set(COMPONENT_SRCS "./source/DAP.c ./source/DAP_vendor.c ./source/JTAG_DP.c ./source/SW_DP.c ./source/SWO.c") +set(COMPONENT_ADD_INCLUDEDIRS "config include $ENV{IDF_PATH}/components/esp8266/include/esp8266/") +set(COMPONENT_SRCS "./source/DAP.c ./source/DAP_vendor.c ./source/JTAG_DP.c ./source/SW_DP.c ") +# ./source/SWO.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 index cc272fe..a4ed661 100644 --- a/components/DAP/config/DAP_config.h +++ b/components/DAP/config/DAP_config.h @@ -28,10 +28,16 @@ #ifndef __DAP_CONFIG_H__ #define __DAP_CONFIG_H__ +#include +#include "cmsis_compiler.h" #include "gpio.h" #include "gpio_struct.h" #include "timer_struct.h" + + + + //************************************************************************************************** /** \defgroup DAP_Config_Debug_gr CMSIS-DAP Debug Unit Information @@ -454,7 +460,7 @@ __STATIC_FORCEINLINE void PIN_TDI_OUT(uint32_t bit) */ __STATIC_FORCEINLINE uint32_t PIN_TDO_IN(void) { - return ((GPIO.in >> PIN_TDO_IN) & 0x1); + return ((GPIO.in >> PIN_TDI) & 0x1); } // nTRST Pin I/O ------------------------------------------- @@ -609,8 +615,8 @@ default, the DWT timer is used. The frequency of this timer is configured with */ __STATIC_INLINE uint32_t TIMESTAMP_GET(void) { - // FRC1 is a 24-bit countdown timer - return (0x1000000U - 1U - (frc1.count.data)); + // FRC1 is a 23-bit countdown timer + return (0x7FFFFF - (frc1.count.data)); } ///@} diff --git a/components/DAP/include/DAP.h b/components/DAP/include/DAP.h index 4194005..516b83d 100644 --- a/components/DAP/include/DAP.h +++ b/components/DAP/include/DAP.h @@ -284,7 +284,10 @@ extern void DAP_Setup (void); #ifndef DELAY_SLOW_CYCLES #define DELAY_SLOW_CYCLES 3U // Number of cycles for one iteration #endif -#if defined(__CC_ARM) + +#define USE_ASSEMBLY 0 + +#if USE_ASSEMBLY == 0 __STATIC_FORCEINLINE void PIN_DELAY_SLOW (uint32_t delay) { uint32_t count = delay; while (--count); diff --git a/components/DAP/include/cmsis_compiler.h b/components/DAP/include/cmsis_compiler.h new file mode 100644 index 0000000..349f5fd --- /dev/null +++ b/components/DAP/include/cmsis_compiler.h @@ -0,0 +1,15 @@ +#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 + + +#endif \ No newline at end of file diff --git a/components/DAP/source/SWO.c b/components/DAP/source/SWO.c index 1093bfb..241d9cb 100644 --- a/components/DAP/source/SWO.c +++ b/components/DAP/source/SWO.c @@ -27,12 +27,14 @@ #include "DAP_config.h" #include "DAP.h" +/* #if (SWO_UART != 0) #include "Driver_USART.h" #endif #if (SWO_STREAM != 0) #include "cmsis_os2.h" #endif +*/ #if (SWO_STREAM != 0) #ifdef DAP_FW_V1 diff --git a/components/USBIP/CMakeLists.txt b/components/USBIP/CMakeLists.txt index d8f96b0..3aeba6c 100644 --- a/components/USBIP/CMakeLists.txt +++ b/components/USBIP/CMakeLists.txt @@ -1,4 +1,4 @@ -set(COMPONENT_ADD_INCLUDEDIRS ".") +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/USB_handle.c b/components/USBIP/USB_handle.c index d7ef3b2..a6dd0ce 100644 --- a/components/USBIP/USB_handle.c +++ b/components/USBIP/USB_handle.c @@ -8,6 +8,7 @@ * */ #include +#include #include "lwip/err.h" #include "lwip/sockets.h" #include "lwip/sys.h" @@ -22,7 +23,7 @@ static void handleGetDescriptor(usbip_stage2_header *header); ////TODO: may be ok -int handleUSBControlRequest(usbip_stage2_header *header) +void handleUSBControlRequest(usbip_stage2_header *header) { // Table 9-3. Standard Device Requests @@ -156,6 +157,7 @@ int handleUSBControlRequest(usbip_stage2_header *header) } break; case 0xC0: // Microsoft OS 2.0 vendor-specific descriptor + { uint16_t *wIndex = (uint16_t *)(&(header->u.cmd_submit.request.wIndex)); switch (*wIndex) { @@ -170,11 +172,12 @@ int handleUSBControlRequest(usbip_stage2_header *header) break; default: - os_printf("USB unknown request, bmRequestType:%d,bRequest:%d,wIndex:%d\r\n", + 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; + } + 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); @@ -182,7 +185,6 @@ int handleUSBControlRequest(usbip_stage2_header *header) } } - static void handleGetDescriptor(usbip_stage2_header *header) { // 9.4.3 Get Descriptor diff --git a/components/USBIP/USB_handle.h b/components/USBIP/USB_handle.h index d23789d..ac4eeec 100644 --- a/components/USBIP/USB_handle.h +++ b/components/USBIP/USB_handle.h @@ -1,5 +1,7 @@ #ifndef __USB_HANDLE_H__ #define __USB_HANDLE_H__ + #include "usbip_defs.h" -int handleUSBControlRequest(usbip_stage2_header *header); +void handleUSBControlRequest(usbip_stage2_header *header); + #endif \ No newline at end of file diff --git a/components/USBIP/usb_defs.h b/components/USBIP/usb_defs.h index 39add9b..c33fa06 100644 --- a/components/USBIP/usb_defs.h +++ b/components/USBIP/usb_defs.h @@ -74,13 +74,13 @@ typedef struct #define USB_REQ_TYPE_STANDARD 0x00 #define USB_REQ_TYPE_CLASS 0x20 #define USB_REQ_TYPE_VENDOR 0x40 -#define USB_REQ_TYPE_RESERVED 0x60 +//#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 +//#define USB_REQ_TYPE_RESERVED 0x1F /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// @@ -223,7 +223,7 @@ typedef struct /////////////////////////////////////////////////////////////// /* USB Standard Endpoint Descriptor - Table 9-13 */ -typedef struct usb_endpoint_descriptor +typedef struct { uint8_t bLength; uint8_t bDescriptorType; @@ -231,7 +231,7 @@ typedef struct usb_endpoint_descriptor uint8_t bmAttributes; uint16_t wMaxPacketSize; uint8_t bInterval; -} __attribute__((packed)); +} __attribute__((packed))usb_endpoint_descriptor; #define USB_DT_ENDPOINT_SIZE sizeof(usb_endpoint_descriptor) /////////////////////////////////////////////////////////////// diff --git a/main/tcp_server.c b/main/tcp_server.c index 7e6f870..5031600 100644 --- a/main/tcp_server.c +++ b/main/tcp_server.c @@ -29,11 +29,11 @@ #include "wifi_configuration.h" #include "usbip_server.h" -uint8_t state = ACCEPTING; +uint8_t kState = ACCEPTING; int kSock = -1; void tcp_server_task(void *pvParameters) { - char rx_buffer[2048]; + uint8_t rx_buffer[2048]; char addr_str[128]; int addr_family; int ip_protocol; @@ -132,10 +132,10 @@ void tcp_server_task(void *pvParameters) 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); - switch (state) + switch (kState) { case ACCEPTING: - state = ATTACHING; + kState = ATTACHING; break; case ATTACHING: @@ -155,7 +155,7 @@ void tcp_server_task(void *pvParameters) // } } } - state = ACCEPTING; + kState = ACCEPTING; if (kSock != -1) { os_printf("Shutting down socket and restarting...\r\n"); diff --git a/main/timer.c b/main/timer.c index 18be76f..6fbe6b7 100644 --- a/main/timer.c +++ b/main/timer.c @@ -22,7 +22,7 @@ void timer_create_task() frc1.ctrl.div = TIMER_CLKDIV_16; // 80MHz / 16 = 5MHz frc1.ctrl.intr_type = TIMER_EDGE_INT; frc1.ctrl.reload = 0x01; - frc1.load.data = 0x1000000U - 1U; + frc1.load.data = 0x7FFFFF; // 23bit?? frc1.ctrl.en = 0x01; vPortExitCritical(); vTaskDelete(NULL); diff --git a/main/usbip_server.c b/main/usbip_server.c index 1fb7e0e..0317f6f 100644 --- a/main/usbip_server.c +++ b/main/usbip_server.c @@ -1,4 +1,5 @@ #include +#include #include "lwip/err.h" #include "lwip/sockets.h" #include "lwip/sys.h" @@ -8,11 +9,13 @@ #include "usbip_defs.h" #include "usb_defs.h" #include "USBd_config.h" +#include "DAP_handle.h" +#include "USB_handle.h" // attach helper function static int read_stage1_command(uint8_t *buffer, uint32_t length); -static int handle_device_list(uint8_t *buffer, uint32_t length); -static int handle_device_attach(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(); @@ -22,7 +25,7 @@ static void send_interface_info(); static void pack(void *data, int size); static void unpack(void *data, int size); static int handle_submit(usbip_stage2_header *header); -static int handle_control_request(usbip_stage2_header *header); +static int read_stage2_command(usbip_stage2_header *header, uint32_t length); int attach(uint8_t *buffer, uint32_t length) { @@ -46,6 +49,7 @@ int attach(uint8_t *buffer, uint32_t length) os_printf("attach Unknown command: %d\r\n", command); break; } + return 0; ////TODO: ... } static int read_stage1_command(uint8_t *buffer, uint32_t length) @@ -58,21 +62,22 @@ static int read_stage1_command(uint8_t *buffer, uint32_t length) return (ntohs(req->command) & 0xFF); // 0x80xx low bit } -static int handle_device_list(uint8_t *buffer, uint32_t length) +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 int handle_device_attach(uint8_t *buffer, uint32_t length) +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)) { - return -1; + os_printf("handle device attach failed!\r\n"); + return; } //client.readBytes((uint8_t *)bus, USBIP_BUSID_SIZE); @@ -80,7 +85,7 @@ static int handle_device_attach(uint8_t *buffer, uint32_t length) send_device_info(); - state = EMULATING; + kState = EMULATING; } static void send_stage1_header(uint16_t command, uint32_t status) @@ -194,7 +199,7 @@ int emulate(uint8_t *buffer, uint32_t length) return 0; } -int read_stage2_command(usbip_stage2_header *header, uint32_t length) +static int read_stage2_command(usbip_stage2_header *header, uint32_t length) { if (length < sizeof(usbip_stage2_header)) { @@ -220,10 +225,10 @@ static void pack(void *data, int size) { // Ignore the setup field - int size = (size / sizeof(uint32_t)) - 2; + int sz = (size / sizeof(uint32_t)) - 2; uint32_t *ptr = (uint32_t *)data; - for (int i = 0; i < size; i++) + for (int i = 0; i < sz; i++) { ptr[i] = htonl(ptr[i]); @@ -244,10 +249,10 @@ static void unpack(void *data, int size) { // Ignore the setup field - int size = (size / sizeof(uint32_t)) - 2; + int sz = (size / sizeof(uint32_t)) - 2; uint32_t *ptr = (uint32_t *)data; - for (int i = 0; i < size; i++) + for (int i = 0; i < sz; i++) { ptr[i] = ntohl(ptr[i]); } @@ -264,7 +269,7 @@ static int handle_submit(usbip_stage2_header *header) { // control endpoint(endpoint 0) case 0x00: - handle_control_request(header); + handleUSBControlRequest(header); break; // data @@ -294,8 +299,7 @@ static int handle_submit(usbip_stage2_header *header) return -1; default: - os_printf("*** WARN ! UNKNOWN ENDPOINT: "); - os_printf((int)header->base.ep); + os_printf("*** WARN ! UNKNOWN ENDPOINT: %d\r\n", (int)header->base.ep); return -1; } return 0; @@ -316,7 +320,7 @@ void send_stage2_submit(usbip_stage2_header *req_header, int32_t status, int32_t send(kSock, req_header, sizeof(usbip_stage2_header), 0); } -void send_stage2_submit_data(usbip_stage2_header *req_header, int32_t status, void *data, int32_t data_length) +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); diff --git a/main/usbip_server.h b/main/usbip_server.h index 12df7d6..2d0effd 100644 --- a/main/usbip_server.h +++ b/main/usbip_server.h @@ -8,12 +8,12 @@ enum state_t ATTACHING, EMULATING }; -extern uint32_t state; +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, void *data, int32_t data_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 From 1070f630748dd5c6938854e713ebeaf34e6d85fe Mon Sep 17 00:00:00 2001 From: windowsair Date: Tue, 28 Jan 2020 20:21:18 +0800 Subject: [PATCH 10/15] feat: DAP function completion 1. Add streaming SWO trace support(Not tested) 2. Fix Unlink function --- components/DAP/CMakeLists.txt | 6 +- components/DAP/config/DAP_config.h | 2 +- components/DAP/include/uart_modify.h | 565 ++++++++++++ components/DAP/source/SWO.c | 790 +++++++++------- components/DAP/source/uart_modify.c | 1256 ++++++++++++++++++++++++++ main/DAP_handle.c | 72 +- main/DAP_handle.h | 1 + main/main.c | 12 +- main/usbip_server.c | 47 +- 9 files changed, 2398 insertions(+), 353 deletions(-) create mode 100644 components/DAP/include/uart_modify.h create mode 100644 components/DAP/source/uart_modify.c diff --git a/components/DAP/CMakeLists.txt b/components/DAP/CMakeLists.txt index 59f8ce1..3eec5a2 100644 --- a/components/DAP/CMakeLists.txt +++ b/components/DAP/CMakeLists.txt @@ -1,5 +1,5 @@ -set(COMPONENT_ADD_INCLUDEDIRS "config include $ENV{IDF_PATH}/components/esp8266/include/esp8266/") -set(COMPONENT_SRCS "./source/DAP.c ./source/DAP_vendor.c ./source/JTAG_DP.c ./source/SW_DP.c ") -# ./source/SWO.c +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 index a4ed661..fccf7d3 100644 --- a/components/DAP/config/DAP_config.h +++ b/components/DAP/config/DAP_config.h @@ -113,7 +113,7 @@ This information includes: #define SWO_UART 1 ///< SWO UART: 1 = available, 0 = not available. /// Maximum SWO UART Baudrate. -#define SWO_UART_MAX_BAUDRATE 50000000U ///< SWO UART Maximum Baudrate in Hz. +#define SWO_UART_MAX_BAUDRATE (115200U*40U) ///< SWO UART Maximum Baudrate in Hz. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<< 5MHz //// TODO: uncertain value 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/SWO.c b/components/DAP/source/SWO.c index 241d9cb..d331a0c 100644 --- a/components/DAP/source/SWO.c +++ b/components/DAP/source/SWO.c @@ -1,3 +1,8 @@ +/** + * @brief Modify this file to fit esp8266 Uart + * + */ + /* * Copyright (c) 2013-2017 ARM Limited. All rights reserved. * @@ -27,14 +32,21 @@ #include "DAP_config.h" #include "DAP.h" -/* -#if (SWO_UART != 0) -#include "Driver_USART.h" -#endif -#if (SWO_STREAM != 0) -#include "cmsis_os2.h" -#endif -*/ + +#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 @@ -44,28 +56,22 @@ #if (SWO_UART != 0) -#ifndef USART_PORT -#define USART_PORT 0 /* USART Port Number */ +#ifndef USART_PORT +#define USART_PORT UART_NUM_0 /* USART Port Number */ #endif -// USART Driver -#define _USART_Driver_(n) Driver_USART##n -#define USART_Driver_(n) _USART_Driver_(n) -extern ARM_DRIVER_USART USART_Driver_(USART_PORT); -#define pUSART (&USART_Driver_(USART_PORT)) + static uint8_t USART_Ready = 0U; -#endif /* (SWO_UART != 0) */ - +#endif /* (SWO_UART != 0) */ #if ((SWO_UART != 0) || (SWO_MANCHESTER != 0)) +#define SWO_STREAM_TIMEOUT (50 / portTICK_RATE_MS) /* Stream timeout in ms */ -#define SWO_STREAM_TIMEOUT 50U /* Stream timeout in ms */ - -#define USB_BLOCK_SIZE 512U /* USB Block Size */ -#define TRACE_BLOCK_SIZE 64U /* Trace Block Size (2^n: 32...512) */ +#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 */ @@ -81,145 +87,190 @@ 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) +#if (TIMESTAMP_CLOCK != 0U) // Trace Timestamp -static volatile struct { +static volatile struct +{ uint32_t index; uint32_t tick; } TraceTimestamp; #endif // Trace Helper functions -static void ClearTrace (void); -static void ResumeTrace (void); -static uint32_t GetTraceCount (void); -static uint8_t GetTraceStatus (void); -static void SetTraceError (uint8_t flag); +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) -extern osThreadId_t SWO_ThreadId; -static volatile uint8_t TransferBusy = 0U; /* Transfer Busy Flag */ -static uint32_t TransferSize; /* Current Transfer Size */ -#endif +static volatile uint8_t TransferBusy = 0U; /* Transfer Busy Flag */ +static uint32_t TransferSize; /* Current Transfer Size */ +#endif #if (SWO_UART != 0) -// USART Driver Callback function -// event: event mask -static void USART_Callback (uint32_t event) { + +void usart_monitor_task(void *argument) +{ uint32_t index_i; uint32_t index_o; uint32_t count; uint32_t num; + uint32_t flags; - if (event & ARM_USART_EVENT_RECEIVE_COMPLETE) { -#if (TIMESTAMP_CLOCK != 0U) - TraceTimestamp.tick = TIMESTAMP_GET(); + 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; + index_o = TraceIndexO; + index_i = TraceIndexI; + index_i += TraceBlockSize; + TraceIndexI = index_i; +#if (TIMESTAMP_CLOCK != 0U) + TraceTimestamp.index = index_i; #endif - num = TRACE_BLOCK_SIZE - (index_i & (TRACE_BLOCK_SIZE - 1U)); - count = index_i - index_o; - if (count <= (SWO_BUFFER_SIZE - num)) { - index_i &= SWO_BUFFER_SIZE - 1U; - TraceBlockSize = num; - pUSART->Receive(&TraceBuf[index_i], num); - } else { - TraceStatus = DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED; - } - TraceUpdate = 1U; -#if (SWO_STREAM != 0) - if (TraceTransport == 2U) { - if (count >= (USB_BLOCK_SIZE - (index_o & (USB_BLOCK_SIZE - 1U)))) { - osThreadFlagsSet(SWO_ThreadId, 1U); + + 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); - } + + // 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) { +__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); - if (enable != 0U) { - status = pUSART->Initialize(USART_Callback); - if (status != ARM_DRIVER_OK) { +#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); } - status = pUSART->PowerControl(ARM_POWER_FULL); - if (status != ARM_DRIVER_OK) { - pUSART->Uninitialize(); - return (0U); - } - } else { - pUSART->Control(ARM_USART_CONTROL_RX, 0U); - pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U); - pUSART->PowerControl(ARM_POWER_OFF); - pUSART->Uninitialize(); + } + 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; +__WEAK uint32_t UART_SWO_Baudrate(uint32_t baudrate) +{ + int32_t status; uint32_t index; uint32_t num; - if (baudrate > SWO_UART_MAX_BAUDRATE) { + if (baudrate > SWO_UART_MAX_BAUDRATE) + { baudrate = SWO_UART_MAX_BAUDRATE; } - if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) { - pUSART->Control(ARM_USART_CONTROL_RX, 0U); - if (pUSART->GetStatus().rx_busy) { - TraceIndexI += pUSART->GetRxCount(); - pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U); - } + 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 = pUSART->Control(ARM_USART_MODE_ASYNCHRONOUS | - ARM_USART_DATA_BITS_8 | - ARM_USART_PARITY_NONE | - ARM_USART_STOP_BITS_1, - baudrate); + ///////////// + status = my_uart_set_baudrate(USART_PORT, baudrate); - if (status == ARM_DRIVER_OK) { + if (status == ESP_OK) + { USART_Ready = 1U; - } else { + } + else + { USART_Ready = 0U; return (0U); } - - if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) { - if ((TraceStatus & DAP_SWO_CAPTURE_PAUSED) == 0U) { + + if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) + { + if ((TraceStatus & DAP_SWO_CAPTURE_PAUSED) == 0U) + { index = TraceIndexI & (SWO_BUFFER_SIZE - 1U); num = TRACE_BLOCK_SIZE - (index & (TRACE_BLOCK_SIZE - 1U)); TraceBlockSize = num; - pUSART->Receive(&TraceBuf[index], num); + //pUSART->Receive(&TraceBuf[index], num); + my_uart_read_bytes(USART_PORT, &TraceBuf[index], num, 20 / portTICK_RATE_MS); } - pUSART->Control(ARM_USART_CONTROL_RX, 1U); + //pUSART->Control(ARM_USART_CONTROL_RX, 1U); ////TODO: } return (baudrate); @@ -228,28 +279,40 @@ __WEAK uint32_t UART_SWO_Baudrate (uint32_t baudrate) { // Control UART SWO Capture // active: active flag // return: 1 - Success, 0 - Error -__WEAK uint32_t UART_SWO_Control (uint32_t active) { +__WEAK uint32_t UART_SWO_Control(uint32_t active) +{ int32_t status; - if (active) { - if (!USART_Ready) { + if (active) + { + if (!USART_Ready) + { return (0U); } TraceBlockSize = 1U; - status = pUSART->Receive(&TraceBuf[0], 1U); - if (status != ARM_DRIVER_OK) { + 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); - } - } else { - pUSART->Control(ARM_USART_CONTROL_RX, 0U); - if (pUSART->GetStatus().rx_busy) { - TraceIndexI += pUSART->GetRxCount(); - pUSART->Control(ARM_USART_ABORT_RECEIVE, 0U); - } + // status = pUSART->Control(ARM_USART_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); } @@ -257,70 +320,83 @@ __WEAK uint32_t UART_SWO_Control (uint32_t active) { // 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) { +__WEAK void UART_SWO_Capture(uint8_t *buf, uint32_t num) +{ TraceBlockSize = num; - pUSART->Receive(buf, 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) { +__WEAK uint32_t UART_SWO_GetCount(void) +{ uint32_t count; - if (pUSART->GetStatus().rx_busy) { - count = pUSART->GetRxCount(); - } else { - count = 0U; - } + // 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) */ - +#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) { +__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) { +__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) { +__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) { +__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) { +__WEAK uint32_t Manchester_SWO_GetCount(void) +{ + return (0U); } -#endif /* (SWO_MANCHESTER != 0) */ - +#endif /* (SWO_MANCHESTER != 0) */ // Clear Trace Errors and Data -static void ClearTrace (void) { +static void ClearTrace(void) +{ #if (SWO_STREAM != 0) - if (TraceTransport == 2U) { - if (TransferBusy != 0U) { + if (TraceTransport == 2U) + { + if (TransferBusy != 0U) + { SWO_AbortTransfer(); TransferBusy = 0U; } @@ -329,41 +405,45 @@ static void ClearTrace (void) { TraceError[0] = 0U; TraceError[1] = 0U; - TraceError_n = 0U; - TraceIndexI = 0U; - TraceIndexO = 0U; + TraceError_n = 0U; + TraceIndexI = 0U; + TraceIndexO = 0U; -#if (TIMESTAMP_CLOCK != 0U) +#if (TIMESTAMP_CLOCK != 0U) TraceTimestamp.index = 0U; - TraceTimestamp.tick = 0U; + TraceTimestamp.tick = 0U; #endif } // Resume Trace Capture -static void ResumeTrace (void) { +static void ResumeTrace(void) +{ uint32_t index_i; uint32_t index_o; - if (TraceStatus == (DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED)) { + if (TraceStatus == (DAP_SWO_CAPTURE_ACTIVE | DAP_SWO_CAPTURE_PAUSED)) + { index_i = TraceIndexI; index_o = TraceIndexO; - if ((index_i - index_o) < SWO_BUFFER_SIZE) { + if ((index_i - index_o) < SWO_BUFFER_SIZE) + { index_i &= SWO_BUFFER_SIZE - 1U; - switch (TraceMode) { + switch (TraceMode) + { #if (SWO_UART != 0) - case DAP_SWO_UART: - TraceStatus = DAP_SWO_CAPTURE_ACTIVE; - UART_SWO_Capture(&TraceBuf[index_i], 1U); - break; + 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; + case DAP_SWO_MANCHESTER: + TraceStatus = DAP_SWO_CAPTURE_ACTIVE; + Manchester_SWO_Capture(&TraceBuf[index_i], 1U); + break; #endif - default: - break; + default: + break; } } } @@ -371,29 +451,35 @@ static void ResumeTrace (void) { // Get Trace Count // return: number of available data bytes in trace buffer -static uint32_t GetTraceCount (void) { +static uint32_t GetTraceCount(void) +{ uint32_t count; - if (TraceStatus == DAP_SWO_CAPTURE_ACTIVE) { - do { + if (TraceStatus == DAP_SWO_CAPTURE_ACTIVE) + { + do + { TraceUpdate = 0U; count = TraceIndexI - TraceIndexO; - switch (TraceMode) { + switch (TraceMode) + { #if (SWO_UART != 0) - case DAP_SWO_UART: - count += UART_SWO_GetCount(); - break; + case DAP_SWO_UART: + count += UART_SWO_GetCount(); + break; #endif #if (SWO_MANCHESTER != 0) - case DAP_SWO_MANCHESTER: - count += Manchester_SWO_GetCount(); - break; + case DAP_SWO_MANCHESTER: + count += Manchester_SWO_GetCount(); + break; #endif - default: - break; + default: + break; } } while (TraceUpdate != 0U); - } else { + } + else + { count = TraceIndexI - TraceIndexO; } @@ -402,8 +488,9 @@ static uint32_t GetTraceCount (void) { // Get Trace Status (clear Error flags) // return: Trace Status (Active flag and Error flags) -static uint8_t GetTraceStatus (void) { - uint8_t status; +static uint8_t GetTraceStatus(void) +{ + uint8_t status; uint32_t n; n = TraceError_n; @@ -416,235 +503,263 @@ static uint8_t GetTraceStatus (void) { // Set Trace Error flag(s) // flag: error flag(s) to set -static void SetTraceError (uint8_t flag) { +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 SWO_Transport(const uint8_t *request, uint8_t *response) +{ + uint8_t transport; uint32_t result; - if ((TraceStatus & DAP_SWO_CAPTURE_ACTIVE) == 0U) { + if ((TraceStatus & DAP_SWO_CAPTURE_ACTIVE) == 0U) + { transport = *request; - switch (transport) { - case 0U: - case 1U: + switch (transport) + { + case 0U: + case 1U: #if (SWO_STREAM != 0) - case 2U: + case 2U: #endif - TraceTransport = transport; - result = 1U; - break; - default: - result = 0U; - break; + TraceTransport = transport; + result = 1U; + break; + default: + result = 0U; + break; } - } else { + } + else + { result = 0U; } - if (result != 0U) { + if (result != 0U) + { *response = DAP_OK; - } else { + } + 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 SWO_Mode(const uint8_t *request, uint8_t *response) +{ + uint8_t mode; uint32_t result; mode = *request; - switch (TraceMode) { + switch (TraceMode) + { #if (SWO_UART != 0) - case DAP_SWO_UART: - UART_SWO_Mode(0U); - break; + case DAP_SWO_UART: + UART_SWO_Mode(0U); + break; #endif #if (SWO_MANCHESTER != 0) - case DAP_SWO_MANCHESTER: - Manchester_SWO_Mode(0U); - break; + case DAP_SWO_MANCHESTER: + Manchester_SWO_Mode(0U); + break; #endif - default: - break; + default: + break; } - switch (mode) { - case DAP_SWO_OFF: - result = 1U; - break; + switch (mode) + { + case DAP_SWO_OFF: + result = 1U; + break; #if (SWO_UART != 0) - case DAP_SWO_UART: - result = UART_SWO_Mode(1U); - break; + 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; + case DAP_SWO_MANCHESTER: + result = Manchester_SWO_Mode(1U); + break; #endif - default: - result = 0U; - break; + default: + result = 0U; + break; } - if (result != 0U) { + if (result != 0U) + { TraceMode = mode; - } else { + } + else + { TraceMode = DAP_SWO_OFF; } TraceStatus = 0U; - if (result != 0U) { + if (result != 0U) + { *response = DAP_OK; - } else { + } + 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 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); + baudrate = (uint32_t)(*(request + 0) << 0) | + (uint32_t)(*(request + 1) << 8) | + (uint32_t)(*(request + 2) << 16) | + (uint32_t)(*(request + 3) << 24); - switch (TraceMode) { + switch (TraceMode) + { #if (SWO_UART != 0) - case DAP_SWO_UART: - baudrate = UART_SWO_Baudrate(baudrate); - break; + 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; + case DAP_SWO_MANCHESTER: + baudrate = Manchester_SWO_Baudrate(baudrate); + break; #endif - default: - baudrate = 0U; - break; + default: + baudrate = 0U; + break; } - if (baudrate == 0U) { + if (baudrate == 0U) + { TraceStatus = 0U; } - *response++ = (uint8_t)(baudrate >> 0); - *response++ = (uint8_t)(baudrate >> 8); + *response++ = (uint8_t)(baudrate >> 0); + *response++ = (uint8_t)(baudrate >> 8); *response++ = (uint8_t)(baudrate >> 16); - *response = (uint8_t)(baudrate >> 24); + *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 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) { + if (active != (TraceStatus & DAP_SWO_CAPTURE_ACTIVE)) + { + if (active) + { ClearTrace(); } - switch (TraceMode) { + switch (TraceMode) + { #if (SWO_UART != 0) - case DAP_SWO_UART: - result = UART_SWO_Control(active); - break; + 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; + case DAP_SWO_MANCHESTER: + result = Manchester_SWO_Control(active); + break; #endif - default: - result = 0U; - break; + default: + result = 0U; + break; } - if (result != 0U) { + if (result != 0U) + { TraceStatus = active; #if (SWO_STREAM != 0) - if (TraceTransport == 2U) { - osThreadFlagsSet(SWO_ThreadId, 1U); + if (TraceTransport == 2U) + { + xEventGroupSetBits(kSWO_Thread_event_group, SWO_GOT_DATA); } #endif } - } else { + } + else + { result = 1U; } - if (result != 0U) { + if (result != 0U) + { *response = DAP_OK; - } else { + } + 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 SWO_Status(uint8_t *response) +{ + uint8_t status; uint32_t count; status = GetTraceStatus(); - count = GetTraceCount(); + count = GetTraceCount(); *response++ = status; - *response++ = (uint8_t)(count >> 0); - *response++ = (uint8_t)(count >> 8); + *response++ = (uint8_t)(count >> 0); + *response++ = (uint8_t)(count >> 8); *response++ = (uint8_t)(count >> 16); - *response = (uint8_t)(count >> 24); + *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 SWO_ExtendedStatus(const uint8_t *request, uint8_t *response) +{ + uint8_t cmd; + uint8_t status; uint32_t count; -#if (TIMESTAMP_CLOCK != 0U) +#if (TIMESTAMP_CLOCK != 0U) uint32_t index; uint32_t tick; #endif @@ -653,36 +768,40 @@ uint32_t SWO_ExtendedStatus (const uint8_t *request, uint8_t *response) { num = 0U; cmd = *request; - if (cmd & 0x01U) { + if (cmd & 0x01U) + { status = GetTraceStatus(); *response++ = status; num += 1U; } - if (cmd & 0x02U) { + if (cmd & 0x02U) + { count = GetTraceCount(); - *response++ = (uint8_t)(count >> 0); - *response++ = (uint8_t)(count >> 8); + *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 { +#if (TIMESTAMP_CLOCK != 0U) + if (cmd & 0x04U) + { + do + { TraceUpdate = 0U; index = TraceTimestamp.index; - tick = TraceTimestamp.tick; + tick = TraceTimestamp.tick; } while (TraceUpdate != 0U); - *response++ = (uint8_t)(index >> 0); - *response++ = (uint8_t)(index >> 8); + *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); + *response++ = (uint8_t)(tick >> 0); + *response++ = (uint8_t)(tick >> 8); + *response++ = (uint8_t)(tick >> 16); + *response++ = (uint8_t)(tick >> 24); num += 4U; } #endif @@ -690,31 +809,36 @@ uint32_t SWO_ExtendedStatus (const uint8_t *request, uint8_t *response) { 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 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(); + count = GetTraceCount(); - if (TraceTransport == 1U) { - n = (uint32_t)(*(request+0) << 0) | - (uint32_t)(*(request+1) << 8); - if (n > (DAP_PACKET_SIZE - 4U)) { + 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) { + if (count > n) + { count = n; } - } else { + } + else + { count = 0U; } @@ -722,9 +846,11 @@ uint32_t SWO_Data (const uint8_t *request, uint8_t *response) { *response++ = (uint8_t)(count >> 0); *response++ = (uint8_t)(count >> 8); - if (TraceTransport == 1U) { + if (TraceTransport == 1U) + { index = TraceIndexO; - for (i = index, n = count; n; n--) { + for (i = index, n = count; n; n--) + { i &= SWO_BUFFER_SIZE - 1U; *response++ = TraceBuf[i++]; } @@ -735,68 +861,86 @@ uint32_t SWO_Data (const uint8_t *request, uint8_t *response) { return ((2U << 16) | (3U + count)); } - #if (SWO_STREAM != 0) // SWO Data Transfer complete callback -void SWO_TransferComplete (void) { +void SWO_TransferComplete(void) +{ TraceIndexO += TransferSize; TransferBusy = 0U; ResumeTrace(); - osThreadFlagsSet(SWO_ThreadId, 1U); + xEventGroupSetBits(kSWO_Thread_event_group, SWO_GOT_DATA); } // SWO Thread -__NO_RETURN void SWO_Thread (void *argument) { +void SWO_Thread(void *argument) +{ uint32_t timeout; uint32_t flags; uint32_t count; uint32_t index; uint32_t i, n; - (void) argument; + (void)argument; - timeout = osWaitForever; - - for (;;) { - flags = osThreadFlagsWait(1U, osFlagsWaitAny, timeout); - if (TraceStatus & DAP_SWO_CAPTURE_ACTIVE) { + 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 = osWaitForever; - flags = osFlagsErrorTimeout; } - if (TransferBusy == 0U) { + else + { + timeout = portMAX_DELAY; + flags = SWO_ERROR_TIME_OUT; + } + if (TransferBusy == 0U) + { count = GetTraceCount(); - if (count != 0U) { + if (count != 0U) + { index = TraceIndexO & (SWO_BUFFER_SIZE - 1U); n = SWO_BUFFER_SIZE - index; - if (count > n) { + if (count > n) + { count = n; } - if (flags != osFlagsErrorTimeout) { + if ((flags & SWO_ERROR_TIME_OUT) == 0) + { i = index & (USB_BLOCK_SIZE - 1U); - if (i == 0U) { + if (i == 0U) + { count &= ~(USB_BLOCK_SIZE - 1U); - } else { + // Take down to the nearest number that is a multiple of USB_BLOCK_SIZE + } + else + { n = USB_BLOCK_SIZE - i; - if (count >= n) { + if (count >= n) + { count = n; - } else { + } + else + { count = 0U; } } } - if (count != 0U) { + if (count != 0U) + { TransferSize = count; TransferBusy = 1U; - SWO_QueueTransfer(&TraceBuf[index], count); + SWO_QueueTransfer(&TraceBuf[index], count); //through USB } } } } } -#endif /* (SWO_STREAM != 0) */ +#endif /* (SWO_STREAM != 0) */ - -#endif /* ((SWO_UART != 0) || (SWO_MANCHESTER != 0)) */ +#endif /* ((SWO_UART != 0) || (SWO_MANCHESTER != 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/main/DAP_handle.c b/main/DAP_handle.c index 98d26c8..02975b9 100644 --- a/main/DAP_handle.c +++ b/main/DAP_handle.c @@ -14,32 +14,70 @@ #include "DAP.h" ////TODO: Merge this -#define DAP_PACKET_SIZE 512 +#define DAP_PACKET_SIZE 512 +static uint8_t data_out[DAP_PACKET_SIZE]; +static int dap_respond = 0; -uint8_t data_out[DAP_PACKET_SIZE]; -int respond = 0; - +// SWO Trace +static int swo_trace_respond = 0; +static uint8_t *swo_data_to_send; +static uint32_t num_swo_data; void handle_dap_data_request(usbip_stage2_header *header) { - uint8_t * data_in = (uint8_t *)header; + uint8_t *data_in = (uint8_t *)header; data_in = &(data_in[sizeof(usbip_stage2_header)]); // Point to the beginning of the URB packet - respond = DAP_ProcessCommand((uint8_t *)data_in, (uint8_t *)data_out); + dap_respond = DAP_ProcessCommand((uint8_t *)data_in, (uint8_t *)data_out); send_stage2_submit(header, 0, 0); - } void handle_dap_data_response(usbip_stage2_header *header) { - if (respond) { - respond = 0; - //os_printf("*** Will respond"); - send_stage2_submit_data(header, 0, data_out, DAP_PACKET_SIZE); - - //os_printf("*** RESPONDED ***"); - } else { - //os_printf("*** Will NOT respond"); - send_stage2_submit(header, 0, 0); - } + if (dap_respond) + { + dap_respond = 0; + //os_printf("*** Will respond"); + send_stage2_submit_data(header, 0, data_out, DAP_PACKET_SIZE); + + //os_printf("*** RESPONDED ***"); + } + else + { + //os_printf("*** Will NOT respond"); + send_stage2_submit(header, 0, 0); + } +} + +void handle_swo_trace_response(usbip_stage2_header *header) +{ + if (swo_trace_respond) + { + swo_trace_respond = 0; + //os_printf("*** Will respond"); + send_stage2_submit_data(header, 0, data_out, DAP_PACKET_SIZE); + + //os_printf("*** RESPONDED ***"); + } + else + { + //os_printf("*** Will NOT respond"); + 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 ... } \ No newline at end of file diff --git a/main/DAP_handle.h b/main/DAP_handle.h index 903bc58..5ac91f2 100644 --- a/main/DAP_handle.h +++ b/main/DAP_handle.h @@ -5,4 +5,5 @@ void handle_dap_data_request(usbip_stage2_header *header); void handle_dap_data_response(usbip_stage2_header *header); +void handle_swo_trace_response(usbip_stage2_header *header); #endif \ No newline at end of file diff --git a/main/main.c b/main/main.c index 03f5354..b658cec 100644 --- a/main/main.c +++ b/main/main.c @@ -26,13 +26,14 @@ #include "tcp_server.h" #include "timer.h" #include "wifi_configuration.h" - /* The examples use simple WiFi configuration that you can set via 'make menuconfig'. If you'd rather not, just change the below entries to strings with the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" */ +extern void SWO_Thread(void *argument); +extern void usart_monitor_task(void *argument); /* FreeRTOS event group to signal when we are connected & ready to make a request */ static EventGroupHandle_t wifi_event_group; @@ -95,6 +96,7 @@ 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)); @@ -109,7 +111,7 @@ static void initialise_wifi(void) ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); ESP_ERROR_CHECK(esp_wifi_start()); - + } static void wait_for_ip() @@ -135,6 +137,10 @@ void app_main() initialise_wifi(); wait_for_ip(); - xTaskCreate(timer_create_task, "timer_create", 1024, NULL, 10, NULL); + xTaskCreate(timer_create_task, "timer_create", 512, NULL, 10, NULL); xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 5, NULL); + // 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/usbip_server.c b/main/usbip_server.c index 0317f6f..cf87a53 100644 --- a/main/usbip_server.c +++ b/main/usbip_server.c @@ -27,6 +27,10 @@ static void unpack(void *data, int size); static int handle_submit(usbip_stage2_header *header); 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); @@ -41,7 +45,7 @@ int attach(uint8_t *buffer, uint32_t length) handle_device_list(buffer, length); break; - case USBIP_STAGE1_CMD_DEVICE_ATTACH: // OP_REQ_IMPORT + case USBIP_STAGE1_CMD_DEVICE_ATTACH: // OP_REQ_IMPORT handle_device_attach(buffer, length); break; @@ -176,7 +180,7 @@ static void send_interface_info() int emulate(uint8_t *buffer, uint32_t length) { // usbip_stage2_header header; - int command = read_stage2_command((usbip_stage2_header *)buffer, length); + int command = read_stage2_command((usbip_stage2_header *)buffer, length); if (command < 0) { return -1; @@ -258,7 +262,6 @@ static void unpack(void *data, int size) } } - /** * @brief * @@ -272,7 +275,7 @@ static int handle_submit(usbip_stage2_header *header) handleUSBControlRequest(header); break; - // data + // endpoint 1 data receicve and response case 0x01: if (header->base.direction == 0) { @@ -285,7 +288,19 @@ static int handle_submit(usbip_stage2_header *header) 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) @@ -320,7 +335,7 @@ void send_stage2_submit(usbip_stage2_header *req_header, int32_t status, int32_t 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) +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); @@ -329,4 +344,24 @@ void send_stage2_submit_data(usbip_stage2_header *req_header, int32_t status, co { 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 From ad6b9b3609207840448b6f3f3d72e438c49936e4 Mon Sep 17 00:00:00 2001 From: windowsair Date: Fri, 31 Jan 2020 15:57:17 +0800 Subject: [PATCH 11/15] fix: Fixed some rookie mistakes This is a temporary "stable" release. See the Readme.md file in the root directory for more instructions. --- README.md | 10 +- components/DAP/config/DAP_config.h | 15 ++- components/README.md | 4 +- components/USBIP/MSOS20Descriptors.c | 166 +++++++++++++-------------- components/USBIP/MSOS20Descriptors.h | 160 +++++++++++++------------- components/USBIP/USB_handle.c | 38 +++++- components/USBIP/USBd_config.c | 34 +++--- main/DAP_handle.c | 29 ++--- main/main.c | 2 + main/tcp_server.c | 122 ++++++++++---------- main/usbip_server.c | 23 ++-- main/wifi_configuration.h | 4 +- 12 files changed, 318 insertions(+), 289 deletions(-) diff --git a/README.md b/README.md index e00d592..4a1abdf 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ -# Setup -1. DAP_Setup() -2. Server begin +# Attention -# Loop \ No newline at end of file +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 under USB HID. Once the USBIP problem is solved, we will immediately transfer it to work under WinUSB \ No newline at end of file diff --git a/components/DAP/config/DAP_config.h b/components/DAP/config/DAP_config.h index fccf7d3..a61956e 100644 --- a/components/DAP/config/DAP_config.h +++ b/components/DAP/config/DAP_config.h @@ -29,6 +29,7 @@ #define __DAP_CONFIG_H__ #include +#include #include "cmsis_compiler.h" #include "gpio.h" #include "gpio_struct.h" @@ -153,8 +154,9 @@ __STATIC_INLINE uint8_t DAP_GetVendorString(char *str) ////TODO: fill this // In fact, Keil can get the corresponding information through USB // without filling in this information. - (void)str; - return (0U); + // (void)str; + strcpy(str, "windowsair"); + return (sizeof("windowsair")); } /** @@ -165,8 +167,9 @@ __STATIC_INLINE uint8_t DAP_GetVendorString(char *str) */ __STATIC_INLINE uint8_t DAP_GetProductString(char *str) { - (void)str; - return (0U); + //(void)str; + strcpy(str, "CMSIS-DAP v2"); + return (sizeof("CMSIS-DAP v2")); } /** @@ -177,8 +180,8 @@ __STATIC_INLINE uint8_t DAP_GetProductString(char *str) */ __STATIC_INLINE uint8_t DAP_GetSerNumString(char *str) { - (void)str; - return (0U); + strcpy(str, "1234"); + return (sizeof("1234")); } ///@} diff --git a/components/README.md b/components/README.md index e52e5e9..3fc0da1 100644 --- a/components/README.md +++ b/components/README.md @@ -1,4 +1,2 @@ # TODO -1. adapt to special hardware -2. USB -3. Significant Bit is difficult to judge, may need to dive into the details of usbip \ No newline at end of file +1. USB \ No newline at end of file diff --git a/components/USBIP/MSOS20Descriptors.c b/components/USBIP/MSOS20Descriptors.c index 4337076..6621557 100644 --- a/components/USBIP/MSOS20Descriptors.c +++ b/components/USBIP/MSOS20Descriptors.c @@ -1,84 +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 +/** + * @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 index 61a7ea3..51bbcb1 100644 --- a/components/USBIP/MSOS20Descriptors.h +++ b/components/USBIP/MSOS20Descriptors.h @@ -1,81 +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 */ - +/** + * @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 index a6dd0ce..666d026 100644 --- a/components/USBIP/USB_handle.c +++ b/components/USBIP/USB_handle.c @@ -19,6 +19,12 @@ #include "usb_defs.h" #include "MSOS20Descriptors.h" +const char *strings_list[] = { + 0, // reserved: available languages + "windowsair", + "CMSIS-DAP v2", + "1234", +}; // handle functions static void handleGetDescriptor(usbip_stage2_header *header); @@ -192,7 +198,7 @@ static void handleGetDescriptor(usbip_stage2_header *header) { case USB_DT_DEVICE: // get device descriptor os_printf("* GET 0x01 DEVICE DESCRIPTOR\r\n"); - send_stage2_submit_data(header, 0, kUSBd0DeviceDescriptor, sizeof(kUSBd0DeviceDescriptor)); + send_stage2_submit_data(header, 0, &kUSBd0DeviceDescriptor[0], sizeof(kUSBd0DeviceDescriptor)); break; case USB_DT_CONFIGURATION: // get configuration descriptor @@ -223,9 +229,29 @@ static void handleGetDescriptor(usbip_stage2_header *header) 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[256]; + 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("***Unsupported operation***\r\n"); + 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; @@ -242,7 +268,7 @@ static void handleGetDescriptor(usbip_stage2_header *header) break; case USB_DT_DEVICE_QUALIFIER: - os_printf("* GET 0x06 DEVICE QUALIFIER DESCRIPTOR"); + os_printf("* GET 0x06 DEVICE QUALIFIER DESCRIPTOR\r\n"); usb_device_qualifier_descriptor desc; @@ -252,13 +278,13 @@ static void handleGetDescriptor(usbip_stage2_header *header) break; case USB_DT_OTHER_SPEED_CONFIGURATION: - os_printf("GET 0x07 [UNIMPLEMENTED] 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"); + os_printf("GET 0x08 [UNIMPLEMENTED] USB_DT_INTERFACE_POWER\r\n"); ////TODO:UNIMPLEMENTED send_stage2_submit(header, 0, 0); break; @@ -268,7 +294,7 @@ static void handleGetDescriptor(usbip_stage2_header *header) send_stage2_submit_data(header, 0, bosDescriptor, sizeof(bosDescriptor)); break; default: - os_printf("USB unknown Get Descriptor requested:%d", header->u.cmd_submit.request.wValue.u8lo); + os_printf("USB unknown Get Descriptor requested:%d\r\n", header->u.cmd_submit.request.wValue.u8lo); break; } } diff --git a/components/USBIP/USBd_config.c b/components/USBIP/USBd_config.c index c266c16..f28d636 100644 --- a/components/USBIP/USBd_config.c +++ b/components/USBIP/USBd_config.c @@ -25,7 +25,7 @@ const uint8_t kUSBd0DeviceDescriptor[0x12] = { 0x12, // bLength - USB_DT_DEVICE, // bDescriptorType (constant) + USB_DT_DEVICE, // bDescriptorType USBShort(0x0210), // bcdUSB ////TODO: Is it also available elsewhere? @@ -34,14 +34,14 @@ const uint8_t kUSBd0DeviceDescriptor[0x12] = 0x00, // bDeviceSubClass 0x00, // bDeviceProtocol - USBD0_MAX_PACKET0, // Maximum packet size for default pipe. - USBShort(USBD0_DEV_DESC_IDVENDOR), // Vendor ID (VID). - USBShort(USBD0_DEV_DESC_IDPRODUCT), // Product ID (PID). - USBShort(USBD0_DEV_DESC_BCDDEVICE), // Device Version BCD. - 0x01, // Index of Manufacturer string identifier. - 0x02, // Index of Product string identifier. - 0x03 * USBD0_STR_DESC_SER_EN, // Index of Product serial number. - 0x01 // Number of configurations. + 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. }; @@ -60,7 +60,7 @@ const uint8_t kUSBd0InterfaceDescriptor[0x1E]= USB_DT_INTERFACE, // bDescriptorType USBD_CUSTOM_CLASS0_IF0_NUM, // bInterfaceNumber USBD_CUSTOM_CLASS0_IF0_ALT, // bAlternateSetting - 0x03, // bNumEndpoints(we will use three endpoints) + 0x03, // bNumEndpoints(we will use 3 endpoints) // USBD_CUSTOM_CLASS0_IF0_CLASS, // bInterfaceClass USBD_CUSTOM_CLASS0_IF0_SUBCLASS, // bInterfaceSubClass @@ -91,7 +91,7 @@ const uint8_t kUSBd0InterfaceDescriptor[0x1E]= USB_DT_ENDPOINT, // bDescriptorType 0x01, // bEndpointAddress USB_ENDPOINT_ATTR_BULK, // bmAttributes - USBShort(512), // wMaxPacketSize + USBShort(512), // wMaxPacketSize // We assume that it always runs in High Speed. 0x00, // bInterval @@ -102,16 +102,17 @@ const uint8_t kUSBd0InterfaceDescriptor[0x1E]= USB_DT_ENDPOINT, // bDescriptorType 0x81, // bEndpointAddress USB_ENDPOINT_ATTR_BULK, // bmAttributes - USBShort(512), // wMaxPacketSize - 0x00, // bInterval + 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 + USBShort(512), // wMaxPacketSize 0x00, // bInterval @@ -123,9 +124,8 @@ const uint8_t kUSBd0ConfigDescriptor[LENGTHOFCONFIGDESCRIPTOR] = { // Configuration descriptor header. - 0x09, // bLength -> 0x09?? may be ok... 1-23 - 0x03, // bDescriptorType - // constant, set to 0x03 + 0x09, // bLength + USB_DT_CONFIGURATION, // bDescriptorType USBShort((sizeof(kUSBd0InterfaceDescriptor)) + (LENGTHOFCONFIGDESCRIPTOR)), // wTotalLength diff --git a/main/DAP_handle.c b/main/DAP_handle.c index 02975b9..d80e4e3 100644 --- a/main/DAP_handle.c +++ b/main/DAP_handle.c @@ -12,7 +12,7 @@ #include "usbip_server.h" #include "DAP_handle.h" #include "DAP.h" - +#include "esp_libc.h" ////TODO: Merge this #define DAP_PACKET_SIZE 512 @@ -30,16 +30,18 @@ void handle_dap_data_request(usbip_stage2_header *header) data_in = &(data_in[sizeof(usbip_stage2_header)]); // Point to the beginning of the URB packet dap_respond = DAP_ProcessCommand((uint8_t *)data_in, (uint8_t *)data_out); - send_stage2_submit(header, 0, 0); + handle_dap_data_response(header); + //send_stage2_submit(header, 0, 0); } void handle_dap_data_response(usbip_stage2_header *header) { if (dap_respond) { - dap_respond = 0; - //os_printf("*** Will respond"); - send_stage2_submit_data(header, 0, data_out, DAP_PACKET_SIZE); + //os_printf("*** Will respond"); + + send_stage2_submit_data(header, 0, data_out, (dap_respond & 0x0000FFFF)); + dap_respond = 0; //os_printf("*** RESPONDED ***"); } else @@ -66,18 +68,19 @@ void handle_swo_trace_response(usbip_stage2_header *header) } } - // 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; +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 SWO_AbortTransfer(void) +{ + //USBD_EndpointAbort(0U, USB_ENDPOINT_IN(2U)); + ////TODO: unlink might be useful ... } \ No newline at end of file diff --git a/main/main.c b/main/main.c index b658cec..5676c15 100644 --- a/main/main.c +++ b/main/main.c @@ -34,6 +34,7 @@ extern void SWO_Thread(void *argument); extern void usart_monitor_task(void *argument); +extern void DAP_Setup(void); /* FreeRTOS event group to signal when we are connected & ready to make a request */ static EventGroupHandle_t wifi_event_group; @@ -136,6 +137,7 @@ 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, 5, NULL); diff --git a/main/tcp_server.c b/main/tcp_server.c index 5031600..fbb16b7 100644 --- a/main/tcp_server.c +++ b/main/tcp_server.c @@ -65,7 +65,7 @@ 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) @@ -73,7 +73,7 @@ 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) @@ -81,7 +81,7 @@ 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 @@ -89,82 +89,76 @@ void tcp_server_task(void *pvParameters) struct sockaddr_in sourceAddr; #endif uint32_t addrLen = sizeof(sourceAddr); - kSock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen); - if (kSock < 0) - { - os_printf("Unable to accept connection: errno %d\r\n", errno); - break; - } - os_printf("Socket accepted"); - while (1) { - int len = recv(kSock, 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 + os_printf("Socket accepted\r\n"); + + while (1) { + int len = recv(kSock, rx_buffer, 2047, 0); + // Error occured during receiving + if (len < 0) + { + 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); - } + // 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); + inet_ntoa_r(((struct sockaddr_in *)&sourceAddr)->sin_addr.s_addr, addr_str, sizeof(addr_str) - 1); #endif - 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); - switch (kState) - { - case ACCEPTING: - kState = ATTACHING; - break; + switch (kState) + { + case ACCEPTING: + kState = ATTACHING; - case ATTACHING: - attach(rx_buffer, len); - break; + case ATTACHING: + attach(rx_buffer, len); + break; - case EMULATING: - emulate(rx_buffer, len); - break; + case EMULATING: + emulate(rx_buffer, len); + break; + default: + os_printf("unkonw kstate!\r\n"); + } } - - // int err = send(sock, rx_buffer, len, 0); - // if (err < 0) - // { - // os_printf("Error occured during sending: errno %d\r\n", errno); - // break; - // } } - } - kState = ACCEPTING; - if (kSock != -1) - { - os_printf("Shutting down socket and restarting...\r\n"); - shutdown(kSock, 0); - close(kSock); + // kState = ACCEPTING; + if (kSock != -1) + { + os_printf("Shutting down socket and restarting...\r\n"); + //shutdown(kSock, 0); + close(kSock); - shutdown(listen_sock, 0); - close(listen_sock); - vTaskDelay(5); + //shutdown(listen_sock, 0); + //close(listen_sock); + //vTaskDelay(5); + } } } vTaskDelete(NULL); diff --git a/main/usbip_server.c b/main/usbip_server.c index cf87a53..f9ad467 100644 --- a/main/usbip_server.c +++ b/main/usbip_server.c @@ -53,7 +53,7 @@ int attach(uint8_t *buffer, uint32_t length) os_printf("attach Unknown command: %d\r\n", command); break; } - return 0; ////TODO: ... + return 0; } static int read_stage1_command(uint8_t *buffer, uint32_t length) @@ -130,16 +130,15 @@ static void send_device_list() static void send_device_info() { - os_printf("Sending 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(2); - device.speed = htonl(2); // what is this??? - //// TODO: 0200H for USB2.0 + 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); @@ -183,7 +182,7 @@ int emulate(uint8_t *buffer, uint32_t length) int command = read_stage2_command((usbip_stage2_header *)buffer, length); if (command < 0) { - return -1; + return -1; } switch (command) @@ -211,7 +210,7 @@ static int read_stage2_command(usbip_stage2_header *header, uint32_t length) } //client.readBytes((uint8_t *)&header, sizeof(usbip_stage2_header)); - unpack((uint32_t *)&header, sizeof(usbip_stage2_header)); + unpack((uint32_t *)header, sizeof(usbip_stage2_header)); return header->base.command; } @@ -263,7 +262,7 @@ static void unpack(void *data, int size) } /** - * @brief + * @brief USB transaction processing * */ static int handle_submit(usbip_stage2_header *header) @@ -324,18 +323,18 @@ void send_stage2_submit(usbip_stage2_header *req_header, int32_t status, int32_t { req_header->base.command = USBIP_STAGE2_RSP_SUBMIT; - req_header->base.direction = !req_header->base.direction; + req_header->base.direction = !(req_header->base.direction); - memset(&req_header->u.ret_submit, 0, sizeof(usbip_stage2_header_ret_submit)); + 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)); + 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) +void send_stage2_submit_data(usbip_stage2_header *req_header, int32_t status, const uint8_t *const data, int32_t data_length) { send_stage2_submit(req_header, status, data_length); diff --git a/main/wifi_configuration.h b/main/wifi_configuration.h index cb2701c..407261e 100644 --- a/main/wifi_configuration.h +++ b/main/wifi_configuration.h @@ -13,6 +13,8 @@ #define EXAMPLE_WIFI_SSID "DAP" #define EXAMPLE_WIFI_PASS "12345678" -#define PORT 22350 +#define PORT 3240 + +#define CONFIG_EXAMPLE_IPV4 1 #endif \ No newline at end of file From 3258b847958f4f340f4883c06b81a2f8fd54df79 Mon Sep 17 00:00:00 2001 From: windowsair Date: Fri, 31 Jan 2020 16:24:06 +0800 Subject: [PATCH 12/15] fix: Fixed some rookie mistakes This is a temporary "stable" release. See the Readme.md file in the root directory for more instructions. --- main/DAP_handle.c | 4 ++-- main/usbip_server.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/main/DAP_handle.c b/main/DAP_handle.c index d80e4e3..9d928fb 100644 --- a/main/DAP_handle.c +++ b/main/DAP_handle.c @@ -30,8 +30,8 @@ void handle_dap_data_request(usbip_stage2_header *header) data_in = &(data_in[sizeof(usbip_stage2_header)]); // Point to the beginning of the URB packet dap_respond = DAP_ProcessCommand((uint8_t *)data_in, (uint8_t *)data_out); - handle_dap_data_response(header); - //send_stage2_submit(header, 0, 0); + //handle_dap_data_response(header); + send_stage2_submit(header, 0, 0); } void handle_dap_data_response(usbip_stage2_header *header) { diff --git a/main/usbip_server.c b/main/usbip_server.c index f9ad467..2227bd2 100644 --- a/main/usbip_server.c +++ b/main/usbip_server.c @@ -283,7 +283,7 @@ static int handle_submit(usbip_stage2_header *header) } else { - // os_printf("EP 01 DATA TO HOST"); + os_printf("EP 01 DATA TO HOST\r\n"); handle_dap_data_response(header); } break; @@ -334,7 +334,7 @@ void send_stage2_submit(usbip_stage2_header *req_header, int32_t status, int32_t send(kSock, req_header, sizeof(usbip_stage2_header), 0); } -void send_stage2_submit_data(usbip_stage2_header *req_header, int32_t status, const uint8_t *const data, int32_t data_length) +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); From c3582e8e2beda2b547fe8783ea319ad2354dc628 Mon Sep 17 00:00:00 2001 From: windowsair Date: Sun, 2 Feb 2020 14:49:14 +0800 Subject: [PATCH 13/15] feat: Switch to USB HID, now fully available --- components/DAP/config/DAP_config.h | 243 +++++++++++++++++++++-------- components/USBIP/USB_handle.c | 57 +++++-- components/USBIP/USBd_config.c | 98 ++++++++++++ components/USBIP/USBd_config.h | 46 ++++-- components/USBIP/usb_defs.h | 11 ++ main/DAP_handle.c | 4 +- main/main.c | 6 +- main/tcp_server.c | 35 +++-- main/usbip_server.c | 8 +- sdkconfig | 10 +- 10 files changed, 399 insertions(+), 119 deletions(-) diff --git a/components/DAP/config/DAP_config.h b/components/DAP/config/DAP_config.h index a61956e..226145b 100644 --- a/components/DAP/config/DAP_config.h +++ b/components/DAP/config/DAP_config.h @@ -34,11 +34,42 @@ #include "gpio.h" #include "gpio_struct.h" #include "timer_struct.h" - - - - - +#include "esp8266/pin_mux_register.h" +#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 //************************************************************************************************** /** \defgroup DAP_Config_Debug_gr CMSIS-DAP Debug Unit Information @@ -63,7 +94,7 @@ This information includes: /// Processor Clock of the Cortex-M MCU used in the Debug Unit. /// This value is used to calculate the SWD/JTAG clock speed. -#define CPU_CLOCK 160000000U ///< Specifies the CPU Clock in Hz. +#define CPU_CLOCK 160000000 ///< Specifies the CPU Clock in Hz. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<160MHz /// Number of processor cycles for I/O Port write operations. @@ -80,7 +111,7 @@ This information includes: /// 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. +#define DAP_JTAG 0 ///< 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. @@ -100,7 +131,7 @@ This information includes: /// This configuration settings is used to optimize the communication performance with the /// debugger and depends on the USB peripheral. Typical vales are 64 for Full-speed USB HID or WinUSB, /// 1024 for High-speed USB HID and 512 for High-speed USB WinUSB. -#define DAP_PACKET_SIZE 512U ///< Specifies Packet Size in bytes. +#define DAP_PACKET_SIZE 64U ///< Specifies Packet Size in bytes. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<< 512 for High-speed USB WinUSB. /// Maximum Package Buffers for Command and Response data. @@ -111,22 +142,22 @@ This information includes: /// 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 1 ///< SWO UART: 1 = available, 0 = not available. +#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. +#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 1 ///< SWO Manchester: 1 = available, 0 = not available. +#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 1 ///< SWO Streaming Trace: 1 = available, 0 = not available. +#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). @@ -168,7 +199,7 @@ __STATIC_INLINE uint8_t DAP_GetVendorString(char *str) __STATIC_INLINE uint8_t DAP_GetProductString(char *str) { //(void)str; - strcpy(str, "CMSIS-DAP v2"); + strcpy(str, "CMSIS-DAP v2"); return (sizeof("CMSIS-DAP v2")); } @@ -180,7 +211,7 @@ __STATIC_INLINE uint8_t DAP_GetProductString(char *str) */ __STATIC_INLINE uint8_t DAP_GetSerNumString(char *str) { - strcpy(str, "1234"); + strcpy(str, "1234"); return (sizeof("1234")); } @@ -189,14 +220,14 @@ __STATIC_INLINE uint8_t DAP_GetSerNumString(char *str) // Modify your pins here // ATTENTION: DO NOT USE RTC GPIO16 -#define PIN_SWDIO 2 -#define PIN_SWCLK 0 -#define PIN_TDO 4 -#define PIN_TDI 5 -#define PIN_nTRST 1 // optional -#define PIN_nRESET 16 +#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 13 +#define PIN_LED_CONNECTED 2 // LED_BUILTIN #define PIN_LED_RUNNING 15 @@ -244,16 +275,49 @@ of the same I/O port. The following SWDIO I/O Pin functions are provided: */ __STATIC_INLINE void PORT_JTAG_SETUP(void) { - gpio_set_direction(PIN_SWCLK, GPIO_MODE_OUTPUT); - gpio_set_direction(PIN_SWDIO, GPIO_MODE_OUTPUT); + gpio_pin_reg_t pin_reg; - gpio_set_direction(PIN_TDO, GPIO_MODE_DEF_INPUT); - gpio_set_direction(PIN_TDI, GPIO_MODE_OUTPUT); + // 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_nTRST, GPIO_MODE_OUTPUT_OD); - gpio_set_direction(PIN_nRESET, GPIO_MODE_OUTPUT_OD); - gpio_set_pull_mode(PIN_nTRST, GPIO_PULLUP_ONLY); - gpio_set_pull_mode(PIN_nRESET, GPIO_PULLUP_ONLY); + // 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); } /** @@ -265,16 +329,49 @@ __STATIC_INLINE void PORT_JTAG_SETUP(void) */ __STATIC_INLINE void PORT_SWD_SETUP(void) { - gpio_set_direction(PIN_SWCLK, GPIO_MODE_OUTPUT); - gpio_set_direction(PIN_SWDIO, GPIO_MODE_OUTPUT); + gpio_pin_reg_t pin_reg; - gpio_set_direction(PIN_TDO, GPIO_MODE_DEF_INPUT); - gpio_set_direction(PIN_TDI, GPIO_MODE_OUTPUT); + // 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_nTRST, GPIO_MODE_OUTPUT_OD); - gpio_set_direction(PIN_nRESET, GPIO_MODE_OUTPUT_OD); - gpio_set_pull_mode(PIN_nTRST, GPIO_PULLUP_ONLY); - gpio_set_pull_mode(PIN_nRESET, GPIO_PULLUP_ONLY); + // 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); } /** @@ -286,14 +383,31 @@ __STATIC_INLINE void PORT_SWD_SETUP(void) __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_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_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_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 ------------------------------------- @@ -306,7 +420,7 @@ __STATIC_INLINE void PORT_OFF(void) __STATIC_FORCEINLINE uint32_t PIN_SWCLK_TCK_IN(void) { ////TODO: can we set to 0? - return ((GPIO.in >> PIN_SWCLK) & 0x1); + return 0; } /** @@ -338,7 +452,7 @@ __STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR(void) */ __STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN(void) { - return ((GPIO.in >> PIN_SWDIO) & 0x1); + return ((GPIO.in >> PIN_SWDIO) & 0x1) ? 1 : 0; } /** @@ -368,7 +482,7 @@ __STATIC_FORCEINLINE void PIN_SWDIO_TMS_CLR(void) */ __STATIC_FORCEINLINE uint32_t PIN_SWDIO_IN(void) { - return ((GPIO.in >> PIN_SWDIO) & 0x1); + return ((GPIO.in >> PIN_SWDIO) & 0x1) ? 1 : 0; } /** @@ -388,11 +502,13 @@ __STATIC_FORCEINLINE void PIN_SWDIO_OUT(uint32_t bit) { //set bit GPIO.out_w1ts |= (0x1 << PIN_SWDIO); + } else { //reset bit GPIO.out_w1tc |= (0x1 << PIN_SWDIO); + } } @@ -407,6 +523,7 @@ __STATIC_FORCEINLINE void PIN_SWDIO_OUT_ENABLE(void) // set \ref gpio_set_direction -> OUTPUT GPIO.enable_w1ts |= (0x1 << PIN_SWDIO); + GPIO.pin[PIN_SWDIO].driver = 0; } /** @@ -420,6 +537,7 @@ __STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE(void) // 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 --------------------------------------------- @@ -431,7 +549,7 @@ __STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE(void) */ __STATIC_FORCEINLINE uint32_t PIN_TDI_IN(void) { - return ((GPIO.in >> PIN_TDI) & 0x1); + return ((GPIO.in >> PIN_TDI) & 0x1) ? 1 : 0; } /** @@ -446,11 +564,13 @@ __STATIC_FORCEINLINE void PIN_TDI_OUT(uint32_t bit) { //set bit GPIO.out_w1ts |= (0x1 << PIN_TDI); + } else { //reset bit GPIO.out_w1tc |= (0x1 << PIN_TDI); + } } @@ -463,7 +583,7 @@ __STATIC_FORCEINLINE void PIN_TDI_OUT(uint32_t bit) */ __STATIC_FORCEINLINE uint32_t PIN_TDO_IN(void) { - return ((GPIO.in >> PIN_TDI) & 0x1); + return ((GPIO.in >> PIN_TDO) & 0x1) ? 1 : 0; } // nTRST Pin I/O ------------------------------------------- @@ -475,7 +595,7 @@ __STATIC_FORCEINLINE uint32_t PIN_TDO_IN(void) */ __STATIC_FORCEINLINE uint32_t PIN_nTRST_IN(void) { - return ((GPIO.in >> PIN_nTRST) & 0x1); + return 0; // not available } /** @@ -487,17 +607,18 @@ __STATIC_FORCEINLINE uint32_t PIN_nTRST_IN(void) */ __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); - } + // ////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------------------------------------------ @@ -509,7 +630,7 @@ __STATIC_FORCEINLINE void PIN_nTRST_OUT(uint32_t bit) */ __STATIC_FORCEINLINE uint32_t PIN_nRESET_IN(void) { - return ((GPIO.in >> PIN_nRESET) & 0x1); + return ((GPIO.in >> PIN_nRESET) & 0x1) ? 1 : 0; } /** diff --git a/components/USBIP/USB_handle.c b/components/USBIP/USB_handle.c index 666d026..62ba946 100644 --- a/components/USBIP/USB_handle.c +++ b/components/USBIP/USB_handle.c @@ -19,11 +19,18 @@ #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", - "CMSIS-DAP v2", - "1234", + 0, // reserved: available languages + "windowsair", + "esp8266 CMSIS-DAP", + "1234", }; // handle functions static void handleGetDescriptor(usbip_stage2_header *header); @@ -106,6 +113,10 @@ void handleUSBControlRequest(usbip_stage2_header *header) break; case 0x80: // *IMPORTANT* +#if (USE_WINUSB == 0) + case 0x81: +#endif + { switch (header->u.cmd_submit.request.bRequest) { case USB_REQ_GET_CONFIGURATION: @@ -125,6 +136,8 @@ void handleUSBControlRequest(usbip_stage2_header *header) break; } break; + } +#if (USE_WINUSB == 1) case 0x81: // ignore... switch (header->u.cmd_submit.request.bRequest) { @@ -147,7 +160,7 @@ void handleUSBControlRequest(usbip_stage2_header *header) break; } break; - +#endif case 0x82: // ignore... switch (header->u.cmd_submit.request.bRequest) { @@ -182,8 +195,22 @@ void handleUSBControlRequest(usbip_stage2_header *header) header->u.cmd_submit.request.bmRequestType, header->u.cmd_submit.request.bRequest, *wIndex); break; } + 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); @@ -222,7 +249,7 @@ static void handleGetDescriptor(usbip_stage2_header *header) break; case USB_DT_STRING: - os_printf("* GET 0x03 STRING DESCRIPTOR\r\n"); + //os_printf("* GET 0x03 STRING DESCRIPTOR\r\n"); if (header->u.cmd_submit.request.wValue.u8lo == 0) { @@ -231,27 +258,27 @@ static void handleGetDescriptor(usbip_stage2_header *header) } 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); + //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[256]; + 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); + } + 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; @@ -293,8 +320,14 @@ static void handleGetDescriptor(usbip_stage2_header *header) 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"); + 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/USBd_config.c b/components/USBIP/USBd_config.c index f28d636..598e7d9 100644 --- a/components/USBIP/USBd_config.c +++ b/components/USBIP/USBd_config.c @@ -54,6 +54,8 @@ const uint8_t kUSBd0DeviceDescriptor[0x12] = // Standard Interface Descriptor + +#if (USE_WINUSB ==1) const uint8_t kUSBd0InterfaceDescriptor[0x1E]= { 0x09, // bLength @@ -118,8 +120,58 @@ const uint8_t kUSBd0InterfaceDescriptor[0x1E]= }; +#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 + 0xff, // bInterval + + /* Pysical endpoint 1 */ + + 0x07, // bLength + USB_DT_ENDPOINT, // bDescriptorType + 0x01, // bEndpointAddress + USB_ENDPOINT_ATTR_INTERRUPT, // bmAttributes + USBShort(64), // wMaxPacketSize + 0xff, // bInterval +}; +#endif + // Standard Configuration Descriptor #define LENGTHOFCONFIGDESCRIPTOR 9 + +#if (USE_WINUSB == 1) const uint8_t kUSBd0ConfigDescriptor[LENGTHOFCONFIGDESCRIPTOR] = { // Configuration descriptor header. @@ -139,6 +191,52 @@ const uint8_t kUSBd0ConfigDescriptor[LENGTHOFCONFIGDESCRIPTOR] = 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, 0x40, // Report Count (64) + 0x09, 0x01, // Usage (0x01) + 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x95, 0x40, // 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 +}; + + + + /** diff --git a/components/USBIP/USBd_config.h b/components/USBIP/USBd_config.h index 6af8944..dc3a3e2 100644 --- a/components/USBIP/USBd_config.h +++ b/components/USBIP/USBd_config.h @@ -1,34 +1,39 @@ #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 +#define USBD0_DEV_DESC_IDVENDOR 0xC251 // Product ID assigned by manufacturer (idProduct). -#define USBD0_DEV_DESC_IDPRODUCT 0xF00A +#define USBD0_DEV_DESC_IDPRODUCT 0xF00A // Device Release Number in binary-coded decimal (bcdDevice). -#define USBD0_DEV_DESC_BCDDEVICE 0x0100 +#define USBD0_DEV_DESC_BCDDEVICE 0x0100 // Maximum packet size for Endpoint 0 (bMaxPacketSize0). -#define USBD0_MAX_PACKET0 64 +#define USBD0_MAX_PACKET0 64 // If disabled Serial Number String will not be assigned to USB Device. -#define USBD0_STR_DESC_SER_EN 1 +#define USBD0_STR_DESC_SER_EN 1 // bmAttributes -#define USBD0_CFG_DESC_BMATTRIBUTES 0x80 +#define USBD0_CFG_DESC_BMATTRIBUTES 0x80 // bMaxPower -#define USBD0_CFG_DESC_BMAXPOWER 250 - +#define USBD0_CFG_DESC_BMAXPOWER 250 // Interface Number -#define USBD_CUSTOM_CLASS0_IF0_NUM 0 +#define USBD_CUSTOM_CLASS0_IF0_NUM 0 // Alternate Setting -#define USBD_CUSTOM_CLASS0_IF0_ALT 0 +#define USBD_CUSTOM_CLASS0_IF0_ALT 0 // Class Code -#define USBD_CUSTOM_CLASS0_IF0_CLASS 0xFF // 0xFF: Vendor Specific +#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 @@ -36,19 +41,26 @@ // Protocol Code #define USBD_CUSTOM_CLASS0_IF0_PROTOCOL 0x00 - - - - ///////////////////////////////////////////// + +// common part extern const uint8_t kUSBd0DeviceDescriptor[0x12]; -extern const uint8_t kUSBd0InterfaceDescriptor[0x1E]; -extern const uint8_t kUSBd0ConfigDescriptor[0x09]; 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 index c33fa06..0377dc4 100644 --- a/components/USBIP/usb_defs.h +++ b/components/USBIP/usb_defs.h @@ -98,6 +98,14 @@ typedef struct #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 /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// @@ -115,6 +123,9 @@ typedef struct #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 /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// diff --git a/main/DAP_handle.c b/main/DAP_handle.c index 9d928fb..4f51da4 100644 --- a/main/DAP_handle.c +++ b/main/DAP_handle.c @@ -14,7 +14,7 @@ #include "DAP.h" #include "esp_libc.h" ////TODO: Merge this -#define DAP_PACKET_SIZE 512 +#define DAP_PACKET_SIZE 64 static uint8_t data_out[DAP_PACKET_SIZE]; static int dap_respond = 0; @@ -40,7 +40,7 @@ void handle_dap_data_response(usbip_stage2_header *header) //os_printf("*** Will respond"); - send_stage2_submit_data(header, 0, data_out, (dap_respond & 0x0000FFFF)); + send_stage2_submit_data(header, 0, data_out, DAP_PACKET_SIZE); dap_respond = 0; //os_printf("*** RESPONDED ***"); } diff --git a/main/main.c b/main/main.c index 5676c15..b26615d 100644 --- a/main/main.c +++ b/main/main.c @@ -140,9 +140,9 @@ void app_main() DAP_Setup(); // DAP Setup xTaskCreate(timer_create_task, "timer_create", 512, NULL, 10, NULL); - xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 5, NULL); + xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 20, NULL); // SWO Trace Task - xTaskCreate(SWO_Thread, "swo_task", 1024, NULL, 6, NULL); - xTaskCreate(usart_monitor_task, "uart_task", 512, NULL, 6, NULL); + //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 fbb16b7..834381f 100644 --- a/main/tcp_server.c +++ b/main/tcp_server.c @@ -31,9 +31,10 @@ uint8_t kState = ACCEPTING; int kSock = -1; + void tcp_server_task(void *pvParameters) { - uint8_t rx_buffer[2048]; + uint8_t tcp_rx_buffer[256]; char addr_str[128]; int addr_family; int ip_protocol; @@ -101,7 +102,7 @@ void tcp_server_task(void *pvParameters) while (1) { - int len = recv(kSock, rx_buffer, 2047, 0); + int len = recv(kSock, tcp_rx_buffer, 255, 0); // Error occured during receiving if (len < 0) { @@ -117,19 +118,19 @@ void tcp_server_task(void *pvParameters) // 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 +// #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) { @@ -137,11 +138,11 @@ void tcp_server_task(void *pvParameters) kState = ATTACHING; case ATTACHING: - attach(rx_buffer, len); + attach(tcp_rx_buffer, len); break; case EMULATING: - emulate(rx_buffer, len); + emulate(tcp_rx_buffer, len); break; default: os_printf("unkonw kstate!\r\n"); diff --git a/main/usbip_server.c b/main/usbip_server.c index 2227bd2..9c41eef 100644 --- a/main/usbip_server.c +++ b/main/usbip_server.c @@ -31,6 +31,9 @@ static void handle_unlink(usbip_stage2_header *header); // unlink helper function static void send_stage2_unlink(usbip_stage2_header *req_header); +static void fast_submit_reply(usbip_stage2_header *req_header); + + int attach(uint8_t *buffer, uint32_t length) { int command = read_stage1_command(buffer, length); @@ -197,6 +200,7 @@ int emulate(uint8_t *buffer, uint32_t length) default: os_printf("emulate unknown command:%d\r\n", command); + handle_submit((usbip_stage2_header *)buffer); return -1; } return 0; @@ -278,12 +282,12 @@ static int handle_submit(usbip_stage2_header *header) case 0x01: if (header->base.direction == 0) { - // os_printf("EP 01 DATA FROM HOST"); + //os_printf("EP 01 DATA FROM HOST"); handle_dap_data_request(header); } else { - os_printf("EP 01 DATA TO HOST\r\n"); + // os_printf("EP 01 DATA TO HOST\r\n"); handle_dap_data_response(header); } break; diff --git a/sdkconfig b/sdkconfig index 0b1692e..08378b1 100644 --- a/sdkconfig +++ b/sdkconfig @@ -25,7 +25,7 @@ CONFIG_ESPTOOLPY_BAUD_921600B=y # CONFIG_ESPTOOLPY_BAUD_2MB is not set # CONFIG_ESPTOOLPY_BAUD_OTHER is not set CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 -CONFIG_ESPTOOLPY_BAUD=921600 +CONFIG_ESPTOOLPY_BAUD=115200 CONFIG_ESPTOOLPY_COMPRESSED=y CONFIG_ESPTOOLPY_FLASHMODE_QIO=y # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set @@ -42,10 +42,10 @@ CONFIG_SPI_FLASH_FREQ=0x0 # 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" From ede735c2a73ed8a911190ec33cd2fb477c493acb Mon Sep 17 00:00:00 2001 From: windowsair Date: Tue, 4 Feb 2020 20:45:01 +0800 Subject: [PATCH 14/15] feat: Improve DAP performance on USB-HID --- components/DAP/config/DAP_config.h | 45 ++----- components/DAP/include/DAP.h | 30 +++-- components/DAP/include/cmsis_compiler.h | 35 ++++++ components/DAP/source/DAP.c | 4 + components/USBIP/USB_handle.c | 2 +- components/USBIP/USBd_config.c | 8 +- main/DAP_handle.c | 155 ++++++++++++++++++++++-- main/DAP_handle.h | 5 +- main/main.c | 10 +- main/tcp_server.c | 32 ++--- main/usbip_server.c | 18 ++- sdkconfig | 62 +++++----- 12 files changed, 277 insertions(+), 129 deletions(-) diff --git a/components/DAP/config/DAP_config.h b/components/DAP/config/DAP_config.h index 226145b..7121a2e 100644 --- a/components/DAP/config/DAP_config.h +++ b/components/DAP/config/DAP_config.h @@ -35,41 +35,7 @@ #include "gpio_struct.h" #include "timer_struct.h" #include "esp8266/pin_mux_register.h" -#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 + //************************************************************************************************** /** \defgroup DAP_Config_Debug_gr CMSIS-DAP Debug Unit Information @@ -97,6 +63,9 @@ This information includes: #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 @@ -111,7 +80,7 @@ This information includes: /// 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 0 ///< JTAG Mode: 1 = available, 0 = not available. +#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. @@ -131,14 +100,14 @@ This information includes: /// 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 64U ///< Specifies Packet Size in bytes. +#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 1U ///< Specifies number of packets buffered. +#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. diff --git a/components/DAP/include/DAP.h b/components/DAP/include/DAP.h index 516b83d..b467714 100644 --- a/components/DAP/include/DAP.h +++ b/components/DAP/include/DAP.h @@ -287,21 +287,25 @@ extern void DAP_Setup (void); #define USE_ASSEMBLY 0 -#if USE_ASSEMBLY == 0 -__STATIC_FORCEINLINE void PIN_DELAY_SLOW (uint32_t delay) { - uint32_t count = delay; - while (--count); -} +#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 ( - ".syntax unified\n" - "0:\n\t" - "subs %0,%0,#1\n\t" - "bne 0b\n" - : "+l" (delay) : : "cc" - ); +__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 diff --git a/components/DAP/include/cmsis_compiler.h b/components/DAP/include/cmsis_compiler.h index 349f5fd..aafbe21 100644 --- a/components/DAP/include/cmsis_compiler.h +++ b/components/DAP/include/cmsis_compiler.h @@ -11,5 +11,40 @@ #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/source/DAP.c b/components/DAP/source/DAP.c index 9e1f620..03f048c 100644 --- a/components/DAP/source/DAP.c +++ b/components/DAP/source/DAP.c @@ -377,6 +377,10 @@ static uint32_t DAP_SWJ_Clock(const uint8_t *request, uint8_t *response) { *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; diff --git a/components/USBIP/USB_handle.c b/components/USBIP/USB_handle.c index 62ba946..f9fe76a 100644 --- a/components/USBIP/USB_handle.c +++ b/components/USBIP/USB_handle.c @@ -321,7 +321,7 @@ static void handleGetDescriptor(usbip_stage2_header *header) send_stage2_submit_data(header, 0, bosDescriptor, sizeof(bosDescriptor)); break; case USB_DT_HID_REPORT: - os_printf("* GET 0x22 HID REPORT DESCRIPTOR"); + os_printf("* GET 0x22 HID REPORT DESCRIPTOR\r\n"); send_stage2_submit_data(header, 0, (void *)kHidReportDescriptor, sizeof(kHidReportDescriptor)); break; default: diff --git a/components/USBIP/USBd_config.c b/components/USBIP/USBd_config.c index 598e7d9..0061a8b 100644 --- a/components/USBIP/USBd_config.c +++ b/components/USBIP/USBd_config.c @@ -155,7 +155,7 @@ const uint8_t kUSBd0InterfaceDescriptor[0x20]= 0x81, // bEndpointAddress USB_ENDPOINT_ATTR_INTERRUPT, // bmAttributes USBShort(64), // wMaxPacketSize - 0xff, // bInterval + 0x01, // bInterval /* Pysical endpoint 1 */ @@ -164,7 +164,7 @@ const uint8_t kUSBd0InterfaceDescriptor[0x20]= 0x01, // bEndpointAddress USB_ENDPOINT_ATTR_INTERRUPT, // bmAttributes USBShort(64), // wMaxPacketSize - 0xff, // bInterval + 0x01, // bInterval }; #endif @@ -221,10 +221,10 @@ const uint8_t kHidReportDescriptor[0x21] = { 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) - 0x95, 0x40, // Report Count (64) + 0x95, 0xFF, // Report Count (64) 0x09, 0x01, // Usage (0x01) 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0x95, 0x40, // Report Count (64) + 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) diff --git a/main/DAP_handle.c b/main/DAP_handle.c index 4f51da4..a3bff99 100644 --- a/main/DAP_handle.c +++ b/main/DAP_handle.c @@ -1,20 +1,35 @@ /** * @file DAP_handle.c * @brief Handle DAP packets and transaction push - * @version 0.1 - * @date 2020-01-25 + * @version 0.2 + * @date 2020-02-04 * * @copyright Copyright (c) 2020 * */ #include +#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 64 +#define DAP_PACKET_SIZE 255 static uint8_t data_out[DAP_PACKET_SIZE]; static int dap_respond = 0; @@ -24,29 +39,40 @@ static int swo_trace_respond = 0; static uint8_t *swo_data_to_send; static uint32_t num_swo_data; -void handle_dap_data_request(usbip_stage2_header *header) +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) { - - //os_printf("*** Will respond"); - send_stage2_submit_data(header, 0, data_out, DAP_PACKET_SIZE); dap_respond = 0; - //os_printf("*** RESPONDED ***"); } else { - //os_printf("*** Will NOT respond"); send_stage2_submit(header, 0, 0); } } @@ -56,14 +82,10 @@ void handle_swo_trace_response(usbip_stage2_header *header) if (swo_trace_respond) { swo_trace_respond = 0; - //os_printf("*** Will respond"); send_stage2_submit_data(header, 0, data_out, DAP_PACKET_SIZE); - - //os_printf("*** RESPONDED ***"); } else { - //os_printf("*** Will NOT respond"); send_stage2_submit(header, 0, 0); } } @@ -83,4 +105,111 @@ 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 index 5ac91f2..2d71be2 100644 --- a/main/DAP_handle.h +++ b/main/DAP_handle.h @@ -3,7 +3,10 @@ #include "usbip_defs.h" -void handle_dap_data_request(usbip_stage2_header *header); +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/main.c b/main/main.c index b26615d..6369f17 100644 --- a/main/main.c +++ b/main/main.c @@ -26,18 +26,17 @@ #include "tcp_server.h" #include "timer.h" #include "wifi_configuration.h" -/* The examples use simple WiFi configuration that you can set via - 'make menuconfig'. - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ + + 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 @@ -141,6 +140,7 @@ void app_main() 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 834381f..99e9fe8 100644 --- a/main/tcp_server.c +++ b/main/tcp_server.c @@ -34,7 +34,7 @@ int kSock = -1; void tcp_server_task(void *pvParameters) { - uint8_t tcp_rx_buffer[256]; + uint8_t tcp_rx_buffer[305]; char addr_str[128]; int addr_family; int ip_protocol; @@ -102,7 +102,7 @@ void tcp_server_task(void *pvParameters) while (1) { - int len = recv(kSock, tcp_rx_buffer, 255, 0); + int len = recv(kSock, tcp_rx_buffer, sizeof(tcp_rx_buffer), 0); // Error occured during receiving if (len < 0) { @@ -118,19 +118,19 @@ void tcp_server_task(void *pvParameters) // 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 + // #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) { @@ -155,6 +155,8 @@ void tcp_server_task(void *pvParameters) os_printf("Shutting down socket and restarting...\r\n"); //shutdown(kSock, 0); close(kSock); + if (kState == EMULATING) + kState = ACCEPTING; //shutdown(listen_sock, 0); //close(listen_sock); diff --git a/main/usbip_server.c b/main/usbip_server.c index 9c41eef..1eb2b75 100644 --- a/main/usbip_server.c +++ b/main/usbip_server.c @@ -11,6 +11,7 @@ #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); @@ -24,14 +25,13 @@ 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); +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); -static void fast_submit_reply(usbip_stage2_header *req_header); int attach(uint8_t *buffer, uint32_t length) @@ -182,6 +182,12 @@ static void send_interface_info() 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) { @@ -191,7 +197,7 @@ int emulate(uint8_t *buffer, uint32_t length) switch (command) { case USBIP_STAGE2_REQ_SUBMIT: - handle_submit((usbip_stage2_header *)buffer); + handle_submit((usbip_stage2_header *)buffer , length); break; case USBIP_STAGE2_REQ_UNLINK: @@ -200,7 +206,7 @@ int emulate(uint8_t *buffer, uint32_t length) default: os_printf("emulate unknown command:%d\r\n", command); - handle_submit((usbip_stage2_header *)buffer); + //handle_submit((usbip_stage2_header *)buffer, length); return -1; } return 0; @@ -269,7 +275,7 @@ static void unpack(void *data, int size) * @brief USB transaction processing * */ -static int handle_submit(usbip_stage2_header *header) +static int handle_submit(usbip_stage2_header *header, uint32_t length) { switch (header->base.ep) { @@ -283,7 +289,7 @@ static int handle_submit(usbip_stage2_header *header) if (header->base.direction == 0) { //os_printf("EP 01 DATA FROM HOST"); - handle_dap_data_request(header); + handle_dap_data_request(header ,length); } else { diff --git a/sdkconfig b/sdkconfig index 08378b1..4db752e 100644 --- a/sdkconfig +++ b/sdkconfig @@ -25,7 +25,7 @@ CONFIG_ESPTOOLPY_BAUD_921600B=y # CONFIG_ESPTOOLPY_BAUD_2MB is not set # CONFIG_ESPTOOLPY_BAUD_OTHER is not set CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 -CONFIG_ESPTOOLPY_BAUD=115200 +CONFIG_ESPTOOLPY_BAUD=921600 CONFIG_ESPTOOLPY_COMPRESSED=y CONFIG_ESPTOOLPY_FLASHMODE_QIO=y # CONFIG_ESPTOOLPY_FLASHMODE_QOUT is not set @@ -33,12 +33,12 @@ 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 @@ -76,9 +76,9 @@ CONFIG_EXAMPLE_IPV4=y 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 +87,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 +107,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 +130,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 +140,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 +150,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 +165,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 +199,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 +218,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 +226,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 +234,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 +340,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 +368,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 From 3ffc698550012e3466a1851fed4f6f6b508d5b7b Mon Sep 17 00:00:00 2001 From: windowsair Date: Tue, 4 Feb 2020 20:58:16 +0800 Subject: [PATCH 15/15] fix: Fix duplicate definitions & Remove redundant build configurations --- components/DAP/include/DAP.h | 2 -- main/Kconfig.projbuild | 37 ------------------------------------ sdkconfig | 5 ----- 3 files changed, 44 deletions(-) delete mode 100644 main/Kconfig.projbuild diff --git a/components/DAP/include/DAP.h b/components/DAP/include/DAP.h index b467714..65e0459 100644 --- a/components/DAP/include/DAP.h +++ b/components/DAP/include/DAP.h @@ -285,8 +285,6 @@ extern void DAP_Setup (void); #define DELAY_SLOW_CYCLES 3U // Number of cycles for one iteration #endif -#define USE_ASSEMBLY 0 - #define USE_ASSEMBLY 1 #if (USE_ASSEMBLY == 0) 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/sdkconfig b/sdkconfig index 4db752e..e20f324 100644 --- a/sdkconfig +++ b/sdkconfig @@ -69,11 +69,6 @@ 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 is not set