From 9876edd6ef5ffca8c08264e84416bb5a7992337e Mon Sep 17 00:00:00 2001 From: windowsair Date: Sat, 5 Jun 2021 20:16:56 +0800 Subject: [PATCH] chore: Refactor build dependencies --- CMakeLists.txt | 5 +- components/DAP/CMakeLists.txt | 2 +- components/DAP/config/DAP_config.h | 1435 +++++++++-------- components/DAP/include/cmsis_compiler.h | 4 +- components/DAP/include/dap_utility.h | 2 +- components/DAP/include/gpio_op.h | 3 +- components/DAP/include/uart_modify.h | 1 + components/DAP/source/DAP.c | 8 +- components/DAP/source/DAP_vendor.c | 14 +- components/DAP/source/JTAG_DP.c | 4 +- components/DAP/source/SWO.c | 8 +- components/DAP/source/SW_DP.c | 1057 ++++++------ components/DAP/source/dap_utility.c | 4 +- components/DAP/source/spi_op.c | 9 +- components/DAP/source/spi_switch.c | 7 +- components/DAP/source/uart_modify.c | 11 +- components/USBIP/CMakeLists.txt | 2 +- ...SOS20Descriptors.c => MSOS20_descriptor.c} | 221 +-- ...SOS20Descriptors.h => MSOS20_descriptor.h} | 185 ++- .../USBIP/{USBd_config.c => usb_descriptor.c} | 7 +- .../USBIP/{USBd_config.h => usb_descriptor.h} | 6 +- .../USBIP/{USB_handle.c => usb_handle.c} | 18 +- .../USBIP/{USB_handle.h => usb_handle.h} | 3 +- components/USBIP/usbip_defs.h | 15 +- main/CMakeLists.txt | 2 +- main/DAP_handle.c | 536 +++--- main/DAP_handle.h | 2 +- main/main.c | 362 ++--- main/monitor.c | 1 + main/tcp_server.c | 361 ++--- main/tcp_server.h | 2 +- main/timer.c | 7 +- main/usbip_server.c | 14 +- main/usbip_server.h | 4 +- 34 files changed, 2168 insertions(+), 2154 deletions(-) rename components/USBIP/{MSOS20Descriptors.c => MSOS20_descriptor.c} (96%) rename components/USBIP/{MSOS20Descriptors.h => MSOS20_descriptor.h} (92%) rename components/USBIP/{USBd_config.c => usb_descriptor.c} (99%) rename components/USBIP/{USBd_config.h => usb_descriptor.h} (94%) rename components/USBIP/{USB_handle.c => usb_handle.c} (98%) rename components/USBIP/{USB_handle.h => usb_handle.h} (69%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7bc2902..ee5b850 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,9 +1,6 @@ -# 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_directories(${CMAKE_CURRENT_SOURCE_DIR}/main) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}) include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(esp8266_dap) diff --git a/components/DAP/CMakeLists.txt b/components/DAP/CMakeLists.txt index c18752a..65ffbff 100644 --- a/components/DAP/CMakeLists.txt +++ b/components/DAP/CMakeLists.txt @@ -1,4 +1,4 @@ -set(COMPONENT_ADD_INCLUDEDIRS "config include $ENV{IDF_PATH}/components/esp8266/include/esp8266/ $ENV{IDF_PATH}//components/esp_ringbuf/include/") +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 ./source/spi_op.c ./source/spi_switch.c ./source/dap_utility.c") diff --git a/components/DAP/config/DAP_config.h b/components/DAP/config/DAP_config.h index 44b3012..1845dc6 100644 --- a/components/DAP/config/DAP_config.h +++ b/components/DAP/config/DAP_config.h @@ -1,715 +1,720 @@ -/* - * 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) - * - *---------------------------------------------------------------------------*/ - -/** - * @file DAP_config.h - * @author windowsair - * @brief Adaptation of GPIO and SPI pin - * @change: 2021-2-10 Support GPIO and SPI - * 2021-2-18 Try to support SWO - * @version 0.1 - * @date 2021-2-10 - * - * @copyright Copyright (c) 2021 - * - */ - - -#ifndef __DAP_CONFIG_H__ -#define __DAP_CONFIG_H__ - -#include -#include -#include "cmsis_compiler.h" -#include "gpio.h" -#include "gpio_struct.h" -#include "timer.h" -#include "esp8266/pin_mux_register.h" - -#include "gpio_op.h" -#include "spi_switch.h" -#include "dap_configuration.h" -//************************************************************************************************** -/** -\defgroup DAP_Config_Debug_gr CMSIS-DAP Debug Unit Information -\ingroup DAP_ConfigIO_gr -@{ -Provides definitions about the hardware and configuration of the Debug Unit. - -This information includes: - - Definition of Cortex-M processor parameters used in CMSIS-DAP Debug Unit. - - Debug Unit Identification strings (Vendor, Product, Serial Number). - - Debug Unit communication packet size. - - Debug Access Port supported modes and settings (JTAG/SWD and SWO). - - Optional information about a connected Target Device (for Evaluation Boards). -*/ - -//#ifdef _RTE_ -//#include "RTE_Components.h" -//#include CMSIS_device_header -//#else -//#include "device.h" // Debug Unit Cortex-M Processor Header File -//#endif - -/// Processor Clock of the Cortex-M MCU used in the Debug Unit. -/// This value is used to calculate the SWD/JTAG clock speed. -#define CPU_CLOCK 160000000 ///< Specifies the CPU Clock in Hz. -// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<160MHz - - -//#define MAX_USER_CLOCK 16000000 ///< Specifies the max Debug Clock in Hz. - -/// Number of processor cycles for I/O Port write operations. -/// This value is used to calculate the SWD/JTAG clock speed that is generated with I/O -/// Port write operations in the Debug Unit by a Cortex-M MCU. Most Cortex-M processors -/// require 2 processor cycles for a I/O Port Write operation. If the Debug Unit uses -/// a Cortex-M0+ processor with high-speed peripheral I/O only 1 processor cycle might be -/// required. -#define IO_PORT_WRITE_CYCLES 2U ///< I/O Cycles: 2=default, 1=Cortex-M0+ fast I/0. - -/// Indicate that Serial Wire Debug (SWD) communication mode is available at the Debug Access Port. -/// This information is returned by the command \ref DAP_Info as part of Capabilities. -#define DAP_SWD 1 ///< SWD Mode: 1 = available, 0 = not available. - -/// Indicate that JTAG communication mode is available at the Debug Port. -/// This information is returned by the command \ref DAP_Info as part of Capabilities. -#define DAP_JTAG 1 ///< JTAG Mode: 1 = available, 0 = not available. - -/// Configure maximum number of JTAG devices on the scan chain connected to the Debug Access Port. -/// This setting impacts the RAM requirements of the Debug Unit. Valid range is 1 .. 255. -#define DAP_JTAG_DEV_CNT 8U ///< Maximum number of JTAG devices on scan chain. - -/// Default communication mode on the Debug Access Port. -/// Used for the command \ref DAP_Connect when Port Default mode is selected. -#define DAP_DEFAULT_PORT 1U ///< Default JTAG/SWJ Port Mode: 1 = SWD, 2 = JTAG. - -/// Default communication speed on the Debug Access Port for SWD and JTAG mode. -/// Used to initialize the default SWD/JTAG clock frequency. -/// The command \ref DAP_SWJ_Clock can be used to overwrite this default setting. -#define DAP_DEFAULT_SWJ_CLOCK 1000000U ///< Default SWD/JTAG clock frequency in Hz. -// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<1MHz - -/// Maximum Package 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 255 ///< Specifies number of packets buffered. - -/// Indicates that the SWO function(UART SWO & Streaming Trace) is available -#define SWO_FUNCTION_ENABLE 0 ///< SWO function: 1 = available, 0 = not available. - - -/// 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 SWO_FUNCTION_ENABLE ///< SWO UART: 1 = available, 0 = not available. - -/// Maximum SWO UART Baudrate. -#define SWO_UART_MAX_BAUDRATE (115200U * 40U) ///< SWO UART Maximum Baudrate in Hz. -// <<<<<<<<<<<<<<<<<<<<<<<<<<<<< 5MHz -//// TODO: uncertain value - -/// Indicate that Manchester Serial Wire Output (SWO) trace is available. -/// This information is returned by the command \ref DAP_Info as part of Capabilities. -#define SWO_MANCHESTER 0 ///< SWO Manchester: 1 = available, 0 = not available. -// (windowsair)Do not modify. Not support. - - -/// SWO Trace Buffer Size. -#define SWO_BUFFER_SIZE 2048U ///< SWO Trace Buffer Size in bytes (must be 2^n). - -/// SWO Streaming Trace. -#define SWO_STREAM SWO_FUNCTION_ENABLE ///< 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) -{ - // In fact, Keil can get the corresponding information through USB - // without filling in this information. - // (void)str; - strcpy(str, "windowsair"); - return (sizeof("windowsair")); -} - -/** - * @brief Get Product ID string. - * - * @param str Pointer to buffer to store the string. - * @return String length. - */ -__STATIC_INLINE uint8_t DAP_GetProductString(char *str) -{ - //(void)str; - strcpy(str, "CMSIS-DAP v2"); - return (sizeof("CMSIS-DAP v2")); -} - -/** - * @brief Get Serial Number string. - * - * @param str Pointer to buffer to store the string. - * @return String length. - */ -__STATIC_INLINE uint8_t DAP_GetSerNumString(char *str) -{ - strcpy(str, "1234"); - return (sizeof("1234")); -} - -///@} - - -// Note: DO NOT modify these pins: PIN_SWDIO PIN_SWDIO_MOSI PIN_SWCLK -// Modify the following pins carefully: PIN_TDO -#define PIN_SWDIO 12 // SPI MISO -#define PIN_SWDIO_MOSI 13 // SPI MOSI -#define PIN_SWCLK 14 -#define PIN_TDO 16 // device TDO -> Host Data Input (use RTC pin 16) -#define PIN_TDI 4 -#define PIN_nTRST 0 // optional -#define PIN_nRESET 5 -// LED_BUILTIN -#define PIN_LED_CONNECTED 2 -// LED_BUILTIN -#define PIN_LED_RUNNING 15 - -//************************************************************************************************** -/** -\defgroup DAP_Config_PortIO_gr CMSIS-DAP Hardware I/O Pin Access -\ingroup DAP_ConfigIO_gr -@{ - -Standard I/O Pins of the CMSIS-DAP Hardware Debug Port support standard JTAG mode -and Serial Wire Debug (SWD) mode. In SWD mode only 2 pins are required to implement the debug -interface of a device. The following I/O Pins are provided: - -JTAG I/O Pin | SWD I/O Pin | CMSIS-DAP Hardware pin mode ----------------------------- | -------------------- | --------------------------------------------- -TCK: Test Clock | SWCLK: Clock | Output Push/Pull -TMS: Test Mode Select | SWDIO: Data I/O | Output Push/Pull; Input (for receiving data) -TDI: Test Data Input | | Output Push/Pull -TDO: Test Data Output | | Input -nTRST: Test Reset (optional) | | Output Open Drain with pull-up resistor -nRESET: Device Reset | nRESET: Device Reset | Output Open Drain with pull-up resistor - - -DAP Hardware I/O Pin Access Functions -------------------------------------- -The various I/O Pins are accessed by functions that implement the Read, Write, Set, or Clear to -these I/O Pins. - -For the SWDIO I/O Pin there are additional functions that are called in SWD I/O mode only. -This functions are provided to achieve faster I/O that is possible with some advanced GPIO -peripherals that can independently write/read a single I/O pin without affecting any other pins -of the same I/O port. The following SWDIO I/O Pin functions are provided: - - \ref PIN_SWDIO_OUT_ENABLE to enable the output mode from the DAP hardware. - - \ref PIN_SWDIO_OUT_DISABLE to enable the input mode to the DAP hardware. - - \ref PIN_SWDIO_IN to read from the SWDIO I/O pin with utmost possible speed. - - \ref PIN_SWDIO_OUT to write to the SWDIO I/O pin with utmost possible speed. -*/ - -/** - * @brief Setup JTAG I/O pins: TCK, TMS, TDI, TDO, nTRST, and nRESET. - * Configures the DAP Hardware I/O pins for JTAG mode: - * - TCK, TMS, TDI, nTRST, nRESET to ***output*** mode and set to high level. - * - TDO to ***input*** mode. - * - */ -__STATIC_INLINE void PORT_JTAG_SETUP(void) -{ - gpio_pin_reg_t pin_reg; - - - // set TCK, TMS pin - DAP_SPI_Deinit(); - - - // use RTC pin 16 - // output disable - WRITE_PERI_REG(PAD_XPD_DCDC_CONF, ((READ_PERI_REG(PAD_XPD_DCDC_CONF) & (uint32_t)0xffffffbc)) | (uint32_t)0x1); // mux configuration for XPD_DCDC and rtc_gpio0 connection - CLEAR_PERI_REG_MASK(RTC_GPIO_CONF, 0x1); // mux configuration for out enable - CLEAR_PERI_REG_MASK(RTC_GPIO_ENABLE, 0x1); // out disable - // pulldown disable - pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_TDO)); - pin_reg.rtc_pin.pulldown = 0; - WRITE_PERI_REG(GPIO_PIN_REG(PIN_TDO), pin_reg.val); - - - - // gpio_set_direction(PIN_TDI, GPIO_MODE_OUTPUT); - GPIO.enable_w1ts |= (0x1 << PIN_TDI); - GPIO.pin[PIN_TDI].driver = 0; - pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_TDI)); - pin_reg.pullup = 0; - WRITE_PERI_REG(GPIO_PIN_REG(PIN_TDI), pin_reg.val); - - // gpio_set_direction(PIN_nTRST, GPIO_MODE_OUTPUT_OD); - // gpio_set_direction(PIN_nRESET, GPIO_MODE_OUTPUT_OD); - GPIO.enable_w1tc |= (0x1 << PIN_nTRST); - GPIO.pin[PIN_nTRST].driver = 1; - GPIO.enable_w1tc |= (0x1 << PIN_nRESET); - GPIO.pin[PIN_nRESET].driver = 1; - - // gpio_set_pull_mode(PIN_nTRST, GPIO_PULLUP_ONLY); - // gpio_set_pull_mode(PIN_nRESET, GPIO_PULLUP_ONLY); - pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_nTRST)); - pin_reg.pullup = 1; - WRITE_PERI_REG(GPIO_PIN_REG(PIN_nTRST), pin_reg.val); - - pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_nRESET)); - pin_reg.pullup = 1; - WRITE_PERI_REG(GPIO_PIN_REG(PIN_nRESET), pin_reg.val); -} - -/** - * @brief Setup SWD I/O pins: SWCLK, SWDIO, and nRESET. - * Configures the DAP Hardware I/O pins for Serial Wire Debug (SWD) mode: - * - SWCLK, SWDIO, nRESET to output mode and set to default high level. - * - TDI, nTRST to HighZ mode (pins are unused in SWD mode). - * - */ -__STATIC_INLINE void PORT_SWD_SETUP(void) -{ - // At this stage we do not consider whether to use SPI or GPIO. - // We will switch to the specific mode when setting the transfer rate. - DAP_SPI_Init(); - DAP_SPI_Disable(); -} - -/** - * @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 - DAP_SPI_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 0; -} - -/** - * @brief SWCLK/TCK I/O pin: Set Output to High. - * - * Set the SWCLK/TCK DAP hardware I/O pin to high level. - */ -__STATIC_FORCEINLINE void PIN_SWCLK_TCK_SET(void) -{ - GPIO.out_w1ts |= (0x1 << PIN_SWCLK); -} - -/** - * @brief SWCLK/TCK I/O pin: Set Output to Low. - * - * Set the SWCLK/TCK DAP hardware I/O pin to low level. - */ -__STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR(void) -{ - GPIO.out_w1tc |= (0x1 << PIN_SWCLK); -} - -// SWDIO/TMS Pin I/O -------------------------------------- - -/** - * @brief SWDIO/TMS I/O pin: Get Input. - * - * @return Current status of the SWDIO/TMS DAP hardware I/O pin. - */ -__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN(void) -{ - // Note that we only use mosi in GPIO mode - return ((GPIO.in >> PIN_SWDIO_MOSI) & 0x1) ? 1 : 0; -} - -/** - * @brief SWDIO/TMS I/O pin: Set Output to High. - * - * Set the SWDIO/TMS DAP hardware I/O pin to high level. - */ -__STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET(void) -{ - GPIO.out_w1ts |= (0x1 << PIN_SWDIO_MOSI); -} - -/** - * @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_MOSI); -} - -/** - * @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) -{ - // Note that we only use mosi in GPIO mode - return ((GPIO.in >> PIN_SWDIO_MOSI) & 0x1) ? 1 : 0; -} - -/** - * @brief SWDIO I/O pin: Set Output (used in SWD mode only). - * - * @param bit Output value for the SWDIO DAP hardware I/O pin. - * - */ -__STATIC_FORCEINLINE void PIN_SWDIO_OUT(uint32_t bit) -{ - /** - * Important: Use only one bit (bit0) of param! - * Sometimes the func "SWD_TransferFunction" of SW_DP.c will - * issue "2" as param instead of "0". Zach Lee - */ - if ((bit & 1U) == 1) - { - //set bit - GPIO.out_w1ts |= (0x1 << PIN_SWDIO_MOSI); - - } - else - { - //reset bit - GPIO.out_w1tc |= (0x1 << PIN_SWDIO_MOSI); - - } -} - -/** - * @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) -{ - // set \ref gpio_set_direction -> OUTPUT - // GPIO.enable_w1ts |= (0x1 << PIN_SWDIO_MOSI); - // GPIO.pin[PIN_SWDIO_MOSI].driver = 0; - do {}while (0); - -} - -/** - * @brief SWDIO I/O pin: Switch to Input mode (used in SWD mode only). - * Configure the SWDIO DAP hardware I/O pin to input mode. This function is - * called prior \ref PIN_SWDIO_IN function calls. - */ -__STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE(void) -{ - // may be unuse. - // set \ref gpio_set_dircetion -> INPUT - // esp8266 input is always connected - // GPIO.enable_w1tc |= (0x1 << PIN_SWDIO_MOSI); - // GPIO.pin[PIN_SWDIO_MOSI].driver = 0; - GPIO.out_w1ts |= (0x1 << PIN_SWDIO_MOSI); -} - -// TDI Pin I/O --------------------------------------------- - -/** - * @brief TDI I/O pin: Get Input. - * - * @return Current status of the TDI DAP hardware I/O pin. - */ -__STATIC_FORCEINLINE uint32_t PIN_TDI_IN(void) -{ - return ((GPIO.in >> PIN_TDI) & 0x1) ? 1 : 0; -} - -/** - * @brief TDI I/O pin: Set Output. - * - * @param bit Output value for the TDI DAP hardware I/O pin. - * - */ -__STATIC_FORCEINLINE void PIN_TDI_OUT(uint32_t bit) -{ - if ((bit & 1U) == 1) - { - //set bit - GPIO.out_w1ts |= (0x1 << PIN_TDI); - - } - else - { - //reset bit - GPIO.out_w1tc |= (0x1 << PIN_TDI); - - } -} - -// TDO Pin I/O --------------------------------------------- - -/** - * @brief TDO I/O pin: Get Input. - * - * @return Current status of the TDO DAP hardware I/O pin. - */ -__STATIC_FORCEINLINE uint32_t PIN_TDO_IN(void) -{ - return READ_PERI_REG(RTC_GPIO_IN_DATA) & 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 0; // not available -} - -/** - * @brief nTRST I/O pin: Set Output. - * - * @param bit JTAG TRST Test Reset pin status: - * - 0: issue a JTAG TRST Test Reset. - - 1: release JTAG TRST Test Reset. - */ -__STATIC_FORCEINLINE void PIN_nTRST_OUT(uint32_t bit) -{ - // Vendor reset sequence - ; // not available -} - -// nRESET Pin I/O------------------------------------------ - -/** - * @brief nRESET I/O pin: Get Input. - * - * @return Current status of the nRESET DAP hardware I/O pin. - */ -__STATIC_FORCEINLINE uint32_t PIN_nRESET_IN(void) -{ - return ((GPIO.in >> PIN_nRESET) & 0x1) ? 1 : 0; -} - -/** - * @brief nRESET I/O pin: Set Output. - * - * @param bit target device hardware reset pin status: - * - 0: issue a device hardware reset. - * - 1: release device hardware reset. - */ -__STATIC_FORCEINLINE void PIN_nRESET_OUT(uint32_t bit) -{ - // Vendor reset sequence - //// FIXME: unavailable - 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) -{ - return get_timer_count(); -} - -///@} - -//************************************************************************************************** -/** -\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) -{ - // Connecting non-SWD pins to GPIO - GPIO_FUNCTION_SET(PIN_TDO); - GPIO_FUNCTION_SET(PIN_TDI); - GPIO_FUNCTION_SET(PIN_nTRST); - GPIO_FUNCTION_SET(PIN_nRESET); - GPIO_FUNCTION_SET(PIN_LED_CONNECTED); - GPIO_FUNCTION_SET(PIN_LED_RUNNING); - - - // Configure: LED as output (turned off) - - GPIO_SET_DIRECTION_NORMAL_OUT(PIN_LED_CONNECTED); - GPIO_SET_DIRECTION_NORMAL_OUT(PIN_LED_RUNNING); - - LED_CONNECTED_OUT(0); - LED_RUNNING_OUT(0); - - PORT_OFF(); -} - -/** 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__ */ +/* + * 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) + * + *---------------------------------------------------------------------------*/ + +/** + * @file DAP_config.h + * @author windowsair + * @brief Adaptation of GPIO and SPI pin + * @change: 2021-2-10 Support GPIO and SPI + * 2021-2-18 Try to support SWO + * @version 0.1 + * @date 2021-2-10 + * + * @copyright Copyright (c) 2021 + * + */ + + +#ifndef __DAP_CONFIG_H__ +#define __DAP_CONFIG_H__ + +#include +#include + +#include "main/dap_configuration.h" +#include "main/timer.h" + +#include "components/DAP/include/cmsis_compiler.h" +#include "components/DAP/include/gpio_op.h" +#include "components/DAP/include/spi_switch.h" + + +#include "gpio.h" +#include "gpio_struct.h" +#include "esp8266/pin_mux_register.h" + + +//************************************************************************************************** +/** +\defgroup DAP_Config_Debug_gr CMSIS-DAP Debug Unit Information +\ingroup DAP_ConfigIO_gr +@{ +Provides definitions about the hardware and configuration of the Debug Unit. + +This information includes: + - Definition of Cortex-M processor parameters used in CMSIS-DAP Debug Unit. + - Debug Unit Identification strings (Vendor, Product, Serial Number). + - Debug Unit communication packet size. + - Debug Access Port supported modes and settings (JTAG/SWD and SWO). + - Optional information about a connected Target Device (for Evaluation Boards). +*/ + +//#ifdef _RTE_ +//#include "RTE_Components.h" +//#include CMSIS_device_header +//#else +//#include "device.h" // Debug Unit Cortex-M Processor Header File +//#endif + +/// Processor Clock of the Cortex-M MCU used in the Debug Unit. +/// This value is used to calculate the SWD/JTAG clock speed. +#define CPU_CLOCK 160000000 ///< Specifies the CPU Clock in Hz. +// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<160MHz + + +//#define MAX_USER_CLOCK 16000000 ///< Specifies the max Debug Clock in Hz. + +/// Number of processor cycles for I/O Port write operations. +/// This value is used to calculate the SWD/JTAG clock speed that is generated with I/O +/// Port write operations in the Debug Unit by a Cortex-M MCU. Most Cortex-M processors +/// require 2 processor cycles for a I/O Port Write operation. If the Debug Unit uses +/// a Cortex-M0+ processor with high-speed peripheral I/O only 1 processor cycle might be +/// required. +#define IO_PORT_WRITE_CYCLES 2U ///< I/O Cycles: 2=default, 1=Cortex-M0+ fast I/0. + +/// Indicate that Serial Wire Debug (SWD) communication mode is available at the Debug Access Port. +/// This information is returned by the command \ref DAP_Info as part of Capabilities. +#define DAP_SWD 1 ///< SWD Mode: 1 = available, 0 = not available. + +/// Indicate that JTAG communication mode is available at the Debug Port. +/// This information is returned by the command \ref DAP_Info as part of Capabilities. +#define DAP_JTAG 1 ///< JTAG Mode: 1 = available, 0 = not available. + +/// Configure maximum number of JTAG devices on the scan chain connected to the Debug Access Port. +/// This setting impacts the RAM requirements of the Debug Unit. Valid range is 1 .. 255. +#define DAP_JTAG_DEV_CNT 8U ///< Maximum number of JTAG devices on scan chain. + +/// Default communication mode on the Debug Access Port. +/// Used for the command \ref DAP_Connect when Port Default mode is selected. +#define DAP_DEFAULT_PORT 1U ///< Default JTAG/SWJ Port Mode: 1 = SWD, 2 = JTAG. + +/// Default communication speed on the Debug Access Port for SWD and JTAG mode. +/// Used to initialize the default SWD/JTAG clock frequency. +/// The command \ref DAP_SWJ_Clock can be used to overwrite this default setting. +#define DAP_DEFAULT_SWJ_CLOCK 1000000U ///< Default SWD/JTAG clock frequency in Hz. +// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<1MHz + +/// Maximum Package 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 255 ///< Specifies number of packets buffered. + +/// Indicates that the SWO function(UART SWO & Streaming Trace) is available +#define SWO_FUNCTION_ENABLE 0 ///< SWO function: 1 = available, 0 = not available. + + +/// 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 SWO_FUNCTION_ENABLE ///< SWO UART: 1 = available, 0 = not available. + +/// Maximum SWO UART Baudrate. +#define SWO_UART_MAX_BAUDRATE (115200U * 40U) ///< SWO UART Maximum Baudrate in Hz. +// <<<<<<<<<<<<<<<<<<<<<<<<<<<<< 5MHz +//// TODO: uncertain value + +/// Indicate that Manchester Serial Wire Output (SWO) trace is available. +/// This information is returned by the command \ref DAP_Info as part of Capabilities. +#define SWO_MANCHESTER 0 ///< SWO Manchester: 1 = available, 0 = not available. +// (windowsair)Do not modify. Not support. + + +/// SWO Trace Buffer Size. +#define SWO_BUFFER_SIZE 2048U ///< SWO Trace Buffer Size in bytes (must be 2^n). + +/// SWO Streaming Trace. +#define SWO_STREAM SWO_FUNCTION_ENABLE ///< 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) +{ + // In fact, Keil can get the corresponding information through USB + // without filling in this information. + // (void)str; + strcpy(str, "windowsair"); + return (sizeof("windowsair")); +} + +/** + * @brief Get Product ID string. + * + * @param str Pointer to buffer to store the string. + * @return String length. + */ +__STATIC_INLINE uint8_t DAP_GetProductString(char *str) +{ + //(void)str; + strcpy(str, "CMSIS-DAP v2"); + return (sizeof("CMSIS-DAP v2")); +} + +/** + * @brief Get Serial Number string. + * + * @param str Pointer to buffer to store the string. + * @return String length. + */ +__STATIC_INLINE uint8_t DAP_GetSerNumString(char *str) +{ + strcpy(str, "1234"); + return (sizeof("1234")); +} + +///@} + + +// Note: DO NOT modify these pins: PIN_SWDIO PIN_SWDIO_MOSI PIN_SWCLK +// Modify the following pins carefully: PIN_TDO +#define PIN_SWDIO 12 // SPI MISO +#define PIN_SWDIO_MOSI 13 // SPI MOSI +#define PIN_SWCLK 14 +#define PIN_TDO 16 // device TDO -> Host Data Input (use RTC pin 16) +#define PIN_TDI 4 +#define PIN_nTRST 0 // optional +#define PIN_nRESET 5 +// LED_BUILTIN +#define PIN_LED_CONNECTED 2 +// LED_BUILTIN +#define PIN_LED_RUNNING 15 + +//************************************************************************************************** +/** +\defgroup DAP_Config_PortIO_gr CMSIS-DAP Hardware I/O Pin Access +\ingroup DAP_ConfigIO_gr +@{ + +Standard I/O Pins of the CMSIS-DAP Hardware Debug Port support standard JTAG mode +and Serial Wire Debug (SWD) mode. In SWD mode only 2 pins are required to implement the debug +interface of a device. The following I/O Pins are provided: + +JTAG I/O Pin | SWD I/O Pin | CMSIS-DAP Hardware pin mode +---------------------------- | -------------------- | --------------------------------------------- +TCK: Test Clock | SWCLK: Clock | Output Push/Pull +TMS: Test Mode Select | SWDIO: Data I/O | Output Push/Pull; Input (for receiving data) +TDI: Test Data Input | | Output Push/Pull +TDO: Test Data Output | | Input +nTRST: Test Reset (optional) | | Output Open Drain with pull-up resistor +nRESET: Device Reset | nRESET: Device Reset | Output Open Drain with pull-up resistor + + +DAP Hardware I/O Pin Access Functions +------------------------------------- +The various I/O Pins are accessed by functions that implement the Read, Write, Set, or Clear to +these I/O Pins. + +For the SWDIO I/O Pin there are additional functions that are called in SWD I/O mode only. +This functions are provided to achieve faster I/O that is possible with some advanced GPIO +peripherals that can independently write/read a single I/O pin without affecting any other pins +of the same I/O port. The following SWDIO I/O Pin functions are provided: + - \ref PIN_SWDIO_OUT_ENABLE to enable the output mode from the DAP hardware. + - \ref PIN_SWDIO_OUT_DISABLE to enable the input mode to the DAP hardware. + - \ref PIN_SWDIO_IN to read from the SWDIO I/O pin with utmost possible speed. + - \ref PIN_SWDIO_OUT to write to the SWDIO I/O pin with utmost possible speed. +*/ + +/** + * @brief Setup JTAG I/O pins: TCK, TMS, TDI, TDO, nTRST, and nRESET. + * Configures the DAP Hardware I/O pins for JTAG mode: + * - TCK, TMS, TDI, nTRST, nRESET to ***output*** mode and set to high level. + * - TDO to ***input*** mode. + * + */ +__STATIC_INLINE void PORT_JTAG_SETUP(void) +{ + gpio_pin_reg_t pin_reg; + + + // set TCK, TMS pin + DAP_SPI_Deinit(); + + + // use RTC pin 16 + // output disable + WRITE_PERI_REG(PAD_XPD_DCDC_CONF, ((READ_PERI_REG(PAD_XPD_DCDC_CONF) & (uint32_t)0xffffffbc)) | (uint32_t)0x1); // mux configuration for XPD_DCDC and rtc_gpio0 connection + CLEAR_PERI_REG_MASK(RTC_GPIO_CONF, 0x1); // mux configuration for out enable + CLEAR_PERI_REG_MASK(RTC_GPIO_ENABLE, 0x1); // out disable + // pulldown disable + pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_TDO)); + pin_reg.rtc_pin.pulldown = 0; + WRITE_PERI_REG(GPIO_PIN_REG(PIN_TDO), pin_reg.val); + + + + // gpio_set_direction(PIN_TDI, GPIO_MODE_OUTPUT); + GPIO.enable_w1ts |= (0x1 << PIN_TDI); + GPIO.pin[PIN_TDI].driver = 0; + pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_TDI)); + pin_reg.pullup = 0; + WRITE_PERI_REG(GPIO_PIN_REG(PIN_TDI), pin_reg.val); + + // gpio_set_direction(PIN_nTRST, GPIO_MODE_OUTPUT_OD); + // gpio_set_direction(PIN_nRESET, GPIO_MODE_OUTPUT_OD); + GPIO.enable_w1tc |= (0x1 << PIN_nTRST); + GPIO.pin[PIN_nTRST].driver = 1; + GPIO.enable_w1tc |= (0x1 << PIN_nRESET); + GPIO.pin[PIN_nRESET].driver = 1; + + // gpio_set_pull_mode(PIN_nTRST, GPIO_PULLUP_ONLY); + // gpio_set_pull_mode(PIN_nRESET, GPIO_PULLUP_ONLY); + pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_nTRST)); + pin_reg.pullup = 1; + WRITE_PERI_REG(GPIO_PIN_REG(PIN_nTRST), pin_reg.val); + + pin_reg.val = READ_PERI_REG(GPIO_PIN_REG(PIN_nRESET)); + pin_reg.pullup = 1; + WRITE_PERI_REG(GPIO_PIN_REG(PIN_nRESET), pin_reg.val); +} + +/** + * @brief Setup SWD I/O pins: SWCLK, SWDIO, and nRESET. + * Configures the DAP Hardware I/O pins for Serial Wire Debug (SWD) mode: + * - SWCLK, SWDIO, nRESET to output mode and set to default high level. + * - TDI, nTRST to HighZ mode (pins are unused in SWD mode). + * + */ +__STATIC_INLINE void PORT_SWD_SETUP(void) +{ + // At this stage we do not consider whether to use SPI or GPIO. + // We will switch to the specific mode when setting the transfer rate. + DAP_SPI_Init(); + DAP_SPI_Disable(); +} + +/** + * @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 + DAP_SPI_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 0; +} + +/** + * @brief SWCLK/TCK I/O pin: Set Output to High. + * + * Set the SWCLK/TCK DAP hardware I/O pin to high level. + */ +__STATIC_FORCEINLINE void PIN_SWCLK_TCK_SET(void) +{ + GPIO.out_w1ts |= (0x1 << PIN_SWCLK); +} + +/** + * @brief SWCLK/TCK I/O pin: Set Output to Low. + * + * Set the SWCLK/TCK DAP hardware I/O pin to low level. + */ +__STATIC_FORCEINLINE void PIN_SWCLK_TCK_CLR(void) +{ + GPIO.out_w1tc |= (0x1 << PIN_SWCLK); +} + +// SWDIO/TMS Pin I/O -------------------------------------- + +/** + * @brief SWDIO/TMS I/O pin: Get Input. + * + * @return Current status of the SWDIO/TMS DAP hardware I/O pin. + */ +__STATIC_FORCEINLINE uint32_t PIN_SWDIO_TMS_IN(void) +{ + // Note that we only use mosi in GPIO mode + return ((GPIO.in >> PIN_SWDIO_MOSI) & 0x1) ? 1 : 0; +} + +/** + * @brief SWDIO/TMS I/O pin: Set Output to High. + * + * Set the SWDIO/TMS DAP hardware I/O pin to high level. + */ +__STATIC_FORCEINLINE void PIN_SWDIO_TMS_SET(void) +{ + GPIO.out_w1ts |= (0x1 << PIN_SWDIO_MOSI); +} + +/** + * @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_MOSI); +} + +/** + * @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) +{ + // Note that we only use mosi in GPIO mode + return ((GPIO.in >> PIN_SWDIO_MOSI) & 0x1) ? 1 : 0; +} + +/** + * @brief SWDIO I/O pin: Set Output (used in SWD mode only). + * + * @param bit Output value for the SWDIO DAP hardware I/O pin. + * + */ +__STATIC_FORCEINLINE void PIN_SWDIO_OUT(uint32_t bit) +{ + /** + * Important: Use only one bit (bit0) of param! + * Sometimes the func "SWD_TransferFunction" of SW_DP.c will + * issue "2" as param instead of "0". Zach Lee + */ + if ((bit & 1U) == 1) + { + //set bit + GPIO.out_w1ts |= (0x1 << PIN_SWDIO_MOSI); + + } + else + { + //reset bit + GPIO.out_w1tc |= (0x1 << PIN_SWDIO_MOSI); + + } +} + +/** + * @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) +{ + // set \ref gpio_set_direction -> OUTPUT + // GPIO.enable_w1ts |= (0x1 << PIN_SWDIO_MOSI); + // GPIO.pin[PIN_SWDIO_MOSI].driver = 0; + do {}while (0); + +} + +/** + * @brief SWDIO I/O pin: Switch to Input mode (used in SWD mode only). + * Configure the SWDIO DAP hardware I/O pin to input mode. This function is + * called prior \ref PIN_SWDIO_IN function calls. + */ +__STATIC_FORCEINLINE void PIN_SWDIO_OUT_DISABLE(void) +{ + // may be unuse. + // set \ref gpio_set_dircetion -> INPUT + // esp8266 input is always connected + // GPIO.enable_w1tc |= (0x1 << PIN_SWDIO_MOSI); + // GPIO.pin[PIN_SWDIO_MOSI].driver = 0; + GPIO.out_w1ts |= (0x1 << PIN_SWDIO_MOSI); +} + +// TDI Pin I/O --------------------------------------------- + +/** + * @brief TDI I/O pin: Get Input. + * + * @return Current status of the TDI DAP hardware I/O pin. + */ +__STATIC_FORCEINLINE uint32_t PIN_TDI_IN(void) +{ + return ((GPIO.in >> PIN_TDI) & 0x1) ? 1 : 0; +} + +/** + * @brief TDI I/O pin: Set Output. + * + * @param bit Output value for the TDI DAP hardware I/O pin. + * + */ +__STATIC_FORCEINLINE void PIN_TDI_OUT(uint32_t bit) +{ + if ((bit & 1U) == 1) + { + //set bit + GPIO.out_w1ts |= (0x1 << PIN_TDI); + + } + else + { + //reset bit + GPIO.out_w1tc |= (0x1 << PIN_TDI); + + } +} + +// TDO Pin I/O --------------------------------------------- + +/** + * @brief TDO I/O pin: Get Input. + * + * @return Current status of the TDO DAP hardware I/O pin. + */ +__STATIC_FORCEINLINE uint32_t PIN_TDO_IN(void) +{ + return READ_PERI_REG(RTC_GPIO_IN_DATA) & 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 0; // not available +} + +/** + * @brief nTRST I/O pin: Set Output. + * + * @param bit JTAG TRST Test Reset pin status: + * - 0: issue a JTAG TRST Test Reset. + - 1: release JTAG TRST Test Reset. + */ +__STATIC_FORCEINLINE void PIN_nTRST_OUT(uint32_t bit) +{ + // Vendor reset sequence + ; // not available +} + +// nRESET Pin I/O------------------------------------------ + +/** + * @brief nRESET I/O pin: Get Input. + * + * @return Current status of the nRESET DAP hardware I/O pin. + */ +__STATIC_FORCEINLINE uint32_t PIN_nRESET_IN(void) +{ + return ((GPIO.in >> PIN_nRESET) & 0x1) ? 1 : 0; +} + +/** + * @brief nRESET I/O pin: Set Output. + * + * @param bit target device hardware reset pin status: + * - 0: issue a device hardware reset. + * - 1: release device hardware reset. + */ +__STATIC_FORCEINLINE void PIN_nRESET_OUT(uint32_t bit) +{ + // Vendor reset sequence + //// FIXME: unavailable + 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) +{ + return get_timer_count(); +} + +///@} + +//************************************************************************************************** +/** +\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) +{ + // Connecting non-SWD pins to GPIO + GPIO_FUNCTION_SET(PIN_TDO); + GPIO_FUNCTION_SET(PIN_TDI); + GPIO_FUNCTION_SET(PIN_nTRST); + GPIO_FUNCTION_SET(PIN_nRESET); + GPIO_FUNCTION_SET(PIN_LED_CONNECTED); + GPIO_FUNCTION_SET(PIN_LED_RUNNING); + + + // Configure: LED as output (turned off) + + GPIO_SET_DIRECTION_NORMAL_OUT(PIN_LED_CONNECTED); + GPIO_SET_DIRECTION_NORMAL_OUT(PIN_LED_RUNNING); + + LED_CONNECTED_OUT(0); + LED_RUNNING_OUT(0); + + PORT_OFF(); +} + +/** 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/cmsis_compiler.h b/components/DAP/include/cmsis_compiler.h index 9d032bb..d448225 100644 --- a/components/DAP/include/cmsis_compiler.h +++ b/components/DAP/include/cmsis_compiler.h @@ -2,13 +2,13 @@ #define __CMSIS_COMPILER_H__ #ifndef __STATIC_FORCEINLINE - #define __STATIC_FORCEINLINE static inline __attribute__((always_inline)) + #define __STATIC_FORCEINLINE static inline __attribute__((always_inline)) #endif #ifndef __STATIC_INLINE #define __STATIC_INLINE static inline __attribute__((always_inline)) #endif #ifndef __FORCEINLINE - #define __FORCEINLINE inline __attribute__((always_inline)) + #define __FORCEINLINE inline __attribute__((always_inline)) #endif #ifndef __WEAK #define __WEAK __attribute__((weak)) diff --git a/components/DAP/include/dap_utility.h b/components/DAP/include/dap_utility.h index ee25c6f..08ea438 100644 --- a/components/DAP/include/dap_utility.h +++ b/components/DAP/include/dap_utility.h @@ -4,7 +4,7 @@ #include #ifndef __STATIC_FORCEINLINE - #define __STATIC_FORCEINLINE static inline __attribute__((always_inline)) + #define __STATIC_FORCEINLINE static inline __attribute__((always_inline)) #endif #ifndef __STATIC_INLINE #define __STATIC_INLINE static inline __attribute__((always_inline)) diff --git a/components/DAP/include/gpio_op.h b/components/DAP/include/gpio_op.h index 30b214d..48888cf 100644 --- a/components/DAP/include/gpio_op.h +++ b/components/DAP/include/gpio_op.h @@ -1,7 +1,8 @@ #ifndef __GPIO_OP_H__ #define __GPIO_OP_H__ -#include "cmsis_compiler.h" +#include "components/DAP/include/cmsis_compiler.h" + #include "gpio.h" #include "gpio_struct.h" #include "timer_struct.h" diff --git a/components/DAP/include/uart_modify.h b/components/DAP/include/uart_modify.h index c6f67f0..2a62ed4 100644 --- a/components/DAP/include/uart_modify.h +++ b/components/DAP/include/uart_modify.h @@ -27,6 +27,7 @@ extern "C" { #include "esp_err.h" #include "esp_log.h" +#include "freertos/FreeRTOS.h" #include "freertos/queue.h" #include "freertos/semphr.h" diff --git a/components/DAP/source/DAP.c b/components/DAP/source/DAP.c index 8f4719e..6079067 100644 --- a/components/DAP/source/DAP.c +++ b/components/DAP/source/DAP.c @@ -26,10 +26,10 @@ *---------------------------------------------------------------------------*/ #include -#include "DAP_config.h" -#include "DAP.h" -#include "spi_switch.h" +#include "components/DAP/config/DAP_config.h" +#include "components/DAP/include/DAP.h" +#include "components/DAP/include/spi_switch.h" #if (DAP_PACKET_SIZE < 64U) @@ -388,6 +388,8 @@ static uint32_t DAP_SWJ_Clock(const uint8_t *request, uint8_t *response) { if (DAP_Data.debug_port != DAP_PORT_JTAG) { DAP_SPI_Init(); SWD_TransferSpeed = kTransfer_SPI; + } else { + SWD_TransferSpeed = kTransfer_GPIO_fast; } DAP_Data.fast_clock = 1U; DAP_Data.clock_delay = 1U; diff --git a/components/DAP/source/DAP_vendor.c b/components/DAP/source/DAP_vendor.c index a4ae496..3579918 100644 --- a/components/DAP/source/DAP_vendor.c +++ b/components/DAP/source/DAP_vendor.c @@ -24,18 +24,18 @@ * Title: DAP_vendor.c CMSIS-DAP Vendor Commands * *---------------------------------------------------------------------------*/ - -#include "DAP_config.h" -#include "DAP.h" + +#include "components/DAP/config/DAP_config.h" +#include "components/DAP/include/DAP.h" //************************************************************************************************** -/** +/** \defgroup DAP_Vendor_Adapt_gr Adapt Vendor Commands -\ingroup DAP_Vendor_gr +\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 +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. */ diff --git a/components/DAP/source/JTAG_DP.c b/components/DAP/source/JTAG_DP.c index 24b1f3f..f5c9d5e 100644 --- a/components/DAP/source/JTAG_DP.c +++ b/components/DAP/source/JTAG_DP.c @@ -25,8 +25,8 @@ * *---------------------------------------------------------------------------*/ -#include "DAP_config.h" -#include "DAP.h" +#include "components/DAP/config/DAP_config.h" +#include "components/DAP/include/DAP.h" // JTAG Macros diff --git a/components/DAP/source/SWO.c b/components/DAP/source/SWO.c index 7497ef6..4e2fcdc 100644 --- a/components/DAP/source/SWO.c +++ b/components/DAP/source/SWO.c @@ -38,16 +38,16 @@ * *---------------------------------------------------------------------------*/ -#include "DAP_config.h" -#include "DAP.h" +#include "components/DAP/config/DAP_config.h" +#include "components/DAP/include/DAP.h" +#include "components/DAP/include/uart_modify.h" +#include "components/DAP/include/swo.h" #include "esp_err.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/event_groups.h" -#include "uart_modify.h" -#include "swo.h" EventGroupHandle_t kSwoThreadEventGroup; diff --git a/components/DAP/source/SW_DP.c b/components/DAP/source/SW_DP.c index b65b1d6..4d0b99d 100644 --- a/components/DAP/source/SW_DP.c +++ b/components/DAP/source/SW_DP.c @@ -1,528 +1,529 @@ -/* - * 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 - * - *---------------------------------------------------------------------------*/ - -/** - * @file SW_DP.c - * @author windowsair - * @brief Adaptation of GPIO and SPI - * @change: - * 2021-2-10 Support GPIO and SPI for SWD sequence / SWJ sequence / SWD transfer - * Note: SWD sequence not yet tested - * @version 0.1 - * @date 2021-2-10 - * - * @copyright Copyright (c) 2021 - * - */ - - -#include "DAP_config.h" -#include "DAP.h" - -#include "spi_op.h" -#include "spi_switch.h" -#include "dap_utility.h" - -// Debug -#define PRINT_SWD_PROTOCOL 0 - -// SW Macros - -#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay) - -#define PIN_SWCLK_SET PIN_SWCLK_TCK_SET -#define PIN_SWCLK_CLR PIN_SWCLK_TCK_CLR - -// Space for time in the original version, -// and time for space in our implementation - -#define SW_CLOCK_CYCLE() \ - PIN_SWCLK_CLR(); \ - if (need_delay) { PIN_DELAY(); } \ - PIN_SWCLK_SET(); \ - if (need_delay) { PIN_DELAY(); } - -#define SW_WRITE_BIT(bit) \ - PIN_SWDIO_OUT(bit); \ - PIN_SWCLK_CLR(); \ - if (need_delay) { PIN_DELAY(); } \ - PIN_SWCLK_SET(); \ - if (need_delay) { PIN_DELAY(); } - -#define SW_READ_BIT(bit) \ - PIN_SWCLK_CLR(); \ - if (need_delay) { PIN_DELAY(); } \ - bit = PIN_SWDIO_IN(); \ - PIN_SWCLK_SET(); \ - if (need_delay) { PIN_DELAY(); } - - - -uint8_t SWD_TransferSpeed = kTransfer_GPIO_normal; - - -void SWJ_Sequence_GPIO (uint32_t count, const uint8_t *data, uint8_t need_delay); -void SWJ_Sequence_SPI (uint32_t count, const uint8_t *data); - -void SWD_Sequence_GPIO (uint32_t info, const uint8_t *swdo, uint8_t *swdi); -void SWD_Sequence_SPI (uint32_t info, const uint8_t *swdo, uint8_t *swdi); - - -// 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) { - // if (count != 8 && count != 16 && count!= 51) - // { - // printf("[ERROR] wrong SWJ Swquence length:%d\r\n", (int)count); - // return; - // } - - if(SWD_TransferSpeed == kTransfer_SPI) { - SWJ_Sequence_SPI(count, data); - } else { - SWJ_Sequence_GPIO(count, data, 1); - } - -} - - -void SWJ_Sequence_GPIO (uint32_t count, const uint8_t *data, uint8_t need_delay) { - 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--; - } -} - -void SWJ_Sequence_SPI (uint32_t count, const uint8_t *data) { - DAP_SPI_Enable(); - DAP_SPI_WriteBits(count, data); -} -#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) { - if (SWD_TransferSpeed == kTransfer_SPI) { - SWD_Sequence_SPI(info, swdo, swdi); - } else { - SWD_Sequence_GPIO(info, swdo, swdi); - } -} - -void SWD_Sequence_GPIO (uint32_t info, const uint8_t *swdo, uint8_t *swdi) { - const uint8_t need_delay = 1; - - uint32_t val; - uint32_t bit; - uint32_t n, k; - - n = info & SWD_SEQUENCE_CLK; - if (n == 0U) { - n = 64U; - } - // n = 1 ~ 64 - - // LSB - 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; - } - } - } -} - -void SWD_Sequence_SPI (uint32_t info, const uint8_t *swdo, uint8_t *swdi) { - uint32_t n; - n = info & SWD_SEQUENCE_CLK; - if (n == 0U) { - n = 64U; - } - // n = 1 ~ 64 - - if (info & SWD_SEQUENCE_DIN) { - DAP_SPI_ReadBits(n, swdi); - } else { - DAP_SPI_WriteBits(n, swdo); - } -} - -#endif - - -#if (DAP_SWD != 0) - - -// SWD Transfer I/O -// request: A[3:2] RnW APnDP -// data: DATA[31:0] -// return: ACK[2:0] -static uint8_t SWD_Transfer_SPI (uint32_t request, uint32_t *data) { - //// FIXME: overrun detection - // SPI transfer mode does not require operations such as PIN_DELAY - uint8_t ack; - // uint32_t bit; - uint32_t val; - uint8_t parity; - uint8_t computedParity; - - uint32_t n; - - const uint8_t constantBits = 0b10000001U; /* Start Bit & Stop Bit & Park Bit is fixed. */ - uint8_t requestByte; /* LSB */ - - - DAP_SPI_Enable(); - - requestByte = constantBits | (((uint8_t)(request & 0xFU)) << 1U) | (ParityEvenUint8(request & 0xFU) << 5U); - /* For 4bit, Parity can be equivalent to 8bit with all 0 high bits */ - - #if (PRINT_SWD_PROTOCOL == 1) - switch (requestByte) - { - case 0xA5U: - printf("IDCODE\r\n"); - break; - case 0xA9U: - printf("W CTRL/STAT\r\n"); - break; - case 0xBDU: - printf("RDBUFF\r\n"); - break; - case 0x8DU: - printf("R CTRL/STAT\r\n"); - break; - case 0x81U: - printf("W ABORT\r\n"); - break; - case 0xB1U: - printf("W SELECT\r\n"); - break; - case 0xBBU: - printf("W APc\r\n"); - break; - case 0x9FU: - printf("R APc\r\n"); - break; - case 0x8BU: - printf("W AP4\r\n"); - break; - case 0xA3U: - printf("W AP0\r\n"); - break; - case 0X87U: - printf("R AP0\r\n"); - break; - case 0xB7U: - printf("R AP8\r\n"); - break; - default: - //W AP8 - printf("Unknown:%08x\r\n", requestByte); - break; - } - #endif - - if (request & DAP_TRANSFER_RnW) { - /* Read data */ - - DAP_SPI_Send_Header(requestByte, &ack, 0); // 0 Trn After ACK - if (ack == DAP_TRANSFER_OK) { - DAP_SPI_Read_Data(&val, &parity); - computedParity = ParityEvenUint32(val); - - if ((computedParity ^ parity) & 1U) { - ack = DAP_TRANSFER_ERROR; - } - if (data) { *data = val; } - - /* Capture Timestamp */ - if (request & DAP_TRANSFER_TIMESTAMP) { - DAP_Data.timestamp = TIMESTAMP_GET(); - } - - } - else if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { - DAP_SPI_Generate_Cycle(1); - #if (PRINT_SWD_PROTOCOL == 1) - printf("WAIT\r\n"); - #endif - - // return DAP_TRANSFER_WAIT; - } - else { - /* Protocol error */ - DAP_SPI_Disable(); - PIN_SWDIO_TMS_SET(); - - DAP_SPI_Enable(); - DAP_SPI_Protocol_Error_Read(); - - DAP_SPI_Disable(); - PIN_SWDIO_TMS_SET(); - #if (PRINT_SWD_PROTOCOL == 1) - printf("Protocol Error: Read\r\n"); - #endif - } - - return ((uint8_t)ack); - } - else { - /* Write data */ - parity = ParityEvenUint32(*data); - DAP_SPI_Send_Header(requestByte, &ack, 1); // 1 Trn After ACK - if (ack == DAP_TRANSFER_OK) { - DAP_SPI_Write_Data(*data, parity); - /* Capture Timestamp */ - if (request & DAP_TRANSFER_TIMESTAMP) { - DAP_Data.timestamp = TIMESTAMP_GET(); - } - /* Idle cycles */ - n = DAP_Data.transfer.idle_cycles; - if (n) { DAP_SPI_Generate_Cycle(n); } - - DAP_SPI_Disable(); - PIN_SWDIO_TMS_SET(); - - return ((uint8_t)ack); - } - else if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { - /* already turnaround. */ - - /* TODO: overrun transfer -> for read */ - #if (PRINT_SWD_PROTOCOL == 1) - printf("WAIT\r\n"); - #endif - - } - else { - /* Protocol error */ - DAP_SPI_Disable(); - PIN_SWDIO_TMS_SET(); - - DAP_SPI_Enable(); - DAP_SPI_Protocol_Error_Write(); - - DAP_SPI_Disable(); - PIN_SWDIO_TMS_SET(); - - #if (PRINT_SWD_PROTOCOL == 1) - printf("Protocol Error: Write\r\n"); - #endif - } - - return ((uint8_t)ack); - - } - - return DAP_TRANSFER_ERROR; -} - - - -static uint8_t SWD_Transfer_GPIO (uint32_t request, uint32_t *data, uint8_t need_delay) { - 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); -} - - -// 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) { - switch (SWD_TransferSpeed) { - case kTransfer_SPI: - return SWD_Transfer_SPI(request, data); - case kTransfer_GPIO_fast: - return SWD_Transfer_GPIO(request, data, 0); - case kTransfer_GPIO_normal: - return SWD_Transfer_GPIO(request, data, 1); - default: - return SWD_Transfer_GPIO(request, data, 1); - } -} - - -#endif /* (DAP_SWD != 0) */ +/* + * 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 + * + *---------------------------------------------------------------------------*/ + +/** + * @file SW_DP.c + * @author windowsair + * @brief Adaptation of GPIO and SPI + * @change: + * 2021-2-10 Support GPIO and SPI for SWD sequence / SWJ sequence / SWD transfer + * Note: SWD sequence not yet tested + * @version 0.1 + * @date 2021-2-10 + * + * @copyright Copyright (c) 2021 + * + */ + +#include + +#include "components/DAP/config/DAP_config.h" +#include "components/DAP/include/DAP.h" +#include "components/DAP/include/spi_op.h" +#include "components/DAP/include/spi_switch.h" +#include "components/DAP/include/dap_utility.h" + + +// Debug +#define PRINT_SWD_PROTOCOL 0 + +// SW Macros + +#define PIN_DELAY() PIN_DELAY_SLOW(DAP_Data.clock_delay) + +#define PIN_SWCLK_SET PIN_SWCLK_TCK_SET +#define PIN_SWCLK_CLR PIN_SWCLK_TCK_CLR + +// Space for time in the original version, +// and time for space in our implementation + +#define SW_CLOCK_CYCLE() \ + PIN_SWCLK_CLR(); \ + if (need_delay) { PIN_DELAY(); } \ + PIN_SWCLK_SET(); \ + if (need_delay) { PIN_DELAY(); } + +#define SW_WRITE_BIT(bit) \ + PIN_SWDIO_OUT(bit); \ + PIN_SWCLK_CLR(); \ + if (need_delay) { PIN_DELAY(); } \ + PIN_SWCLK_SET(); \ + if (need_delay) { PIN_DELAY(); } + +#define SW_READ_BIT(bit) \ + PIN_SWCLK_CLR(); \ + if (need_delay) { PIN_DELAY(); } \ + bit = PIN_SWDIO_IN(); \ + PIN_SWCLK_SET(); \ + if (need_delay) { PIN_DELAY(); } + + + +uint8_t SWD_TransferSpeed = kTransfer_GPIO_normal; + + +void SWJ_Sequence_GPIO (uint32_t count, const uint8_t *data, uint8_t need_delay); +void SWJ_Sequence_SPI (uint32_t count, const uint8_t *data); + +void SWD_Sequence_GPIO (uint32_t info, const uint8_t *swdo, uint8_t *swdi); +void SWD_Sequence_SPI (uint32_t info, const uint8_t *swdo, uint8_t *swdi); + + +// 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) { + // if (count != 8 && count != 16 && count!= 51) + // { + // printf("[ERROR] wrong SWJ Swquence length:%d\r\n", (int)count); + // return; + // } + + if(SWD_TransferSpeed == kTransfer_SPI) { + SWJ_Sequence_SPI(count, data); + } else { + SWJ_Sequence_GPIO(count, data, 1); + } + +} + + +void SWJ_Sequence_GPIO (uint32_t count, const uint8_t *data, uint8_t need_delay) { + 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--; + } +} + +void SWJ_Sequence_SPI (uint32_t count, const uint8_t *data) { + DAP_SPI_Enable(); + DAP_SPI_WriteBits(count, data); +} +#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) { + if (SWD_TransferSpeed == kTransfer_SPI) { + SWD_Sequence_SPI(info, swdo, swdi); + } else { + SWD_Sequence_GPIO(info, swdo, swdi); + } +} + +void SWD_Sequence_GPIO (uint32_t info, const uint8_t *swdo, uint8_t *swdi) { + const uint8_t need_delay = 1; + + uint32_t val; + uint32_t bit; + uint32_t n, k; + + n = info & SWD_SEQUENCE_CLK; + if (n == 0U) { + n = 64U; + } + // n = 1 ~ 64 + + // LSB + 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; + } + } + } +} + +void SWD_Sequence_SPI (uint32_t info, const uint8_t *swdo, uint8_t *swdi) { + uint32_t n; + n = info & SWD_SEQUENCE_CLK; + if (n == 0U) { + n = 64U; + } + // n = 1 ~ 64 + + if (info & SWD_SEQUENCE_DIN) { + DAP_SPI_ReadBits(n, swdi); + } else { + DAP_SPI_WriteBits(n, swdo); + } +} + +#endif + + +#if (DAP_SWD != 0) + + +// SWD Transfer I/O +// request: A[3:2] RnW APnDP +// data: DATA[31:0] +// return: ACK[2:0] +static uint8_t SWD_Transfer_SPI (uint32_t request, uint32_t *data) { + //// FIXME: overrun detection + // SPI transfer mode does not require operations such as PIN_DELAY + uint8_t ack; + // uint32_t bit; + uint32_t val; + uint8_t parity; + uint8_t computedParity; + + uint32_t n; + + const uint8_t constantBits = 0b10000001U; /* Start Bit & Stop Bit & Park Bit is fixed. */ + uint8_t requestByte; /* LSB */ + + + DAP_SPI_Enable(); + + requestByte = constantBits | (((uint8_t)(request & 0xFU)) << 1U) | (ParityEvenUint8(request & 0xFU) << 5U); + /* For 4bit, Parity can be equivalent to 8bit with all 0 high bits */ + + #if (PRINT_SWD_PROTOCOL == 1) + switch (requestByte) + { + case 0xA5U: + printf("IDCODE\r\n"); + break; + case 0xA9U: + printf("W CTRL/STAT\r\n"); + break; + case 0xBDU: + printf("RDBUFF\r\n"); + break; + case 0x8DU: + printf("R CTRL/STAT\r\n"); + break; + case 0x81U: + printf("W ABORT\r\n"); + break; + case 0xB1U: + printf("W SELECT\r\n"); + break; + case 0xBBU: + printf("W APc\r\n"); + break; + case 0x9FU: + printf("R APc\r\n"); + break; + case 0x8BU: + printf("W AP4\r\n"); + break; + case 0xA3U: + printf("W AP0\r\n"); + break; + case 0X87U: + printf("R AP0\r\n"); + break; + case 0xB7U: + printf("R AP8\r\n"); + break; + default: + //W AP8 + printf("Unknown:%08x\r\n", requestByte); + break; + } + #endif + + if (request & DAP_TRANSFER_RnW) { + /* Read data */ + + DAP_SPI_Send_Header(requestByte, &ack, 0); // 0 Trn After ACK + if (ack == DAP_TRANSFER_OK) { + DAP_SPI_Read_Data(&val, &parity); + computedParity = ParityEvenUint32(val); + + if ((computedParity ^ parity) & 1U) { + ack = DAP_TRANSFER_ERROR; + } + if (data) { *data = val; } + + /* Capture Timestamp */ + if (request & DAP_TRANSFER_TIMESTAMP) { + DAP_Data.timestamp = TIMESTAMP_GET(); + } + + } + else if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { + DAP_SPI_Generate_Cycle(1); + #if (PRINT_SWD_PROTOCOL == 1) + printf("WAIT\r\n"); + #endif + + // return DAP_TRANSFER_WAIT; + } + else { + /* Protocol error */ + DAP_SPI_Disable(); + PIN_SWDIO_TMS_SET(); + + DAP_SPI_Enable(); + DAP_SPI_Protocol_Error_Read(); + + DAP_SPI_Disable(); + PIN_SWDIO_TMS_SET(); + #if (PRINT_SWD_PROTOCOL == 1) + printf("Protocol Error: Read\r\n"); + #endif + } + + return ((uint8_t)ack); + } + else { + /* Write data */ + parity = ParityEvenUint32(*data); + DAP_SPI_Send_Header(requestByte, &ack, 1); // 1 Trn After ACK + if (ack == DAP_TRANSFER_OK) { + DAP_SPI_Write_Data(*data, parity); + /* Capture Timestamp */ + if (request & DAP_TRANSFER_TIMESTAMP) { + DAP_Data.timestamp = TIMESTAMP_GET(); + } + /* Idle cycles */ + n = DAP_Data.transfer.idle_cycles; + if (n) { DAP_SPI_Generate_Cycle(n); } + + DAP_SPI_Disable(); + PIN_SWDIO_TMS_SET(); + + return ((uint8_t)ack); + } + else if ((ack == DAP_TRANSFER_WAIT) || (ack == DAP_TRANSFER_FAULT)) { + /* already turnaround. */ + + /* TODO: overrun transfer -> for read */ + #if (PRINT_SWD_PROTOCOL == 1) + printf("WAIT\r\n"); + #endif + + } + else { + /* Protocol error */ + DAP_SPI_Disable(); + PIN_SWDIO_TMS_SET(); + + DAP_SPI_Enable(); + DAP_SPI_Protocol_Error_Write(); + + DAP_SPI_Disable(); + PIN_SWDIO_TMS_SET(); + + #if (PRINT_SWD_PROTOCOL == 1) + printf("Protocol Error: Write\r\n"); + #endif + } + + return ((uint8_t)ack); + + } + + return DAP_TRANSFER_ERROR; +} + + + +static uint8_t SWD_Transfer_GPIO (uint32_t request, uint32_t *data, uint8_t need_delay) { + 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); +} + + +// 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) { + switch (SWD_TransferSpeed) { + case kTransfer_SPI: + return SWD_Transfer_SPI(request, data); + case kTransfer_GPIO_fast: + return SWD_Transfer_GPIO(request, data, 0); + case kTransfer_GPIO_normal: + return SWD_Transfer_GPIO(request, data, 1); + default: + return SWD_Transfer_GPIO(request, data, 1); + } +} + + +#endif /* (DAP_SWD != 0) */ diff --git a/components/DAP/source/dap_utility.c b/components/DAP/source/dap_utility.c index 94c0381..2a4be5a 100644 --- a/components/DAP/source/dap_utility.c +++ b/components/DAP/source/dap_utility.c @@ -1,6 +1,6 @@ -#include "dap_utility.h" +#include "components/DAP/include/dap_utility.h" -const uint8_t kParityByteTable[256] = +const uint8_t kParityByteTable[256] = { #define P2(n) n, n^1, n^1, n #define P4(n) P2(n), P2(n^1), P2(n^1), P2(n) diff --git a/components/DAP/source/spi_op.c b/components/DAP/source/spi_op.c index bf36c14..a3c0d5d 100644 --- a/components/DAP/source/spi_op.c +++ b/components/DAP/source/spi_op.c @@ -14,10 +14,13 @@ #include #include +#include "main/dap_configuration.h" + +#include "components/DAP/include/cmsis_compiler.h" +#include "components/DAP/include/spi_op.h" + #include "esp8266/spi_struct.h" -#include "cmsis_compiler.h" -#include "spi_op.h" -#include "dap_configuration.h" + #define DAP_SPI SPI1 diff --git a/components/DAP/source/spi_switch.c b/components/DAP/source/spi_switch.c index 418faaf..36d1d96 100644 --- a/components/DAP/source/spi_switch.c +++ b/components/DAP/source/spi_switch.c @@ -12,14 +12,13 @@ */ #include +#include "components/DAP/include/cmsis_compiler.h" +#include "components/DAP/include/spi_switch.h" + #include "esp8266/spi_struct.h" #include "esp8266/pin_mux_register.h" #include "esp8266/gpio_struct.h" -#include "cmsis_compiler.h" -#include "spi_switch.h" -#include "dap_configuration.h" - #define DAP_SPI SPI1 diff --git a/components/DAP/source/uart_modify.c b/components/DAP/source/uart_modify.c index df5ad3a..d9ce6ce 100644 --- a/components/DAP/source/uart_modify.c +++ b/components/DAP/source/uart_modify.c @@ -19,6 +19,11 @@ #include #include + +#include "components/DAP/config/DAP_config.h" +#include "components/DAP/include/uart_modify.h" +#include "components/DAP/include/swo.h" + #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" @@ -26,12 +31,9 @@ #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" @@ -39,9 +41,6 @@ #include "esp8266/rom_functions.h" #include "rom/ets_sys.h" - -#include "uart_modify.h" -#include "swo.h" #include "driver/uart_select.h" #define portYIELD_FROM_ISR() taskYIELD() diff --git a/components/USBIP/CMakeLists.txt b/components/USBIP/CMakeLists.txt index 3aeba6c..ce9a251 100644 --- a/components/USBIP/CMakeLists.txt +++ b/components/USBIP/CMakeLists.txt @@ -1,4 +1,4 @@ set(COMPONENT_ADD_INCLUDEDIRS ". ../../main") -set(COMPONENT_SRCS "MSOS20Descriptors.c USB_handle.c USBd_config.c") +set(COMPONENT_SRCS "MSOS20_descriptor.c usb_handle.c usb_descriptor.c") register_component() \ No newline at end of file diff --git a/components/USBIP/MSOS20Descriptors.c b/components/USBIP/MSOS20_descriptor.c similarity index 96% rename from components/USBIP/MSOS20Descriptors.c rename to components/USBIP/MSOS20_descriptor.c index 18dcd40..e18f5f3 100644 --- a/components/USBIP/MSOS20Descriptors.c +++ b/components/USBIP/MSOS20_descriptor.c @@ -1,111 +1,112 @@ -/** - * @file MSOS20Descriptors.c - * @author windowsair - * @brief Store related data of Microsoft OS 2.0 descriptor - * @change: 2021-5-12 Add support for USB 3.0 - * @version 0.2 - * @date 2021-5-12 - * - * @copyright Copyright (c) 2021 - * - */ - - ////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] = -{ - // USB 3.0 Specification, Table 9-9. - 0x05, // bLength of this descriptor - USB_DESCRIPTOR_TYPE_BOS, // BOS Descriptor type(Constant) - USBShort(kLengthOfBos), // wLength - - -#if (USE_USB_3_0 == 1) - 0x03, // bNumDeviceCaps -> USB2.0 extension & SuperSpeed USB Device & OS2.0 descriptor -#else - 0x01, // bNumDeviceCaps -> only 0x01 for OS2.0 descriptor -#endif // USE_USB_3_0 == 1 - -#if (USE_USB_3_0 == 1) - // USB 2.0 extension, USB 3.0 Specification, Table 9-12. - 0x07, // bLength of this descriptor - USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY, // DEVICE CAPABILITY Descriptor type - USB_DEVICE_CAPABILITY_TYPE_USB2_0_EXTENSION, // Capability type: USB 2.0 EXTENSION - 0x02, 0x00, 0x00, 0x00, // bmAttributes -> LPM Support - - // SuperSpeed USB Device, USB 3.0 Specification, Table 9-13. - 0x0A, // bLength of this descriptor - USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY, // DEVICE CAPABILITY Descriptor type - USB_DEVICE_CAPABILITY_TYPE_SUPERSPEED_USB, // Capability type: SUPERSPEED_USB - 0x00, // bmAttributes -> LTM Capable - 0x08, 0x00, // wSpeedsSupported -> only support SuperSpeed - 0x03, // bFunctionalitySupport - 0x00, // bU1DevExitLat -> 0 may be ok - 0x00, 0x00, // wU2DevExitLat -> 0 may be ok -#endif // USE_USB_3_0 == 1 - - - - // Microsoft OS 2.0 platform capability descriptor header (Table 4) - // See also: - // USB 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 USB 3.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 MSOS20_descriptor.c + * @author windowsair + * @brief Store related data of Microsoft OS 2.0 descriptor + * @change: 2021-5-12 Add support for USB 3.0 + * @version 0.2 + * @date 2021-5-12 + * + * @copyright Copyright (c) 2021 + * + */ + + ////TODO: refactoring into structure + +#include + +#include "components/USBIP/MSOS20_descriptor.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] = +{ + // USB 3.0 Specification, Table 9-9. + 0x05, // bLength of this descriptor + USB_DESCRIPTOR_TYPE_BOS, // BOS Descriptor type(Constant) + USBShort(kLengthOfBos), // wLength + + +#if (USE_USB_3_0 == 1) + 0x03, // bNumDeviceCaps -> USB2.0 extension & SuperSpeed USB Device & OS2.0 descriptor +#else + 0x01, // bNumDeviceCaps -> only 0x01 for OS2.0 descriptor +#endif // USE_USB_3_0 == 1 + +#if (USE_USB_3_0 == 1) + // USB 2.0 extension, USB 3.0 Specification, Table 9-12. + 0x07, // bLength of this descriptor + USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY, // DEVICE CAPABILITY Descriptor type + USB_DEVICE_CAPABILITY_TYPE_USB2_0_EXTENSION, // Capability type: USB 2.0 EXTENSION + 0x02, 0x00, 0x00, 0x00, // bmAttributes -> LPM Support + + // SuperSpeed USB Device, USB 3.0 Specification, Table 9-13. + 0x0A, // bLength of this descriptor + USB_DESCRIPTOR_TYPE_DEVICE_CAPABILITY, // DEVICE CAPABILITY Descriptor type + USB_DEVICE_CAPABILITY_TYPE_SUPERSPEED_USB, // Capability type: SUPERSPEED_USB + 0x00, // bmAttributes -> LTM Capable + 0x08, 0x00, // wSpeedsSupported -> only support SuperSpeed + 0x03, // bFunctionalitySupport + 0x00, // bU1DevExitLat -> 0 may be ok + 0x00, 0x00, // wU2DevExitLat -> 0 may be ok +#endif // USE_USB_3_0 == 1 + + + + // Microsoft OS 2.0 platform capability descriptor header (Table 4) + // See also: + // USB 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 USB 3.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/MSOS20_descriptor.h similarity index 92% rename from components/USBIP/MSOS20Descriptors.h rename to components/USBIP/MSOS20_descriptor.h index 1f2b4e2..4520249 100644 --- a/components/USBIP/MSOS20Descriptors.h +++ b/components/USBIP/MSOS20_descriptor.h @@ -1,94 +1,93 @@ -/** - * @file MSOS20Descriptors.h - * @author windowsair - * @brief - * @version 0.2 - * @date 2021-5-12 - * - * @copyright Copyright (c) 2021 - * - */ - -#ifndef __MSOS20DESCRIPTORS_H__ -#define __MSOS20DESCRIPTORS_H__ - -#include "dap_configuration.h" - -#define kLengthOfMsOS20 0xA2 - -#if (USE_USB_3_0 == 1) -#define kLengthOfBos 0x32 -#else -#define kLengthOfBos 0x21 -#endif // USE_USB_3_0 == 1 - -#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 - -// USB 2.0 Extension Descriptor, USB3.0 Specification Table 9-11 -#define USB_DEVICE_CAPABILITY_TYPE_USB2_0_EXTENSION 2 -// SuperSpeed USB specific device level capabilities, USB3.0 Specification Table 9-11 -#define USB_DEVICE_CAPABILITY_TYPE_SUPERSPEED_USB 3 - -// 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 MSOS20_descriptor.h + * @author windowsair + * @brief + * @version 0.2 + * @date 2021-5-12 + * + * @copyright Copyright (c) 2021 + * + */ + +#ifndef __MSOS20_DESCRIPTOR_H__ +#define __MSOS20_DESCRIPTOR_H__ + + +#define kLengthOfMsOS20 0xA2 + +#if (USE_USB_3_0 == 1) +#define kLengthOfBos 0x32 +#else +#define kLengthOfBos 0x21 +#endif // USE_USB_3_0 == 1 + +#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 + +// USB 2.0 Extension Descriptor, USB3.0 Specification Table 9-11 +#define USB_DEVICE_CAPABILITY_TYPE_USB2_0_EXTENSION 2 +// SuperSpeed USB specific device level capabilities, USB3.0 Specification Table 9-11 +#define USB_DEVICE_CAPABILITY_TYPE_SUPERSPEED_USB 3 + +// 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/USBd_config.c b/components/USBIP/usb_descriptor.c similarity index 99% rename from components/USBIP/USBd_config.c rename to components/USBIP/usb_descriptor.c index 6d3d10f..12752c4 100644 --- a/components/USBIP/USBd_config.c +++ b/components/USBIP/usb_descriptor.c @@ -1,6 +1,6 @@ ////TODO: refactoring into structure /** - * @file USBd_config.c + * @file usb_descriptor.c * @brief Standard USB Descriptor Definitions * @change: 2020-1-23 : fix bugs * 2021-5-12 : Add support for USB 3.0 @@ -11,8 +11,9 @@ */ #include #include -#include "USBd_config.h" -#include "usb_defs.h" + +#include "components/USBIP/usb_descriptor.h" +#include "components/USBIP/usb_defs.h" #define USBShort(ui16Value) ((ui16Value) & 0xff), ((ui16Value) >> 8) diff --git a/components/USBIP/USBd_config.h b/components/USBIP/usb_descriptor.h similarity index 94% rename from components/USBIP/USBd_config.h rename to components/USBIP/usb_descriptor.h index e4d1ca3..8b2a31b 100644 --- a/components/USBIP/USBd_config.h +++ b/components/USBIP/usb_descriptor.h @@ -1,7 +1,7 @@ -#ifndef __USBD_CONFIG_H__ -#define __USBD_CONFIG_H__ +#ifndef __USB_DESCRIPTOR_H__ +#define __USB_DESCRIPTOR_H__ -#include "dap_configuration.h" +#include "main/dap_configuration.h" // Vendor ID assigned by USB-IF (idVendor). #define USBD0_DEV_DESC_IDVENDOR 0xC251 diff --git a/components/USBIP/USB_handle.c b/components/USBIP/usb_handle.c similarity index 98% rename from components/USBIP/USB_handle.c rename to components/USBIP/usb_handle.c index e806f1e..496d8e8 100644 --- a/components/USBIP/USB_handle.c +++ b/components/USBIP/usb_handle.c @@ -3,21 +3,23 @@ * @brief Handle all Standard Device Requests on endpoint 0 * @version 0.1 * @date 2020-01-23 - * + * * @copyright Copyright (c) 2020 - * + * */ #include #include + +#include "main/usbip_server.h" + +#include "components/USBIP/usb_handle.h" +#include "components/USBIP/usb_descriptor.h" +#include "components/USBIP/MSOS20_descriptor.h" + #include "lwip/err.h" #include "lwip/sockets.h" #include "lwip/sys.h" #include -#include "USB_handle.h" -#include "USBd_config.h" -#include "usbip_server.h" -#include "usb_defs.h" -#include "MSOS20Descriptors.h" const char *strings_list[] = { @@ -263,7 +265,7 @@ static void handleGetDescriptor(usbip_stage2_header *header) 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); } diff --git a/components/USBIP/USB_handle.h b/components/USBIP/usb_handle.h similarity index 69% rename from components/USBIP/USB_handle.h rename to components/USBIP/usb_handle.h index ac4eeec..f61edf5 100644 --- a/components/USBIP/USB_handle.h +++ b/components/USBIP/usb_handle.h @@ -1,7 +1,8 @@ #ifndef __USB_HANDLE_H__ #define __USB_HANDLE_H__ -#include "usbip_defs.h" +#include "components/USBIP/usbip_defs.h" + void handleUSBControlRequest(usbip_stage2_header *header); #endif \ No newline at end of file diff --git a/components/USBIP/usbip_defs.h b/components/USBIP/usbip_defs.h index d36d16e..84112a7 100644 --- a/components/USBIP/usbip_defs.h +++ b/components/USBIP/usbip_defs.h @@ -3,9 +3,9 @@ * @brief Simple modification * @version 0.1 * @date 2020-01-22 - * + * * @copyright Copyright (c) 2020 - * + * */ // Focus on the following structures in this file: @@ -20,7 +20,8 @@ #define __USBIP_DEFS_H__ #include -#include "usb_defs.h" + +#include "components/USBIP/usb_defs.h" #define USBIP_SYSFS_PATH_SIZE 256 #define USBIP_BUSID_SIZE 32 @@ -33,7 +34,7 @@ enum usbip_stage1_command }; enum usbip_stager2_command -{ +{ //Offset 0 USBIP_STAGE2_REQ_SUBMIT = 0x0001, USBIP_STAGE2_REQ_UNLINK = 0x0002, @@ -106,7 +107,7 @@ typedef struct /** * 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 @@ -127,7 +128,7 @@ typedef struct /** * 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 @@ -154,7 +155,7 @@ typedef struct /** * struct usbip_header_ret_submit - USBIP_RET_SUBMIT packet header * << -#include - -#include "usbip_server.h" -#include "DAP_handle.h" -#include "DAP.h" -#include "esp_libc.h" -#include "USBd_config.h" -#include "swo.h" -#include "dap_configuration.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 - -#if (USE_WINUSB == 1) -typedef struct -{ - uint32_t length; - uint8_t buf[DAP_PACKET_SIZE]; -} DapPacket_t; -#else -typedef struct -{ - uint8_t buf[DAP_PACKET_SIZE]; -} DapPacket_t; -#endif - -#define DAP_HANDLE_SIZE (sizeof(DapPacket_t)) - - -extern int kSock; -extern TaskHandle_t kDAPTaskHandle; - -int kRestartDAPHandle = 0; - - -static DapPacket_t DAPDataProcessed; -static int dap_respond = 0; - -// SWO Trace -static uint8_t *swo_data_to_send = NULL; -static uint32_t swo_data_num; - -// DAP handle -static RingbufHandle_t dap_dataIN_handle = NULL; -static RingbufHandle_t dap_dataOUT_handle = NULL; -static SemaphoreHandle_t data_response_mux = NULL; - - -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) - send_stage2_submit(header, 0, 0); - - // always send constant size buf -> cuz we don't care about the IN packet size - // and to unify the style, we set aside the length of the section - xRingbufferSend(dap_dataIN_handle, data_in - sizeof(uint32_t), DAP_HANDLE_SIZE, portMAX_DELAY); - xTaskNotifyGive(kDAPTaskHandle); - -#else - send_stage2_submit(header, 0, 0); - - xRingbufferSend(dap_dataIN_handle, data_in, DAP_HANDLE_SIZE, portMAX_DELAY); - xTaskNotifyGive(kDAPTaskHandle); - -#endif - - // dap_respond = DAP_ProcessCommand((uint8_t *)data_in, (uint8_t *)data_out); - // //handle_dap_data_response(header); - // send_stage2_submit(header, 0, 0); -} - -void handle_dap_data_response(usbip_stage2_header *header) -{ - return; - // int resLength = dap_respond & 0xFFFF; - // if (resLength) - // { - - // send_stage2_submit_data(header, 0, (void *)DAPDataProcessed.buf, resLength); - // dap_respond = 0; - // } - // else - // { - // send_stage2_submit(header, 0, 0); - // } -} - -void handle_swo_trace_response(usbip_stage2_header *header) -{ -#if (SWO_FUNCTION_ENABLE == 1) - if (kSwoTransferBusy) - { - // busy indicates that there is data to be send - printf("swo use data\r\n"); - send_stage2_submit_data(header, 0, (void *)swo_data_to_send, swo_data_num); - SWO_TransferComplete(); - } - else - { - // nothing to send. - send_stage2_submit(header, 0, 0); - } -#else - send_stage2_submit(header, 0, 0); -#endif -} - -// 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; - swo_data_num = num; -} - -void DAP_Thread(void *argument) -{ - dap_dataIN_handle = xRingbufferCreate(DAP_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF); - dap_dataOUT_handle = xRingbufferCreate(DAP_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF); - data_response_mux = xSemaphoreCreateMutex(); - size_t packetSize; - int resLength; - DapPacket_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) - { - if (kRestartDAPHandle) - { - vRingbufferDelete(dap_dataIN_handle); - vRingbufferDelete(dap_dataOUT_handle); - dap_dataIN_handle = dap_dataOUT_handle = NULL; - - dap_dataIN_handle = xRingbufferCreate(DAP_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF); - dap_dataOUT_handle = xRingbufferCreate(DAP_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF); - if (dap_dataIN_handle == NULL || dap_dataIN_handle == NULL) - { - os_printf("Can not create DAP ringbuf/mux!\r\n"); - vTaskDelete(NULL); - } - kRestartDAPHandle = 0; - } - - ulTaskNotifyTake(pdFALSE, portMAX_DELAY); - packetSize = 0; - item = (DapPacket_t *)xRingbufferReceiveUpTo(dap_dataIN_handle, &packetSize, - pdMS_TO_TICKS(1), DAP_HANDLE_SIZE); - if (packetSize == 0) - { - break; - } - - else if (packetSize < DAP_HANDLE_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->buf[0] == ID_DAP_QueueCommands) - { - item->buf[0] = ID_DAP_ExecuteCommands; - } - - resLength = DAP_ProcessCommand((uint8_t *)item->buf, (uint8_t *)DAPDataProcessed.buf); // use first 4 byte to save length - resLength &= 0xFFFF; // res length in lower 16 bits - - vRingbufferReturnItem(dap_dataIN_handle, (void *)item); // process done. - - // now prepare to reply -#if (USE_WINUSB == 1) - DAPDataProcessed.length = resLength; -#endif - xRingbufferSend(dap_dataOUT_handle, (void *)&DAPDataProcessed, DAP_HANDLE_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) -{ - usbip_stage2_header *buf_header = (usbip_stage2_header *)buf; - if (length == 48 && - buf_header->base.command == PP_HTONL(USBIP_STAGE2_REQ_SUBMIT) && - buf_header->base.direction == PP_HTONL(USBIP_DIR_IN) && - buf_header->base.ep == PP_HTONL(1)) - { - if (dap_respond > 0) - { - DapPacket_t *item; - size_t packetSize = 0; - item = (DapPacket_t *)xRingbufferReceiveUpTo(dap_dataOUT_handle, &packetSize, - pdMS_TO_TICKS(10), DAP_HANDLE_SIZE); - if (packetSize == DAP_HANDLE_SIZE) - { -#if (USE_WINUSB == 1) - send_stage2_submit_data_fast((usbip_stage2_header *)buf, item->buf, item->length); -#else - send_stage2_submit_data_fast((usbip_stage2_header *)buf, item->buf, DAP_HANDLE_SIZE); -#endif - - 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_header->base.command = PP_HTONL(USBIP_STAGE2_RSP_SUBMIT); - buf_header->base.direction = PP_HTONL(USBIP_DIR_OUT); - buf_header->u.ret_submit.status = 0; - buf_header->u.ret_submit.data_length = 0; - buf_header->u.ret_submit.error_count = 0; - send(kSock, buf, 48, 0); - return 1; - } - } - return 0; -} +/** + * @file DAP_handle.c + * @brief Handle DAP packets and transaction push + * @version 0.4 + * @change: 2020.02.04 first version + * 2020.11.11 support WinUSB mode + * 2021.02.17 support SWO + * + * @copyright Copyright (c) 2021 + * + */ + +#include +#include + +#include "main/usbip_server.h" +#include "main/DAP_handle.h" +#include "main/dap_configuration.h" + +#include "components/USBIP/usb_descriptor.h" +#include "components/DAP/include/DAP.h" +#include "components/DAP/include/swo.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 + +#if (USE_WINUSB == 1) +typedef struct +{ + uint32_t length; + uint8_t buf[DAP_PACKET_SIZE]; +} DapPacket_t; +#else +typedef struct +{ + uint8_t buf[DAP_PACKET_SIZE]; +} DapPacket_t; +#endif + +#define DAP_HANDLE_SIZE (sizeof(DapPacket_t)) + + +extern int kSock; +extern TaskHandle_t kDAPTaskHandle; + +int kRestartDAPHandle = 0; + + +static DapPacket_t DAPDataProcessed; +static int dap_respond = 0; + +// SWO Trace +static uint8_t *swo_data_to_send = NULL; +static uint32_t swo_data_num; + +// DAP handle +static RingbufHandle_t dap_dataIN_handle = NULL; +static RingbufHandle_t dap_dataOUT_handle = NULL; +static SemaphoreHandle_t data_response_mux = NULL; + + +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) + send_stage2_submit(header, 0, 0); + + // always send constant size buf -> cuz we don't care about the IN packet size + // and to unify the style, we set aside the length of the section + xRingbufferSend(dap_dataIN_handle, data_in - sizeof(uint32_t), DAP_HANDLE_SIZE, portMAX_DELAY); + xTaskNotifyGive(kDAPTaskHandle); + +#else + send_stage2_submit(header, 0, 0); + + xRingbufferSend(dap_dataIN_handle, data_in, DAP_HANDLE_SIZE, portMAX_DELAY); + xTaskNotifyGive(kDAPTaskHandle); + +#endif + + // dap_respond = DAP_ProcessCommand((uint8_t *)data_in, (uint8_t *)data_out); + // //handle_dap_data_response(header); + // send_stage2_submit(header, 0, 0); +} + +void handle_dap_data_response(usbip_stage2_header *header) +{ + return; + // int resLength = dap_respond & 0xFFFF; + // if (resLength) + // { + + // send_stage2_submit_data(header, 0, (void *)DAPDataProcessed.buf, resLength); + // dap_respond = 0; + // } + // else + // { + // send_stage2_submit(header, 0, 0); + // } +} + +void handle_swo_trace_response(usbip_stage2_header *header) +{ +#if (SWO_FUNCTION_ENABLE == 1) + if (kSwoTransferBusy) + { + // busy indicates that there is data to be send + printf("swo use data\r\n"); + send_stage2_submit_data(header, 0, (void *)swo_data_to_send, swo_data_num); + SWO_TransferComplete(); + } + else + { + // nothing to send. + send_stage2_submit(header, 0, 0); + } +#else + send_stage2_submit(header, 0, 0); +#endif +} + +// 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; + swo_data_num = num; +} + +void DAP_Thread(void *argument) +{ + dap_dataIN_handle = xRingbufferCreate(DAP_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF); + dap_dataOUT_handle = xRingbufferCreate(DAP_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF); + data_response_mux = xSemaphoreCreateMutex(); + size_t packetSize; + int resLength; + DapPacket_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) + { + if (kRestartDAPHandle) + { + vRingbufferDelete(dap_dataIN_handle); + vRingbufferDelete(dap_dataOUT_handle); + dap_dataIN_handle = dap_dataOUT_handle = NULL; + + dap_dataIN_handle = xRingbufferCreate(DAP_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF); + dap_dataOUT_handle = xRingbufferCreate(DAP_HANDLE_SIZE * 20, RINGBUF_TYPE_BYTEBUF); + if (dap_dataIN_handle == NULL || dap_dataIN_handle == NULL) + { + os_printf("Can not create DAP ringbuf/mux!\r\n"); + vTaskDelete(NULL); + } + kRestartDAPHandle = 0; + } + + ulTaskNotifyTake(pdFALSE, portMAX_DELAY); + packetSize = 0; + item = (DapPacket_t *)xRingbufferReceiveUpTo(dap_dataIN_handle, &packetSize, + pdMS_TO_TICKS(1), DAP_HANDLE_SIZE); + if (packetSize == 0) + { + break; + } + + else if (packetSize < DAP_HANDLE_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->buf[0] == ID_DAP_QueueCommands) + { + item->buf[0] = ID_DAP_ExecuteCommands; + } + + resLength = DAP_ProcessCommand((uint8_t *)item->buf, (uint8_t *)DAPDataProcessed.buf); // use first 4 byte to save length + resLength &= 0xFFFF; // res length in lower 16 bits + + vRingbufferReturnItem(dap_dataIN_handle, (void *)item); // process done. + + // now prepare to reply +#if (USE_WINUSB == 1) + DAPDataProcessed.length = resLength; +#endif + xRingbufferSend(dap_dataOUT_handle, (void *)&DAPDataProcessed, DAP_HANDLE_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) +{ + usbip_stage2_header *buf_header = (usbip_stage2_header *)buf; + if (length == 48 && + buf_header->base.command == PP_HTONL(USBIP_STAGE2_REQ_SUBMIT) && + buf_header->base.direction == PP_HTONL(USBIP_DIR_IN) && + buf_header->base.ep == PP_HTONL(1)) + { + if (dap_respond > 0) + { + DapPacket_t *item; + size_t packetSize = 0; + item = (DapPacket_t *)xRingbufferReceiveUpTo(dap_dataOUT_handle, &packetSize, + pdMS_TO_TICKS(10), DAP_HANDLE_SIZE); + if (packetSize == DAP_HANDLE_SIZE) + { +#if (USE_WINUSB == 1) + send_stage2_submit_data_fast((usbip_stage2_header *)buf, item->buf, item->length); +#else + send_stage2_submit_data_fast((usbip_stage2_header *)buf, item->buf, DAP_HANDLE_SIZE); +#endif + + 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_header->base.command = PP_HTONL(USBIP_STAGE2_RSP_SUBMIT); + buf_header->base.direction = PP_HTONL(USBIP_DIR_OUT); + buf_header->u.ret_submit.status = 0; + buf_header->u.ret_submit.data_length = 0; + buf_header->u.ret_submit.error_count = 0; + send(kSock, buf, 48, 0); + return 1; + } + } + return 0; +} diff --git a/main/DAP_handle.h b/main/DAP_handle.h index 2d71be2..bce40ca 100644 --- a/main/DAP_handle.h +++ b/main/DAP_handle.h @@ -1,7 +1,7 @@ #ifndef __DAP_HANDLE_H__ #define __DAP_HANDLE_H__ -#include "usbip_defs.h" +#include "components/USBIP/usbip_defs.h" void handle_dap_data_request(usbip_stage2_header *header, uint32_t length); void handle_dap_data_response(usbip_stage2_header *header); diff --git a/main/main.c b/main/main.c index de1b1fa..597cd52 100644 --- a/main/main.c +++ b/main/main.c @@ -1,181 +1,181 @@ -/* BSD Socket API Example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ -#include -#include -#include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" -#include "esp_system.h" -#include "esp_wifi.h" -#include "esp_event_loop.h" -#include "esp_log.h" -#include "nvs_flash.h" - -#include "lwip/err.h" -#include "lwip/sockets.h" -#include "lwip/sys.h" -#include - -#include "tcp_server.h" -#include "timer.h" -#include "wifi_configuration.h" -#include "DAP_config.h" - - -extern void DAP_Setup(void); -extern void DAP_Thread(void *argument); -extern void SWO_Thread(); - -TaskHandle_t kDAPTaskHandle = NULL; - - - -/* FreeRTOS event group to signal when we are connected & ready to make a request */ -static EventGroupHandle_t wifi_event_group; - -const int IPV4_GOTIP_BIT = BIT0; -#ifdef CONFIG_EXAMPLE_IPV6 -const int IPV6_GOTIP_BIT = BIT1; -#endif - - -static esp_err_t event_handler(void *ctx, system_event_t *event) -{ - /* For accessing reason codes in case of disconnection */ - system_event_info_t *info = &event->event_info; - - switch (event->event_id) - { - case SYSTEM_EVENT_STA_START: - esp_wifi_connect(); - os_printf("SYSTEM_EVENT_STA_START\r\n"); - break; - case SYSTEM_EVENT_STA_CONNECTED: -#ifdef CONFIG_EXAMPLE_IPV6 - /* enable ipv6 */ - tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA); -#endif - break; - case SYSTEM_EVENT_STA_GOT_IP: - xEventGroupSetBits(wifi_event_group, IPV4_GOTIP_BIT); - os_printf("SYSTEM EVENT STA GOT IP : %s\r\n", ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); - break; - case SYSTEM_EVENT_STA_DISCONNECTED: - os_printf("Disconnect reason : %d\r\n", info->disconnected.reason); - if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) - { - /*Switch to 802.11 bgn mode */ - esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); - } - esp_wifi_connect(); - xEventGroupClearBits(wifi_event_group, IPV4_GOTIP_BIT); -#ifdef CONFIG_EXAMPLE_IPV6 - xEventGroupClearBits(wifi_event_group, IPV6_GOTIP_BIT); -#endif - break; - case SYSTEM_EVENT_AP_STA_GOT_IP6: -#ifdef CONFIG_EXAMPLE_IPV6 - xEventGroupSetBits(wifi_event_group, IPV6_GOTIP_BIT); - os_printf("SYSTEM_EVENT_STA_GOT_IP6\r\n"); - - char *ip6 = ip6addr_ntoa(&event->event_info.got_ip6.ip6_info.ip); - os_printf("IPv6: %s\r\n", ip6); -#endif - default: - break; - } - return ESP_OK; -} - -static void initialise_wifi(void) -{ - tcpip_adapter_init(); - -#if (USE_STATIC_IP == 1) - tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_STA); - - tcpip_adapter_ip_info_t ip_info; - -#define MY_IP4_ADDR(...) IP4_ADDR(__VA_ARGS__) - MY_IP4_ADDR(&ip_info.ip, DAP_IP_ADDRESS); - MY_IP4_ADDR(&ip_info.gw, DAP_IP_GATEWAY); - MY_IP4_ADDR(&ip_info.netmask, DAP_IP_NETMASK); -#undef MY_IP4_ADDR - - tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info); -#endif // (USE_STATIC_IP == 1) - - - wifi_event_group = xEventGroupCreate(); - - ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - wifi_config_t wifi_config = { - .sta = { - .ssid = WIFI_SSID, - .password = WIFI_PASS, - }, - }; - os_printf("Setting WiFi configuration SSID %s...\r\n", wifi_config.sta.ssid); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); -} - -static void wait_for_ip() -{ -#ifdef CONFIG_EXAMPLE_IPV6 - uint32_t bits = IPV4_GOTIP_BIT | IPV6_GOTIP_BIT; -#else - uint32_t bits = IPV4_GOTIP_BIT; -#endif - - os_printf("Waiting for AP connection...\r\n"); - xEventGroupWaitBits(wifi_event_group, bits, false, true, portMAX_DELAY); - os_printf("Connected to AP\r\n"); -} - - -void app_main() -{ - // struct rst_info *rtc_info = system_get_rst_info(); - - // os_printf("reset reason: %x\n", rtc_info->reason); - - // if (rtc_info->reason == REASON_WDT_RST || - // rtc_info->reason == REASON_EXCEPTION_RST || - // rtc_info->reason == REASON_SOFT_WDT_RST) - // { - // if (rtc_info->reason == REASON_EXCEPTION_RST) - // { - // os_printf("Fatal exception (%d):\n", rtc_info->exccause); - // } - // os_printf("epc1=0x%08x, epc2=0x%08x, epc3=0x%08x,excvaddr=0x%08x, depc=0x%08x\n", - // rtc_info->epc1, rtc_info->epc2, rtc_info->epc3, - // rtc_info->excvaddr, rtc_info->depc); - // } - - ESP_ERROR_CHECK(nvs_flash_init()); - initialise_wifi(); - wait_for_ip(); - DAP_Setup(); - timer_init(); - - - xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 14, NULL); - xTaskCreate(DAP_Thread, "DAP_Task", 2048, NULL, 10, &kDAPTaskHandle); - // SWO Trace Task - #if (SWO_FUNCTION_ENABLE == 1) - xTaskCreate(SWO_Thread, "SWO_Task", 512, NULL, 10, NULL); - #endif - // It seems that the task is overly stressful... -} +/* BSD Socket API Example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#include +#include +#include + +#include "main/tcp_server.h" +#include "main/timer.h" +#include "main/wifi_configuration.h" + +#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 + + +extern void DAP_Setup(void); +extern void DAP_Thread(void *argument); +extern void SWO_Thread(); + +TaskHandle_t kDAPTaskHandle = NULL; + + + +/* FreeRTOS event group to signal when we are connected & ready to make a request */ +static EventGroupHandle_t wifi_event_group; + +const int IPV4_GOTIP_BIT = BIT0; +#ifdef CONFIG_EXAMPLE_IPV6 +const int IPV6_GOTIP_BIT = BIT1; +#endif + + +static esp_err_t event_handler(void *ctx, system_event_t *event) +{ + /* For accessing reason codes in case of disconnection */ + system_event_info_t *info = &event->event_info; + + switch (event->event_id) + { + case SYSTEM_EVENT_STA_START: + esp_wifi_connect(); + os_printf("SYSTEM_EVENT_STA_START\r\n"); + break; + case SYSTEM_EVENT_STA_CONNECTED: +#ifdef CONFIG_EXAMPLE_IPV6 + /* enable ipv6 */ + tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA); +#endif + break; + case SYSTEM_EVENT_STA_GOT_IP: + xEventGroupSetBits(wifi_event_group, IPV4_GOTIP_BIT); + os_printf("SYSTEM EVENT STA GOT IP : %s\r\n", ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); + break; + case SYSTEM_EVENT_STA_DISCONNECTED: + os_printf("Disconnect reason : %d\r\n", info->disconnected.reason); + if (info->disconnected.reason == WIFI_REASON_BASIC_RATE_NOT_SUPPORT) + { + /*Switch to 802.11 bgn mode */ + esp_wifi_set_protocol(ESP_IF_WIFI_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N); + } + esp_wifi_connect(); + xEventGroupClearBits(wifi_event_group, IPV4_GOTIP_BIT); +#ifdef CONFIG_EXAMPLE_IPV6 + xEventGroupClearBits(wifi_event_group, IPV6_GOTIP_BIT); +#endif + break; + case SYSTEM_EVENT_AP_STA_GOT_IP6: +#ifdef CONFIG_EXAMPLE_IPV6 + xEventGroupSetBits(wifi_event_group, IPV6_GOTIP_BIT); + os_printf("SYSTEM_EVENT_STA_GOT_IP6\r\n"); + + char *ip6 = ip6addr_ntoa(&event->event_info.got_ip6.ip6_info.ip); + os_printf("IPv6: %s\r\n", ip6); +#endif + default: + break; + } + return ESP_OK; +} + +static void initialise_wifi(void) +{ + tcpip_adapter_init(); + +#if (USE_STATIC_IP == 1) + tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_STA); + + tcpip_adapter_ip_info_t ip_info; + +#define MY_IP4_ADDR(...) IP4_ADDR(__VA_ARGS__) + MY_IP4_ADDR(&ip_info.ip, DAP_IP_ADDRESS); + MY_IP4_ADDR(&ip_info.gw, DAP_IP_GATEWAY); + MY_IP4_ADDR(&ip_info.netmask, DAP_IP_NETMASK); +#undef MY_IP4_ADDR + + tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_STA, &ip_info); +#endif // (USE_STATIC_IP == 1) + + + wifi_event_group = xEventGroupCreate(); + + ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL)); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + wifi_config_t wifi_config = { + .sta = { + .ssid = WIFI_SSID, + .password = WIFI_PASS, + }, + }; + os_printf("Setting WiFi configuration SSID %s...\r\n", wifi_config.sta.ssid); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); +} + +static void wait_for_ip() +{ +#ifdef CONFIG_EXAMPLE_IPV6 + uint32_t bits = IPV4_GOTIP_BIT | IPV6_GOTIP_BIT; +#else + uint32_t bits = IPV4_GOTIP_BIT; +#endif + + os_printf("Waiting for AP connection...\r\n"); + xEventGroupWaitBits(wifi_event_group, bits, false, true, portMAX_DELAY); + os_printf("Connected to AP\r\n"); +} + + +void app_main() +{ + // struct rst_info *rtc_info = system_get_rst_info(); + + // os_printf("reset reason: %x\n", rtc_info->reason); + + // if (rtc_info->reason == REASON_WDT_RST || + // rtc_info->reason == REASON_EXCEPTION_RST || + // rtc_info->reason == REASON_SOFT_WDT_RST) + // { + // if (rtc_info->reason == REASON_EXCEPTION_RST) + // { + // os_printf("Fatal exception (%d):\n", rtc_info->exccause); + // } + // os_printf("epc1=0x%08x, epc2=0x%08x, epc3=0x%08x,excvaddr=0x%08x, depc=0x%08x\n", + // rtc_info->epc1, rtc_info->epc2, rtc_info->epc3, + // rtc_info->excvaddr, rtc_info->depc); + // } + + ESP_ERROR_CHECK(nvs_flash_init()); + initialise_wifi(); + wait_for_ip(); + DAP_Setup(); + timer_init(); + + + xTaskCreate(tcp_server_task, "tcp_server", 4096, NULL, 14, NULL); + xTaskCreate(DAP_Thread, "DAP_Task", 2048, NULL, 10, &kDAPTaskHandle); + // SWO Trace Task + #if (SWO_FUNCTION_ENABLE == 1) + xTaskCreate(SWO_Thread, "SWO_Task", 512, NULL, 10, NULL); + #endif + // It seems that the task is overly stressful... +} diff --git a/main/monitor.c b/main/monitor.c index 14a52d8..6ac83be 100644 --- a/main/monitor.c +++ b/main/monitor.c @@ -1,5 +1,6 @@ #include #include + #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_system.h" diff --git a/main/tcp_server.c b/main/tcp_server.c index 3fa4187..2967f08 100644 --- a/main/tcp_server.c +++ b/main/tcp_server.c @@ -1,181 +1,182 @@ -/** - * @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" - -extern TaskHandle_t kDAPTaskHandle; -extern int kRestartDAPHandle; - -uint8_t kState = ACCEPTING; -int kSock = -1; - -void tcp_server_task(void *pvParameters) -{ - uint8_t tcp_rx_buffer[1500]; - char addr_str[128]; - int addr_family; - int ip_protocol; - - int on = 1; - 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\r\n"); - - setsockopt(listen_sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on)); - setsockopt(listen_sock, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(on)); - - 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\r\n"); - - err = listen(listen_sock, 1); - if (err != 0) - { - os_printf("Error occured during listen: errno %d\r\n", errno); - break; - } - os_printf("Socket listening\r\n"); - -#ifdef CONFIG_EXAMPLE_IPV6 - struct sockaddr_in6 sourceAddr; // Large enough for both IPv4 or IPv6 -#else - struct sockaddr_in sourceAddr; -#endif - uint32_t addrLen = sizeof(sourceAddr); - while (1) - { - kSock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen); - if (kSock < 0) - { - os_printf("Unable to accept connection: errno %d\r\n", errno); - break; - } - setsockopt(kSock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on)); - setsockopt(kSock, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(on)); - os_printf("Socket accepted\r\n"); - - while (1) - { - int len = recv(kSock, tcp_rx_buffer, sizeof(tcp_rx_buffer), 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 - - switch (kState) - { - case ACCEPTING: - kState = ATTACHING; - - case ATTACHING: - attach(tcp_rx_buffer, len); - break; - - case EMULATING: - emulate(tcp_rx_buffer, len); - break; - default: - os_printf("unkonw kstate!\r\n"); - } - } - } - // kState = ACCEPTING; - if (kSock != -1) - { - os_printf("Shutting down socket and restarting...\r\n"); - //shutdown(kSock, 0); - close(kSock); - if (kState == EMULATING) - kState = ACCEPTING; - - // Restart DAP Handle - kRestartDAPHandle = 1; - xTaskNotifyGive(kDAPTaskHandle); - - //shutdown(listen_sock, 0); - //close(listen_sock); - //vTaskDelay(5); - } - } - } - vTaskDelete(NULL); +/** + * @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 "main/wifi_configuration.h" +#include "main/usbip_server.h" + +#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 + +extern TaskHandle_t kDAPTaskHandle; +extern int kRestartDAPHandle; + +uint8_t kState = ACCEPTING; +int kSock = -1; + +void tcp_server_task(void *pvParameters) +{ + uint8_t tcp_rx_buffer[1500]; + char addr_str[128]; + int addr_family; + int ip_protocol; + + int on = 1; + 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\r\n"); + + setsockopt(listen_sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on)); + setsockopt(listen_sock, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(on)); + + 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\r\n"); + + err = listen(listen_sock, 1); + if (err != 0) + { + os_printf("Error occured during listen: errno %d\r\n", errno); + break; + } + os_printf("Socket listening\r\n"); + +#ifdef CONFIG_EXAMPLE_IPV6 + struct sockaddr_in6 sourceAddr; // Large enough for both IPv4 or IPv6 +#else + struct sockaddr_in sourceAddr; +#endif + uint32_t addrLen = sizeof(sourceAddr); + while (1) + { + kSock = accept(listen_sock, (struct sockaddr *)&sourceAddr, &addrLen); + if (kSock < 0) + { + os_printf("Unable to accept connection: errno %d\r\n", errno); + break; + } + setsockopt(kSock, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, sizeof(on)); + setsockopt(kSock, IPPROTO_TCP, TCP_NODELAY, (void *)&on, sizeof(on)); + os_printf("Socket accepted\r\n"); + + while (1) + { + int len = recv(kSock, tcp_rx_buffer, sizeof(tcp_rx_buffer), 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 + + switch (kState) + { + case ACCEPTING: + kState = ATTACHING; + + case ATTACHING: + attach(tcp_rx_buffer, len); + break; + + case EMULATING: + emulate(tcp_rx_buffer, len); + break; + default: + os_printf("unkonw kstate!\r\n"); + } + } + } + // kState = ACCEPTING; + if (kSock != -1) + { + os_printf("Shutting down socket and restarting...\r\n"); + //shutdown(kSock, 0); + close(kSock); + if (kState == EMULATING) + kState = ACCEPTING; + + // Restart DAP Handle + kRestartDAPHandle = 1; + xTaskNotifyGive(kDAPTaskHandle); + + //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 index 877ab2a..7f94d11 100644 --- a/main/tcp_server.h +++ b/main/tcp_server.h @@ -3,4 +3,4 @@ void tcp_server_task(void *pvParameters); -#endif \ No newline at end of file +#endif \ No newline at end of file diff --git a/main/timer.c b/main/timer.c index 5682c8f..59de98f 100644 --- a/main/timer.c +++ b/main/timer.c @@ -12,12 +12,9 @@ #include #include -#include "timer.h" +#include "main/timer.h" + #include "hw_timer.h" -#include "timer_struct.h" - -#include "cmsis_compiler.h" - #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/event_groups.h" diff --git a/main/usbip_server.c b/main/usbip_server.c index f0784e9..d0a8ee5 100644 --- a/main/usbip_server.c +++ b/main/usbip_server.c @@ -1,17 +1,17 @@ #include #include + +#include "main/usbip_server.h" +#include "main/DAP_handle.h" + +#include "components/USBIP/usb_handle.h" +#include "components/USBIP/usb_descriptor.h" + #include "lwip/err.h" #include "lwip/sockets.h" #include "lwip/sys.h" #include -#include "usbip_server.h" -#include "usbip_defs.h" -#include "usb_defs.h" -#include "USBd_config.h" -#include "DAP_handle.h" -#include "USB_handle.h" -#include "USBd_config.h" // attach helper function static int read_stage1_command(uint8_t *buffer, uint32_t length); diff --git a/main/usbip_server.h b/main/usbip_server.h index 8d68243..92c17c2 100644 --- a/main/usbip_server.h +++ b/main/usbip_server.h @@ -1,7 +1,9 @@ #ifndef __USBIP_SERVER_H__ #define __USBIP_SERVER_H__ #include -#include "usbip_defs.h" + +#include "components/USBIP/usbip_defs.h" + enum state_t { ACCEPTING,